Skip to content

Commit

Permalink
Allow qtestlib to use a "fake_now" implementation
Browse files Browse the repository at this point in the history
We then use it in test_corrupted_data() to remove an OSSL_sleep() which
may fail in some builds.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from #21332)
  • Loading branch information
mattcaswell authored and paulidale committed Jul 6, 2023
1 parent d001006 commit f9fcc7c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
24 changes: 21 additions & 3 deletions test/helpers/quictestlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,16 @@ static void handshake_finish(void *arg);

static BIO_METHOD *get_bio_method(void);

static OSSL_TIME fake_now;

static OSSL_TIME fake_now_cb(void *arg)
{
return fake_now;
}

int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
char *certfile, char *keyfile,
int block, QUIC_TSERVER **qtserv, SSL **cssl,
int flags, QUIC_TSERVER **qtserv, SSL **cssl,
QTEST_FAULT **fault)
{
/* ALPN value as recognised by QUIC_TSERVER */
Expand All @@ -92,7 +99,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
if (!TEST_ptr(peeraddr = BIO_ADDR_new()))
goto err;

if (block) {
if ((flags & QTEST_FLAG_BLOCK) != 0) {
#if !defined(OPENSSL_NO_POSIX_IO)
int cfd, sfd;

Expand Down Expand Up @@ -132,7 +139,8 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,

SSL_set_bio(*cssl, cbio, cbio);

if (!TEST_true(SSL_set_blocking_mode(*cssl, block)))
if (!TEST_true(SSL_set_blocking_mode(*cssl,
(flags & QTEST_FLAG_BLOCK) != 0 ? 1 : 0)))
goto err;

if (!TEST_true(SSL_set_initial_peer_addr(*cssl, peeraddr)))
Expand All @@ -157,6 +165,10 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
tserver_args.net_rbio = sbio;
tserver_args.net_wbio = fisbio;
tserver_args.alpn = NULL;
if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
fake_now = ossl_time_zero();
tserver_args.now_cb = fake_now_cb;
}

if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile,
keyfile)))
Expand Down Expand Up @@ -186,6 +198,11 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
return 0;
}

void qtest_add_time(uint64_t millis)
{
fake_now = ossl_time_add(fake_now, ossl_ms2time(millis));
}

int qtest_supports_blocking(void)
{
#if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
Expand Down Expand Up @@ -271,6 +288,7 @@ int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl)
if (!clienterr && retc <= 0)
SSL_handle_events(clientssl);
if (!servererr && rets <= 0) {
qtest_add_time(1);
ossl_quic_tserver_tick(qtserv);
servererr = ossl_quic_tserver_is_term_any(qtserv);
if (!servererr)
Expand Down
14 changes: 12 additions & 2 deletions test/helpers/quictestlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,26 @@ typedef struct qtest_fault_encrypted_extensions {
size_t extensionslen;
} QTEST_ENCRYPTED_EXTENSIONS;

/* Flags for use with qtest_create_quic_objects() */

/* Indicates whether we are using blocking mode or not */
#define QTEST_FLAG_BLOCK 1
/* Use fake time rather than real time */
#define QTEST_FLAG_FAKE_TIME 2

/*
* Given an SSL_CTX for the client and filenames for the server certificate and
* keyfile, create a server and client instances as well as a fault injector
* instance. |block| indicates whether we are using blocking mode or not.
* instance. |flags| is the logical or of flags defined above, or 0 if none.
*/
int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
char *certfile, char *keyfile, int block,
char *certfile, char *keyfile, int flags,
QUIC_TSERVER **qtserv, SSL **cssl,
QTEST_FAULT **fault);

/* Where QTEST_FLAG_FAKE_TIME is used, add millis to the current time */
void qtest_add_time(uint64_t millis);

/*
* Free up a Fault Injector instance
*/
Expand Down
4 changes: 2 additions & 2 deletions test/quicapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ static int test_quic_write_read(int idx)

if (!TEST_ptr(cctx)
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey,
idx, &qtserv, &clientquic,
NULL))
idx == 1 ? QTEST_FLAG_BLOCK : 0,
&qtserv, &clientquic, NULL))
|| !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost"))
|| !TEST_true(qtest_create_quic_connection(qtserv, clientquic)))
goto end;
Expand Down
16 changes: 5 additions & 11 deletions test/quicfaultstest.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,9 @@ static int test_corrupted_data(int idx)
if (!TEST_ptr(cctx))
goto err;

if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0,
&qtserv, &cssl, &fault)))
if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey,
QTEST_FLAG_FAKE_TIME, &qtserv,
&cssl, &fault)))
goto err;

if (idx == 0) {
Expand Down Expand Up @@ -315,16 +316,9 @@ static int test_corrupted_data(int idx)
* Introduce a small delay so that the above packet has time to be detected
* as lost. Loss detection times are based on RTT which should be very
* fast for us since there isn't really a network. The loss delay timer is
* always at least 1ms though. We sleep for 100ms.
* TODO(QUIC): This assumes the calculated RTT will always be way less than
* 100ms - which it should be...but can we always guarantee this? An
* alternative might be to put in our own ossl_time_now() implementation for
* these tests and control the timer as part of the test. This approach has
* the added advantage that the test will behave reliably when run in a
* debugger. Without it may get unreliable debugging results. This would
* require some significant refactoring of the ssl/quic code though.
* always at least 1ms though. We skip forward 100ms
*/
OSSL_sleep(100);
qtest_add_time(100);

/* Send rest of message */
if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, (unsigned char *)msg + 5,
Expand Down

0 comments on commit f9fcc7c

Please sign in to comment.