Index: protocols/oscar/conn.c
===================================================================
--- protocols/oscar/conn.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/oscar/conn.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -627,7 +627,5 @@
 	}
 
-#ifndef _WIN32
-	fcntl(conn->fd, F_SETFL, 0); /* XXX should restore original flags */
-#endif
+	sock_make_blocking(conn->fd);
 
 	conn->status &= ~AIM_CONN_STATUS_INPROGRESS;
Index: protocols/proxy.c
===================================================================
--- protocols/proxy.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/proxy.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -133,6 +133,6 @@
 		return;
 	}
-	fcntl(source, F_SETFL, 0);
 #endif
+	sock_make_blocking(source);
 	gaim_input_remove(phb->inpa);
 	if( phb->proxy_func )
@@ -229,7 +229,5 @@
 		return;
 	}
-#ifdef F_SETFL
-	fcntl(source, F_SETFL, 0);
-#endif
+	sock_make_blocking(source);
 
 	g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port,
@@ -322,7 +320,5 @@
 		return;
 	}
-#ifdef F_SETFL
-	fcntl(source, F_SETFL, 0);
-#endif
+	sock_make_blocking(source);
 
 	/* XXX does socks4 not support host name lookups by the proxy? */
@@ -509,7 +505,5 @@
 		return;
 	}
-#ifdef F_SETFL
-	fcntl(source, F_SETFL, 0);
-#endif
+	sock_make_blocking(source);
 
 	i = 0;
Index: protocols/ssl_bogus.c
===================================================================
--- protocols/ssl_bogus.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/ssl_bogus.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -26,4 +26,6 @@
 #include "ssl_client.h"
 
+int ssl_errno;
+
 void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data )
 {
Index: protocols/ssl_client.h
===================================================================
--- protocols/ssl_client.h	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/ssl_client.h	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -27,4 +27,10 @@
 #include "proxy.h"
 
+#define SSL_OK            0
+#define SSL_NOHANDSHAKE   1
+#define SSL_AGAIN         2
+
+extern int ssl_errno;
+
 typedef void (*SslInputFunction)(gpointer, void*, GaimInputCondition);
 
Index: protocols/ssl_gnutls.c
===================================================================
--- protocols/ssl_gnutls.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/ssl_gnutls.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -25,8 +25,12 @@
 
 #include <gnutls/gnutls.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "proxy.h"
 #include "ssl_client.h"
 #include "sock.h"
 #include "stdlib.h"
+
+int ssl_errno = 0;
 
 static gboolean initialized = FALSE;
@@ -38,4 +42,5 @@
 	int fd;
 	gboolean established;
+	int inpa;
 	
 	gnutls_session session;
@@ -44,5 +49,4 @@
 
 static void ssl_connected( gpointer data, gint source, GaimInputCondition cond );
-
 
 
@@ -54,4 +58,5 @@
 	conn->func = func;
 	conn->data = data;
+	conn->inpa = -1;
 	
 	if( conn->fd < 0 )
@@ -76,4 +81,6 @@
 }
 
+static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond );
+
 static void ssl_connected( gpointer data, gint source, GaimInputCondition cond )
 {
@@ -81,22 +88,57 @@
 	
 	if( source == -1 )
-		goto ssl_connected_failure;
+	{
+		conn->func( conn->data, NULL, cond );
+		
+		gnutls_deinit( conn->session );
+		gnutls_certificate_free_credentials( conn->xcred );
+		
+		g_free( conn );
+		
+		return;
+	}
 	
+	sock_make_nonblocking( conn->fd );
 	gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd );
 	
-	if( gnutls_handshake( conn->session ) < 0 )
-		goto ssl_connected_failure;
+	ssl_handshake( data, source, cond );
+}
+
+static void ssl_handshake( gpointer data, gint source, GaimInputCondition cond )
+{
+	struct scd *conn = data;
+	int st;
 	
-	conn->established = TRUE;
-	conn->func( conn->data, conn, cond );
-	return;
+	if( conn->inpa != -1 )
+		gaim_input_remove( conn->inpa );
 	
-ssl_connected_failure:
-	conn->func( conn->data, NULL, cond );
-	
-	gnutls_deinit( conn->session );
-	gnutls_certificate_free_credentials( conn->xcred );
-	if( source >= 0 ) closesocket( source );
-	g_free( conn );
+	if( ( st = gnutls_handshake( conn->session ) ) < 0 )
+	{
+		if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+		{
+			conn->inpa = gaim_input_add( conn->fd,
+			                             gnutls_record_get_direction( conn->session ) ?
+			                                 GAIM_INPUT_WRITE : GAIM_INPUT_READ,
+			                             ssl_handshake, data );
+		}
+		else
+		{
+			conn->func( conn->data, NULL, cond );
+			
+			gnutls_deinit( conn->session );
+			gnutls_certificate_free_credentials( conn->xcred );
+			closesocket( conn->fd );
+			
+			g_free( conn );
+		}
+	}
+	else
+	{
+		/* For now we can't handle non-blocking perfectly everywhere... */
+		sock_make_blocking( conn->fd );
+		
+		conn->established = TRUE;
+		conn->func( conn->data, conn, cond );
+	}
 }
 
@@ -104,7 +146,11 @@
 {
 	if( !((struct scd*)conn)->established )
-		return( 0 );
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return( -1 );
+	}
 	
 	return( gnutls_record_recv( ((struct scd*)conn)->session, buf, len ) );
+	
 }
 
@@ -112,5 +158,8 @@
 {
 	if( !((struct scd*)conn)->established )
-		return( 0 );
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return( -1 );
+	}
 	
 	return( gnutls_record_send( ((struct scd*)conn)->session, buf, len ) );
Index: protocols/ssl_nss.c
===================================================================
--- protocols/ssl_nss.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/ssl_nss.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -38,4 +38,6 @@
 #include <secerr.h>
 #include <sslerr.h>
+
+int ssl_errno = 0;
 
 static gboolean initialized = FALSE;
Index: protocols/ssl_openssl.c
===================================================================
--- protocols/ssl_openssl.c	(revision bf02a679c61b0f030ee8f2f01698699a7775f7d5)
+++ protocols/ssl_openssl.c	(revision 12c6634050984e3a7da472b603ddb63e7c7500c8)
@@ -34,4 +34,6 @@
 #include "ssl_client.h"
 #include "sock.h"
+
+int ssl_errno = 0;
 
 static gboolean initialized = FALSE;
