changeset 14104:b0566d50291f

[gaim-migrate @ 16735] Oscar peer connections now use the proxy_connect_cancel() function, so they don't need to use GAIM_CONNECTION_IS_VALID() anymore. Also, peer connection attempts will time out after 15 seconds. Yay. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 13 Aug 2006 08:41:07 +0000
parents eec0c7fd8529
children eaf7f35635bc
files src/protocols/oscar/peer.c src/protocols/oscar/peer.h src/protocols/oscar/peer_proxy.c
diffstat 3 files changed, 91 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/peer.c	Sun Aug 13 08:38:02 2006 +0000
+++ b/src/protocols/oscar/peer.c	Sun Aug 13 08:41:07 2006 +0000
@@ -139,6 +139,18 @@
 	else if (conn->type == OSCAR_CAPABILITY_SENDFILE)
 		peer_oft_close(conn);
 
+	if (conn->connect_info != NULL)
+	{
+		gaim_proxy_connect_cancel(conn->connect_info);
+		conn->connect_info = NULL;
+	}
+
+	if (conn->connect_timeout_timer != 0)
+	{
+		gaim_timeout_remove(conn->connect_timeout_timer);
+		conn->connect_timeout_timer = 0;
+	}
+
 	if (conn->watcher_incoming != 0)
 	{
 		gaim_input_remove(conn->watcher_incoming);
@@ -472,21 +484,13 @@
 static void
 peer_connection_established_cb(gpointer data, gint source)
 {
-	NewPeerConnectionData *new_conn_data;
-	GaimConnection *gc;
 	PeerConnection *conn;
 
-	new_conn_data = data;
-	gc = new_conn_data->gc;
-	conn = new_conn_data->conn;
-	g_free(new_conn_data);
+	conn = data;
 
-	if (!GAIM_CONNECTION_IS_VALID(gc))
-	{
-		if (source >= 0)
-			close(source);
-		return;
-	}
+	conn->connect_info = NULL;
+	gaim_timeout_remove(conn->connect_timeout_timer);
+	conn->connect_timeout_timer = 0;
 
 	if (source < 0)
 	{
@@ -627,20 +631,53 @@
 }
 
 /**
+ * This is a callback function used when we're connecting to a peer
+ * using either the client IP or the verified IP and the connection
+ * took longer than 15 seconds to complete.  We do this because
+ * waiting for the OS to time out the connection attempt is not
+ * practical--the default timeout on many OSes can be 3 minutes or
+ * more, and users are impatient.
+ *
+ * Worst case scenario: the user is connected to the Internet using
+ * a modem with severe lag.  The peer connections fail and Gaim falls
+ * back to using a proxied connection.  The lower bandwidth
+ * limitations imposed by the proxied connection won't matter because
+ * the user is using a modem.
+ *
+ * I suppose this line of thinking is discriminatory against people
+ * with very high lag but decent throughput who are transferring
+ * large files.  But we don't care about those people.
+ */
+static gboolean
+peer_connection_tooktoolong(gpointer data)
+{
+	PeerConnection *conn;
+
+	conn = data;
+
+	gaim_debug_info("oscar", "Peer connection timed out after 15 seconds.  "
+			"Trying next method...\n");
+
+	gaim_proxy_connect_cancel(conn->connect_info);
+	conn->connect_info = NULL;
+	conn->connect_timeout_timer = 0;
+
+	peer_connection_trynext(conn);
+
+	/* Cancel this timer.  It'll be added again, if needed. */
+	return FALSE;
+}
+
+/**
  * Try to establish the given PeerConnection using a defined
  * sequence of steps.
  */
 void
 peer_connection_trynext(PeerConnection *conn)
 {
-	NewPeerConnectionData *new_conn_data;
 	GaimAccount *account;
 
-	new_conn_data = g_new(NewPeerConnectionData, 1);
-	new_conn_data->gc = conn->od->gc;
-	new_conn_data->conn = conn;
-
-	account = gaim_connection_get_account(new_conn_data->gc);
+	account = gaim_connection_get_account(conn->od->gc);
 
 	/*
 	 * Close any remnants of a previous failed connection attempt.
@@ -667,10 +704,14 @@
 			g_free(tmp);
 		}
 
-		if (gaim_proxy_connect(account, conn->verifiedip, conn->port,
-				peer_connection_established_cb, NULL, new_conn_data) != NULL)
+		conn->connect_info = gaim_proxy_connect(account,
+				conn->verifiedip, conn->port,
+				peer_connection_established_cb, NULL, conn);
+		if (conn->connect_info != NULL)
 		{
 			/* Connecting... */
+			conn->connect_timeout_timer = gaim_timeout_add(15000,
+					peer_connection_tooktoolong, conn);
 			return;
 		}
 	}
@@ -698,10 +739,14 @@
 				g_free(tmp);
 			}
 
