From ef94a3d5a05f41570143f5aa4dcd629d1b5c0c92 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 15 Mar 2021 10:22:10 -0400 Subject: [PATCH] Fix #862, comments describing select after connect A select() is used after connect() to provide application-controlled timeout on the connection initiation. This just adds some comments to describe why this is done. It also adds a debug statement if the connect fails for a reason other than EINPROGRESS. --- src/os/portable/os-impl-bsd-sockets.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/os/portable/os-impl-bsd-sockets.c b/src/os/portable/os-impl-bsd-sockets.c index 59bc5d26a..ac722f809 100644 --- a/src/os/portable/os-impl-bsd-sockets.c +++ b/src/os/portable/os-impl-bsd-sockets.c @@ -273,10 +273,24 @@ int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t { if (errno != EINPROGRESS) { + OS_DEBUG("connect: %s\n", strerror(errno)); return_code = OS_ERROR; } else { + /* + * If the socket was created in nonblocking mode (O_NONBLOCK flag) then the connect + * runs in the background and connect() returns EINPROGRESS. In this case we still + * want to provide the "normal" (blocking) semantics to the calling app, such that + * when OS_SocketConnect() returns, the socket is ready for use. + * + * To provide consistent behavior to calling apps, this does a select() to wait + * for the socket to become writable, meaning that the remote side is connected. + * + * An important point here is that the calling app can control the timeout. If the + * normal/blocking connect() was used, the OS/IP stack controls the timeout, and it + * can be quite long. + */ operation = OS_STREAM_STATE_WRITABLE; if (impl->selectable) { @@ -290,6 +304,10 @@ int32 OS_SocketConnect_Impl(const OS_object_token_t *token, const OS_SockAddr_t } else { + /* + * The SO_ERROR socket flag should also read back zero. + * If not zero, something went wrong during connect + */ sockopt = 0; slen = sizeof(sockopt); os_status = getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, &sockopt, &slen);