Skip to content

Commit

Permalink
Extend the test_quic_write_read() test to include resumption
Browse files Browse the repository at this point in the history
We add an additional loop around test_quic_write_read() to repeat the
test but using a session obtained from the initial iteration to confirm
that we can successfully resume the session.
  • Loading branch information
mattcaswell committed Jul 28, 2023
1 parent 987ce59 commit e43cde0
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 80 deletions.
8 changes: 4 additions & 4 deletions doc/designs/quic-design/quic-fault-injector.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ typedef struct ossl_qf_encrypted_extensions {
* instance. |block| indicates whether we are using blocking mode or not.
*/
int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
char *certfile, char *keyfile, int block,
QUIC_TSERVER **qtserv, SSL **cssl,
SSL_CTX *serverctx, char *certfile, char *keyfile,
int block, QUIC_TSERVER **qtserv, SSL **cssl,
OSSL_QUIC_FAULT **fault);

/*
Expand Down Expand Up @@ -432,7 +432,7 @@ static int test_unknown_frame(void)
if (!TEST_ptr(cctx))
goto err;
if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0,
if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0,
&qtserv, &cssl, &fault)))
goto err;
Expand Down Expand Up @@ -525,7 +525,7 @@ static int test_no_transport_params(void)
if (!TEST_ptr(cctx))
goto err;

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

Expand Down
4 changes: 2 additions & 2 deletions test/helpers/quictestlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static OSSL_TIME fake_now_cb(void *arg)
}

int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
char *certfile, char *keyfile,
SSL_CTX *serverctx, char *certfile, char *keyfile,
int flags, QUIC_TSERVER **qtserv, SSL **cssl,
QTEST_FAULT **fault)
{
Expand Down Expand Up @@ -166,7 +166,7 @@ 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;
tserver_args.ctx = NULL;
tserver_args.ctx = serverctx;
if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
fake_now = ossl_time_zero();
tserver_args.now_cb = fake_now_cb;
Expand Down
4 changes: 2 additions & 2 deletions test/helpers/quictestlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ typedef struct qtest_fault_encrypted_extensions {
* 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 flags,
QUIC_TSERVER **qtserv, SSL **cssl,
SSL_CTX *serverctx, 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 */
Expand Down
2 changes: 1 addition & 1 deletion test/quic_newcid_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static int test_ncid_frame(int fail)
if (!TEST_ptr(cctx))
goto err;

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

Expand Down
177 changes: 110 additions & 67 deletions test/quicapitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,100 +45,143 @@ static int is_fips = 0;
static int test_quic_write_read(int idx)
{
SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method());
SSL_CTX *sctx = NULL;
SSL *clientquic = NULL;
QUIC_TSERVER *qtserv = NULL;
int j, ret = 0;
int j, k, ret = 0;
unsigned char buf[20];
static char *msg = "A test message";
size_t msglen = strlen(msg);
size_t numbytes = 0;
int ssock = 0, csock = 0;
uint64_t sid = UINT64_MAX;
SSL_SESSION *sess = NULL;

if (idx >= 1 && !qtest_supports_blocking())
return TEST_skip("Blocking tests not supported in this build");

if (!TEST_ptr(cctx)
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey,
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;

if (idx >= 1) {
if (!TEST_true(BIO_get_fd(ossl_quic_tserver_get0_rbio(qtserv), &ssock)))
for (k = 0; k < 2; k++) {
if (!TEST_ptr(cctx)
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, sctx,
cert, privkey,
idx >= 1
? QTEST_FLAG_BLOCK
: 0,
&qtserv, &clientquic,
NULL))
|| !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost")))
goto end;
if (!TEST_int_gt(csock = SSL_get_rfd(clientquic), 0))
goto end;
}

sid = 0; /* client-initiated bidirectional stream */
if (sess != NULL && !TEST_true(SSL_set_session(clientquic, sess)))
goto end;

for (j = 0; j < 2; j++) {
/* Check that sending and receiving app data is ok */
if (!TEST_true(SSL_write_ex(clientquic, msg, msglen, &numbytes))
|| !TEST_size_t_eq(numbytes, msglen))
if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic)))
goto end;

if (idx >= 1) {
do {
if (!TEST_true(wait_until_sock_readable(ssock)))
if (!TEST_true(BIO_get_fd(ossl_quic_tserver_get0_rbio(qtserv),
&ssock)))
goto end;
if (!TEST_int_gt(csock = SSL_get_rfd(clientquic), 0))
goto end;
}

sid = 0; /* client-initiated bidirectional stream */

for (j = 0; j < 2; j++) {
/* Check that sending and receiving app data is ok */
if (!TEST_true(SSL_write_ex(clientquic, msg, msglen, &numbytes))
|| !TEST_size_t_eq(numbytes, msglen))
goto end;
if (idx >= 1) {
do {
if (!TEST_true(wait_until_sock_readable(ssock)))
goto end;

ossl_quic_tserver_tick(qtserv);

if (!TEST_true(ossl_quic_tserver_read(qtserv, sid, buf,
sizeof(buf),
&numbytes)))
goto end;
} while (numbytes == 0);

if (!TEST_mem_eq(buf, numbytes, msg, msglen))
goto end;
}

ossl_quic_tserver_tick(qtserv);
if (idx >= 2 && j > 0)
/* Introduce permanent socket error */
BIO_closesocket(csock);

if (!TEST_true(ossl_quic_tserver_read(qtserv, sid, buf, sizeof(buf),
&numbytes)))
ossl_quic_tserver_tick(qtserv);
if (!TEST_true(ossl_quic_tserver_write(qtserv, sid,
(unsigned char *)msg,
msglen, &numbytes)))
goto end;
ossl_quic_tserver_tick(qtserv);
SSL_handle_events(clientquic);

if (idx >= 2 && j > 0) {
if (!TEST_false(SSL_read_ex(clientquic, buf, 1, &numbytes))
|| !TEST_int_eq(SSL_get_error(clientquic, 0),
SSL_ERROR_SYSCALL)
|| !TEST_false(SSL_write_ex(clientquic, msg, msglen,
&numbytes))
|| !TEST_int_eq(SSL_get_error(clientquic, 0),
SSL_ERROR_SYSCALL))
goto end;
} while (numbytes == 0);
break;
}

if (!TEST_mem_eq(buf, numbytes, msg, msglen))
/*
* In blocking mode the SSL_read_ex call will block until the socket
* is readable and has our data. In non-blocking mode we're doing
* everything in memory, so it should be immediately available
*/
if (!TEST_true(SSL_read_ex(clientquic, buf, 1, &numbytes))
|| !TEST_size_t_eq(numbytes, 1)
|| !TEST_true(SSL_has_pending(clientquic))
|| !TEST_int_eq(SSL_pending(clientquic), msglen - 1)
|| !TEST_true(SSL_read_ex(clientquic, buf + 1,
sizeof(buf) - 1, &numbytes))
|| !TEST_mem_eq(buf, numbytes + 1, msg, msglen))
goto end;
}

