From d5fdd715efddfe5838996eeee7840223f81f52bd Mon Sep 17 00:00:00 2001 From: Felix Weinrank Date: Tue, 9 Jul 2019 18:48:05 +0200 Subject: [PATCH] WiFiClient.cpp - Fix connect() behavior (#2784) * WiFiClient.cpp - Fix connect() behavior * lwip_connect_r() : check return code --- libraries/WiFi/src/WiFiClient.cpp | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index f7902773..616b5de9 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -226,14 +226,41 @@ int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout) FD_SET(sockfd, &fdset); tv.tv_sec = 0; tv.tv_usec = timeout * 1000; - lwip_connect_r(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); - int res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv); - if (res != 1) - { - log_e("select: %d",errno); + + int res = lwip_connect_r(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)); + if (res < 0 && errno != EINPROGRESS) { + log_e("connect on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno)); close(sockfd); return 0; } + + res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv); + if (res < 0) { + log_e("select on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno)); + close(sockfd); + return 0; + } else if (res == 0) { + log_i("select returned due to timeout %d ms for fd %d", timeout, sockfd); + close(sockfd); + return 0; + } else { + int sockerr; + socklen_t len = (socklen_t)sizeof(int); + res = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &sockerr, &len); + + if (res < 0) { + log_e("getsockopt on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno)); + close(sockfd); + return 0; + } + + if (sockerr != 0) { + log_e("socket error on fd %d, errno: %d, \"%s\"", sockfd, sockerr, strerror(sockerr)); + close(sockfd); + return 0; + } + } + fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) ); clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd)); _rxBuffer.reset(new WiFiClientRxBuffer(sockfd));