]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
openssl: improve ssl shutdown handling
authorStefan Eissing <stefan@eissing.org>
Fri, 15 Sep 2023 07:12:52 +0000 (09:12 +0200)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 26 Sep 2023 07:40:20 +0000 (03:40 -0400)
- If SSL shutdown is not finished then make an additional call to
  SSL_read to gather additional tracing.

- Fix http2 and h2-proxy filters to forward do_close() calls to the next
  filter.

For example h2 and SSL shutdown before and after this change:

Before:

Curl_conn_close -> cf_hc_close -> Curl_conn_cf_discard_chain ->
ssl_cf_destroy

After:

Curl_conn_close -> cf_hc_close -> cf_h2_close -> cf_setup_close ->
ssl_cf_close

Note that currently the tracing does not show output on the connection
closure handle. Refer to discussion in #11878.

Ref: https://github.com/curl/curl/discussions/11878

Closes https://github.com/curl/curl/pull/11858

lib/cf-h2-proxy.c
lib/http2.c
lib/vtls/openssl.c
lib/vtls/vtls.c

index 9cb804d047ee1b3aa88fc467f93a5d5473371322..922212082d0b605f8dd59aae026210301f0b2175 100644 (file)
@@ -1160,6 +1160,8 @@ static void cf_h2_proxy_close(struct Curl_cfilter *cf, struct Curl_easy *data)
     cf_h2_proxy_ctx_clear(ctx);
     CF_DATA_RESTORE(cf, save);
   }
+  if(cf->next)
+    cf->next->cft->do_close(cf->next, data);
 }
 
 static void cf_h2_proxy_destroy(struct Curl_cfilter *cf,
index 4732cf7025ad8a751b349a88d54bfc6a626cccb5..1857c23b52f3def9a3cc750b91217d7faeb17d81 100644 (file)
@@ -2425,6 +2425,8 @@ static void cf_h2_close(struct Curl_cfilter *cf, struct Curl_easy *data)
     cf_h2_ctx_clear(ctx);
     CF_DATA_RESTORE(cf, save);
   }
+  if(cf->next)
+    cf->next->cft->do_close(cf->next, data);
 }
 
 static void cf_h2_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
index 3388e8b976223cb45e684b478c74e69332e4a0ab..bbc9f594e0ade3b5eab1d5d03f4a6905cd1ebaec 100644 (file)
@@ -1876,15 +1876,45 @@ static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
 
   if(backend->handle) {
     if(cf->next && cf->next->connected) {
-      char buf[32];
+      char buf[1024];
+      int nread, err;
+      long sslerr;
+
       /* 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);
-
       ERR_clear_error();
+      if(SSL_shutdown(backend->handle) == 1) {
+        CURL_TRC_CF(data, cf, "SSL shutdown finished");
+      }
+      else {
+        nread = SSL_read(backend->handle, buf, (int)sizeof(buf));
+        err = SSL_get_error(backend->handle, nread);
+        switch(err) {
+        case SSL_ERROR_NONE: /* this is not an error */
+        case SSL_ERROR_ZERO_RETURN: /* no more data */
+          CURL_TRC_CF(data, cf, "SSL shutdown, EOF from server");
+          break;
+        case SSL_ERROR_WANT_READ:
+          /* SSL has send its notify and now wants to read the reply
+           * from the server. We are not really interested in that. */
+          CURL_TRC_CF(data, cf, "SSL shutdown sent");
+          break;
+        case SSL_ERROR_WANT_WRITE:
+          CURL_TRC_CF(data, cf, "SSL shutdown send blocked");
+          break;
+        default:
+          sslerr = ERR_get_error();
+          CURL_TRC_CF(data, cf, "SSL shutdown, error: '%s', errno %d",
+                      (sslerr ?
+                       ossl_strerror(sslerr, buf, sizeof(buf)) :
+                       SSL_ERROR_to_str(err)),
+                      SOCKERRNO);
+          break;
+        }
+      }
 
+      ERR_clear_error();
       SSL_set_connect_state(backend->handle);
     }
 
index 38a20e8bea273b3c8d49b590977c6ee8696710f9..494b660a98aab113af3dd70e0c07fb596b91a642 100644 (file)
@@ -1494,7 +1494,8 @@ static void ssl_cf_close(struct Curl_cfilter *cf,
 
   CF_DATA_SAVE(save, cf, data);
   cf_close(cf, data);
-  cf->next->cft->do_close(cf->next, data);
+  if(cf->next)
+    cf->next->cft->do_close(cf->next, data);
   CF_DATA_RESTORE(cf, save);
 }