]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
gnutls: improve TLS shutdown
authorStefan Eissing <stefan@eissing.org>
Mon, 27 May 2024 09:51:03 +0000 (11:51 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 28 May 2024 08:37:52 +0000 (10:37 +0200)
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

lib/vtls/gtls.c

index 3862405d53526d13a25771a68ea2dba92552d535..262933e50e1b300ba35b7e3cca7c2777cd2199e4 100644 (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;
   }