Skip to content

WiFiClientSecure doesn't respect timeout in send_ssl_data #7356

Closed
@cziter15

Description

@cziter15

No details about the device required as whole ecosystem is affected.

Affected component: WiFiClientSecure, ssl_client

Description

Function send_ssl_data, called by WiFiClientSecure doesn't respect timeout set on socket.

After disconnecting the network (not WiFi directly, just turn off LTE or disconnect network cable), having some small piece of code sending periodically few messages to MQTT broker via SSL, I've encountered freeze inside send_ssl_data function.

After some investigation, it appears to hang inside while loop.

Temporary working solution, but 5000 is a magic constant:

int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len)
{
    log_v("Writing HTTP request with % bytes...", len); //for low level debug
    int ret = -1;

    unsigned long send_start_time=millis();
    while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) {
        if((millis()-send_start_time)>5000)
            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);
        }
        //wait for space to become available
        vTaskDelay(2);
    }

    return ret;
}

The best way to fix this will be to introduce send_timeout inside sslclient_context and set it to socket timeout (passed in connect method by WiFiClientSecure).

Activity

changed the title [-]WiFiClientSecure don't respect timeout in ssl_send[/-] [+]WiFiClientSecure don't respect timeout in send_ssl_data[/+] on Oct 14, 2022
changed the title [-]WiFiClientSecure don't respect timeout in send_ssl_data[/-] [+]WiFiClientSecure doesn't respect timeout in send_ssl_data[/+] on Oct 16, 2022
cziter15

cziter15 commented on Oct 18, 2022

@cziter15
ContributorAuthor

I've submitted PR which adds socket_timeout to ssl_context and copies timeout value there. Then this socket_timeout variable is used in send_ssl_data as timeout.

VojtechBartoska

VojtechBartoska commented on Oct 21, 2022

@VojtechBartoska
Contributor

@cziter15 Thank you for contribution, we will review your PR soon.

TD-er

TD-er commented on Nov 7, 2022

@TD-er
Contributor

Could the timeout (also) be related to this one?
#6676

cziter15

cziter15 commented on Nov 9, 2022

@cziter15
ContributorAuthor

This timeout here is something specific, not related to ms vs second interpretation.

dsilletti

dsilletti commented on Nov 20, 2022

@dsilletti

@cziter15 could you please provide your fix (socket_timeout)? This is probably the reason why my ESP32 remain stuck if I disconnect the WAN interface of my router, while connected via Wi-Fi to the MQTT broker (using PubSubClient with WiFiClientSecure and publishing every second).

Both the PubSubClient setSocketTimeout(1) and the setKeepAlive(15) do not help, the ESP32 remain stuck for 60s till the watchdog get triggered.

Thanks

dsilletti

dsilletti commented on Nov 20, 2022

@dsilletti

temporary fixed limiting the loop to 100 retries, finally the MQTT get disconnected and reconnects properly when the WAN is back.
The timer based fix you used (I tried with 3000ms) was not working properly for me, the MQTT was disconnecting but not reconnecting.

int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, size_t len)
{
    log_v("Writing HTTP request with %d bytes...", len); //for low level debug
    int ret = -1;

    int retry = 0; 

    while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) {
        
        if (retry > 100) {
            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);
        }
        //wait for space to become available
        vTaskDelay(2);
       
        retry = retry + 1;
    }

    return ret;
}
cziter15

cziter15 commented on Nov 20, 2022

@cziter15
ContributorAuthor
dsilletti

dsilletti commented on Nov 20, 2022

@dsilletti

Thanks @cziter15, I had to tune my timers, it works now properly also configuring the timeout in seconds, according to your code.

It should definitely be fixed, probably using the value configured with:

int WiFiClientSecure::setTimeout(uint32_t seconds)

because it's not a timeout in the connection but while sending the data.

@VojtechBartoska could you please prioritize this? All ESP32 devices using WiFiClientSecure get stuck in a while loop if they lose internet connectivity while sending data (if Wi-Fi stays connected). Thanks

9 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      WiFiClientSecure doesn't respect timeout in send_ssl_data · Issue #7356 · espressif/arduino-esp32