1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-25 20:02:37 +03:00
Max Prokhorov 9dce0764af
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
2022-12-16 12:12:58 +01:00

132 lines
3.7 KiB
C++

// Shows how to use the Maximum Fragment Length option in
// BearSSL to reduce SSL memory needs.
//
// Mar 2018 by Earle F. Philhower, III
// Released to the public domain
#include <ESP8266WiFi.h>
#include <PolledTimeout.h>
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char *ssid = STASSID;
const char *pass = STAPSK;
void fetch(BearSSL::WiFiClientSecure *client) {
client->write("GET / HTTP/1.0\r\nHost: tls.mbed.org\r\nUser-Agent: ESP8266\r\n\r\n");
client->flush();
using oneShot = esp8266::polledTimeout::oneShot;
oneShot timeout(5000);
do {
char tmp[32];
int rlen = client->read((uint8_t *)tmp, sizeof(tmp) - 1);
yield();
if (rlen < 0) { break; }
if (rlen == 0) {
delay(10); // Give background processes some time
continue;
}
tmp[rlen] = '\0';
Serial.print(tmp);
} while (!timeout);
client->stop();
Serial.printf("\n-------\n");
}
int fetchNoMaxFragmentLength() {
int ret = ESP.getFreeHeap();
Serial.printf("\nConnecting to https://tls.mbed.org\n");
Serial.printf("No MFLN attempted\n");
BearSSL::WiFiClientSecure client;
client.setInsecure();
if (client.connect("tls.mbed.org", 443)) {
Serial.printf("Memory used: %d\n", ret - ESP.getFreeHeap());
ret -= ESP.getFreeHeap();
fetch(&client);
} else {
Serial.printf("Unable to connect\n");
}
return ret;
}
int fetchMaxFragmentLength() {
int ret = ESP.getFreeHeap();
// Servers which implement RFC6066's Maximum Fragment Length Negotiation
// can be configured to limit the size of TLS fragments they transmit.
// This lets small clients, like the ESP8266, use a smaller memory buffer
// on the receive end (all the way down to under 1KB). Unfortunately,
// as of March 2018, there are not many public HTTPS servers which
// implement this option. You can deploy your own HTTPS or MQTT server
// with MFLN enabled, of course.
//
// To determine if MFLN is supported by a server use the
// ::probeMaxFragmentLength() method before connecting, and if it
// returns true then you can use the ::setBufferSizes(rx, tx) to shrink
// the needed BearSSL memory while staying within protocol limits.
//
// If MFLN is not supported, you may still be able to minimize the buffer
// sizes assuming you can ensure the server never transmits fragments larger
// than the size (i.e. by using HTTP GET RANGE methods, etc.).
BearSSL::WiFiClientSecure client;
client.setInsecure();
bool mfln = client.probeMaxFragmentLength("tls.mbed.org", 443, 512);
Serial.printf("\nConnecting to https://tls.mbed.org\n");
Serial.printf("MFLN supported: %s\n", mfln ? "yes" : "no");
if (mfln) { client.setBufferSizes(512, 512); }
if (client.connect("tls.mbed.org", 443)) {
Serial.printf("MFLN status: %s\n", client.getMFLNStatus() ? "true" : "false");
Serial.printf("Memory used: %d\n", ret - ESP.getFreeHeap());
ret -= ESP.getFreeHeap();
fetch(&client);
} else {
Serial.printf("Unable to connect\n");
}
return ret;
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println();
// We start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.print(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
Serial.printf("\n\n\n\n\n");
yield();
int a = fetchNoMaxFragmentLength();
yield();
int b = fetchMaxFragmentLength();
yield();
Serial.printf("\n\n");
Serial.printf("Default SSL: %d bytes used\n", a);
Serial.printf("512 byte MFLN SSL: %d bytes used\n", b);
}