diff options
author | Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> | 2009-01-19 16:14:02 -0600 |
---|---|---|
committer | Jonathon Jongsma <jonathon.jongsma@collabora.co.uk> | 2009-01-19 16:14:02 -0600 |
commit | 8c87b6e3b219d720038420201382b1b66ab7e789 (patch) | |
tree | f6c3d05fef8cb0e04593d58cc7b65dce65c652bc | |
parent | fbd509b4e34f0e96fbd2a87e18fbecfdfedaef70 (diff) |
Handle connect()s that return success immediately
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.
-rw-r--r-- | src/idle-server-connection.c | 12 | ||||
-rw-r--r-- | 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); |