if (idx >= 2 && j > 0)
/* Introduce permanent socket error */
BIO_closesocket(csock);

ossl_quic_tserver_tick(qtserv);
if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, (unsigned char *)msg,
msglen, &numbytes)))
goto end;
ossl_quic_tserver_tick(qtserv);
SSL_handle_events(clientquic);

if (idx >= 2 && j > 0) {
if (!TEST_false(SSL_read_ex(clientquic, buf, 1, &numbytes))
|| !TEST_int_eq(SSL_get_error(clientquic, 0),
SSL_ERROR_SYSCALL)
|| !TEST_false(SSL_write_ex(clientquic, msg, msglen,
&numbytes))
|| !TEST_int_eq(SSL_get_error(clientquic, 0),
SSL_ERROR_SYSCALL))
if (sess == NULL) {
/* We didn't supply a session so we're not expecting resumption */
if (!TEST_false(SSL_session_reused(clientquic)))
goto end;
/* We should have a session ticket by now */
sess = SSL_get1_session(clientquic);
if (!TEST_ptr(sess))
goto end;
} else {
/* We supplied a session so we should have resumed */
if (!TEST_true(SSL_session_reused(clientquic)))
goto end;
break;
}

/*
* In blocking mode the SSL_read_ex call will block until the socket is
* readable and has our data. In non-blocking mode we're doing everything
* in memory, so it should be immediately available
*/
if (!TEST_true(SSL_read_ex(clientquic, buf, 1, &numbytes))
|| !TEST_size_t_eq(numbytes, 1)
|| !TEST_true(SSL_has_pending(clientquic))
|| !TEST_int_eq(SSL_pending(clientquic), msglen - 1)
|| !TEST_true(SSL_read_ex(clientquic, buf + 1, sizeof(buf) - 1, &numbytes))
|| !TEST_mem_eq(buf, numbytes + 1, msg, msglen))
if (!TEST_true(qtest_shutdown(qtserv, clientquic)))
goto end;
}

if (!TEST_true(qtest_shutdown(qtserv, clientquic)))
goto end;
sctx = ossl_quic_tserver_get0_ssl_ctx(qtserv);
if (!TEST_true(SSL_CTX_up_ref(sctx)))
goto end;
ossl_quic_tserver_free(qtserv);
qtserv = NULL;
SSL_free(clientquic);
clientquic = NULL;

if (idx >= 2)
break;
}

ret = 1;

end:
SSL_SESSION_free(sess);
ossl_quic_tserver_free(qtserv);
SSL_free(clientquic);
SSL_CTX_free(cctx);
Expand Down Expand Up @@ -209,9 +252,9 @@ static int test_version(void)
int testresult = 0;

if (!TEST_ptr(cctx)
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey,
0, &qtserv, &clientquic,
NULL))
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert,
privkey, 0, &qtserv,
&clientquic, NULL))
|| !TEST_true(qtest_create_quic_connection(qtserv, clientquic)))
goto err;

Expand Down Expand Up @@ -315,9 +358,9 @@ static int test_ssl_trace(void)

if (!TEST_ptr(cctx)
|| !TEST_ptr(bio)
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey,
0, &qtserv, &clientquic,
NULL)))
|| !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert,
privkey, 0, &qtserv,
&clientquic, NULL)))
goto err;

SSL_set_msg_callback(clientquic, SSL_trace);
Expand Down Expand Up @@ -643,7 +686,7 @@ static int test_bio_ssl(void)
if (!TEST_int_eq(BIO_get_ssl(cbio, &clientquic), 1))
goto err;

if (!TEST_true(qtest_create_quic_objects(libctx, NULL, cert, privkey,
if (!TEST_true(qtest_create_quic_objects(libctx, NULL, NULL, cert, privkey,
0, &qtserv, &clientquic, NULL)))
goto err;

Expand Down
8 changes: 4 additions & 4 deletions test/quicfaultstest.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static int test_basic(void)
if (!TEST_ptr(cctx))
goto err;

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

Expand Down Expand Up @@ -104,7 +104,7 @@ static int test_unknown_frame(void)
if (!TEST_ptr(cctx))
goto err;

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

Expand Down Expand Up @@ -184,7 +184,7 @@ static int test_no_transport_params(void)
if (!TEST_ptr(cctx))
goto err;

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

Expand Down Expand Up @@ -263,7 +263,7 @@ static int test_corrupted_data(int idx)
if (!TEST_ptr(cctx))
goto err;

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

0 comments on commit e43cde0

Please sign in to comment.