gnutls: improve TLS shutdown

local ftp upload tests sometimes failed with an invalid TLS record being
reported by gnutls. vsftp did log that the shutdown was not regarded as
clean, failing the control connection thereafter.

These changes make test_31_05 work reliable locally.

- on closing the SSL filter, shutdown READ *and* WRITE
- on closing, try a receive after shutdown is sent
- convert to DEBUGF to CURL_TRC_CF

Closes #13790
This commit is contained in:
Stefan Eissing 2024-05-27 11:51:03 +02:00 committed by Daniel Stenberg
parent 70a65e1b47
commit 7bbad0c033
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -567,8 +567,8 @@ static CURLcode gtls_update_session_id(struct Curl_cfilter *cf,
/* extract session ID to the allocated buffer */
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
DEBUGF(infof(data, "get session id (len=%zu) and store in cache",
connect_idsize));
CURL_TRC_CF(data, cf, "get session id (len=%zu) and store in cache",
connect_idsize);
Curl_ssl_sessionid_lock(data);
incache = !(Curl_ssl_getsessionid(cf, data, &connssl->peer,
&ssl_sessionid, NULL));
@ -599,8 +599,8 @@ static int gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
if(when) { /* after message has been processed */
struct Curl_easy *data = CF_DATA_CURRENT(cf);
if(data) {
DEBUGF(infof(data, "handshake: %s message type %d",
incoming? "incoming" : "outgoing", htype));
CURL_TRC_CF(data, cf, "handshake: %s message type %d",
incoming? "incoming" : "outgoing", htype);
switch(htype) {
case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: {
gtls_update_session_id(cf, data, session);
@ -1629,13 +1629,18 @@ static void gtls_close(struct Curl_cfilter *cf,
(void) data;
DEBUGASSERT(backend);
CURL_TRC_CF(data, cf, "close");
if(backend->gtls.session) {
char buf[32];
/* Maybe the server has already sent a close notify alert.
Read it to avoid an RST on the TCP connection. */
CURL_TRC_CF(data, cf, "close, try receive before bye");
(void)gnutls_record_recv(backend->gtls.session, buf, sizeof(buf));
CURL_TRC_CF(data, cf, "close, send bye");
gnutls_bye(backend->gtls.session, GNUTLS_SHUT_RDWR);
/* try one last receive */
CURL_TRC_CF(data, cf, "close, receive after bye");
(void)gnutls_record_recv(backend->gtls.session, buf, sizeof(buf));
gnutls_bye(backend->gtls.session, GNUTLS_SHUT_WR);
gnutls_deinit(backend->gtls.session);
backend->gtls.session = NULL;
}