Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision 64768d4ec0c3ad473573c3f3c34871e0081b4e59)
+++ protocols/msn/msn.c	(revision bae06178bbe3863b39ec307c34d2781a53472272)
@@ -53,5 +53,4 @@
 	
 	ic->proto_data = md;
-	md->fd = -1;
 	
 	if( strchr( acc->user, '@' ) == NULL )
@@ -62,19 +61,12 @@
 	}
 	
-	imcb_log( ic, "Connecting" );
-	
-	md->fd = proxy_connect( "messenger.hotmail.com", 1863, msn_ns_connected, ic );
-	if( md->fd < 0 )
-	{
-		imcb_error( ic, "Could not connect to server" );
-		imc_logout( ic, TRUE );
-		return;
-	}
-	
 	md->ic = ic;
 	md->away_state = msn_away_state_list;
 	md->domaintree = g_tree_new( msn_domaintree_cmp );
 	
-	msn_connections = g_slist_append( msn_connections, ic );
+	msn_connections = g_slist_prepend( msn_connections, ic );
+	
+	imcb_log( ic, "Connecting" );
+	msn_ns_connect( ic, md->ns, MSN_NS_HOST, MSN_NS_PORT );
 }
 
@@ -93,13 +85,6 @@
 		*/
 		
-		if( md->fd >= 0 )
-			closesocket( md->fd );
-		
-		if( md->handler )
-		{
-			if( md->handler->rxq ) g_free( md->handler->rxq );
-			if( md->handler->cmd_text ) g_free( md->handler->cmd_text );
-			g_free( md->handler );
-		}
+		msn_ns_close( md->ns );
+		msn_ns_close( md->auth );
 		
 		while( md->switchboards )
Index: protocols/msn/msn.h
===================================================================
--- protocols/msn/msn.h	(revision 64768d4ec0c3ad473573c3f3c34871e0081b4e59)
+++ protocols/msn/msn.h	(revision bae06178bbe3863b39ec307c34d2781a53472272)
@@ -44,4 +44,7 @@
 */
 
+#define MSN_NS_HOST "messenger.hotmail.com"
+#define MSN_NS_PORT 1863
+
 /* Some other version.
 #define MSNP11_PROD_KEY "O4BG@C7BWLYQX?5G"
@@ -80,10 +83,25 @@
 } msn_flags_t;
 
+struct msn_handler_data
+{
+	int fd, inpa;
+	int rxlen;
+	char *rxq;
+	
+	int msglen;
+	char *cmd_text;
+	
+	/* Either ic or sb */
+	gpointer data;
+	
+	int (*exec_command) ( struct msn_handler_data *handler, char **cmd, int count );
+	int (*exec_message) ( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int count );
+};
+
 struct msn_data
 {
 	struct im_connection *ic;
 	
-	int fd;
-	struct msn_handler_data *handler;
+	struct msn_handler_data ns[1], auth[1];
 	msn_flags_t flags;
 	
@@ -111,4 +129,5 @@
 	struct im_connection *ic;
 	
+	/* The following two are also in the handler. TODO: Clean up. */
 	int fd;
 	gint inp;
@@ -150,19 +169,4 @@
 	char *who;
 	char *group;
-};
-
-struct msn_handler_data
-{
-	int fd;
-	int rxlen;
-	char *rxq;
-	
-	int msglen;
-	char *cmd_text;
-	
-	gpointer data;
-	
-	int (*exec_command) ( gpointer data, char **cmd, int count );
-	int (*exec_message) ( gpointer data, char *msg, int msglen, char **cmd, int count );
 };
 
@@ -209,5 +213,6 @@
 /* ns.c */
 int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... );
-gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond );
+gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port );
+void msn_ns_close( struct msn_handler_data *handler );
 void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error );
 void msn_auth_got_contact_list( struct im_connection *ic );
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision 64768d4ec0c3ad473573c3f3c34871e0081b4e59)
+++ protocols/msn/msn_util.c	(revision bae06178bbe3863b39ec307c34d2781a53472272)
@@ -351,5 +351,5 @@
 					cmd = msn_linesplit( cmd_text );
 					for( count = 0; cmd[count]; count ++ );
-					st = h->exec_command( h->data, cmd, count );
+					st = h->exec_command( h, cmd, count );
 					g_free( cmd_text );
 					
@@ -386,5 +386,5 @@
 			for( count = 0; cmd[count]; count ++ );
 			
