1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Fix for crash in WiFiClientSecure when WiFi is disconnected (#2139)

* WiFiClient: implement stopAll() via stop()

* WiFiClientSecure: clean up ClientContext used by axTLS when stop is called (#2097)
This commit is contained in:
Ivan Grokhotkov 2016-06-13 18:36:30 +08:00 committed by GitHub
parent 6f3785b4b7
commit 43412970ae
2 changed files with 21 additions and 24 deletions

View File

@ -339,24 +339,16 @@ void WiFiClient::_s_err(void* arg, int8_t err)
void WiFiClient::stopAll() void WiFiClient::stopAll()
{ {
for (WiFiClient* it = _s_first; it; it = it->_next) { for (WiFiClient* it = _s_first; it; it = it->_next) {
ClientContext* c = it->_client; it->stop();
if (c) {
c->abort();
c->unref();
it->_client = 0;
}
} }
} }
void WiFiClient::stopAllExcept(WiFiClient * exC) { void WiFiClient::stopAllExcept(WiFiClient* except)
{
for (WiFiClient* it = _s_first; it; it = it->_next) { for (WiFiClient* it = _s_first; it; it = it->_next) {
ClientContext* c = it->_client; if (it != except) {
it->stop();
if (c && c != exC->_client) {
c->abort();
c->unref();
it->_client = 0;
} }
} }
} }

View File

@ -57,6 +57,7 @@ static int s_pk_refcnt = 0;
uint8_t* default_certificate = 0; uint8_t* default_certificate = 0;
uint32_t default_certificate_len = 0; uint32_t default_certificate_len = 0;
static bool default_certificate_dynamic = false; static bool default_certificate_dynamic = false;
static ClientContext* s_io_ctx = nullptr;
static void clear_private_key(); static void clear_private_key();
static void clear_certificate(); static void clear_certificate();
@ -94,7 +95,7 @@ public:
} }
void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) { void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) {
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0, hostName); _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, hostName);
uint32_t t = millis(); uint32_t t = millis();
while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) {
@ -211,6 +212,7 @@ WiFiClientSecure::WiFiClientSecure() {
} }
WiFiClientSecure::~WiFiClientSecure() { WiFiClientSecure::~WiFiClientSecure() {
s_io_ctx = nullptr;
if (_ssl) { if (_ssl) {
_ssl->unref(); _ssl->unref();
} }
@ -262,6 +264,8 @@ int WiFiClientSecure::_connectSSL(const char* hostName) {
_ssl = nullptr; _ssl = nullptr;
} }
s_io_ctx = _client;
_ssl = new SSLContext; _ssl = new SSLContext;
_ssl->ref(); _ssl->ref();
_ssl->connect(_client, hostName, 5000); _ssl->connect(_client, hostName, 5000);
@ -325,6 +329,10 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
yield(); yield();
} }
if(!_ssl) {
return 0;
}
if(available() < (int) length) { if(available() < (int) length) {
count = available(); count = available();
} else { } else {
@ -363,11 +371,8 @@ uint8_t WiFiClientSecure::connected() {
} }
void WiFiClientSecure::stop() { void WiFiClientSecure::stop() {
if (_ssl) { s_io_ctx = nullptr;
_ssl->unref(); WiFiClient::stop();
_ssl = nullptr;
}
return WiFiClient::stop();
} }
static bool parseHexNibble(char pb, uint8_t* res) { static bool parseHexNibble(char pb, uint8_t* res) {
@ -520,10 +525,10 @@ static void clear_certificate() {
} }
extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) { extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) {
ClientContext* _client = reinterpret_cast<ClientContext*>(fd); ClientContext* _client = s_io_ctx;
if (_client->state() != ESTABLISHED && !_client->getSize()) { if (!_client || _client->state() != ESTABLISHED && !_client->getSize()) {
return -1;
errno = EIO; errno = EIO;
return -1;
} }
size_t cb = _client->read((char*) buffer, count); size_t cb = _client->read((char*) buffer, count);
if (cb != count) { if (cb != count) {
@ -537,8 +542,8 @@ extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) {
} }
extern "C" int ax_port_write(int fd, uint8_t* buffer, size_t count) { extern "C" int ax_port_write(int fd, uint8_t* buffer, size_t count) {
ClientContext* _client = reinterpret_cast<ClientContext*>(fd); ClientContext* _client = s_io_ctx;
if (_client->state() != ESTABLISHED) { if (!_client || _client->state() != ESTABLISHED) {
errno = EIO; errno = EIO;
return -1; return -1;
} }