diff --git a/lib/modules/SSL.pmod/asn1.pmod.pike b/lib/modules/SSL.pmod/asn1.pmod.pike
index 28f0af9ff475d80d2cc3211c8af4f49a957b2fd1..e041e69d82f67808dfbe10dc55108dbf061f9f8e 100644
--- a/lib/modules/SSL.pmod/asn1.pmod.pike
+++ b/lib/modules/SSL.pmod/asn1.pmod.pike
@@ -2,7 +2,7 @@
  *
  * Rudimentary support for decoding ASN.1 encoded data.
  *
- * $Id: asn1.pmod.pike,v 1.2 1997/03/15 07:10:53 nisse Exp $
+ * $Id: asn1.pmod.pike,v 1.3 1997/03/15 12:15:07 nisse Exp $
  */
 
 /* BER decoder
@@ -23,17 +23,22 @@ class ber_decode {
     string contents;
     mixed value;
     
+#ifdef SSL3_DEBUG
     werror(sprintf("decoding tag %x\n", tag));
+#endif
     if ( (tag & 0x1f) == 0x1f)
       throw( ({ "high tag numbers is not supported\n", backtrace() }) );
     int len = get_int(1);
     if (len & 0x80)
       len = get_int(len & 0x7f);
     
+#ifdef SSL3_DEBUG
     werror(sprintf("len : %d\n", len));
-
+#endif
     contents = get_fix_string(len);
+#ifdef SSL3_DEBUG
     werror(sprintf("contents: %O\n", contents));
+#endif
     if (tag & 0x20)
     {
       object seq = object_program(this_object())(contents);
@@ -41,7 +46,9 @@ class ber_decode {
       while(! seq->is_empty())
       {
 	array elem = seq->get_asn1();
+#ifdef SSL3_DEBUG
 	// werror(sprintf("elem: %O\n", elem));
+#endif
 	value += ({ elem });
       }
     }
diff --git a/lib/modules/SSL.pmod/cipher.pike b/lib/modules/SSL.pmod/cipher.pike
index c1fb2eda6ea039a8dcd7e3ab32129e5314358380..558c56672cdbeca5407348ef13ebfd035544ef9d 100644
--- a/lib/modules/SSL.pmod/cipher.pike
+++ b/lib/modules/SSL.pmod/cipher.pike
@@ -46,7 +46,9 @@ class mac_sha
 		       "\0\0\0\0\0\0\0\0", seq_num->digits(256),
 		       packet->content_type, strlen(packet->fragment),
 		       packet->fragment);
+#ifdef SSL3_DEBUG
 //    werror(sprintf("SSL.cipher: hashing '%s'\n", s));
+#endif
     return hash_raw(secret + pad_2 +
 		    hash_raw(secret + pad_1 + s));
   }
diff --git a/lib/modules/SSL.pmod/connection.pike b/lib/modules/SSL.pmod/connection.pike
index d5ccf40ff39349392ed2142661a4f62cbc90a3a7..cfcc98b177ea1308803ac2c00d0f3b7c257b817f 100644
--- a/lib/modules/SSL.pmod/connection.pike
+++ b/lib/modules/SSL.pmod/connection.pike
@@ -16,7 +16,7 @@ inherit "constants";
 inherit "handshake";
 
 constant Queue = ADT.queue;
-constant State = (program) "state";
+constant State = SSL.state;
 
 inherit Queue : alert;
 inherit Queue : urgent;
@@ -36,7 +36,9 @@ object recv_packet(string data)
 {
   mixed res;
 
+#ifdef SSL3_DEBUG
 //  werror(sprintf("SSL.connection->recv_packet('%s')\n", data));
+#endif
   if (left_over || !packet)
   {
     packet = Packet(2048);
@@ -57,8 +59,10 @@ object recv_packet(string data)
 
 void send_packet(object packet, int|void fatal)
 {
+#ifdef SSL3_DEBUG
 //  werror(sprintf("SSL.connection->send_packet: type %d, '%s'\n",
 //		 packet->content_type, packet->fragment));
+#endif
   switch (packet->content_type)
   {
   default:
@@ -101,13 +105,15 @@ string|int to_write()
     packet = urgent::get() || application::get();
   }
   if (packet)
-    {
-      werror(sprintf("SSL.connection: writing packet of type %d, '%s'\n",
-		     packet->content_type, packet->fragment[..6]));
-      res = current_write_state->encrypt_packet(packet)->send();
-      if (packet->content_type == PACKET_change_cipher_spec)
-	current_write_state = pending_write_state;
-    }
+  {
+#ifdef SSL3_DEBUG
+    werror(sprintf("SSL.connection: writing packet of type %d, '%s'\n",
+		   packet->content_type, packet->fragment[..6]));
+#endif
+    res = current_write_state->encrypt_packet(packet)->send();
+    if (packet->content_type == PACKET_change_cipher_spec)
+      current_write_state = pending_write_state;
+  }
   else
     res = closing ? 1 : "";
   return res;
@@ -126,7 +132,9 @@ int handle_alert(string s)
   }
   if (level == ALERT_fatal)
   {
+#ifdef SSL3_DEBUG
     werror(sprintf("SSL.connection: Fatal alert %d\n", description));
+#endif
     return -1;
   }
   if (description == ALERT_close_notify)
@@ -182,15 +190,19 @@ string|int got_data(string s)
 
     if (packet->is_alert)
     { /* Reply alert */
+#ifdef SSL3_DEBUG
       werror("SSL.connection: Bad recieved packet\n");
+#endif
       send_packet(packet);
       if (packet->level == ALERT_fatal)
 	return -1;
     }
     else
     {
+#ifdef SSL3_DEBUG
       werror(sprintf("SSL.connection: recieved packet of type %d\n",
 		     packet->content_type));
+#endif
       switch (packet->content_type)
       {
       case PACKET_alert:
@@ -215,7 +227,9 @@ string|int got_data(string s)
 	 for (i = 0; (i < strlen(packet->fragment)); i++)
 	 {
 	   err = handle_change_cipher(packet->fragment[i]);
+#ifdef SSL3_DEBUG
 	   werror(sprintf("tried change_cipher: %d\n", err));
+#endif
 	   if (err)
 	     return err;
 	 }
diff --git a/lib/modules/SSL.pmod/context.pike b/lib/modules/SSL.pmod/context.pike
index e08b6352a9bf4163eda7b23c2a587c33f80d0521..74764d2c68734de91566888124cffb19589e583b 100644
--- a/lib/modules/SSL.pmod/context.pike
+++ b/lib/modules/SSL.pmod/context.pike
@@ -36,7 +36,7 @@ array(int) preferred_suites =
 array(int) preferred_compressors =
 ({ COMPRESSION_null });
 
-constant Session = (program) "session";
+constant Session = SSL.session;
 constant Queue = ADT.queue;
 
 int use_cache = 1;
@@ -44,7 +44,7 @@ int session_lifetime = 600; /* Time to remember a session, in seconds */
 
 /* Session cache */
 object active_sessions;  /* Queue of pairs (time, id), in cronological order */
-mapping(string:object(Session)) session_cache;
+mapping(string:object) session_cache;
 
 int session_number; /* Incremented for each session, and used when constructing the
 		     * session id */
@@ -87,6 +87,9 @@ void record_session(object s)
 
 void purge_session(object s)
 {
+#ifdef SSL3_DEBUG
+  werror(sprintf("SSL.context->purge_session: '%s'\n", s->identity || ""));
+#endif
   if (s->identity)
     session_cache[s->identity] = 0;
   /* There's no need to remove the id from the active_sessions queue */
@@ -94,6 +97,9 @@ void purge_session(object s)
 
 void create()
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.context->create\n");
+#endif
   active_sessions = Queue();
   session_cache = ([ ]);
 }
diff --git a/lib/modules/SSL.pmod/handshake.pike b/lib/modules/SSL.pmod/handshake.pike
index b7c99ea5178c27f8b328df9605019e8858932d82..82c820854f9046377be80759f24f4c9ba1e3c939 100644
--- a/lib/modules/SSL.pmod/handshake.pike
+++ b/lib/modules/SSL.pmod/handshake.pike
@@ -38,9 +38,9 @@ string my_random;
 string other_random;
 
 constant Struct = ADT.struct;
-constant Session = (program) "session";
-constant Packet = (program) "packet";
-constant Alert = (program) "alert";
+constant Session = SSL.session;
+constant Packet = SSL.packet;
+constant Alert = SSL.alert;
 
 /* Defined in connection.pike */
 void send_packet(object packet, int|void fatal);
@@ -68,7 +68,9 @@ object server_hello_packet()
   struct->put_int(session->compression_algorithm, 1);
 
   string data = struct->pop_data();
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.handshake: Server hello: '%s'\n", data));
+#endif
   return handshake_packet(HANDSHAKE_server_hello, data);
 }
 
@@ -78,13 +80,16 @@ int reply_new_session(array(int) cipher_suites, array(int) compression_methods)
   session = context->new_session();
   multiset(int) common_suites;
   
+#ifdef SSL3_DEBUG
   werror(sprintf("ciphers: me: %O, client: %O\n",
 		   context->preferred_suites, cipher_suites)); 
 //  werror(sprintf("compr: me: %O, client: %O\n",
 //		   context->preferred_compressors, compression_methods)); 
-  
+#endif
   common_suites = mkmultiset(cipher_suites & context->preferred_suites);
+#ifdef SSL3_DEBUG
   werror(sprintf("intersection: %O\n", common_suites));
+#endif
   if (sizeof(common_suites))
   {
     int suite;
@@ -115,7 +120,9 @@ int reply_new_session(array(int) cipher_suites, array(int) compression_methods)
     object struct = Struct();
     
     int len = `+( @ Array.map(context->certificates, strlen));
+#ifdef SSL3_DEBUG
 //    werror(sprintf("SSL.handshake: certificate_message size %d\n", len));
+#endif
     struct->put_int(len + 3 * sizeof(context->certificates), 3);
     foreach(context->certificates, string cert)
       struct->put_var_string(cert, 3);
@@ -175,7 +182,9 @@ string server_derive_master_secret(string data)
    {
      /* Decrypt the pre_master_secret */
      string s = context->rsa->decrypt(data);
+#ifdef SSL3_DEBUG
 //     werror(sprintf("premaster_secret: '%s'\n", s));
+#endif
      if (!s || (strlen(s) != 48) || (s[0] != 3))
        return 0;
      if (s[1] > 0)
@@ -188,7 +197,9 @@ string server_derive_master_secret(string data)
      break;
    }
   }
+#ifdef SSL3_DEBUG
 //  werror(sprintf("master: '%s'\n", res));
+#endif
   return res;
 }
 
@@ -198,7 +209,9 @@ int handle_handshake(int type, string data, string raw)
 {
   object input = Struct(data);
 
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.handshake: state %d, type %d\n", handshake_state, type));
+#endif
   
   switch(handshake_state)
   {
@@ -250,12 +263,16 @@ int handle_handshake(int type, string data, string raw)
 	  werror(sprintf("SSL.connection->handle_handshake: "
 			 "Version %d.%d hello detected\n", @version));
 
+#ifdef SSL3_DEBUG
 	if (strlen(id))
 	  werror(sprintf("SSL.handshake: Looking up session %s\n", id));
+#endif
 	session = strlen(id) && context->lookup_session(id);
 	if (session)
 	{
+#ifdef SSL3_DEBUG
 	  werror(sprintf("SSL.handshake: Reusing session %s\n", id));
+#endif
 	  /* Reuse session */
 	  reuse = 1;
 	  if (! ( (cipher_suites & ({ session->cipher_suite }))
@@ -286,7 +303,9 @@ int handle_handshake(int type, string data, string raw)
       }
      case HANDSHAKE_hello_v2:
       {
+#ifdef SSL3_DEBUG
 	werror("SSL.handshake: SSL2 hello message recieved\n");
+#endif
 	int ci_len;
 	int id_len;
 	int ch_len;
@@ -379,7 +398,9 @@ int handle_handshake(int type, string data, string raw)
 			backtrace()));
       return -1;
     case HANDSHAKE_client_key_exchange:
+#ifdef SSL3_DEBUG
 //      werror("client_key_exchange\n");
+#endif
       if (certificate_state == CERT_requested)
       { /* Certificate should be sent before key exchange message */
 	send_packet(Alert(ALERT_fatal, ALERT_unexpected_message,
@@ -398,7 +419,9 @@ int handle_handshake(int type, string data, string raw)
       pending_read_state = res[0];
       pending_write_state = res[1];
 
+#ifdef SSL3_DEBUG
 //      werror(sprintf("certificate_state: %d\n", certificate_state));
+#endif
       if (certificate_state != CERT_recieved)
       {
 	handshake_state = STATE_server_wait_for_finish;
@@ -462,7 +485,9 @@ int handle_handshake(int type, string data, string raw)
    {
    }
   }
+#ifdef SSL3_DEBUG
 //  werror(sprintf("SSL.handshake: messages = '%s'\n", handshake_messages));
+#endif
   return 0;
 }
 
diff --git a/lib/modules/SSL.pmod/https.pike b/lib/modules/SSL.pmod/https.pike
index 0a5939bd7515e262b8e3719f01be9dbb6a3e7634..a7b193d164250fa6a5608d6efa44e0f851929b34 100644
--- a/lib/modules/SSL.pmod/https.pike
+++ b/lib/modules/SSL.pmod/https.pike
@@ -56,7 +56,9 @@ class conn {
   
   void read_callback(mixed id, string data)
   {
+#ifdef SSL3_DEBUG
     werror("Recieved: '" + data + "'\n");
+#endif
     do_write();
   }
 
@@ -102,17 +104,23 @@ class ber_decode {
     int len;
     string contents;
     
+#ifdef SSL3_DEBUG
     werror(sprintf("decoding tag %x\n", tag));
+#endif
     if ( (tag & 0x1f) == 0x1f)
       throw( ({ "high tag numbers is not supported\n", backtrace() }) );
     int len = get_int(1);
     if (len & 0x80)
       len = get_int(len & 0x7f);
     
+#ifdef SSL3_DEBUG
     werror(sprintf("len : %d\n", len));
+#endif
 
     contents = get_fix_string(len);
+#ifdef SSL3_DEBUG
     werror(sprintf("contents: %O\n", contents));
+#endif
     if (tag & 0x20)
     {
       object seq = object_program(this_object())(contents);
@@ -120,7 +128,9 @@ class ber_decode {
       while(! seq->is_empty())
       {
 	array elem = seq->get_asn1();
+#ifdef SSL3_DEBUG
 	// werror(sprintf("elem: %O\n", elem));
+#endif
 	res += ({ elem });
       }
       return ({ tag, res });
@@ -156,11 +166,15 @@ void my_accept_callback(object f)
 
 int main()
 {
+#ifdef SSL3_DEBUG
   werror(sprintf("Cert: '%s'\n", Crypto.string_to_hex(my_certificate)));
   werror(sprintf("Key:  '%s'\n", Crypto.string_to_hex(my_key)));
 //  werror(sprintf("Decoded cert: %O\n", SSL.asn1.ber_decode(my_certificate)->get_asn1()));
+#endif
   array key = SSL.asn1.ber_decode(my_key)->get_asn1()[1];
+#ifdef SSL3_DEBUG
   werror(sprintf("Decoded key: %O\n", key));
+#endif
   object n = key[1][1];
   object e = key[2][1];
   object d = key[3][1];
@@ -169,6 +183,7 @@ int main()
 
   werror(sprintf("n =  %s\np =  %s\nq =  %s\npq = %s\n",
 		 n->digits(), p->digits(), q->digits(), (p*q)->digits()));
+
   rsa = Crypto.rsa();
   rsa->set_public_key(n, e);
   rsa->set_private_key(d);
@@ -186,6 +201,8 @@ int main()
 
 void create()
 {
+#ifdef SSL3_DEBUG
   werror("https->create\n");
+#ifdef SSL3_DEBUG
   sslport::create();
 }
diff --git a/lib/modules/SSL.pmod/packet.pike b/lib/modules/SSL.pmod/packet.pike
index 0fcbdaa899b53d85bcbd9ce91e5dbd8585073e1a..6f19dbb3e19038fe67b290d9d6c1d6b1317a7192 100644
--- a/lib/modules/SSL.pmod/packet.pike
+++ b/lib/modules/SSL.pmod/packet.pike
@@ -17,8 +17,9 @@ private int needed_chars;
 
 int marginal_size;
 
-// constant Alert = (program) "alert";
-#define Alert ((program) "alert")
+/* Circular dependence */
+program Alert = master()->resolv("SSL")->alert;
+// #define Alert ((program) "alert")
 
 void create(void|int extra)
 {
@@ -46,8 +47,10 @@ object|string recv(string data)
   buffer += data;
   while (strlen(buffer) >= needed_chars)
   {
+#ifdef SSL3_DEBUG
 //    werror(sprintf("SSL.packet->recv: needed = %d, avail = %d\n",
 //		     needed_chars, strlen(buffer)));
+#endif
     if (needed_chars == HEADER_SIZE)
     {
       content_type = buffer[0];
@@ -56,7 +59,9 @@ object|string recv(string data)
       {
 	if (SUPPORT_V2)
 	{
+#ifdef SSL3_DEBUG
 //	  werror(sprintf("SSL.packet: Recieving SSL2 packet '%s'\n", buffer[..4]));
+#endif
 
 	  content_type = PACKET_V2;
 	  if ( (!(buffer[0] & 0x80)) /* Support only short SSL2 headers */
@@ -64,7 +69,9 @@ object|string recv(string data)
 	    return Alert(ALERT_fatal, ALERT_unexpected_message);
 	  length = ((buffer[0] & 0x7f) << 8 | buffer[1]
 		    - 3);
+#ifdef SSL3_DEBUG
 //	  werror(sprintf("SSL2 length = %d\n", length));
+#endif
 	  protocol_version = values(buffer[3..4]);
 	}
 	else
@@ -105,8 +112,10 @@ string send()
     throw( ({ sprintf("SSL.packet->send: Version %d is not supported\n",
 		      protocol_version[0]), backtrace() }) );
   if (protocol_version[1] > 0)
+#ifdef SSL3_DEBUG
     werror(sprintf("SSL.packet->send: recieved version %d.%d packet\n",
 		   @ protocol_version));
+#endif
   if (strlen(fragment) > (PACKET_MAX_SIZE + marginal_size))
     throw( ({ "SSL.packet->send: maximum packet size exceeded\n",
 		backtrace() }) );
diff --git a/lib/modules/SSL.pmod/session.pike b/lib/modules/SSL.pmod/session.pike
index 6c4dbf9a4d93ddc6fd382eae8d29c5361fc7bc16..0e589e73a181b21f9005f08f19994bd6ff88c277 100644
--- a/lib/modules/SSL.pmod/session.pike
+++ b/lib/modules/SSL.pmod/session.pike
@@ -14,7 +14,7 @@ int ke_method;
 string master_secret; /* 48 byte secret shared between client and server */
 
 constant Struct = ADT.struct;
-constant State = (program) "state";
+constant State = SSL.state;
 
 void set_cipher_suite(int suite)
 {
@@ -22,8 +22,10 @@ void set_cipher_suite(int suite)
   cipher_suite = suite;
   ke_method = res[0];
   cipher_spec = res[1];
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.session: cipher_spec %O\n",
 		 mkmapping(indices(cipher_spec), values(cipher_spec))));
+#endif
 }
 
 void set_compression_method(int compr)
@@ -49,12 +51,16 @@ string generate_key_block(string client_random, string server_random)
   {
     i++;
     string cookie = replace(allocate(i), 0, sprintf("%c", 64+i)) * "";
+#ifdef SSL3_DEBUG
 //    werror(sprintf("cookie '%s'\n", cookie));
+#endif
     key += md5->hash_raw(master_secret +
 			 sha->hash_raw(cookie + master_secret +
 				       server_random + client_random));
   }
+#ifdef SSL3_DEBUG
 //  werror(sprintf("key_block: '%s'\n", key));
+#endif
   return key;
 }
 
@@ -63,8 +69,10 @@ array generate_keys(string client_random, string server_random)
   object key_data = Struct(generate_key_block(client_random, server_random));
   array keys = allocate(6);
 
-  write(sprintf("client_random: '%s'\nserver_random: '%s'\n",
+#ifdef SSL3_DEBUG
+  werror(sprintf("client_random: '%s'\nserver_random: '%s'\n",
 		client_random, server_random));
+#endif
 
   /* client_write_MAC_secret */
   keys[0] = key_data->get_fix_string(cipher_spec->hash_size);
diff --git a/lib/modules/SSL.pmod/sslfile.pike b/lib/modules/SSL.pmod/sslfile.pike
index a153cab49724680f021e8e3a38ec028de1568d7e..3cc5322f1058199ea00cbb27e68dfd4c204e81f4 100644
--- a/lib/modules/SSL.pmod/sslfile.pike
+++ b/lib/modules/SSL.pmod/sslfile.pike
@@ -16,17 +16,26 @@ function(mixed:void) close_callback;
 function(mixed:void) accept_callback;
 
 int connected; /* 1 if the connect callback has been called */
+int blocking;  /* 1 if in blocking mode.
+		* So far, there's no true blocking i/o, read and write
+		* requests are just queued up. */
 
 private void die(int status)
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->die\n");
+#endif
   if (status < 0)
   {
     /* Other end closed without sending a close_notify alert */
     context->purge_session(this_object());
+#ifdef SSL3_DEBUG
     werror("SSL.sslfile: Killed\n");
+#endif
   }
   if (close_callback)
     close_callback(socket::query_id());
+  socket::close();
 }
   
 /* Return 0 if the connection is still alive,
@@ -35,26 +44,35 @@ private void die(int status)
 private int try_write()
 {
   int|string data = to_write();
-//    werror(sprintf("sslport->try_write: %O\n", data));
+#ifdef SSL3_DEBUG
+  werror(sprintf("sslport->try_write: '%O'\n", data));
+#endif
   if (stringp(data))
-  {
     write_buffer += data;
-    if (strlen(write_buffer))
+  if (strlen(write_buffer))
+  {
+    int written = socket::write(write_buffer);
+    if (written > 0)
+      write_buffer = write_buffer[written..];
+    else
     {
-      int written = socket::write(write_buffer);
-      if (written > 0)
-	write_buffer = write_buffer[written..];
-      else
-	werror("SSL.sslfile->try_write: write failed\n");
+#ifdef SSL3_DEBUG
+      werror("SSL.sslfile->try_write: write failed\n");
+#endif
+      return -1;
     }
-    return 0;
   }
-  socket::close();
-  return data;
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->try_write: end\n");
+#endif
+  return stringp(data) ? 0 : data;
 }
 
 void close()
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->close\n");
+#endif
   send_packet(Alert(ALERT_warning, ALERT_close_notify));
   try_write();
   read_callback = 0;
@@ -64,6 +82,10 @@ void close()
 
 int write(string s)
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->write\n");
+#endif
+  int len = strlen(s);
   object packet;
   int res;
   while(strlen(s))
@@ -75,6 +97,7 @@ int write(string s)
     s = s[PACKET_MAX_SIZE..];
   }
   (res = try_write()) && die(res);
+  return len;
 }
 
 string read(mixed ...args)
@@ -84,11 +107,15 @@ string read(mixed ...args)
   
 private void ssl_read_callback(mixed id, string s)
 {
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.sslfile->ssl_read_callback\n"));
+#endif
   string|int data = got_data(s);
   if (stringp(data))
   {
+#ifdef SSL3_DEBUG
     werror(sprintf("SSL.sslfile: application_data: '%s'\n", data));
+#endif
     if (strlen(data))
     {
       read_buffer += data;
@@ -98,7 +125,7 @@ private void ssl_read_callback(mixed id, string s)
 	if (accept_callback)
 	  accept_callback(this_object());
       }
-      if (read_callback && strlen(read_buffer))
+      if (!blocking && read_callback && strlen(read_buffer))
       {
 	read_callback(id, read_buffer + data);
 	read_buffer = "";
@@ -111,16 +138,27 @@ private void ssl_read_callback(mixed id, string s)
       /* Fatal error, remove from session cache */
       context->purge_session(this_object());
   }
-  try_write() || (close_callback && close_callback());
+  int res = try_write();
+  if (res)
+    die(res);
 }
   
 private void ssl_write_callback(mixed id)
 {
-  werror("SSL.sslport: ssl_write_callback\n");
+#ifdef SSL3_DEBUG
+  werror(sprintf("SSL.sslport->ssl_write_callback: handshake_finished = %d\n"
+		 "blocking = %d, write_callback = %O\n",
+		 handshake_finished, blocking, write_callback));
+#endif
   int res;
+  
   if ( !(res = try_write()) && !strlen(write_buffer)
-       && handshake_finished && write_callback)
+       && handshake_finished && !blocking && write_callback)
   {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslport->ssl_write_callback: Calling write_callback\n");
+#endif
+    
     write_callback(id);
     res = try_write();
   }
@@ -130,14 +168,15 @@ private void ssl_write_callback(mixed id)
 
 private void ssl_close_callback(mixed id)
 {
+#ifdef SSL3_DEBUG
   werror("SSL.sslport: ssl_close_callback\n");
-  socket::close();
+#endif
   die(-1);
 }
 
-void set_accept_callback(function(mixed:void) w)
+void set_accept_callback(function(mixed:void) a)
 {
-  accept_callback = w;
+  accept_callback = a;
 }
 
 void set_read_callback(function(mixed,string:void) r)
@@ -157,6 +196,9 @@ void set_close_callback(function(mixed:void) c)
   
 void set_nonblocking(function ...args)
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->set_nonblocking\n");
+#endif
   switch (sizeof(args))
   {
   case 0:
@@ -170,22 +212,38 @@ void set_nonblocking(function ...args)
     throw( ({ "SSL.sslfile->set_blocking: Wrong number of arguments\n",
 		backtrace() }) );
   }
+  blocking = 0;
+  if (strlen(read_buffer))
+    ssl_read_callback(socket::query_id(), "");
+  ssl_write_callback(socket::query_id());
 }
 
 void set_blocking()
 {
-  throw( ({ "SSL.sslfile->set_blocking: Not supported\n",
-	      backtrace() }) );
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->set_blocking\n");
+#endif
+#if 0
+  if (!connected)
+    throw( ({ "SSL.sslfile->set_blocking: Not supported\n",
+		backtrace() }) );
+#endif
+  blocking = 1;
 }
 
+#if 0
 object accept()
 {
   /* Dummy method, for compatibility with Stdio.Port */
   return this_object();
 }
-  
+#endif
+
 void create(object f, object c)
 {
+#ifdef SSL3_DEBUG
+  werror("SSL.sslfile->create\n");
+#endif
   context = c;
   read_buffer = write_buffer = "";
   socket::assign(f);
diff --git a/lib/modules/SSL.pmod/sslport.pike b/lib/modules/SSL.pmod/sslport.pike
index d1bc9883c21045d75f6d98e70c1d7e67c7b9bd55..e6573a36c4d133dfc93ec201c79882b973c27af9 100644
--- a/lib/modules/SSL.pmod/sslport.pike
+++ b/lib/modules/SSL.pmod/sslport.pike
@@ -6,7 +6,7 @@ inherit Stdio.Port : socket;
 inherit "context";
 inherit ADT.queue : accept_queue;
 
-constant sslfile = (program) "sslfile";
+constant sslfile = SSL.sslfile;
 
 function(object:void) accept_callback;
 
@@ -62,7 +62,9 @@ int accept()
 
 void create()
 {
+#ifdef SSL3_DEBUG
   werror("SSL.sslport->create\n");
+#endif
   context::create();
   accept_queue::create();
 }
diff --git a/lib/modules/SSL.pmod/state.pike b/lib/modules/SSL.pmod/state.pike
index 895445ef441c6c504261a34b9c52b2591182c22f..65e5721d9abf4efc07da8e379dd577fbf0f05a5e 100644
--- a/lib/modules/SSL.pmod/state.pike
+++ b/lib/modules/SSL.pmod/state.pike
@@ -14,7 +14,7 @@ object compress;
 
 object(Gmp.mpz) seq_num;    /* Bignum, values 0, .. 2^64-1 are valid */
 
-constant Alert = (program) "alert";
+constant Alert = SSL.alert;
 
 void create(object s)
 {
@@ -27,12 +27,16 @@ void create(object s)
  * there was an error, otherwise 0. */
 object decrypt_packet(object packet)
 {
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.state->decrypt_packet: data = '%s'\n", packet->fragment));
+#endif
   
   if (crypt)
   {
     string msg;
+#ifdef SSL3_DEBUG
     werror("SSL.state: Trying decrypt..\n");
+#endif
     msg = crypt->crypt(packet->fragment); 
     if (! msg)
       return Alert(ALERT_fatal, ALERT_unexpected_message);
@@ -42,11 +46,15 @@ object decrypt_packet(object packet)
     packet->fragment = msg;
   }
 
+#ifdef SSL3_DEBUG
   werror(sprintf("SSL.state: Decrypted_packet '%s'\n", packet->fragment));
+#endif
 
   if (mac)
   {
+#ifdef SSL3_DEBUG
     werror("SSL.state: Trying mac verification...\n");
+#endif
     int length = strlen(packet->fragment) - session->cipher_spec->hash_size;
     string digest = packet->fragment[length ..];
     packet->fragment = packet->fragment[.. length - 1];
@@ -58,7 +66,9 @@ object decrypt_packet(object packet)
 
   if (compress)
   {
+#ifdef SSL3_DEBUG
     werror("SSL.state: Trying decompression...\n");
+#endif
     string msg;
     msg = compress(packet->fragment);
     if (!msg)