diff --git a/lib/modules/SSL.pmod/connection.pike b/lib/modules/SSL.pmod/connection.pike
index 8fc0ca26016172ec72d3b10b0c070591ec24edb3..3a698dcfac897dc9f2aabdb23d1be0b7f493f753 100644
--- a/lib/modules/SSL.pmod/connection.pike
+++ b/lib/modules/SSL.pmod/connection.pike
@@ -200,10 +200,10 @@ int send_streaming_data (string data)
   if (!sizeof(data)) return 0;
   Packet packet = Packet();
   packet->content_type = PACKET_application_data;
-  int max_packet_size = current_write_state->session->max_packet_size;
+  int max_packet_size = session->max_packet_size;
   int size;
   if ((!sent) && (version < PROTOCOL_TLS_1_1) &&
-      (current_write_state->session->cipher_spec->cipher_type ==
+      (session->cipher_spec->cipher_type ==
        CIPHER_block)) {
     // Workaround for the BEAST attack.
     // This method is known as the 1/(n-1) split:
diff --git a/lib/modules/SSL.pmod/handshake.pike b/lib/modules/SSL.pmod/handshake.pike
index bd8ae5c92f3a7be2e8da8dc56cb2bf60a2757b1c..7b0b626fc648550f66f2a4c32b2c6ac5bd4f0360 100644
--- a/lib/modules/SSL.pmod/handshake.pike
+++ b/lib/modules/SSL.pmod/handshake.pike
@@ -402,7 +402,7 @@ Packet client_key_exchange_packet()
   }
 
   array(.state) res =
-    session->new_client_states(client_random, server_random, version);
+    session->new_client_states(this, client_random, server_random, version);
   pending_read_state = res[0];
   pending_write_state = res[1];
 
@@ -1159,7 +1159,8 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw)
 
 	  array(.state) res;
 	  mixed err;