-			if (gaim_proxy_connect(account, conn->clientip, conn->port,
-					peer_connection_established_cb, NULL, new_conn_data) != NULL)
+			conn->connect_info = gaim_proxy_connect(account,
+					conn->clientip, conn->port,
+					peer_connection_established_cb, NULL, conn);
+			if (conn->connect_info != NULL)
 			{
 				/* Connecting... */
+				conn->connect_timeout_timer = gaim_timeout_add(15000,
+						peer_connection_tooktoolong, conn);
 				return;
 			}
 		}
@@ -714,6 +759,12 @@
 	if (!(conn->flags & PEER_CONNECTION_FLAG_TRIED_INCOMING) &&
 		(!conn->use_proxy))
 	{
+		NewPeerConnectionData *new_conn_data;
+
+		new_conn_data = g_new(NewPeerConnectionData, 1);
+		new_conn_data->gc = conn->od->gc;
+		new_conn_data->conn = conn;
+
 		conn->flags |= PEER_CONNECTION_FLAG_TRIED_INCOMING;
 
 		/*
@@ -728,6 +779,8 @@
 			/* Opening listener socket... */
 			return;
 		}
+
+		g_free(new_conn_data);
 	}
 
 	/*
@@ -757,18 +810,17 @@
 			g_free(tmp);
 		}
 
-		if (gaim_proxy_connect(account,
+		conn->connect_info = gaim_proxy_connect(account,
 				(conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER,
 				PEER_PROXY_PORT,
-				peer_proxy_connection_established_cb, NULL, new_conn_data) != NULL)
+				peer_proxy_connection_established_cb, NULL, conn);
+		if (conn->connect_info != NULL)
 		{
 			/* Connecting... */
 			return;
 		}
 	}
 
-	g_free(new_conn_data);
-
 	/* Give up! */
 	peer_connection_destroy(conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT);
 }
--- a/src/protocols/oscar/peer.h	Sun Aug 13 08:38:02 2006 +0000
+++ b/src/protocols/oscar/peer.h	Sun Aug 13 08:41:07 2006 +0000
@@ -159,10 +159,21 @@
 	gpointer frame;
 
 	/**
+	 * This is only used when the peer connection is being established.
+	 */
+	GaimProxyConnectInfo *connect_info;
+
+	/**
+	 * This is only used when the peer connection is being established.
+	 */
+	guint connect_timeout_timer;
+
+	/**
 	 * This is only used while the remote user is attempting to
 	 * connect to us.
 	 */
 	int listenerfd;
+
 	int fd;
 
 	guint watcher_incoming;
--- a/src/protocols/oscar/peer_proxy.c	Sun Aug 13 08:38:02 2006 +0000
+++ b/src/protocols/oscar/peer_proxy.c	Sun Aug 13 08:41:07 2006 +0000
@@ -328,21 +328,11 @@
 void
 peer_proxy_connection_established_cb(gpointer data, gint source)
 {
-	NewPeerConnectionData *new_conn_data;
-	GaimConnection *gc;
 	PeerConnection *conn;
 
-	new_conn_data = data;
-	gc = new_conn_data->gc;
-	conn = new_conn_data->conn;
-	g_free(new_conn_data);
+	conn = data;
 
-	if (!GAIM_CONNECTION_IS_VALID(gc))
-	{
-		if (source >= 0)
-			close(source);
-		return;
-	}
+	conn->connect_info = NULL;
 
 	if (source < 0)
 	{