changeset 11214:751de30689ef

[gaim-migrate @ 13346] Bug fix for OSCAR file transfer timeouts. Also, aim_get_command now accepts zero as a valid fd; this was necessary to get this fix to work in HEAD. committer: Tailor Script <tailor@pidgin.im>
author Jonathan Clark <ardentlygnarly>
date Tue, 09 Aug 2005 00:25:39 +0000
parents ff728e84d59a
children 986160f7b6ca
files src/protocols/oscar/aim.h src/protocols/oscar/ft.c src/protocols/oscar/oscar.c src/protocols/oscar/rxqueue.c
diffstat 4 files changed, 38 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/aim.h	Mon Aug 08 21:43:44 2005 +0000
+++ b/src/protocols/oscar/aim.h	Tue Aug 09 00:25:39 2005 +0000
@@ -925,6 +925,7 @@
 	fu16_t port;
 	aim_conn_t *conn;
 	aim_session_t *sess;
+	int success; /* Was the connection successful? Used for timing out the transfer. */
 	struct aim_fileheader_t fh;
 	struct aim_oft_info *next;
 };
--- a/src/protocols/oscar/ft.c	Mon Aug 08 21:43:44 2005 +0000
+++ b/src/protocols/oscar/ft.c	Tue Aug 09 00:25:39 2005 +0000
@@ -672,6 +672,7 @@
 	if (sn)
 		new->sn = strdup(sn);
 	new->port = port;
+	new->success = FALSE;
 	new->fh.totfiles = 1;
 	new->fh.filesleft = 1;
 	new->fh.totparts = 1;
--- a/src/protocols/oscar/oscar.c	Mon Aug 08 21:43:44 2005 +0000
+++ b/src/protocols/oscar/oscar.c	Tue Aug 09 00:25:39 2005 +0000
@@ -1599,7 +1599,7 @@
 	aim_session_t *sess = aim_conn_getsess(conn);
 	GaimConnection *gc = sess ? sess->aux_data : NULL;
 	OscarData *od;
-
+	
 	if (!gc) {
 		gaim_debug_info("oscar",
 				   "oscar callback for closed connection (1).\n");
@@ -1700,6 +1700,7 @@
 				} else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
 					if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)
 						gaim_odc_disconnect(od->sess, conn);
