From fb28a03c2b79cdb35ca51ff03ca998f396796be2 Mon Sep 17 00:00:00 2001 From: Fred Nicolson Date: Thu, 12 Jul 2018 11:46:59 +0100 Subject: [PATCH] Fixed Windows connect() bug for TcpSocket The socket is put into non-blocking mode prior to connecting. Previously, errno was being checked after connecting to see if the socket would block. This is the correct behaviour on Linux. On Windows however, errno remains 0, and WSAGetLastError() needs to be compared against WSAEWOULDBLOCK instead. --- src/SSLSocket.cpp | 2 +- src/TcpSocket.cpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/SSLSocket.cpp b/src/SSLSocket.cpp index 79ab9dd..2181b53 100644 --- a/src/SSLSocket.cpp +++ b/src/SSLSocket.cpp @@ -88,7 +88,7 @@ namespace fr mbedtls_ssl_init(ssl.get()); mbedtls_net_init(ssl_socket_descriptor.get()); - //Do to mbedtls not supporting connect timeouts, we have to use an fr::TcpSocket to + //Due to mbedtls not supporting connect timeouts, we have to use an fr::TcpSocket to //Open the descriptor, and then steal it. This is a hack. { fr::TcpSocket socket; diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index 5f0d290..a42fe8e 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -11,7 +11,7 @@ namespace fr { TcpSocket::TcpSocket() noexcept - : socket_descriptor(-1) + : socket_descriptor(-1) { } @@ -54,7 +54,7 @@ namespace fr received = 0; //Read RECV_CHUNK_SIZE bytes into the recv buffer - int64_t status = ::recv(socket_descriptor, (char*)data, buffer_size, 0); + int64_t status = ::recv(socket_descriptor, (char*)data, buffer_size, 0); if(status > 0) { @@ -125,10 +125,18 @@ namespace fr //Try and connect ret = ::connect(socket_descriptor, c->ai_addr, c->ai_addrlen); +#ifdef _WIN32 + if(ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK) +#else if(ret < 0 && errno != EINPROGRESS) +#endif + { continue; + } else if(ret == 0) //If it connected immediately then break out of the connect loop + { break; + } //Wait for the socket to do something/expire timeval tv = {};