From c18ff4b5317c9496b2cf5d6b0ccc4a9e7ad75720 Mon Sep 17 00:00:00 2001 From: Prooma <86158218+prooma@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:46:10 +0200 Subject: [PATCH 1/3] fix(ssl_client,wifi): Write full TLS buffer and avoid zero-length writes Loop in send_ssl_data() until the entire buffer is written; handle MBEDTLS_ERR_SSL_WANT_{READ,WRITE} and respect socket timeouts. Return 0 for len==0 to prevent zero-length TLS writes. Add a size==0 guard in WiFiClientSecure::write() for symmetry. No API changes. --- .../src/NetworkClientSecure.cpp | 4 +++ .../NetworkClientSecure/src/ssl_client.cpp | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp b/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp index b24c9f1adc3..08da928668e 100644 --- a/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp +++ b/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp @@ -227,6 +227,10 @@ size_t NetworkClientSecure::write(const uint8_t *buf, size_t size) { return 0; } + if (size == 0) { + return 0; + } + if (_stillinPlainStart) { return send_net_data(sslclient.get(), buf, size); } diff --git a/libraries/NetworkClientSecure/src/ssl_client.cpp b/libraries/NetworkClientSecure/src/ssl_client.cpp index 19f75673133..1276434ee69 100644 --- a/libraries/NetworkClientSecure/src/ssl_client.cpp +++ b/libraries/NetworkClientSecure/src/ssl_client.cpp @@ -409,25 +409,31 @@ int data_to_read(sslclient_context *ssl_client) { } int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len) { - unsigned long write_start_time = millis(); - int ret = -1; + if (len == 0) { + return 0; // Skipping zero-length write + } + + const unsigned long write_start_time = millis(); - while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) { + size_t sent = 0; + while (sent < len) { + const size_t to_send = len - sent; + const int ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data + sent, to_send); + if (ret > 0) { + sent += ret; + continue; + } if ((millis() - write_start_time) > ssl_client->socket_timeout) { - log_v("SSL write timed out."); - return -1; + log_v("SSL write timed out."); + return -1; } - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) { - log_v("Handling error %d", ret); //for low level debug - return handle_error(ret); + log_v("Handling error %d", ret); + return handle_error(ret); } - - //wait for space to become available vTaskDelay(2); } - - return ret; + return (int)sent; } // Some protocols, such as SMTP, XMPP, MySQL/Posgress and various others From 010e6a05a5aa142c750d9071059cdde2cefdb9de Mon Sep 17 00:00:00 2001 From: Prooma <86158218+prooma@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:43:48 +0200 Subject: [PATCH 2/3] fix(ssl_client): Chunk TLS writes and reset timeout after progress Chunk TLS writes and reset timeout after progress to reduce mid-body resets Send large TLS payloads in moderate chunks (4 KiB) instead of a single large write, and measure the write timeout from the last successful progress. This significantly reduces sporadic MBEDTLS_ERR_NET_CONN_RESET (-0x0050) observed during long HTTP bodies (e.g., multipart uploads). - write loop remains intact; now caps per-call size to 4096 bytes - updates timeout window after each positive write to avoid false timeouts on slow links - no API changes; handshake/verification paths unaffected Sources Ask ChatGPT --- .../NetworkClientSecure/src/ssl_client.cpp | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/libraries/NetworkClientSecure/src/ssl_client.cpp b/libraries/NetworkClientSecure/src/ssl_client.cpp index 1276434ee69..af9529128e9 100644 --- a/libraries/NetworkClientSecure/src/ssl_client.cpp +++ b/libraries/NetworkClientSecure/src/ssl_client.cpp @@ -413,26 +413,36 @@ int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len return 0; // Skipping zero-length write } - const unsigned long write_start_time = millis(); - + const size_t kChunk = 4096; + unsigned long last_progress = millis(); // Timeout since last progress size_t sent = 0; + while (sent < len) { - const size_t to_send = len - sent; - const int ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data + sent, to_send); + size_t to_send = len - sent; + if (to_send > kChunk) { + to_send = kChunk; + } + + int ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data + sent, to_send); if (ret > 0) { sent += ret; + last_progress = millis(); // refresh timeout window continue; } - if ((millis() - write_start_time) > ssl_client->socket_timeout) { - log_v("SSL write timed out."); - return -1; + + if ((millis() - last_progress) > ssl_client->socket_timeout) { + log_v("SSL write timed out."); + return -1; } + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) { - log_v("Handling error %d", ret); - return handle_error(ret); + log_v("Handling error %d", ret); + return handle_error(ret); } + vTaskDelay(2); } + return (int)sent; } From c78c814201e4646a89f1394878a2dd5fe9d5a61c Mon Sep 17 00:00:00 2001 From: Prooma <86158218+prooma@users.noreply.github.com> Date: Sun, 21 Sep 2025 14:49:51 +0200 Subject: [PATCH 3/3] refactor(ssl_client): Constexpr chunk size; rename max_write_chunk_size --- libraries/NetworkClientSecure/src/ssl_client.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/NetworkClientSecure/src/ssl_client.cpp b/libraries/NetworkClientSecure/src/ssl_client.cpp index af9529128e9..f70aefec034 100644 --- a/libraries/NetworkClientSecure/src/ssl_client.cpp +++ b/libraries/NetworkClientSecure/src/ssl_client.cpp @@ -413,14 +413,14 @@ int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len return 0; // Skipping zero-length write } - const size_t kChunk = 4096; + static constexpr size_t max_write_chunk_size = 4096; unsigned long last_progress = millis(); // Timeout since last progress size_t sent = 0; while (sent < len) { size_t to_send = len - sent; - if (to_send > kChunk) { - to_send = kChunk; + if (to_send > max_write_chunk_size) { + to_send = max_write_chunk_size; } int ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data + sent, to_send);