-          if( err = catch(res = session->new_server_states(client_random,
+          if( err = catch(res = session->new_server_states(this,
+							   client_random,
 							   server_random,
 							   version)) )
           {
@@ -1309,7 +1310,8 @@ int(-1..1) handle_handshake(int type, string(0..255) data, string(0..255) raw)
 
 	// trace(1);
 	array(.state) res =
-	  session->new_server_states(client_random, server_random, version);
+	  session->new_server_states(this, client_random, server_random,
+				     version);
 	pending_read_state = res[0];
 	pending_write_state = res[1];
 	
diff --git a/lib/modules/SSL.pmod/session.pike b/lib/modules/SSL.pmod/session.pike
index cf995d8ee8d67d06d6a9a138acf83bb886c95c0d..1c8d050aaa9acb8aac7b83acb97d06778d08686b 100644
--- a/lib/modules/SSL.pmod/session.pike
+++ b/lib/modules/SSL.pmod/session.pike
@@ -601,12 +601,13 @@ array(string(0..255)) generate_keys(string(0..255) client_random,
 //!     @elem SSL.state write_state
 //!       Write state
 //!   @endarray
-array(.state) new_server_states(string(0..255) client_random,
+array(.state) new_server_states(object/*(connection)*/ con,
+				string(0..255) client_random,
 				string(0..255) server_random,
 				ProtocolVersion version)
 {
-  .state write_state = .state(this);
-  .state read_state = .state(this);
+  .state write_state = .state(con);
+  .state read_state = .state(con);
   array(string) keys = generate_keys(client_random, server_random, version);
 
   if (cipher_spec->mac_algorithm)
@@ -676,12 +677,13 @@ array(.state) new_server_states(string(0..255) client_random,
 //!     @elem SSL.state write_state
 //!       Write state
 //!   @endarray
-array(.state) new_client_states(string(0..255) client_random,
+array(.state) new_client_states(object/*(connection)*/ con,
+				string(0..255) client_random,
 				string(0..255) server_random,
 				ProtocolVersion version)
 {
-  .state write_state = .state(this);
-  .state read_state = .state(this);
+  .state write_state = .state(con);
+  .state read_state = .state(con);
   array(string) keys = generate_keys(client_random, server_random, version);
   
   if (cipher_spec->mac_algorithm)
diff --git a/lib/modules/SSL.pmod/state.pike b/lib/modules/SSL.pmod/state.pike
index c7f71820a1c635def5036ad13e0836a7eed64281..ba06cd1ebe3f3853715200cafebd929b0b9529e1 100644
--- a/lib/modules/SSL.pmod/state.pike
+++ b/lib/modules/SSL.pmod/state.pike
@@ -9,13 +9,19 @@
 
 import .Constants;
 
-protected void create(object/*(.session)*/ s)
+//!
+constant Alert = .alert;
+
+function(int, int, string|void: Alert) alert;
+
+protected void create(object/*(.connection)*/ con)
 {
-  session = s;
+  connection = con;
+  alert = con->Alert;
 }
 
 //! Information about the used algorithms.
-object/*(.session)*/ session;
+object/*(.connection)*/ connection;
 
 //! Message Authentication Code
 .Cipher.MACAlgorithm mac;
@@ -28,9 +34,6 @@ object compress;
 //! 64-bit sequence number.
 int seq_num = 0;    /* Bignum, values 0, .. 2^64-1 are valid */
 
-//!
-constant Alert = .alert;
-
 //! TLS IV prefix length.
 int tls_iv;
 
@@ -53,21 +56,21 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
    *       function, and attempt to make the same amount of work
    *       even if we have already detected a failure.
    */
-  object(Alert) alert;
+  object(Alert) fail;
 
 #ifdef SSL3_DEBUG_CRYPT
   werror("SSL.state->decrypt_packet (3.%d, type: %d): data = %O\n",
 	 version & 0xff, packet->content_type, packet->fragment);
 #endif
 
-  int hmac_size = session->truncated_hmac ? 10 :
-    session->cipher_spec?->hash_size;
+  int hmac_size = mac && (connection->session->truncated_hmac ? 10 :
+			  connection->session->cipher_spec?->hash_size);
   int padding;
 
   if (crypt)
   {
 #ifdef SSL3_DEBUG_CRYPT
-    werror("SSL.state: Trying decrypt..\n");
+    werror("SSL.state: Trying decrypt...\n");
     //    werror("SSL.state: The encrypted packet is:%O\n",packet->fragment);
     werror("sizeof of the encrypted packet is:"+sizeof(packet->fragment)+"\n");
 #endif
@@ -75,14 +78,16 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
     string msg = packet->fragment;
     if (!msg) {
       packet->fragment = #string "alert.pike";	// Some junk data.
-      alert = Alert(ALERT_fatal, ALERT_unexpected_message, version);
+      fail = alert(ALERT_fatal, ALERT_unexpected_message,
+		   "SSL.state: Failed to get fragment.\n");
     } else {
-      switch(session->cipher_spec->cipher_type) {
+      switch(connection->session->cipher_spec->cipher_type) {
       case CIPHER_stream:
 
         // If data is too small, we can safely abort early.
         if( sizeof(msg) < hmac_size+1 )
-          return Alert(ALERT_fatal, ALERT_unexpected_message, version);
+          return alert(ALERT_fatal, ALERT_unexpected_message,
+		       "SSL.state: Too short message.\n");
 
 	msg = crypt->crypt(msg);
 	break;
@@ -92,21 +97,28 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
         // If data is too small or doesn't match block size, we can
         // safely abort early.
         if( sizeof(msg) < hmac_size+1 || sizeof(msg) % crypt->block_size() )
-          return Alert(ALERT_fatal, ALERT_unexpected_message, version);
+          return alert(ALERT_fatal, ALERT_unexpected_message,
+		       "SSL.state: Too short message.\n");
 
 	if(version == PROTOCOL_SSL_3_0) {
 	  // crypt->unpad() performs decrypt.
 	  if (catch { msg = crypt->unpad(msg, Crypto.PAD_SSL); })
-	    alert = Alert(ALERT_fatal, ALERT_unexpected_message, version);
+	    fail = alert(ALERT_fatal, ALERT_unexpected_message,
+			 "SSL.state: Invalid padding.\n");
 	} else if (version >= PROTOCOL_TLS_1_0) {
 
-	  if (catch { msg = crypt->unpad(msg, Crypto.PAD_TLS); })
-            alert = Alert(ALERT_fatal, ALERT_unexpected_message, version);
-          else if (!msg) {
+#ifdef SSL3_DEBUG_CRYPT
+	  werror("SSL.state: Decrypted message: %O.\n", msg);
+#endif
+	  if (catch { msg = crypt->unpad(msg, Crypto.PAD_TLS); }) {
+            fail = alert(ALERT_fatal, ALERT_unexpected_message,
+			 "SSL.state: Invalid padding.\n");
+          } else if (!msg) {
 	    // TLS 1.1 requires a bad_record_mac alert on invalid padding.
             // Note that mac will still be calculated below even if
             // padding was wrong, to mitigate Lucky Thirteen attacks.
-	    alert = Alert(ALERT_fatal, ALERT_bad_record_mac, version);
+	    fail = alert(ALERT_fatal, ALERT_bad_record_mac,
+			 "SSL.state: Invalid padding.\n");
 	  }
 	}
 	break;
@@ -115,7 +127,7 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
 
 	// NB: Only valid in TLS 1.2 and later.
 	// The message consists of explicit_iv + crypted-msg + digest.
-	string iv = salt + msg[..session->cipher_spec->explicit_iv_size-1];
+	string iv = salt + msg[..connection->session->cipher_spec->explicit_iv_size-1];
 	int digest_size = crypt->digest_size();
 	string digest = msg[<digest_size-1..];
 	crypt->set_iv(iv);
@@ -123,18 +135,16 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
 				   seq_num, packet->content_type,
 				   packet->protocol_version,
 				   sizeof(msg) -
-				   (session->cipher_spec->explicit_iv_size +
+				   (connection->session->cipher_spec->explicit_iv_size +
 				    digest_size));
 	crypt->update(auth_data);
-	msg = crypt->crypt(msg[session->cipher_spec->explicit_iv_size..
+	msg = crypt->crypt(msg[connection->session->cipher_spec->explicit_iv_size..
 			       <digest_size]);
 	seq_num++;
 	if (digest != crypt->digest()) {
 	  // Bad digest.
-#ifdef SSL3_DEBUG
-	  werror("Failed AEAD-verification!!\n");
-#endif
-	  alert = Alert(ALERT_fatal, ALERT_bad_record_mac, version);
+	  fail = alert(ALERT_fatal, ALERT_bad_record_mac,
+		       "Failed AEAD-verification!!\n");
 	}
 	break;
       }
@@ -176,7 +186,7 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
     string pad_string = "\0"*block_size;
     string junk = pad_string[<padding-1..];
     if (!((sizeof(packet->fragment) +
-           mac->hash_header_size - session->cipher_spec->hash_size) %
+           mac->hash_header_size - connection->session->cipher_spec->hash_size) %
           block_size ) ||
         !(padding % block_size)) {
       // We're at the edge of a MAC block, so we need to
@@ -196,7 +206,8 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
 	       "Seqence number: %O\n",
 	       digest, mac->hash_packet(packet, seq_num), seq_num);
 #endif
-	alert = alert || Alert(ALERT_fatal, ALERT_bad_record_mac, version);
+	fail = fail || alert(ALERT_fatal, ALERT_bad_record_mac,
+			     "Bad MAC.\n");
       }
     seq_num++;
   }
@@ -208,11 +219,12 @@ Alert|.packet decrypt_packet(.packet packet, ProtocolVersion version)
 #endif
     string msg = [string]compress(packet->fragment);
     if (!msg)
-      alert = alert || Alert(ALERT_fatal, ALERT_unexpected_message, version);
+      fail = fail || alert(ALERT_fatal, ALERT_unexpected_message,
+			   "Invalid compression.\n");
     packet->fragment = msg;
   }
 
-  if (alert) return alert;
+  if (fail) return fail;
 
   return [object(Alert)]packet->check_size(version) || packet;
 }
@@ -230,14 +242,14 @@ Alert|.packet encrypt_packet(.packet packet, ProtocolVersion version)
 
   if (mac) {
     digest = mac->hash_packet(packet, seq_num);
-    if (session->truncated_hmac)
+    if (connection->session->truncated_hmac)
       digest = digest[..9];
   } else
     digest = "";
 
   if (crypt)
   {
-    switch(session->cipher_spec->cipher_type) {
+    switch(connection->session->cipher_spec->cipher_type) {
     case CIPHER_stream:
       packet->fragment=crypt->crypt(packet->fragment + digest);
       break;
@@ -264,7 +276,8 @@ Alert|.packet encrypt_packet(.packet packet, ProtocolVersion version)
       // The nonce_explicit MAY be the 64-bit sequence number.
       // FIXME: Do we need to pay attention to threads here?
       string explicit_iv =
-	sprintf("%*c", session->cipher_spec->explicit_iv_size, seq_num);
+	sprintf("%*c", connection->session->cipher_spec->explicit_iv_size,
+		seq_num);
       crypt->set_iv(salt + explicit_iv);
       string auth_data = sprintf("%8c%c%2c%2c",
 				 seq_num, packet->content_type,