+					gaim_debug_info("oscar","killing rendezvous connection\n");
 					aim_conn_kill(od->sess, &conn);
 				} else {
 					gaim_debug_error("oscar",
@@ -2024,19 +2025,21 @@
 	GaimXfer *xfer;
 	struct aim_oft_info *oft_info;
 	char *msg = NULL;
-
+	
 	gaim_debug_info("oscar","AAA - in oscar_clientip_timeout\n");
 	xfer = (GaimXfer*) data;
 	if(xfer->data) {
 		oft_info = (struct aim_oft_info*) xfer->data;
-
+		
 		/* Check to see if the clientip has produced any results */
-		if(oft_info->conn && oft_info->conn->status != AIM_CONN_STATUS_INPROGRESS) {
+		if(!oft_info->success) {
 			msg = g_strdup_printf(_("Transfer of file %s timed out."),gaim_xfer_get_filename(xfer));
 			gaim_xfer_conversation_write(xfer, msg, TRUE);
 			g_free(msg);
 			gaim_xfer_unref(xfer);
 			gaim_xfer_cancel_local(xfer);
+		} else {
+			gaim_debug_info("oscar","connection successful; no action taken\n");
 		}
 	}
 	return FALSE;
@@ -2058,18 +2061,21 @@
 		oft_info = (struct aim_oft_info*) xfer->data;
 		
 		/* Check to see if the verifiedip has produced any results */
-		if(oft_info->conn && oft_info->conn->status != AIM_CONN_STATUS_INPROGRESS) {
+		if(!oft_info->success) {
 			/* gaim_xfer_conversation_write(xfer,
 				"Attempting file transfer via secondary IP address...", FALSE); */
 		
 			/* The verifiedip connection has worn out its welcome. Goodbye. */
+			close(oft_info->conn->fd);
 			aim_conn_kill(oft_info->sess, &oft_info->conn);
 			
 			/* Try the file transfer again with the clientip */
 			g_free(xfer->remote_ip);
 			xfer->remote_ip = g_strdup(oft_info->clientip);
-			gaim_debug_info("oscar","attempting connection using clientip\n");
+			gaim_debug_info("oscar","attempting connection using clientip: %s\n", xfer->remote_ip);
 			oscar_xfer_init_recv(xfer);
+		} else {
+			gaim_debug_info("oscar","connection successful; no action taken\n");
 		}
 	}
 	return FALSE;
@@ -2082,7 +2088,7 @@
 	OscarData *od = gc->proto_data;
 
 	gaim_debug_info("oscar", "AAA - in oscar_xfer_recv_init\n");
-
+	
 	/* Start a timer for this ip address
 	 * If the verifiedip fails, try the clientip
 	 * If clientip fails, declare the whole file transfer dead
@@ -2103,7 +2109,7 @@
 		oft_info->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
 		aim_conn_addhandler(od->sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_PROMPT, oscar_sendfile_prompt, 0);
 		oft_info->conn->fd = xfer->fd = gaim_proxy_connect(gaim_connection_get_account(gc),
-					xfer->remote_ip, xfer->remote_port,	oscar_sendfile_connected, xfer);
+					xfer->remote_ip, xfer->remote_port, oscar_sendfile_connected, xfer);
 		if (xfer->fd == -1) {
 			gaim_xfer_error(GAIM_XFER_RECEIVE, gaim_xfer_get_account(xfer), xfer->who,
 							_("Unable to establish file descriptor."));
@@ -3272,9 +3278,23 @@
 	if (!(oft_info = xfer->data))
 		return;
 	if (source < 0) {
-		gaim_xfer_cancel_remote(xfer);
-		return;
-	}
+		/* This will also be called 3 minutes after the verifiedip times out.
+		 * However, we might have made a successful connection with the clientip
+		 * so we need to make sure the verifiedip's failures aren't taken out
+		 * on the poor little clientip, which might actually have been a success. */
+		if(oft_info->success) {
+			gaim_debug_info("oscar","fd of %d for verifiedip, but clientip succeeded; ignoring\n",
+				source);
+			return;
+		} else {
+			gaim_debug_info("oscar","received fd of %d; aborting transfer\n", source);
+			gaim_xfer_cancel_remote(xfer);
+			return;
+		}
+	}
+	
+	gaim_debug_info("oscar","marking connection as success; fd is %d\n", source);
+	oft_info->success = TRUE; /* Mark this connection as successful before it times out */
 
 	xfer->fd = source;
 	oft_info->conn->fd = source;
@@ -3642,6 +3662,8 @@
 			 * get this, then maybe a third party connected 
 			 * to us, and we shouldn't send them anything.
 			 */
+			 gaim_debug_info("oscar",
+			 	"AAA - received chan 2 AIM_RENDEZVOUS_ACCEPT; ignoring\n");
 		} else {
 			gaim_debug_error("oscar",
 					   "unknown rendezvous status!\n");
--- a/src/protocols/oscar/rxqueue.c	Mon Aug 08 21:43:44 2005 +0000
+++ b/src/protocols/oscar/rxqueue.c	Tue Aug 09 00:25:39 2005 +0000
@@ -172,8 +172,10 @@
 	if (conn->fd == -1)
 		return -1; /* it's an aim_conn_close()'d connection */
 
-	if (conn->fd < 3) /* can happen when people abuse the interface */
+	/* If stdin is closed, then zero becomes a valid fd
+	if (conn->fd < 3)
 		return -1;
+	*/
 
 	if (conn->status & AIM_CONN_STATUS_INPROGRESS)
 		return aim_conn_completeconnect(sess, conn);