]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add support into qtest_shutdown for blocking mode
authorMatt Caswell <matt@openssl.org>
Tue, 1 Aug 2023 11:22:58 +0000 (12:22 +0100)
committerHugo Landau <hlandau@openssl.org>
Wed, 2 Aug 2023 19:27:07 +0000 (20:27 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21591)

test/helpers/quictestlib.c
test/quicapitest.c

index d081b121e856768e55b5d04bc0e7cf8fa9f47081..8f28dfb898fc54b5bb2c4a169589cd10e1498c3d 100644 (file)
@@ -20,6 +20,7 @@
 #include "internal/quic_record_tx.h"
 #include "internal/quic_error.h"
 #include "internal/packet.h"
+#include "internal/tsan_assist.h"
 
 #define GROWTH_ALLOWANCE 1024
 
@@ -338,22 +339,77 @@ int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl)
     return ret;
 }
 
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+static TSAN_QUALIFIER int shutdowndone;
+
+static void run_server_shutdown_thread(void)
+{
+    /*
+     * This will operate in a busy loop because the server does not block,
+     * but should be acceptable because it is local and we expect this to be
+     * fast
+     */
+    do {
+        ossl_quic_tserver_tick(globtserv);
+    } while(!tsan_load(&shutdowndone));
+}
+#endif
+
 int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl)
 {
+    int tickserver = 1;
+    int ret = 0;
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+    /*
+     * Pointless initialisation to avoid bogus compiler warnings about using
+     * t uninitialised
+     */
+    thread_t t = thread_zero;
+#endif
+
+    if (SSL_get_blocking_mode(clientssl) > 0) {
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+        /*
+         * clientssl is blocking. We will need a thread to complete the
+         * connection
+         */
+        globtserv = qtserv;
+        shutdowndone = 0;
+        if (!TEST_true(run_thread(&t, run_server_shutdown_thread)))
+            return 0;
+
+        tickserver = 0;
+#else
+        TEST_error("No thread support in this build");
+        return 0;
+#endif
+    }
+
     /* Busy loop in non-blocking mode. It should be quick because its local */
     for (;;) {
         int rc = SSL_shutdown(clientssl);
 
-        if (rc == 1)
+        if (rc == 1) {
+            ret = 1;
             break;
+        }
 
         if (rc < 0)
-            return 0;
+            break;
 
-        ossl_quic_tserver_tick(qtserv);
+        if (tickserver)
+            ossl_quic_tserver_tick(qtserv);
     }
 
-    return 1;
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+    tsan_store(&shutdowndone, 1);
+    if (!tickserver) {
+        if (!TEST_true(wait_for_thread(t)))
+            ret = 0;
+    }
+#endif
+
+    return ret;
 }
 
 int qtest_check_server_transport_err(QUIC_TSERVER *qtserv, uint64_t code)
index 3267b1b283c61096c6a9ddb8548166131948f2ee..c694988d830188806e321e22f16f009457135389 100644 (file)
@@ -164,21 +164,8 @@ static int test_quic_write_read(int idx)
                 goto end;
         }
 
-        if (idx < 1) {
-            /*
-            * Blocking SSL_shutdown cannot be tested here due to requirement to
-            * tick TSERVER during drainage.
-            */
-            if (!TEST_true(qtest_shutdown(qtserv, clientquic)))
-                goto end;
-        } else {
-            /*
-             * We cheat here because we have not shutdown correctly. We make the
-             * client think it has been shutdown normally so the session is
-             * eligible for reuse.
-             */
-            SSL_CONNECTION_FROM_SSL(clientquic)->shutdown = SSL_SENT_SHUTDOWN;
-        }
+        if (!TEST_true(qtest_shutdown(qtserv, clientquic)))
+            goto end;
 
         if (sctx == NULL) {
             sctx = ossl_quic_tserver_get0_ssl_ctx(qtserv);