diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index aa479a2d57..bc6e516637 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -216,7 +216,6 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) { return 0; } - _client->setTimeout(_timeout); return _client->write((const char*)buf, size); } @@ -229,7 +228,6 @@ size_t WiFiClient::write(Stream& stream) return 0; } // core up to 2.7.4 was equivalent to this - _client->setTimeout(_timeout); return stream.sendAll(this); } @@ -239,7 +237,6 @@ size_t WiFiClient::write_P(PGM_P buf, size_t size) { return 0; } - _client->setTimeout(_timeout); StreamConstPtr nopeek(buf, size); return nopeek.sendAll(this); } @@ -267,13 +264,11 @@ int WiFiClient::read() int WiFiClient::read(uint8_t* buf, size_t size) { - _client->setTimeout(_timeout); return (int)_client->read((char*)buf, size); } int WiFiClient::read(char* buf, size_t size) { - _client->setTimeout(_timeout); return (int)_client->read(buf, size); } @@ -282,7 +277,6 @@ int WiFiClient::peek() if (!available()) return -1; - _client->setTimeout(_timeout); return _client->peek(); } @@ -304,7 +298,6 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { count = length; } - _client->setTimeout(_timeout); return _client->peekBytes((char *)buffer, count); } @@ -459,7 +452,6 @@ const char* WiFiClient::peekBuffer () // return number of byte accessible by peekBuffer() size_t WiFiClient::peekAvailable () { - _client->setTimeout(_timeout); return _client? _client->peekAvailable(): 0; } @@ -469,3 +461,10 @@ void WiFiClient::peekConsume (size_t consume) if (_client) _client->peekConsume(consume); } + +void WiFiClient::setTimeout(uint16_t timeout) { + _timeout = timeout; + if (_client) { + _client->setTimeout(timeout); + } +} diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h index 41ec5d8547..34ab42eecb 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/libraries/ESP8266WiFi/src/WiFiClient.h @@ -96,6 +96,8 @@ class WiFiClient : public Client, public SList { virtual IPAddress localIP(); virtual uint16_t localPort(); + void setTimeout(uint16_t); + static void setLocalPortStart(uint16_t port) { _localPort = port; } int availableForWrite() override; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 08f4d1e49b..57435d3fc8 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -80,7 +80,7 @@ void WiFiClientSecureCtx::_clear() { _now = 0; // You can override or ensure time() is correct w/configTime _ta = nullptr; setBufferSizes(16384, 512); // Minimum safe - _set_handshake_done(false); // refreshes _timeout + _handshake_done = false; _recvapp_buf = nullptr; _recvapp_len = 0; _oom_err = false; @@ -201,14 +201,12 @@ bool WiFiClientSecureCtx::stop(unsigned int maxWaitMs) { } bool WiFiClientSecureCtx::flush(unsigned int maxWaitMs) { - auto savedNormal = _normalTimeout; - auto savedHandshake = _handshakeTimeout; - _normalTimeout = maxWaitMs; - _handshakeTimeout = maxWaitMs; - (void) _run_until(BR_SSL_SENDAPP); - _normalTimeout = savedNormal; - _handshakeTimeout = savedHandshake; - return WiFiClient::flush(maxWaitMs); + const auto result = _run_until(BR_SSL_SENDAPP); + if (result != -1 && _engineConnected()) { + return WiFiClient::flush(maxWaitMs); + } + + return false; } int WiFiClientSecureCtx::connect(IPAddress ip, uint16_t port) { @@ -248,7 +246,7 @@ void WiFiClientSecureCtx::_freeSSL() { _recvapp_buf = nullptr; _recvapp_len = 0; // This connection is toast - _set_handshake_done(false); // refreshes _timeout + _handshake_done = false; } bool WiFiClientSecureCtx::_clientConnected() { @@ -463,7 +461,6 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) { return 0; } - _updateStreamTimeout(); _startMillis = millis(); while ((_pollRecvBuffer() < (int)length) && ((millis() - _startMillis) < _timeout)) { yield(); @@ -488,8 +485,8 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { // _run_until() is called prior to inherited read/write methods // -> refreshing _timeout here, which is also used by ancestors - DEBUG_BSSL("_run_until starts, timeout=%lu\n", _updateStreamTimeout()); - esp8266::polledTimeout::oneShotMs loopTimeout(_updateStreamTimeout()); + DEBUG_BSSL("_run_until starts, timeout=%lu\n", _runtimeTimeout); + esp8266::polledTimeout::oneShotMs loopTimeout(_runtimeTimeout); for (int no_work = 0; blocking || no_work < 2;) { optimistic_yield(100); @@ -607,8 +604,24 @@ int WiFiClientSecureCtx::_run_until(unsigned target, bool blocking) { return -1; } +void WiFiClientSecureCtx::_update_runtime_timeout(unsigned long timeout) { + _runtimeTimeout = timeout * 1.2; +} + +void WiFiClientSecureCtx::setTimeout(uint16_t timeout) { + WiFiClient::setTimeout(timeout); + if (_handshake_done) { + _update_runtime_timeout(timeout); + } +} + +void WiFiClientSecureCtx::_set_handshake_done(bool value) { + _handshake_done = value; + _update_runtime_timeout(value? _timeout: _handshakeTimeout); +} + bool WiFiClientSecureCtx::_wait_for_handshake() { - _set_handshake_done(false); // refreshes _timeout + _set_handshake_done(false); while (!_handshake_done && _clientConnected()) { int ret = _run_until(BR_SSL_SENDAPP); if (ret < 0) { @@ -616,7 +629,7 @@ bool WiFiClientSecureCtx::_wait_for_handshake() { break; } if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - _set_handshake_done(true); // refreshes _timeout + _set_handshake_done(true); } optimistic_yield(1000); } @@ -1212,8 +1225,6 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_insecure = nullptr; _x509_knownkey = nullptr; - // _timeout has been refreshed to normal operation as _handshake_done turned to true - return ret; } diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index f03792ee5b..89059ad25b 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -149,10 +149,11 @@ class WiFiClientSecureCtx : public WiFiClient { // consume bytes after use (see peekBuffer) virtual void peekConsume (size_t consume) override; - void setNormalTimeout (unsigned long timeout) { _normalTimeout = timeout; } void setHandshakeTimeout (unsigned long timeout) { _handshakeTimeout = timeout; } unsigned long getHandshakeTimeout () const { return _handshakeTimeout; } + void setTimeout(uint16_t); + protected: bool _connectSSL(const char *hostName); // Do initial SSL handshake @@ -242,12 +243,11 @@ class WiFiClientSecureCtx : public WiFiClient { uint8_t *_streamLoad(Stream& stream, size_t size); - // timeout management - - unsigned long _updateStreamTimeout () { return _timeout = _handshake_done? _normalTimeout: _handshakeTimeout; } - void _set_handshake_done (bool handshake_done) { _handshake_done = handshake_done; _updateStreamTimeout(); } + void _update_runtime_timeout(unsigned long); + void _set_handshake_done(bool); - unsigned long _normalTimeout = 5000, _handshakeTimeout = 15000; + unsigned long _handshakeTimeout = 15000; + unsigned long _runtimeTimeout; }; // class WiFiClientSecureCtx @@ -277,24 +277,24 @@ class WiFiClientSecure : public WiFiClient { std::unique_ptr clone() const override { return std::unique_ptr(new WiFiClientSecure(*this)); } uint8_t status() override { return _ctx->status(); } - int connect(IPAddress ip, uint16_t port) override { uto(); return _ctx->connect(ip, port); } - int connect(const String& host, uint16_t port) override { uto(); return _ctx->connect(host, port); } - int connect(const char* name, uint16_t port) override { uto(); return _ctx->connect(name, port); } - - uint8_t connected() override { uto(); return _ctx->connected(); } - size_t write(const uint8_t *buf, size_t size) override { uto(); return _ctx->write(buf, size); } - size_t write_P(PGM_P buf, size_t size) override { uto(); return _ctx->write_P(buf, size); } - size_t write(const char *buf) { uto(); return write((const uint8_t*)buf, strlen(buf)); } - size_t write_P(const char *buf) { uto(); return write_P((PGM_P)buf, strlen_P(buf)); } - size_t write(Stream& stream) /* Note this is not virtual */ { uto(); return _ctx->write(stream); } - int read(uint8_t *buf, size_t size) override { uto(); return _ctx->read(buf, size); } - int available() override { uto(); return _ctx->available(); } - int availableForWrite() override { uto(); return _ctx->availableForWrite(); } - int read() override { uto(); return _ctx->read(); } - int peek() override { uto(); return _ctx->peek(); } - size_t peekBytes(uint8_t *buffer, size_t length) override { uto(); return _ctx->peekBytes(buffer, length); } - bool flush(unsigned int maxWaitMs) { uto(); return _ctx->flush(maxWaitMs); } - bool stop(unsigned int maxWaitMs) { uto(); return _ctx->stop(maxWaitMs); } + int connect(IPAddress ip, uint16_t port) override { return _ctx->connect(ip, port); } + int connect(const String& host, uint16_t port) override { return _ctx->connect(host, port); } + int connect(const char* name, uint16_t port) override { return _ctx->connect(name, port); } + + uint8_t connected() override { return _ctx->connected(); } + size_t write(const uint8_t *buf, size_t size) override { return _ctx->write(buf, size); } + size_t write_P(PGM_P buf, size_t size) override { return _ctx->write_P(buf, size); } + size_t write(const char *buf) { return write((const uint8_t*)buf, strlen(buf)); } + size_t write_P(const char *buf) { return write_P((PGM_P)buf, strlen_P(buf)); } + size_t write(Stream& stream) /* Note this is not virtual */ { return _ctx->write(stream); } + int read(uint8_t *buf, size_t size) override { return _ctx->read(buf, size); } + int available() override { return _ctx->available(); } + int availableForWrite() override { return _ctx->availableForWrite(); } + int read() override { return _ctx->read(); } + int peek() override { return _ctx->peek(); } + size_t peekBytes(uint8_t *buffer, size_t length) override { return _ctx->peekBytes(buffer, length); } + bool flush(unsigned int maxWaitMs) { return _ctx->flush(maxWaitMs); } + bool stop(unsigned int maxWaitMs) { return _ctx->stop(maxWaitMs); } void flush() override { (void)flush(0); } void stop() override { (void)stop(0); } @@ -376,6 +376,10 @@ class WiFiClientSecure : public WiFiClient { void setHandshakeTimeout (unsigned long timeout) { _ctx->setHandshakeTimeout(timeout); } unsigned long getHandshakeTimeout () const { return _ctx->getHandshakeTimeout(); } + void setTimeout(uint16_t timeout) { + _ctx->setTimeout(timeout); + } + private: std::shared_ptr _ctx; @@ -393,12 +397,6 @@ class WiFiClientSecure : public WiFiClient { _ctx(new WiFiClientSecureCtx(client, chain, sk, iobuf_in_size, iobuf_out_size, cache, client_CA_ta, tls_min, tls_max)) { } - // (because Stream::setTimeout() is not virtual,) - // forward user timeout from Stream:: to SSL context - // this is internally called on every user operations - inline void uto () { _ctx->setNormalTimeout(_timeout); } - - }; // class WiFiClientSecure }; // namespace BearSSL