changeset 18608:a244c34ce59c

Call the AIM_CB_SPECIAL_CONNERR callback from flap_connection_destroy_cb() rather than parse_flap_ch4(). This ensures that the AIM_CB_SPECIAL_CONNERR callback function gets called even if AOL ends our FLAP connection without sending the customary channel 4 FLAP. Apparently you're not allowed to be in chat rooms from two locations. So when you sign on from a second location AOL severs the chat connections from your first location. It does this by sending a TCP RST rather than the expected channel 4 FLAP. This lead to a crash if you were in a chat room, then signed on from a second location. Fixes #1937.
author Mark Doliner <mark@kingant.net>
date Sun, 22 Jul 2007 08:18:27 +0000
parents ac9f19a31051
children 2774acdb1cff
files libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 3 files changed, 14 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/flap_connection.c	Sun Jul 22 07:09:33 2007 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Sun Jul 22 08:18:27 2007 +0000
@@ -356,16 +356,21 @@
 	FlapConnection *conn;
 	OscarData *od;
 	PurpleAccount *account;
+	aim_rxcallback_t userfunc;
 
 	conn = data;
 	od = conn->od;
 	account = (PURPLE_CONNECTION_IS_VALID(od->gc) ? purple_connection_get_account(od->gc) : NULL);
 
 	purple_debug_info("oscar", "Destroying oscar connection of "
-			"type 0x%04hx\n", conn->type);
+			"type 0x%04hx.  Disconnect reason is %d\n",
+			conn->type, conn->disconnect_reason);
 
 	od->oscar_connections = g_slist_remove(od->oscar_connections, conn);
 
+	if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR)))
+		userfunc(od, conn, NULL, conn->disconnect_code, conn->error_message);
+
 	/*
 	 * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then
 	 * we should try to request one instead of disconnecting.
@@ -695,8 +700,6 @@
 {
 	GSList *tlvlist;
 	char *msg = NULL;
-	guint16 code = 0;
-	aim_rxcallback_t userfunc;
 
 	if (byte_stream_empty(&frame->data) == 0) {
 		/* XXX should do something with this */
@@ -713,13 +716,17 @@
 	tlvlist = aim_tlvlist_read(&frame->data);
 
 	if (aim_tlv_gettlv(tlvlist, 0x0009, 1))
-		code = aim_tlv_get16(tlvlist, 0x0009, 1);
+		conn->disconnect_code = aim_tlv_get16(tlvlist, 0x0009, 1);
 
 	if (aim_tlv_gettlv(tlvlist, 0x000b, 1))
 		msg = aim_tlv_getstr(tlvlist, 0x000b, 1);
 
-	if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR)))
-		userfunc(od, conn, frame, code, msg);
+	/*
+	 * The server ended this FLAP connnection, so let's be nice and
+	 * close the physical TCP connection
+	 */
+	flap_connection_schedule_destroy(conn,
+			OSCAR_DISCONNECT_REMOTE_CLOSED, msg);
 
 	aim_tlvlist_free(tlvlist);
 
--- a/libpurple/protocols/oscar/oscar.c	Sun Jul 22 07:09:33 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sun Jul 22 08:18:27 2007 +0000
@@ -3472,7 +3472,6 @@
 	purple_debug_info("oscar", "Disconnected.  Code is 0x%04x and msg is %s\n",
 					code, (msg != NULL ? msg : ""));
 
-	g_return_val_if_fail(fr       != NULL, 1);
 	g_return_val_if_fail(conn != NULL, 1);
 
 	if (conn->type == SNAC_FAMILY_LOCATE) {
--- a/libpurple/protocols/oscar/oscar.h	Sun Jul 22 07:09:33 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Sun Jul 22 08:18:27 2007 +0000
@@ -378,6 +378,7 @@
 	guint destroy_timeout;
 	OscarDisconnectReason disconnect_reason;
 	gchar *error_message;
+	guint16 disconnect_code;
 
 	/* A few variables that are only used when connecting */
 	PurpleProxyConnectData *connect_data;