openssl: improve retries on shutdown

Once SSL_shutdown() has been called, OpenSSL does not really seem to
like it when it is called again and the other side has some finally data
to deliver.

Instead SSL_read() needs to be used solely, once the close notify has
been sent from curl's side.

Closes #15321
This commit is contained in:
Stefan Eissing 2024-10-17 13:53:06 +02:00 committed by Daniel Stenberg
parent 8cdbaba4bf
commit b42eb27c1f
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 7 additions and 3 deletions

View File

@ -1935,8 +1935,9 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf,
/* SSL should now have started the shutdown from our side. Since it
* was not complete, we are lacking the close notify from the server. */
if(send_shutdown) {
if(send_shutdown && !(SSL_get_shutdown(octx->ssl) & SSL_SENT_SHUTDOWN)) {
ERR_clear_error();
CURL_TRC_CF(data, cf, "send SSL close notify");
if(SSL_shutdown(octx->ssl) == 1) {
CURL_TRC_CF(data, cf, "SSL shutdown finished");
*done = TRUE;
@ -1961,7 +1962,10 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf,
err = SSL_get_error(octx->ssl, nread);
switch(err) {
case SSL_ERROR_ZERO_RETURN: /* no more data */
CURL_TRC_CF(data, cf, "SSL shutdown not received, but closed");
if(SSL_shutdown(octx->ssl) == 1)
CURL_TRC_CF(data, cf, "SSL shutdown finished");
else
CURL_TRC_CF(data, cf, "SSL shutdown not received, but closed");
*done = TRUE;
break;
case SSL_ERROR_NONE: /* just did not get anything */

View File

@ -73,7 +73,7 @@ class TestShutdown:
pytest.skip('only works for curl debug builds')
curl = CurlClient(env=env, run_env={
'CURL_GRACEFUL_SHUTDOWN': '2000',
'CURL_DEBUG': 'ssl'
'CURL_DEBUG': 'ssl,tcp'
})
url = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-1]'
r = curl.http_download(urls=[url], alpn_proto=proto, with_tcpdump=True, extra_args=[