Skip to content

Commit 823fe77

Browse files
authored
Uniform behaviour of WiFiClientSecure and WiFiClient setTimeout() (#6562)
* Uniform timeout WiFiClient-WiFiClientSecure * Added missing prototype * Add socket check on setTimeout
1 parent a9d33de commit 823fe77

File tree

4 files changed

+64
-27
lines changed

4 files changed

+64
-27
lines changed

Diff for: libraries/WiFi/src/WiFiClient.cpp

+34-18
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ class WiFiClientSocketHandle {
175175
}
176176
};
177177

178-
WiFiClient::WiFiClient():_connected(false),next(NULL)
178+
WiFiClient::WiFiClient():_connected(false),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL)
179179
{
180180
}
181181

182-
WiFiClient::WiFiClient(int fd):_connected(true),next(NULL)
182+
WiFiClient::WiFiClient(int fd):_connected(true),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL)
183183
{
184184
clientSocketHandle.reset(new WiFiClientSocketHandle(fd));
185185
_rxBuffer.reset(new WiFiClientRxBuffer(fd));
@@ -208,10 +208,11 @@ void WiFiClient::stop()
208208

209209
int WiFiClient::connect(IPAddress ip, uint16_t port)
210210
{
211-
return connect(ip,port,WIFI_CLIENT_DEF_CONN_TIMEOUT_MS);
212-
}
213-
int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout )
211+
return connect(ip,port,_timeout);
212+
}
213+
int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout)
214214
{
215+
_timeout = timeout;
215216
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
216217
if (sockfd < 0) {
217218
log_e("socket: %d", errno);
@@ -230,7 +231,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
230231
FD_ZERO(&fdset);
231232
FD_SET(sockfd, &fdset);
232233
tv.tv_sec = 0;
233-
tv.tv_usec = timeout * 1000;
234+
tv.tv_usec = _timeout * 1000;
234235

235236
#ifdef ESP_IDF_VERSION_MAJOR
236237
int res = lwip_connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
@@ -243,13 +244,13 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
243244
return 0;
244245
}
245246

246-
res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv);
247+
res = select(sockfd + 1, nullptr, &fdset, nullptr, _timeout<0 ? nullptr : &tv);
247248
if (res < 0) {
248249
log_e("select on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
249250
close(sockfd);
250251
return 0;
251252
} else if (res == 0) {
252-
log_i("select returned due to timeout %d ms for fd %d", timeout, sockfd);
253+
log_i("select returned due to timeout %d ms for fd %d", _timeout, sockfd);
253254
close(sockfd);
254255
return 0;
255256
} else {
@@ -270,6 +271,14 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
270271
}
271272
}
272273

274+
#define ROE_WIFICLIENT(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }}
275+
ROE_WIFICLIENT(lwip_setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),"SO_RCVTIMEO");
276+
ROE_WIFICLIENT(lwip_setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),"SO_SNDTIMEO");
277+
278+
// These are also set in WiFiClientSecure, should be set here too?
279+
//ROE_WIFICLIENT(lwip_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY");
280+
//ROE_WIFICLIENT (lwip_setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE");
281+
273282
fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) );
274283
clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd));
275284
_rxBuffer.reset(new WiFiClientRxBuffer(sockfd));
@@ -279,9 +288,10 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
279288

