Skip to content

Commit

Permalink
WiFiClientSecure owns context, fix stopAllExcept
Browse files Browse the repository at this point in the history
Fixes esp8266#8079

Because WiFiClientSecure inherits WiFiClient, and WiFiClientSecureCtx also
inherits WiFiClient, they both end up in the list of TCP connections that
are used for WiFiClient::stopAllExcept().  This would cause the underlying
SSL connection to be closed whenever you attempted to
stopAllExcept(WiFiClientSecure)

Fix by adding a "_owner" pointer in the WiFiClient object which points to
nullptr (default case) or to the associated upper-layer connection.
When stopping all connections except one, only look at the uppermost
connections.
  • Loading branch information
earlephilhower committed Jun 17, 2021
1 parent f1310c0 commit d2b0178
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 4 deletions.
15 changes: 13 additions & 2 deletions libraries/ESP8266WiFi/src/WiFiClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ WiFiClient* SList<WiFiClient>::_s_first = 0;


WiFiClient::WiFiClient()
: _client(0)
: _client(0), _owner(0)
{
_timeout = 5000;
WiFiClient::_add(this);
}

WiFiClient::WiFiClient(ClientContext* client)
: _client(client)
: _client(client), _owner(0)
{
_timeout = 5000;
_client->ref();
Expand All @@ -106,6 +106,7 @@ WiFiClient::WiFiClient(const WiFiClient& other)
_client = other._client;
_timeout = other._timeout;
_localPort = other._localPort;
_owner = other._owner;
if (_client)
_client->ref();
WiFiClient::_add(this);
Expand All @@ -118,6 +119,7 @@ WiFiClient& WiFiClient::operator=(const WiFiClient& other)
_client = other._client;
_timeout = other._timeout;
_localPort = other._localPort;
_owner = other._owner;
if (_client)
_client->ref();
return *this;
Expand Down Expand Up @@ -382,7 +384,16 @@ void WiFiClient::stopAll()

void WiFiClient::stopAllExcept(WiFiClient* except)
{
// Stop all will look at the highest-level wrapper connections only
// Find the "except" top-level connection
while (except->_owner) {
except = except->_owner;
}
for (WiFiClient* it = _s_first; it; it = it->_next) {
// Find the top-level owner of the current list entry
while (it->_owner) {
it = it->_owner;
}
if (it != except) {
it->stop();
}
Expand Down
1 change: 1 addition & 0 deletions libraries/ESP8266WiFi/src/WiFiClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class WiFiClient : public Client, public SList<WiFiClient> {
void _err(int8_t err);

ClientContext* _client;
WiFiClient* _owner;
static uint16_t _localPort;
};

Expand Down
4 changes: 2 additions & 2 deletions libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ class WiFiClientSecure : public WiFiClient {

public:

WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { }
WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { }
WiFiClientSecure():_ctx(new WiFiClientSecureCtx()) { _ctx->_owner = this; }
WiFiClientSecure(const WiFiClientSecure &rhs): WiFiClient(), _ctx(rhs._ctx) { if (_ctx) _ctx->_owner = this; }
~WiFiClientSecure() override { _ctx = nullptr; }

WiFiClientSecure& operator=(const WiFiClientSecure&) = default; // The shared-ptrs handle themselves automatically
Expand Down

0 comments on commit d2b0178

Please sign in to comment.