-			st = h->exec_message( h->data, msg, h->msglen, cmd, count );
+			st = h->exec_message( h, msg, h->msglen, cmd, count );
 			g_free( msg );
 			g_free( h->cmd_text );
Index: protocols/msn/ns.c
===================================================================
--- protocols/msn/ns.c	(revision 64768d4ec0c3ad473573c3f3c34871e0081b4e59)
+++ protocols/msn/ns.c	(revision bae06178bbe3863b39ec307c34d2781a53472272)
@@ -31,7 +31,8 @@
 #include "xmltree.h"
 
+static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond );
 static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond );
-static int msn_ns_command( gpointer data, char **cmd, int num_parts );
-static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
+static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num_parts );
+static int msn_ns_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts );
 
 static void msn_ns_send_adl_start( struct im_connection *ic );
@@ -51,5 +52,5 @@
 	
 	if( fd < 0 )
-		fd = md->fd;
+		fd = md->ns->fd;
 	
 	if( getenv( "BITLBEE_DEBUG" ) )
@@ -69,13 +70,14 @@
 }
 
-gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
-{
-	struct im_connection *ic = data;
-	struct msn_data *md;
-	
-	if( !g_slist_find( msn_connections, ic ) )
-		return FALSE;
-	
-	if( source == -1 )
+gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port )
+{
+	if( handler->fd >= 0 )
+		closesocket( handler->fd );
+	
+	handler->exec_command = msn_ns_command;
+	handler->exec_message = msn_ns_message;
+	handler->data = ic;
+	handler->fd = proxy_connect( host, port, msn_ns_connected, handler );
+	if( handler->fd < 0 )
 	{
 		imcb_error( ic, "Could not connect to server" );
@@ -84,27 +86,32 @@
 	}
 	
+	return TRUE;
+}
+
+static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
+{
+	struct msn_handler_data *handler = data;
+	struct im_connection *ic = handler->data;
+	struct msn_data *md;
+	
+	if( !g_slist_find( msn_connections, ic ) )
+		return FALSE;
+	
 	md = ic->proto_data;
 	
-	if( !md->handler )
-	{
-		md->handler = g_new0( struct msn_handler_data, 1 );
-		md->handler->data = ic;
-		md->handler->exec_command = msn_ns_command;
-		md->handler->exec_message = msn_ns_message;
-	}
-	else
-	{
-		if( md->handler->rxq )
-			g_free( md->handler->rxq );
-		
-		md->handler->rxlen = 0;
-	}
-	
-	md->handler->fd = md->fd;
-	md->handler->rxq = g_new0( char, 1 );
+	if( source == -1 )
+	{
+		imcb_error( ic, "Could not connect to server" );
+		imc_logout( ic, TRUE );
+		return FALSE;
+	}
+	
+	g_free( handler->rxq );
+	handler->rxlen = 0;
+	handler->rxq = g_new0( char, 1 );
 	
 	if( msn_ns_write( ic, -1, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
 	{
-		ic->inpa = b_input_add( md->fd, B_EV_IO_READ, msn_ns_callback, ic );
+		handler->inpa = b_input_add( handler->fd, B_EV_IO_READ, msn_ns_callback, handler );
 		imcb_log( ic, "Connected to server, waiting for reply" );
 	}
@@ -113,10 +120,27 @@
 }
 
+void msn_ns_close( struct msn_handler_data *handler )
+{
+	if( handler->fd >= 0 )
+	{
+		closesocket( handler->fd );
+		b_event_remove( handler->inpa );
+	}
+	
+	handler->fd = handler->inpa = -1;
+	g_free( handler->rxq );
+	g_free( handler->cmd_text );
+	
+	handler->rxlen = 0;
+	handler->rxq = NULL;
+	handler->cmd_text = NULL;
+}
+
 static gboolean msn_ns_callback( gpointer data, gint source, b_input_condition cond )
 {
-	struct im_connection *ic = data;
-	struct msn_data *md = ic->proto_data;
-	
-	if( msn_handler( md->handler ) == -1 ) /* Don't do this on ret == 0, it's already done then. */
+	struct msn_handler_data *handler = data;
+	struct im_connection *ic = handler->data;
+	
+	if( msn_handler( handler ) == -1 ) /* Don't do this on ret == 0, it's already done then. */
 	{
 		imcb_error( ic, "Error while reading from server" );
@@ -129,7 +153,7 @@
 }
 
-static int msn_ns_command( gpointer data, char **cmd, int num_parts )
-{
-	struct im_connection *ic = data;
+static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num_parts )
+{
+	struct im_connection *ic = handler->data;
 	struct msn_data *md = ic->proto_data;
 	
@@ -164,7 +188,6 @@
 		if( num_parts >= 6 && strcmp( cmd[2], "NS" ) == 0 )
 		{
-			b_event_remove( ic->inpa );
-			ic->inpa = 0;
-			closesocket( md->fd );
+			b_event_remove( handler->inpa );
+			handler->inpa = -1;
 			
 			server = strchr( cmd[3], ':' );
@@ -180,6 +203,5 @@
 			
 			imcb_log( ic, "Transferring to other server" );
-			
-			md->fd = proxy_connect( server, port, msn_ns_connected, ic );
+			return msn_ns_connect( ic, handler, server, port );
 		}
 		else if( num_parts >= 6 && strcmp( cmd[2], "SB" ) == 0 )
@@ -273,7 +295,7 @@
 		}
 		
-		md->handler->msglen = atoi( cmd[3] );
-		
-		if( md->handler->msglen <= 0 )
+		handler->msglen = atoi( cmd[3] );
+		
+		if( handler->msglen <= 0 )
 		{
 			imcb_error( ic, "Syntax error" );
@@ -296,5 +318,5 @@
 		else if( num_parts >= 3 )
 		{
-			md->handler->msglen = atoi( cmd[2] );
+			handler->msglen = atoi( cmd[2] );
 		}
 	}
@@ -460,7 +482,7 @@
 		imcb_error( ic, "Received IPG command, we don't handle them yet." );
 		
-		md->handler->msglen = atoi( cmd[1] );
-		
-		if( md->handler->msglen <= 0 )
+		handler->msglen = atoi( cmd[1] );
+		
+		if( handler->msglen <= 0 )
 		{
 			imcb_error( ic, "Syntax error" );
@@ -519,5 +541,5 @@
 		/* Coming up is cmd[2] bytes of stuff we're supposed to
 		   censore. Meh. */
-		md->handler->msglen = atoi( cmd[2] );
+		handler->msglen = atoi( cmd[2] );
 	}
 	else if( strcmp( cmd[0], "UBX" ) == 0 )
@@ -525,5 +547,5 @@
 		/* Status message. */
 		if( num_parts >= 4 )
-			md->handler->msglen = atoi( cmd[3] );
+			handler->msglen = atoi( cmd[3] );
 	}
 	else if( strcmp( cmd[0], "NOT" ) == 0 )
@@ -532,5 +554,5 @@
 		   apparently used to announce address book changes. */
 		if( num_parts >= 2 )
-			md->handler->msglen = atoi( cmd[1] );
+			handler->msglen = atoi( cmd[1] );
 	}
 	else if( isdigit( cmd[0][0] ) )
@@ -549,5 +571,5 @@
 		/* Oh yes, errors can have payloads too now. Discard them for now. */
 		if( num_parts >= 3 )
-			md->handler->msglen = atoi( cmd[2] );
+			handler->msglen = atoi( cmd[2] );
 	}
 	else