280289
int WiFiClient::connect(const char *host, uint16_t port)
281290
{
282-
return connect(host,port,WIFI_CLIENT_DEF_CONN_TIMEOUT_MS);
283-
}
284-
int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout )
291+
return connect(host,port,_timeout);
292+
}
293+
294+
int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout)
285295
{
286296
IPAddress srv((uint32_t)0);
287297
if(!WiFiGenericClass::hostByName(host, srv)){
@@ -301,14 +311,20 @@ int WiFiClient::setSocketOption(int option, char* value, size_t len)
301311

302312
int WiFiClient::setTimeout(uint32_t seconds)
303313
{
304-
Client::setTimeout(seconds * 1000);
305-
struct timeval tv;
306-
tv.tv_sec = seconds;
307-
tv.tv_usec = 0;
308-
if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) {
309-
return -1;
314+
Client::setTimeout(seconds * 1000); // This should be here?
315+
_timeout = seconds * 1000;
316+
if(fd() >= 0) {
317+
struct timeval tv;
318+
tv.tv_sec = seconds;
319+
tv.tv_usec = 0;
320+
if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) {
321+
return -1;
322+
}
323+
return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
324+
}
325+
else {
326+
return 0;
310327
}
311-
return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
312328
}
313329

314330
int WiFiClient::setOption(int option, int *value)

Diff for: libraries/WiFi/src/WiFiClient.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class WiFiClient : public ESPLwIPClient
4242
std::shared_ptr<WiFiClientSocketHandle> clientSocketHandle;
4343
std::shared_ptr<WiFiClientRxBuffer> _rxBuffer;
4444
bool _connected;
45+
int _timeout;
4546

4647
public:
4748
WiFiClient *next;

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

+26-7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
WiFiClientSecure::WiFiClientSecure()
3333
{
3434
_connected = false;
35+
_timeout = 30000; // Same default as ssl_client
3536

3637
sslclient = new sslclient_context;
3738
ssl_init(sslclient);
@@ -52,7 +53,7 @@ WiFiClientSecure::WiFiClientSecure()
5253
WiFiClientSecure::WiFiClientSecure(int sock)
5354
{
5455
_connected = false;
55-
_timeout = 0;
56+
_timeout = 30000; // Same default as ssl_client
5657

5758
sslclient = new sslclient_context;
5859
ssl_init(sslclient);
@@ -128,9 +129,6 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert,
128129

129130
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key)
130131
{
131-
if(_timeout > 0){
132-
sslclient->handshake_timeout = _timeout;
133-
}
134132
int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, _use_ca_bundle, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos);
135133
_lastError = ret;
136134
if (ret < 0) {
@@ -148,9 +146,6 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *pskIdent,
148146

149147
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) {
150148
log_v("start_ssl_client with PSK");
151-
if(_timeout > 0){
152-
sslclient->handshake_timeout = _timeout;
153-
}
154149
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, false, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos);
155150
_lastError = ret;
156151
if (ret < 0) {
@@ -365,3 +360,27 @@ void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos)
365360
{
366361
_alpn_protos = alpn_protos;
367362
}
363+
int WiFiClientSecure::setTimeout(uint32_t seconds)
364+
{
365+
_timeout = seconds * 1000;
366+
if (sslclient->socket >= 0) {
367+
struct timeval tv;
368+
tv.tv_sec = seconds;
369+
tv.tv_usec = 0;
370+
if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) {
371+
return -1;
372+
}
373+
return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
374+
}
375+
else {
376+
return 0;
377+
}
378+
}
379+
int WiFiClientSecure::setSocketOption(int option, char* value, size_t len)
380+
{
381+
int res = setsockopt(sslclient->socket, SOL_SOCKET, option, value, len);
382+
if(res < 0) {
383+
log_e("%X : %d", option, errno);
384+
}
385+
return res;
386+
}

Diff for: libraries/WiFiClientSecure/src/WiFiClientSecure.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class WiFiClientSecure : public WiFiClient
3232

3333
int _lastError = 0;
3434
int _peek = -1;
35-
int _timeout = 0;
35+
int _timeout;
3636
bool _use_insecure;
3737
const char *_CA_cert;
3838
const char *_cert;
@@ -79,7 +79,8 @@ class WiFiClientSecure : public WiFiClient
7979
void setAlpnProtocols(const char **alpn_protos);
8080
const mbedtls_x509_crt* getPeerCertificate() { return mbedtls_ssl_get_peer_cert(&sslclient->ssl_ctx); };
8181
bool getFingerprintSHA256(uint8_t sha256_result[32]) { return get_peer_fingerprint(sslclient, sha256_result); };
82-
int setTimeout(uint32_t seconds){ return 0; }
82+
int setTimeout(uint32_t seconds);
83+
int setSocketOption(int option, char* value, size_t len);
8384

8485
operator bool()
8586
{

0 commit comments

Comments
 (0)