summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Jongsma <jonathon.jongsma@collabora.co.uk>2009-01-19 16:14:02 -0600
committerJonathon Jongsma <jonathon.jongsma@collabora.co.uk>2009-01-19 16:14:02 -0600
commit8c87b6e3b219d720038420201382b1b66ab7e789 (patch)
treef6c3d05fef8cb0e04593d58cc7b65dce65c652bc
parentfbd509b4e34f0e96fbd2a87e18fbecfdfedaef70 (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.c12
-rw-r--r--src/idle-ssl-server-connection.c4
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);