@@ -559,7 +581,7 @@
 }
 
-static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts )
-{
-	struct im_connection *ic = data;
+static int msn_ns_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts )
+{
+	struct im_connection *ic = handler->data;
 	char *body;
 	int blen = 0;
Index: protocols/msn/sb.c
===================================================================
--- protocols/msn/sb.c	(revision 64768d4ec0c3ad473573c3f3c34871e0081b4e59)
+++ protocols/msn/sb.c	(revision bae06178bbe3863b39ec307c34d2781a53472272)
@@ -32,6 +32,6 @@
 
 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );
-static int msn_sb_command( gpointer data, char **cmd, int num_parts );
-static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts );
+static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts );
+static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts );
 
 int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... )
@@ -392,7 +392,7 @@
 }
 
-static int msn_sb_command( gpointer data, char **cmd, int num_parts )
-{
-	struct msn_switchboard *sb = data;
+static int msn_sb_command( struct msn_handler_data *handler, char **cmd, int num_parts )
+{
+	struct msn_switchboard *sb = handler->data;
 	struct im_connection *ic = sb->ic;
 	
@@ -665,7 +665,7 @@
 }
 
-static int msn_sb_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts )
-{
-	struct msn_switchboard *sb = data;
+static int msn_sb_message( struct msn_handler_data *handler, char *msg, int msglen, char **cmd, int num_parts )
+{
+	struct msn_switchboard *sb = handler->data;
 	struct im_connection *ic = sb->ic;
 	char *body;
