QUIC: Add tests for datagram injection API
authorHugo Landau <hlandau@openssl.org>
Tue, 7 Mar 2023 19:07:50 +0000 (19:07 +0000)
committerPauli <pauli@openssl.org>
Tue, 21 Mar 2023 23:14:25 +0000 (10:14 +1100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20451)

doc/build.info
test/quic_tserver_test.c

index f6a8b951f3a86b583a0ea7f14ce3f81500767943..a7897abdb3b8932f4273b7bc2792c0506b554095 100644 (file)
@@ -2583,6 +2583,10 @@ DEPEND[html/man3/SSL_in_init.html]=man3/SSL_in_init.pod
 GENERATE[html/man3/SSL_in_init.html]=man3/SSL_in_init.pod
 DEPEND[man/man3/SSL_in_init.3]=man3/SSL_in_init.pod
 GENERATE[man/man3/SSL_in_init.3]=man3/SSL_in_init.pod
+DEPEND[html/man3/SSL_inject_net_dgram.html]=man3/SSL_inject_net_dgram.pod
+GENERATE[html/man3/SSL_inject_net_dgram.html]=man3/SSL_inject_net_dgram.pod
+DEPEND[man/man3/SSL_inject_net_dgram.3]=man3/SSL_inject_net_dgram.pod
+GENERATE[man/man3/SSL_inject_net_dgram.3]=man3/SSL_inject_net_dgram.pod
 DEPEND[html/man3/SSL_key_update.html]=man3/SSL_key_update.pod
 GENERATE[html/man3/SSL_key_update.html]=man3/SSL_key_update.pod
 DEPEND[man/man3/SSL_key_update.3]=man3/SSL_key_update.pod
@@ -3489,6 +3493,7 @@ html/man3/SSL_get_verify_result.html \
 html/man3/SSL_get_version.html \
 html/man3/SSL_group_to_name.html \
 html/man3/SSL_in_init.html \
+html/man3/SSL_inject_net_dgram.html \
 html/man3/SSL_key_update.html \
 html/man3/SSL_library_init.html \
 html/man3/SSL_load_client_CA_file.html \
@@ -4112,6 +4117,7 @@ man/man3/SSL_get_verify_result.3 \
 man/man3/SSL_get_version.3 \
 man/man3/SSL_group_to_name.3 \
 man/man3/SSL_in_init.3 \
+man/man3/SSL_inject_net_dgram.3 \
 man/man3/SSL_key_update.3 \
 man/man3/SSL_library_init.3 \
 man/man3/SSL_load_client_CA_file.3 \
index e743adbeab41ecd1caa45a645a4bffa144a56f25..393b11172fb4d31d3b5b0d916e0ce56fc7666006 100644 (file)
@@ -27,12 +27,19 @@ static int is_want(SSL *s, int ret)
     return ec == SSL_ERROR_WANT_READ || ec == SSL_ERROR_WANT_WRITE;
 }
 
-static int test_tserver(void)
+#define TEST_KIND_SIMPLE        0
+#define TEST_KIND_INJECT        1
+#define TEST_KIND_COUNT         2
+
+static unsigned char scratch_buf[2048];
+
+static int test_tserver(int test_kind)
 {
     int testresult = 0, ret;
     int s_fd = -1, c_fd = -1;
     BIO *s_net_bio = NULL, *s_net_bio_own = NULL;
     BIO *c_net_bio = NULL, *c_net_bio_own = NULL;
+    BIO *c_pair_own = NULL, *s_pair_own = NULL;
     QUIC_TSERVER_ARGS tserver_args = {0};
     QUIC_TSERVER *tserver = NULL;
     BIO_ADDR *s_addr_ = NULL;
@@ -92,6 +99,18 @@ static int test_tserver(void)
 
     s_net_bio_own = NULL;
 
+    if (test_kind == TEST_KIND_INJECT) {
+        /*
+         * In inject mode we create a dgram pair to feed to the QUIC client on
+         * the read side. We don't feed anything to this, it is just a
+         * placeholder to give the client something which never returns any
+         * datagrams..
+         */
+        if (!TEST_true(BIO_new_bio_dgram_pair(&c_pair_own, 5000,
+                                              &s_pair_own, 5000)))
+            goto err;
+    }
+
     /* Setup test client. */
     c_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0);
     if (!TEST_int_ge(c_fd, 0))
@@ -117,12 +136,17 @@ static int test_tserver(void)
         goto err;
 
     /* Takes ownership of our reference to the BIO. */
-    SSL_set0_rbio(c_ssl, c_net_bio);
-
-    /* Get another reference to be transferred in the SSL_set0_wbio call. */
-    if (!TEST_true(BIO_up_ref(c_net_bio))) {
-        c_net_bio_own = NULL; /* SSL_free will free the first reference. */
-        goto err;
+    if (test_kind == TEST_KIND_INJECT) {
+        SSL_set0_rbio(c_ssl, c_pair_own);
+        c_pair_own = NULL;
+    } else {
+        SSL_set0_rbio(c_ssl, c_net_bio);
+
+        /* Get another reference to be transferred in the SSL_set0_wbio call. */
+        if (!TEST_true(BIO_up_ref(c_net_bio))) {
+            c_net_bio_own = NULL; /* SSL_free will free the first reference. */
+            goto err;
+        }
     }
 
     SSL_set0_wbio(c_ssl, c_net_bio);
@@ -234,6 +258,29 @@ static int test_tserver(void)
          */
         SSL_tick(c_ssl);
         ossl_quic_tserver_tick(tserver);
+
+        if (test_kind == TEST_KIND_INJECT) {
+            BIO_MSG rmsg = {0};
+            size_t msgs_processed = 0;
+
+            for (;;) {
+                /*
+                 * Manually spoonfeed received datagrams from the real BIO_dgram
+                 * into QUIC via the injection interface, thereby testing the
+                 * injection interface.
+                 */
+                rmsg.data       = scratch_buf;
+                rmsg.data_len   = sizeof(scratch_buf);
+
+                if (!BIO_recvmmsg(c_net_bio, &rmsg, sizeof(rmsg), 1, 0, &msgs_processed)
+                    || msgs_processed == 0 || rmsg.data_len == 0)
+                    break;
+
+                if (!TEST_true(SSL_inject_net_dgram(c_ssl, rmsg.data, rmsg.data_len,
+                                                    NULL, NULL)))
+                    goto err;
+            }
+        }
     }
 
     testresult = 1;
@@ -244,6 +291,8 @@ err:
     BIO_ADDR_free(s_addr_);
     BIO_free(s_net_bio_own);
     BIO_free(c_net_bio_own);
+    BIO_free(c_pair_own);
+    BIO_free(s_pair_own);
     if (s_fd >= 0)
         BIO_closesocket(s_fd);
     if (c_fd >= 0)
@@ -264,6 +313,6 @@ int setup_tests(void)
             || !TEST_ptr(keyfile = test_get_argument(1)))
         return 0;
 
-    ADD_TEST(test_tserver);
+    ADD_ALL_TESTS(test_tserver, TEST_KIND_COUNT);
     return 1;
 }