Skip to content

Commit e12d8c8

Browse files
authored
fix: WiFiClientSecure connection timeout (#5398) (#5418)
Closes #5398 Using the same non-blocking socket connect pattern for respecting connection timeout, copied from WiFiClient::connect. WiFiClient::connect uses lwip_connect_r, whereas start_ssl_client uses lwip_connect. I haven't found what is the difference between them. I tested both, both work ok, so I kept lwip_connect.
1 parent 4ada3f5 commit e12d8c8

File tree

1 file changed

+50
-13
lines changed

1 file changed

+50
-13
lines changed

Diff for: libraries/WiFiClientSecure/src/ssl_client.cpp

+50-13
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,67 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
7676
return -1;
7777
}
7878

79+
fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
7980
struct sockaddr_in serv_addr;
8081
memset(&serv_addr, 0, sizeof(serv_addr));
8182
serv_addr.sin_family = AF_INET;
8283
serv_addr.sin_addr.s_addr = srv;
8384
serv_addr.sin_port = htons(port);
8485

85-
if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
86-
if(timeout <= 0){
87-
timeout = 30000; // Milli seconds.
88-
}
89-
timeval so_timeout = { .tv_sec = timeout / 1000, .tv_usec = (timeout % 1000) * 1000 };
86+
if(timeout <= 0){
87+
timeout = 30000; // Milli seconds.
88+
}
9089

91-
#define ROE(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }}
92-
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &so_timeout, sizeof(so_timeout)),"SO_RCVTIMEO");
93-
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &so_timeout, sizeof(so_timeout)),"SO_SNDTIMEO");
90+
fd_set fdset;
91+
struct timeval tv;
92+
FD_ZERO(&fdset);
93+
FD_SET(ssl_client->socket, &fdset);
94+
tv.tv_sec = timeout / 1000;
95+
tv.tv_usec = (timeout % 1000) * 1000;
9496

95-
ROE(lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY");
96-
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE");
97-
} else {
98-
log_e("Connect to Server failed!");
97+
int res = lwip_connect(ssl_client->socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
98+
if (res < 0 && errno != EINPROGRESS) {
99+
log_e("connect on fd %d, errno: %d, \"%s\"", ssl_client->socket, errno, strerror(errno));
100+
close(ssl_client->socket);
99101
return -1;
100102
}
101103

102-
fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
104+
res = select(ssl_client->socket + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv);
105+
if (res < 0) {
106+
log_e("select on fd %d, errno: %d, \"%s\"", ssl_client->socket, errno, strerror(errno));
107+
close(ssl_client->socket);
108+
return -1;
109+
} else if (res == 0) {
110+
log_i("select returned due to timeout %d ms for fd %d", timeout, ssl_client->socket);
111+
close(ssl_client->socket);
112+
return -1;
113+
} else {
114+
int sockerr;
115+
socklen_t len = (socklen_t)sizeof(int);
116+
res = getsockopt(ssl_client->socket, SOL_SOCKET, SO_ERROR, &sockerr, &len);
117+
118+
if (res < 0) {
119+
log_e("getsockopt on fd %d, errno: %d, \"%s\"", ssl_client->socket, errno, strerror(errno));
120+
close(ssl_client->socket);
121+
return -1;
122+
}
123+
124+
if (sockerr != 0) {
125+
log_e("socket error on fd %d, errno: %d, \"%s\"", ssl_client->socket, sockerr, strerror(sockerr));
126+
close(ssl_client->socket);
127+
return -1;
128+
}
129+
}
130+
131+
132+
#define ROE(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }}
133+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),"SO_RCVTIMEO");
134+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),"SO_SNDTIMEO");
135+
136+
ROE(lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY");
137+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE");
138+
139+
103140

104141
log_v("Seeding the random number generator");
105142
mbedtls_entropy_init(&ssl_client->entropy_ctx);

0 commit comments

Comments
 (0)