Skip to content

Commit

Permalink
Fix for crash in WiFiClientSecure when WiFi is disconnected (esp8266#…
Browse files Browse the repository at this point in the history
…2139)

* WiFiClient: implement stopAll() via stop()

* WiFiClientSecure: clean up ClientContext used by axTLS when stop is called (esp8266#2097)
  • Loading branch information
igrr authored Jun 13, 2016
1 parent 6f3785b commit 4341297
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 24 deletions.
18 changes: 5 additions & 13 deletions libraries/ESP8266WiFi/src/WiFiClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,24 +339,16 @@ void WiFiClient::_s_err(void* arg, int8_t err)
void WiFiClient::stopAll()
{
for (WiFiClient* it = _s_first; it; it = it->_next) {
ClientContext* c = it->_client;
if (c) {
c->abort();
c->unref();
it->_client = 0;
}
it->stop();
}
}


void WiFiClient::stopAllExcept(WiFiClient * exC) {
void WiFiClient::stopAllExcept(WiFiClient* except)
{
for (WiFiClient* it = _s_first; it; it = it->_next) {
ClientContext* c = it->_client;

if (c && c != exC->_client) {
c->abort();
c->unref();
it->_client = 0;
if (it != except) {
it->stop();
}
}
}
27 changes: 16 additions & 11 deletions libraries/ESP8266WiFi/src/WiFiClientSecure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static int s_pk_refcnt = 0;
uint8_t* default_certificate = 0;
uint32_t default_certificate_len = 0;
static bool default_certificate_dynamic = false;
static ClientContext* s_io_ctx = nullptr;

static void clear_private_key();
static void clear_certificate();
Expand Down Expand Up @@ -94,7 +95,7 @@ class SSLContext {
}

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();

while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) {
Expand Down Expand Up @@ -211,6 +212,7 @@ WiFiClientSecure::WiFiClientSecure() {
}

WiFiClientSecure::~WiFiClientSecure() {
s_io_ctx = nullptr;
if (_ssl) {
_ssl->unref();
}
Expand Down Expand Up @@ -262,6 +264,8 @@ int WiFiClientSecure::_connectSSL(const char* hostName) {
_ssl = nullptr;
}

s_io_ctx = _client;

_ssl = new SSLContext;
_ssl->ref();
_ssl->connect(_client, hostName, 5000);
Expand Down Expand Up @@ -325,6 +329,10 @@ size_t WiFiClientSecure::peekBytes(uint8_t *buffer, size_t length) {
yield();
}

if(!_ssl) {
return 0;
}

if(available() < (int) length) {
count = available();
} else {
Expand Down Expand Up @@ -363,11 +371,8 @@ uint8_t WiFiClientSecure::connected() {
}

void WiFiClientSecure::stop() {
if (_ssl) {
_ssl->unref();
_ssl = nullptr;
}
return WiFiClient::stop();
s_io_ctx = nullptr;
WiFiClient::stop();
}

static bool parseHexNibble(char pb, uint8_t* res) {
Expand Down Expand Up @@ -520,10 +525,10 @@ static void clear_certificate() {
}

extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) {
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
if (_client->state() != ESTABLISHED && !_client->getSize()) {
return -1;
ClientContext* _client = s_io_ctx;
if (!_client || _client->state() != ESTABLISHED && !_client->getSize()) {
errno = EIO;
return -1;
}
size_t cb = _client->read((char*) buffer, count);
if (cb != count) {
Expand All @@ -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) {
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
if (_client->state() != ESTABLISHED) {
ClientContext* _client = s_io_ctx;
if (!_client || _client->state() != ESTABLISHED) {
errno = EIO;
return -1;
}
Expand Down

0 comments on commit 4341297

Please sign in to comment.