You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
curl/curl#6785 is curl w/OpenSSL/1.1.1j appears to hang when a second TLS handshake is not completed.
The fail case on a non-blocking socket is basically this:
SSL_write is called with the POST data.
SSL_write returns SSL_ERROR_WANT_WRITE.
Data has arrived (the HelloRequest) and SSL_read is called.
The debug callback shows the HelloRequest was received: * TLSv1.2 (IN), TLS handshake, Hello request (0):
The debug callback does not show that a ClientHello or anything else was sent (normally it would do this).
SSL_read returns SSL_ERROR_WANT_READ
SSL_write is called again and the POST data is sent.
The server does nothing.
Here are my thoughts, from the issue:
The server says the TLS handshake is finished so curl prepares and sends the request. However at almost the exact same time that happens a TLS hello request is received. Then curl is waiting for an HTTP response from the server while at the same time the server is waiting for a handshake response from curl (presumably since nothing else happens but keep alives). I don't know what curl could do here, I would expect it to be handled by OpenSSL.
In the success case SSL_write is called again and succeeds before SSL_read, because the HelloRequest has not yet arrived. Then it arrives and SSL_read is called but this time OpenSSL responds with a ClientHello and completes the handshake.
The scenario here as described seems confusing to me. If SSL_write() returns SSL_ERROR_WANT_WRITE, then shouldn't curl wait for the socket to be writeable? Likewise, SSL_read() returning SSL_ERROR_WANT_READ is not normally a trigger to call SSL_write() again.
That said, this scenario does kind of remind me of #12485 (which I have not had a chance to look into closely).
I think it's reasonable for an application to call SSL_read() when
something like select() says there is data available to read. I
assume that this is what curl is doing. I'm just not sure that
OpenSSL can always handle it properly.
We can't fully process the incoming data, since we'll also have
to write something. We can't write until the previous SSL_write()
is complete.
If we think that there are cases where SSL_read() should not be
called, or that it should not attempt to read data from the
socket, we should change SSL_read() to check for that condition,
and just do the right thing. That might mean that even when
data is available to read, SSL_read() might not actually read it,
and the application can end up in a loop where it repeatably calls
SSL_read() without making progress until it can write.
The API I would actually like to have is that the data is read
from the socket. But since we can't fully process it because we
can't write yet, I expect the processing to continue in the
SSL_write() call after the user data has been sent.
curl/curl#6785 is curl w/OpenSSL/1.1.1j appears to hang when a second TLS handshake is not completed.
The fail case on a non-blocking socket is basically this:
SSL_write is called with the POST data.
SSL_write returns SSL_ERROR_WANT_WRITE.
Data has arrived (the HelloRequest) and SSL_read is called.
The debug callback shows the HelloRequest was received:
* TLSv1.2 (IN), TLS handshake, Hello request (0):
The debug callback does not show that a ClientHello or anything else was sent (normally it would do this).
SSL_read returns SSL_ERROR_WANT_READ
SSL_write is called again and the POST data is sent.
The server does nothing.
Here are my thoughts, from the issue:
In the success case SSL_write is called again and succeeds before SSL_read, because the HelloRequest has not yet arrived. Then it arrives and SSL_read is called but this time OpenSSL responds with a ClientHello and completes the handshake.
/cc @danjohansson @bagder
The text was updated successfully, but these errors were encountered: