summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2024-02-14 12:45:15 +0100
committerTomas Mraz <tomas@openssl.org>2024-03-15 10:19:19 +0100
commitb7de38e84c13bbf56a9703fb600f925b86a9a28d (patch)
treea65c1789b9cc9a197fafe8e72505d36764a85dbe
parent37ffd4a1fa02b37919b5c7a8059ba57d3c49b1f0 (diff)
Add a test using the bandwidth limit filter
Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23588)
-rw-r--r--test/helpers/quictestlib.c46
-rw-r--r--test/helpers/quictestlib.h14
-rw-r--r--test/quicapitest.c93
3 files changed, 153 insertions, 0 deletions
diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c
index 403e1f4384..0454e332cf 100644
--- a/test/helpers/quictestlib.c
+++ b/test/helpers/quictestlib.c
@@ -80,6 +80,7 @@ static void qtest_reset_time(void);
static int using_fake_time = 0;
static OSSL_TIME fake_now;
static CRYPTO_RWLOCK *fake_now_lock = NULL;
+static OSSL_TIME start_time;
static OSSL_TIME fake_now_cb(void *arg)
{
@@ -220,6 +221,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
if ((flags & QTEST_FLAG_NOISE) != 0) {
BIO *noisebio;
+ struct bio_noise_now_cb_st now_cb = { fake_now_cb, NULL };
/*
* It is an error to not have a QTEST_FAULT object when introducing noise
@@ -232,12 +234,22 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
if (!TEST_ptr(noisebio))
goto err;
cbio = BIO_push(noisebio, cbio);
+ if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
+ if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_SET_NOW_CB,
+ 0, &now_cb), 1))
+ goto err;
+ }
noisebio = BIO_new(bio_f_noisy_dgram_filter());
if (!TEST_ptr(noisebio))
goto err;
sbio = BIO_push(noisebio, sbio);
+ if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
+ if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SET_NOW_CB,
+ 0, &now_cb), 1))
+ goto err;
+ }
/*
* TODO(QUIC SERVER):
* Currently the simplistic handler of the quic tserver cannot cope
@@ -364,6 +376,16 @@ static void qtest_reset_time(void)
qtest_add_time(1);
}
+void qtest_start_stopwatch(void)
+{
+ start_time = qtest_get_time();
+}
+
+uint64_t qtest_get_stopwatch_time(void)
+{
+ return ossl_time2ms(ossl_time_subtract(qtest_get_time(), start_time));
+}
+
QTEST_FAULT *qtest_create_injector(QUIC_TSERVER *ts)
{
QTEST_FAULT *f;
@@ -1207,6 +1229,30 @@ int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen)
return 1;
}
+int qtest_fault_set_bw_limit(QTEST_FAULT *fault,
+ size_t ctos_bw, size_t stoc_bw,
+ int noise_rate)
+{
+ BIO *sbio = fault->noiseargs.sbio;
+ BIO *cbio = fault->noiseargs.cbio;
+
+ if (!TEST_ptr(sbio) || !TEST_ptr(cbio))
+ return 0;
+ if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_RATE, noise_rate, NULL), 1))
+ return 0;
+ if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_RATE, noise_rate, NULL), 1))
+ return 0;
+ /* We set the bandwidth limit on the sending side */
+ if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_SEND_BANDWIDTH,
+ (long)ctos_bw, NULL), 1))
+ return 0;
+ if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SEND_BANDWIDTH,
+ (long)stoc_bw, NULL), 1))
+ return 0;
+ return 1;
+}
+
+
int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src)
{
/*
diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h
index 228d396f41..d9d01f7fc1 100644
--- a/test/helpers/quictestlib.h
+++ b/test/helpers/quictestlib.h
@@ -49,6 +49,11 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
/* Where QTEST_FLAG_FAKE_TIME is used, add millis to the current time */
void qtest_add_time(uint64_t millis);
+/* Starts time measurement */
+void qtest_start_stopwatch(void);
+/* Returns the duration from the start in millis */
+uint64_t qtest_get_stopwatch_time(void);
+
QTEST_FAULT *qtest_create_injector(QUIC_TSERVER *ts);
BIO_METHOD *qtest_get_bio_method(void);
@@ -244,6 +249,15 @@ int qtest_fault_set_datagram_listener(QTEST_FAULT *fault,
*/
int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen);
+/*
+ * Set bandwidth and noise rate on noisy dgram filter.
+ * Arguments with values of 0 mean no limit/no noise.
+ */
+
+int qtest_fault_set_bw_limit(QTEST_FAULT *fault,
+ size_t ctos_bw, size_t stoc_bw,
+ int noise_rate);
+
/* Copy a BIO_MSG */
int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src);
diff --git a/test/quicapitest.c b/test/quicapitest.c
index 098e1a9b39..2b6c2fc6e0 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -1566,6 +1566,98 @@ static int test_noisy_dgram(int idx)
return testresult;
}
+/*
+ * Create a connection and send some big data using a transport with limited bandwidth.
+ */
+
+#define TEST_TRANSFER_DATA_SIZE (2*1024*1024) /* 2 MBytes */
+#define TEST_SINGLE_WRITE_SIZE (16*1024) /* 16 kBytes */
+#define TEST_BW_LIMIT 1000 /* 1000 Bytes/ms */
+static int test_bw_limit(void)
+{
+ SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method());
+ SSL *clientquic = NULL;
+ QUIC_TSERVER *qtserv = NULL;
+ int testresult = 0;
+ unsigned char *msg = NULL, *recvbuf = NULL;
+ size_t sendlen = TEST_TRANSFER_DATA_SIZE;
+ size_t recvlen = TEST_TRANSFER_DATA_SIZE;
+ size_t written, readbytes;
+ int flags = QTEST_FLAG_NOISE | QTEST_FLAG_FAKE_TIME;
+ QTEST_FAULT *fault = NULL;
+ uint64_t real_bw;
+
+ if (!TEST_ptr(cctx)
+ || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert,
+ privkey, flags,
+ &qtserv,
+ &clientquic, &fault, NULL)))
+ goto err;
+
+ if (!TEST_ptr(msg = OPENSSL_zalloc(TEST_SINGLE_WRITE_SIZE))
+ || !TEST_ptr(recvbuf = OPENSSL_zalloc(TEST_SINGLE_WRITE_SIZE)))
+ goto err;
+
+ /* Set BW to 1000 Bytes/ms -> 1MByte/s both ways */
+ if (!TEST_true(qtest_fault_set_bw_limit(fault, 1000, 1000, 0)))
+ goto err;
+
+ if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic)))
+ goto err;
+
+ qtest_start_stopwatch();
+
+ while (recvlen > 0) {
+ qtest_add_time(1);
+
+ if (sendlen > 0) {
+ if (!SSL_write_ex(clientquic, msg,
+ sendlen > TEST_SINGLE_WRITE_SIZE ? TEST_SINGLE_WRITE_SIZE
+ : sendlen,
+ &written)) {
+ TEST_info("Retrying to send: %llu", (unsigned long long) sendlen);
+ if (!TEST_int_eq(SSL_get_error(clientquic, 0), SSL_ERROR_WANT_WRITE))
+ goto err;
+ } else {
+ sendlen -= written;
+ TEST_info("Remaining to send: %llu", (unsigned long long) sendlen);
+ }
+ } else {
+ SSL_handle_events(clientquic);
+ }
+
+ if (ossl_quic_tserver_read(qtserv, 0, recvbuf,
+ recvlen > TEST_SINGLE_WRITE_SIZE ? TEST_SINGLE_WRITE_SIZE
+ : recvlen,
+ &readbytes)
+ && readbytes > 1) {
+ recvlen -= readbytes;
+ TEST_info("Remaining to recv: %llu", (unsigned long long) recvlen);
+ } else {
+ TEST_info("No progress on recv: %llu", (unsigned long long) recvlen);
+ }
+ ossl_quic_tserver_tick(qtserv);
+ }
+ real_bw = TEST_TRANSFER_DATA_SIZE / qtest_get_stopwatch_time();
+
+ TEST_info("BW limit: %d Bytes/ms Real bandwidth reached: %llu Bytes/ms",
+ TEST_BW_LIMIT, (unsigned long long)real_bw);
+
+ if (!TEST_uint64_t_lt(real_bw, TEST_BW_LIMIT))
+ goto err;
+
+ testresult = 1;
+ err:
+ OPENSSL_free(msg);
+ OPENSSL_free(recvbuf);
+ ossl_quic_tserver_free(qtserv);
+ SSL_free(clientquic);
+ SSL_CTX_free(cctx);
+ qtest_fault_free(fault);
+
+ return testresult;
+}
+
enum {
TPARAM_OP_DUP,
TPARAM_OP_DROP,
@@ -2165,6 +2257,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_client_auth, 3);
ADD_ALL_TESTS(test_alpn, 2);
ADD_ALL_TESTS(test_noisy_dgram, 2);
+ ADD_TEST(test_bw_limit);
ADD_TEST(test_get_shutdown);
ADD_ALL_TESTS(test_tparam, OSSL_NELEM(tparam_tests));