Skip to content

Commit 9dce076

Browse files
authored
Don't return true with WiFiClientSecureBearSSL::connected() when really disconnected (#8330)
* Don't return `true` with WiFiClientSecureBearSSL::connected() when disconnected Apply the same condition as with normal WiFiClient - we are not connected when it's not possible to both write and read. Implement separate methods for actual connection status and the internal ssl engine status and update methods that were previously using available() for this purpose Update examples to check available() when the intent is to only read the data and not interact with the client in any other way. Also, use connect() as a way to notify errors, no need to check things twice
1 parent 4a0b66b commit 9dce076

File tree

7 files changed

+59
-31
lines changed

7 files changed

+59
-31
lines changed

Diff for: libraries/ESP8266WiFi/examples/BearSSL_CertStore/BearSSL_CertStore.ino

+2-3
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
7575
if (!path) { path = "/"; }
7676

7777
Serial.printf("Trying: %s:443...", host);
78-
client->connect(host, port);
79-
if (!client->connected()) {
78+
if (!client->connect(host, port)) {
8079
Serial.printf("*** Can't connect. ***\n-------\n");
8180
return;
8281
}
@@ -88,7 +87,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
8887
client->write("\r\nUser-Agent: ESP8266\r\n");
8988
client->write("\r\n");
9089
uint32_t to = millis() + 5000;
91-
if (client->connected()) {
90+
while (client->available()) {
9291
do {
9392
char tmp[32];
9493
memset(tmp, 0, 32);

Diff for: libraries/ESP8266WiFi/examples/BearSSL_MaxFragmentLength/BearSSL_MaxFragmentLength.ino

+2-4
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ int fetchNoMaxFragmentLength() {
4444

4545
BearSSL::WiFiClientSecure client;
4646
client.setInsecure();
47-
client.connect("tls.mbed.org", 443);
48-
if (client.connected()) {
47+
if (client.connect("tls.mbed.org", 443)) {
4948
Serial.printf("Memory used: %d\n", ret - ESP.getFreeHeap());
5049
ret -= ESP.getFreeHeap();
5150
fetch(&client);
@@ -81,8 +80,7 @@ int fetchMaxFragmentLength() {
8180
Serial.printf("\nConnecting to https://tls.mbed.org\n");
8281
Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no");
8382
if (mfln) { client.setBufferSizes(512, 512); }
84-
client.connect("tls.mbed.org", 443);
85-
if (client.connected()) {
83+
if (client.connect("tls.mbed.org", 443)) {
8684
Serial.printf("MFLN status: %s\n", client.getMFLNStatus() ? "true" : "false");
8785
Serial.printf("Memory used: %d\n", ret - ESP.getFreeHeap());
8886
ret -= ESP.getFreeHeap();

Diff for: libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino

+2-3
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
6363
if (!path) { path = "/"; }
6464

6565
Serial.printf("Trying: %s:443...", host);
66-
client->connect(host, port);
67-
if (!client->connected()) {
66+
if (!client->connect(host, port)) {
6867
Serial.printf("*** Can't connect. ***\n-------\n");
6968
return;
7069
}
@@ -76,7 +75,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
7675
client->write("\r\nUser-Agent: ESP8266\r\n");
7776
client->write("\r\n");
7877
uint32_t to = millis() + 5000;
79-
if (client->connected()) {
78+
while (client->available()) {
8079
do {
8180
char tmp[32];
8281
memset(tmp, 0, 32);

Diff for: libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino

+2-3
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
4949
ESP.resetFreeContStack();
5050
uint32_t freeStackStart = ESP.getFreeContStack();
5151
Serial.printf("Trying: %s:443...", host);
52-
client->connect(host, port);
53-
if (!client->connected()) {
52+
if (!client->connect(host, port)) {
5453
Serial.printf("*** Can't connect. ***\n-------\n");
5554
return;
5655
}
@@ -62,7 +61,7 @@ void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_
6261
client->write("\r\nUser-Agent: ESP8266\r\n");
6362
client->write("\r\n");
6463
uint32_t to = millis() + 5000;
65-
if (client->connected()) {
64+
while (client->available()) {
6665
do {
6766
char tmp[32];
6867
memset(tmp, 0, 32);

Diff for: libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void setup() {
7777
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + github_host + "\r\n" + "User-Agent: BuildFailureDetectorESP8266\r\n" + "Connection: close\r\n\r\n");
7878

7979
Serial.println("Request sent");
80-
while (client.connected()) {
80+
while (client.available()) {
8181
String line = client.readStringUntil('\n');
8282
if (line == "\r") {
8383
Serial.println("Headers received");

Diff for: libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

+44-17
Original file line numberDiff line numberDiff line change
@@ -250,19 +250,32 @@ void WiFiClientSecureCtx::_freeSSL() {
250250
}
251251

252252
bool WiFiClientSecureCtx::_clientConnected() {
253-
return (_client && _client->state() == ESTABLISHED);
253+
if (!_client || (_client->state() == CLOSED)) {
254+
return false;
255+
}
256+
257+
return _client->state() == ESTABLISHED;
258+
}
259+
260+
bool WiFiClientSecureCtx::_engineConnected() {
261+
return _clientConnected() && _handshake_done && _eng && (br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED);
254262
}
255263

256264
uint8_t WiFiClientSecureCtx::connected() {
257-
if (available() || (_clientConnected() && _handshake_done && (br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED))) {
265+
if (!_engineConnected()) {
266+
return false;
267+
}
268+
269+
if (_pollRecvBuffer() > 0) {
258270
return true;
259271
}
260-
return false;
272+
273+
return _engineConnected();
261274
}
262275

263276
int WiFiClientSecureCtx::availableForWrite () {
264-
// code taken from ::_write()
265-
if (!connected() || !_handshake_done) {
277+
// Can't write things when there's no connection or br_ssl engine is closed
278+
if (!_engineConnected()) {
266279
return 0;
267280
}
268281
// Get BearSSL to a state where we can send
@@ -284,7 +297,7 @@ int WiFiClientSecureCtx::availableForWrite () {
284297
size_t WiFiClientSecureCtx::_write(const uint8_t *buf, size_t size, bool pmem) {
285298
size_t sent_bytes = 0;
286299

287-
if (!connected() || !size || !_handshake_done) {
300+
if (!size || !_engineConnected()) {
288301
return 0;
289302
}
290303

@@ -331,10 +344,11 @@ size_t WiFiClientSecureCtx::write_P(PGM_P buf, size_t size) {
331344
}
332345

333346
size_t WiFiClientSecureCtx::write(Stream& stream) {
334-
if (!connected() || !_handshake_done) {
335-
DEBUG_BSSL("write: Connect/handshake not completed yet\n");
347+
if (!_engineConnected()) {
348+
DEBUG_BSSL("write: no br_ssl engine to work with\n");
336349
return 0;
337350
}
351+
338352
return stream.sendAll(this);
339353
}
340354

@@ -343,12 +357,20 @@ int WiFiClientSecureCtx::read(uint8_t *buf, size_t size) {
343357
return -1;
344358
}
345359

346-
int avail = available();
347-
bool conn = connected();
348-
if (!avail && conn) {
349-
return 0; // We're still connected, but nothing to read
360+
// will either check the internal buffer, or try to wait for some data
361+
// *may* attempt to write some pending ::write() data b/c of _run_until
362+
int avail = _pollRecvBuffer();
363+
364+
// internal buffer might still be available for some time
365+
bool engine = _engineConnected();
366+
367+
// we're still connected, but nothing to read
368+
if (!avail && engine) {
369+
return 0;
350370
}
351-
if (!avail && !conn) {
371+
372+
// or, available failed to assign the internal buffer and we are already disconnected
373+
if (!avail && !engine) {
352374
DEBUG_BSSL("read: Not connected, none left available\n");
353375
return -1;
354376
}
@@ -363,10 +385,11 @@ int WiFiClientSecureCtx::read(uint8_t *buf, size_t size) {
363385
return to_copy;
364386
}
365387

366-
if (!conn) {
388+
if (!engine) {
367389
DEBUG_BSSL("read: Not connected\n");
368390
return -1;
369391
}
392+
370393
return 0; // If we're connected, no error but no read.
371394
}
372395

@@ -395,7 +418,7 @@ int WiFiClientSecureCtx::read() {
395418
return -1;
396419
}
397420

398-
int WiFiClientSecureCtx::available() {
421+
int WiFiClientSecureCtx::_pollRecvBuffer() {
399422
if (_recvapp_buf) {
400423
return _recvapp_len; // Anything from last call?
401424
}
@@ -416,8 +439,12 @@ int WiFiClientSecureCtx::available() {
416439
return 0;
417440
}
418441

442+
int WiFiClientSecureCtx::available() {
443+
return _pollRecvBuffer();
444+
}
445+
419446
int WiFiClientSecureCtx::peek() {
420-
if (!ctx_present() || !available()) {
447+
if (!ctx_present() || (0 == _pollRecvBuffer())) {
421448
DEBUG_BSSL("peek: Not connected, none left available\n");
422449
return -1;
423450
}
@@ -436,7 +463,7 @@ size_t WiFiClientSecureCtx::peekBytes(uint8_t *buffer, size_t length) {
436463
}
437464

438465
_startMillis = millis();
439-
while ((available() < (int) length) && ((millis() - _startMillis) < 5000)) {
466+
while ((_pollRecvBuffer() < (int) length) && ((millis() - _startMillis) < 5000)) {
440467
yield();
441468
}
442469

Diff for: libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h

+6
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,13 @@ class WiFiClientSecureCtx : public WiFiClient {
195195
unsigned char *_recvapp_buf;
196196
size_t _recvapp_len;
197197

198+
int _pollRecvBuffer(); // If there's a buffer with some pending data, return it's length
199+
// If there's no buffer, poll the engine and store any received data there and return the length
200+
// (which also may change the internal state, e.g. make us disconnected)
201+
198202
bool _clientConnected(); // Is the underlying socket alive?
203+
bool _engineConnected(); // Are both socket and the bearssl engine alive?
204+
199205
std::shared_ptr<unsigned char> _alloc_iobuf(size_t sz);
200206
void _freeSSL();
201207
int _run_until(unsigned target, bool blocking = true);

0 commit comments

Comments
 (0)