From: Matt Caswell Date: Thu, 14 Sep 2023 09:59:47 +0000 (+0100) Subject: Create a noisy dgram test X-Git-Tag: openssl-3.2.0-alpha2~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43b94c7fe4a427ad95f7401dd24f42d2ae094dfb;p=thirdparty%2Fopenssl.git Create a noisy dgram test Create a noisy dgram test that can drop/duplicate/reorder UDP packets and ensure that the QUIC connection is tolerant of this. At this stage we just create the outline of the test. Adding in the noise will come in future commits. Reviewed-by: Tim Hudson Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/22157) --- diff --git a/test/build.info b/test/build.info index d897f726a86..4736e28c8b0 100644 --- a/test/build.info +++ b/test/build.info @@ -339,7 +339,7 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic_client_test]=../include ../apps/include DEPEND[quic_client_test]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quic_multistream_test]=quic_multistream_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quic_multistream_test]=../include ../apps/include DEPEND[quic_multistream_test]=../libcrypto.a ../libssl.a libtestutil.a @@ -818,15 +818,15 @@ IF[{- !$disabled{tests} -}] INCLUDE[event_queue_test]=../include ../apps/include DEPEND[event_queue_test]=../libcrypto ../libssl.a libtestutil.a - SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quicfaultstest]=quicfaultstest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quicfaultstest]=../include ../apps/include .. DEPEND[quicfaultstest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quicapitest]=quicapitest.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quicapitest]=../include ../apps/include DEPEND[quicapitest]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c helpers/quictestlib.c + SOURCE[quic_newcid_test]=quic_newcid_test.c helpers/ssltestlib.c helpers/quictestlib.c helpers/noisydgrambio.c INCLUDE[quic_newcid_test]=../include ../apps/include .. DEPEND[quic_newcid_test]=../libcrypto.a ../libssl.a libtestutil.a ENDIF diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c new file mode 100644 index 00000000000..890ff7904c0 --- /dev/null +++ b/test/helpers/noisydgrambio.c @@ -0,0 +1,130 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "quictestlib.h" + +static int noisy_dgram_read(BIO *bio, char *out, int outl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_write(BIO *bio, const char *in, int inl) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + switch (cmd) { + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(next, cmd, num, ptr); + break; + } + return ret; +} + +static int noisy_dgram_gets(BIO *bio, char *buf, int size) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_puts(BIO *bio, const char *str) +{ + /* We don't support this - not needed anyway */ + return -1; +} + +static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + /* + * We only introduce noise when receiving messages. We just pass this on + * to the underlying BIO. + */ + return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + /* + * We will introduce noise here. None implemented yet. + */ + return BIO_recvmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +static int noisy_dgram_new(BIO *bio) +{ + BIO_set_init(bio, 1); + + return 1; +} + +static int noisy_dgram_free(BIO *bio) +{ + BIO_set_init(bio, 0); + + return 1; +} + +/* Choose a sufficiently large type likely to be unused for this custom BIO */ +#define BIO_TYPE_NOISY_DGRAM_FILTER (0x80 | BIO_TYPE_FILTER) + +static BIO_METHOD *method_noisy_dgram = NULL; + +/* Note: Not thread safe! */ +const BIO_METHOD *bio_f_noisy_dgram_filter(void) +{ + if (method_noisy_dgram == NULL) { + method_noisy_dgram = BIO_meth_new(BIO_TYPE_NOISY_DGRAM_FILTER, + "Nosiy datagram filter"); + if (method_noisy_dgram == NULL + || !BIO_meth_set_write(method_noisy_dgram, noisy_dgram_write) + || !BIO_meth_set_read(method_noisy_dgram, noisy_dgram_read) + || !BIO_meth_set_puts(method_noisy_dgram, noisy_dgram_puts) + || !BIO_meth_set_gets(method_noisy_dgram, noisy_dgram_gets) + || !BIO_meth_set_ctrl(method_noisy_dgram, noisy_dgram_ctrl) + || !BIO_meth_set_sendmmsg(method_noisy_dgram, noisy_dgram_sendmmsg) + || !BIO_meth_set_recvmmsg(method_noisy_dgram, noisy_dgram_recvmmsg) + || !BIO_meth_set_create(method_noisy_dgram, noisy_dgram_new) + || !BIO_meth_set_destroy(method_noisy_dgram, noisy_dgram_free)) + return NULL; + } + return method_noisy_dgram; +} + +void bio_f_noisy_dgram_filter_free(void) +{ + BIO_meth_free(method_noisy_dgram); +} diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index f0955559dca..bc135eec95b 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -140,6 +140,14 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, goto err; } + if ((flags & QTEST_FLAG_NOISE) != 0) { + BIO *noisebio = BIO_new(bio_f_noisy_dgram_filter()); + + if (!TEST_ptr(noisebio)) + goto err; + cbio = BIO_push(noisebio, cbio); + } + SSL_set_bio(*cssl, cbio, cbio); if (!TEST_true(SSL_set_blocking_mode(*cssl, diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 45f6ebec791..7a72e352d9a 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -27,9 +27,11 @@ typedef struct qtest_fault_encrypted_extensions { /* Flags for use with qtest_create_quic_objects() */ /* Indicates whether we are using blocking mode or not */ -#define QTEST_FLAG_BLOCK 1 +#define QTEST_FLAG_BLOCK (1 << 0) /* Use fake time rather than real time */ -#define QTEST_FLAG_FAKE_TIME 2 +#define QTEST_FLAG_FAKE_TIME (1 << 1) +/* Introduce noise in the BIO */ +#define QTEST_FLAG_NOISE (1 << 2) /* * Given an SSL_CTX for the client and filenames for the server certificate and @@ -230,3 +232,9 @@ int qtest_fault_set_datagram_listener(QTEST_FAULT *fault, * exceeds the over allocation. */ int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen); + +/* BIO filter for simulating a noisy UDP socket */ +const BIO_METHOD *bio_f_noisy_dgram_filter(void); + +/* Free the BIO filter method object */ +void bio_f_noisy_dgram_filter_free(void); \ No newline at end of file diff --git a/test/quicapitest.c b/test/quicapitest.c index c471495aa21..ed11b73ba24 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -1250,6 +1250,34 @@ static int test_alpn(int idx) return testresult; } +static int test_noisy_dgram(void) +{ + SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL *clientquic = NULL; + QUIC_TSERVER *qtserv = NULL; + int testresult = 0; + + if (!TEST_ptr(cctx) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, + privkey, + QTEST_FLAG_NOISE, + &qtserv, + &clientquic, NULL))) + goto err; + + if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) + goto err; + + testresult = 1; + err: + ossl_quic_tserver_free(qtserv); + SSL_free(clientquic); + SSL_CTX_free(cctx); + + return testresult; +} + + OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") int setup_tests(void) @@ -1323,6 +1351,8 @@ int setup_tests(void) ADD_ALL_TESTS(test_non_io_retry, 2); ADD_TEST(test_quic_psk); ADD_ALL_TESTS(test_alpn, 2); + ADD_TEST(test_noisy_dgram); + return 1; err: cleanup_tests(); @@ -1331,6 +1361,7 @@ int setup_tests(void) void cleanup_tests(void) { + bio_f_noisy_dgram_filter_free(); OPENSSL_free(cert); OPENSSL_free(privkey); OSSL_PROVIDER_unload(defctxnull);