diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index ecde5c44d..d9bc5611e 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -1438,6 +1438,10 @@ static void close_one(struct ssl_connect_data *connssl) { struct ssl_backend_data *backend = connssl->backend; if(backend->session) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)gnutls_record_recv(backend->session, buf, sizeof(buf)); gnutls_bye(backend->session, GNUTLS_SHUT_WR); gnutls_deinit(backend->session); backend->session = NULL; diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 335b58527..addbff5c2 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -813,8 +813,13 @@ static void mbedtls_close(struct Curl_easy *data, { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + char buf[32]; (void) data; + + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, sizeof(buf)); + mbedtls_pk_free(&backend->pk); mbedtls_x509_crt_free(&backend->clicert); mbedtls_x509_crt_free(&backend->cacert); diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index 1582b1e58..f7583d504 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -1546,6 +1546,14 @@ static void close_one(struct ssl_connect_data *connssl) const bool client_cert = (backend->client_nickname != NULL) || (backend->obj_clicert != NULL); + if(backend->handle) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)PR_Recv(backend->handle, buf, (int)sizeof(buf), 0, + PR_INTERVAL_NO_WAIT); + } + free(backend->client_nickname); backend->client_nickname = NULL; diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index ebd7abc3b..c8958e0f6 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -1400,7 +1400,13 @@ static void ossl_closeone(struct Curl_easy *data, { struct ssl_backend_data *backend = connssl->backend; if(backend->handle) { + char buf[32]; set_logger(conn, data); + + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); + (void)SSL_shutdown(backend->handle); SSL_set_connect_state(backend->handle); diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 60e27e366..8d217ec54 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -810,6 +810,10 @@ static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn, (void) data; if(backend->handle) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); (void)SSL_shutdown(backend->handle); SSL_free(backend->handle); backend->handle = NULL;