[Telepathy-commits] [telepathy-idle/master] Handle connect()s that return success immediately

Jonathon Jongsma jonathon.jongsma at collabora.co.uk
Fri Feb 13 17:43:16 PST 2009


The documentation on connect() is cryptic about in what situations a
non-blocking socket can connect immediately, but in theory it is possible.  I
had several test failures caused by violating the assumption that the return
status from connect() is always -1 on a non-blocking socket.  These turned out
to be caused by attempting to connect a UDP socket (which apparently is
instantaneous even on non-blocking sockets), but it seems wise to handle this
case more gracefully anyway, rather than simply asserting.
---
 src/idle-server-connection.c     |   12 ++++++------
 src/idle-ssl-server-connection.c |    4 +---
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/idle-server-connection.c b/src/idle-server-connection.c
index 1808cae..fc935a1 100644
--- a/src/idle-server-connection.c
+++ b/src/idle-server-connection.c
@@ -377,13 +377,13 @@ static gboolean connect_io_func(GIOChannel *src, GIOCondition cond, gpointer dat
 		opt = 1;
 
 		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
-			g_warning("%s: failed to set TCP_NODELAY", G_STRFUNC);
+			g_warning("%s: failed to set TCP_NODELAY: %s", G_STRFUNC, g_strerror(errno));
 		}
 
 		opt = 1;
 
 		if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)) < 0) {
-			g_warning("%s: failed to set SO_KEEPALIVE", G_STRFUNC);
+			g_warning("%s: failed to set SO_KEEPALIVE: %s", G_STRFUNC, g_strerror(errno));
 		}
 
 		return FALSE;
@@ -404,7 +404,7 @@ static gboolean connect_io_func(GIOChannel *src, GIOCondition cond, gpointer dat
 		IDLE_DEBUG("re-using existing socket for trying again");
 
 		errno = 0;
-		connect(connect_data->fd, next->ai_addr, next->ai_addrlen);
+		rc = connect(connect_data->fd, next->ai_addr, next->ai_addrlen);
 
 		for (int i = 0; i < 5 && errno == ECONNABORTED; i++) {
 			IDLE_DEBUG("got ECONNABORTED for %ith time", i + 1);
@@ -412,7 +412,7 @@ static gboolean connect_io_func(GIOChannel *src, GIOCondition cond, gpointer dat
 			connect(connect_data->fd, next->ai_addr, next->ai_addrlen);
 		}
 
-		if (errno != EINPROGRESS) {
+		if ((errno != EINPROGRESS) && (rc == -1)) {
 			IDLE_DEBUG("connect() failed: %s", g_strerror(errno));
 			change_state(conn, SERVER_CONNECTION_STATE_NOT_CONNECTED, SERVER_CONNECTION_STATE_REASON_ERROR);
 			return FALSE;
@@ -463,9 +463,9 @@ static gboolean connect_io_func(GIOChannel *src, GIOCondition cond, gpointer dat
 	}
 
 	errno = 0;
-	connect(fd, cur->ai_addr, cur->ai_addrlen);
+	rc = connect(fd, cur->ai_addr, cur->ai_addrlen);
 
-	if (errno != EINPROGRESS) {
+	if ((errno != EINPROGRESS) && (rc == -1)) {
 		IDLE_DEBUG("initial connect() failed: %s", g_strerror(errno));
 		g_io_channel_shutdown(io_chan, FALSE, NULL);
 		g_io_channel_unref(io_chan);
diff --git a/src/idle-ssl-server-connection.c b/src/idle-ssl-server-connection.c
index 046ece2..d21599a 100644
--- a/src/idle-ssl-server-connection.c
+++ b/src/idle-ssl-server-connection.c
@@ -480,9 +480,7 @@ static void ssl_do_connect(AsyncConnectData *data) {
 
 	rc = connect(fd, data->cur->ai_addr, data->cur->ai_addrlen);
 
-	g_assert(rc == -1);
-
-	if (errno != EINPROGRESS) {
+	if ((errno != EINPROGRESS) && (rc == -1)) {
 		IDLE_DEBUG("connect() failed: %s", g_strerror(errno));
 		close(fd);
 		return data->finished_cb(data->conn, FALSE);
-- 
1.5.6.5




More information about the telepathy-commits mailing list