Handshake behavior with asynchronous socket

I would like to understand better the behavior of MbedTLS library when doing handshake over non-blocking sockets. Answers are appreciated :slight_smile:

I am making call to mbedtls_ssl_handshake and retrying it if I got MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE. In other cases I assume the return value is the actual result of the negotiation.

When running this code I noticed that mbedtls_ssl_handshake returns -1 result which does not seem to be a documented return value.

I understood that I get this return value due to the fact that in the underlying bio I simply call into libc’s send and recv over non-blocking socket which returns -1 when reading from a socket which has an empty incoming buffer. As a test, I have made retries to mbedtls_ssl_handshake while the return value was -1 (busy loop) and as a result the TLS handshake was eventually completed successfully.

I have to tell that the behavior is strange for me and I wanted to clarify it.

In case that the application calls into mbedtls_ssl_handshake and it expect incoming data, but gets -1 from recv (with errno set to EAGAIN) shouldn’t it return MBEDTLS_ERR_SSL_WANT_READ? This would mean that caller can call select/poll/epoll on the socket and wait until data can be accessed and mbedtls_ssl_handshake can be called again.

I don’t see anywhere that mbedtls_ssl_handshake can return -1. Is it an expected behavior?