butok / FNET

The FNET is a free, open source, dual TCP/IPv4 and IPv6 Stack (under Apache Version 2.0 license) for building embedded communication software on 32bit MCUs.
http://fnet.sourceforge.net/
Apache License 2.0
117 stars 58 forks source link

TLS connections don't close on errors #8

Open Rastloser opened 3 years ago

Rastloser commented 3 years ago

If using TLS connections, errors in the underlying FNET write or read functions won't cause the TLS connections to close as expected. This error can be traced down to the callback functions "_fnet_tls_mbedtls_send" and "_fnet_tls_mbedtls_recv". If the underlying FNET connection returns FNET_ERR, these functions return 0, but according to the mbedtls documentation https://tls.mbed.org/api/ssl_8h.html#a38e2b400d361f42f85833cdc30b3916e, the callback must return the number of bytes sent if any, or a non-zero error code.

To fix that, just return -1 or simply remove the else-if-clause.

butok commented 3 years ago

Guess, you are right:

New version of the send function:

/************************************************************************
* Write callback
************************************************************************/
static int _fnet_tls_mbedtls_send(void *ctx, unsigned char const *buf, size_t len)
{
    int result;

    fnet_service_mutex_lock();

    /* The callback must return the number of bytes sent if any, or a non-zero error code. */
    result = fnet_socket_send((fnet_socket_t)ctx, buf, len, 0);

    FNET_DEBUG_TLS("TLS: TX(%d) %d", len, result);

    fnet_service_mutex_unlock();

    return result;
}

What about the receive function? Guess, it is valid for it too.

static int _fnet_tls_mbedtls_recv(void *ctx, unsigned char *buf, size_t len)
{
    fnet_ssize_t result;

    fnet_service_mutex_lock();

    result = fnet_socket_recv((fnet_socket_t)ctx, buf, len, 0);

    /* The callback must return the number of bytes received, or a non-zero error code. If performing non-blocking I/O, 
      MBEDTLS_ERR_SSL_WANT_READ must be returned when the operation would block.*/
    if(result == 0)
    {
        result = MBEDTLS_ERR_SSL_WANT_READ;
    }
    else if(result == FNET_ERR)
    {
#if 0 /* result should contain a non-zero error code */
        result = 0; /* Close connection.*/
#endif
    }
    else
    {
        FNET_DEBUG_TLS("TLS: RX(%d) %d", len, result);
    }

    fnet_service_mutex_unlock();

    return result;
}

Are you OK with this version of functions?

Rastloser commented 3 years ago

Sorry, I missed the notification, but that will do - at least it's working for me.