Skip to content

Commit

Permalink
Verify the idle timeout negotiation
Browse files Browse the repository at this point in the history
  • Loading branch information
huitema committed Dec 13, 2023
1 parent deb0ac6 commit 55a9ea1
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ else()
endif()

project(picoquic
VERSION 1.1.16.0
VERSION 1.1.16.1
DESCRIPTION "picoquic library"
LANGUAGES C CXX)

Expand Down
7 changes: 7 additions & 0 deletions UnitTest1/unittest1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,13 @@ namespace UnitTest1
Assert::AreEqual(ret, 0);
}

TEST_METHOD(idle_timeout)
{
int ret = idle_timeout_test();

Assert::AreEqual(ret, 0);
}

TEST_METHOD(ready_to_send)
{
int ret = ready_to_send_test();
Expand Down
4 changes: 2 additions & 2 deletions picoquic/picoquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
extern "C" {
#endif

#define PICOQUIC_VERSION "1.1.16.0"
#define PICOQUIC_VERSION "1.1.16.1"
#define PICOQUIC_ERROR_CLASS 0x400
#define PICOQUIC_ERROR_DUPLICATE (PICOQUIC_ERROR_CLASS + 1)
#define PICOQUIC_ERROR_AEAD_CHECK (PICOQUIC_ERROR_CLASS + 3)
Expand Down Expand Up @@ -642,7 +642,7 @@ void picoquic_set_cwin_max(picoquic_quic_t* quic, uint64_t cwin_max);
void picoquic_set_max_data_control(picoquic_quic_t* quic, uint64_t max_data);

/* Set the idle timeout parameter for the context. Value is in milliseconds. */
void picoquic_set_default_idle_timeout(picoquic_quic_t* quic, uint64_t idle_timeout);
void picoquic_set_default_idle_timeout(picoquic_quic_t* quic, uint64_t idle_timeout_ms);

/* Set the length of a crypto epoch -- force rotation after that many packets sent */
void picoquic_set_default_crypto_epoch_length(picoquic_quic_t* quic, uint64_t crypto_epoch_length_max);
Expand Down
1 change: 0 additions & 1 deletion picoquic/picoquic_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,6 @@ typedef struct st_picoquic_quic_t {
picoquic_spinbit_version_enum default_spin_policy;
picoquic_lossbit_version_enum default_lossbit_policy;
uint32_t default_multipath_option;
uint64_t default_idle_timeout;
uint64_t crypto_epoch_length_max; /* Default packet interval between key rotations */
uint32_t max_simultaneous_logs;
uint32_t current_number_of_open_logs;
Expand Down
5 changes: 2 additions & 3 deletions picoquic/quicctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,10 +835,9 @@ void picoquic_set_max_data_control(picoquic_quic_t* quic, uint64_t max_data)
}
}

void picoquic_set_default_idle_timeout(picoquic_quic_t* quic, uint64_t idle_timeout)
void picoquic_set_default_idle_timeout(picoquic_quic_t* quic, uint64_t idle_timeout_ms)
{
quic->default_idle_timeout = idle_timeout;
quic->default_tp.idle_timeout = idle_timeout;
quic->default_tp.idle_timeout = idle_timeout_ms;
}

void picoquic_set_default_crypto_epoch_length(picoquic_quic_t* quic, uint64_t crypto_epoch_length_max)
Expand Down
1 change: 1 addition & 0 deletions picoquic_t/picoquic_t.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ static const picoquic_test_def_t test_table[] = {
{ "ec5c_silly_cid", ec5c_silly_cid_test },
{ "ec9a_preemptive_amok", ec9a_preemptive_amok_test },
{ "error_reason", error_reason_test },
{ "idle_timeout", idle_timeout_test },
{ "ready_to_send", ready_to_send_test },
{ "ready_to_skip", ready_to_skip_test },
{ "ready_to_zfin", ready_to_zfin_test },
Expand Down
121 changes: 121 additions & 0 deletions picoquictest/edge_cases.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,5 +616,126 @@ int ec9a_preemptive_amok_test()
test_ctx = NULL;
}

return ret;
}

/* testing the negotiation of the idle timeout.
*/
int idle_timeout_test_one(uint8_t test_id, uint64_t client_timeout, uint64_t server_timeout, uint64_t expected_timeout)
{
picoquic_test_tls_api_ctx_t* test_ctx = NULL;
uint64_t simulated_time = 0;
uint64_t loss_mask = 0;
picoquic_connection_id_t initial_cid = { { 0x41, 0x9e, 0x00, 0x94, 0, 0, 0, 0}, 8 };
uint64_t latency = 17000;
uint64_t half_time = (expected_timeout == UINT64_MAX) ? 20000000 : (expected_timeout / 2);
uint64_t full_time = (expected_timeout == UINT64_MAX) ? 600000000 : (half_time + 100000);
int ret = 0;

initial_cid.id[4] = test_id;

/* Create the test context */
if (ret == 0) {
ret = tls_api_init_ctx_ex(&test_ctx, PICOQUIC_INTERNAL_TEST_VERSION_1,
PICOQUIC_TEST_SNI, PICOQUIC_TEST_ALPN, &simulated_time, NULL, NULL, 0, 1, 0, &initial_cid);
}
/* Set the binlog */
if (ret == 0) {
picoquic_set_binlog(test_ctx->qclient, ".");
picoquic_set_binlog(test_ctx->qserver, ".");
/* Set the timeout */
picoquic_set_default_idle_timeout(test_ctx->qclient, client_timeout);
picoquic_set_default_idle_timeout(test_ctx->qserver, server_timeout);
/* Directly set the timeout in the client parameters,
because the connection context is already created */
test_ctx->cnx_client->local_parameters.idle_timeout = client_timeout;
}

/* Do the connection */
if (ret == 0) {
test_ctx->cnx_client->max_early_data_size = 0;

if ((ret = picoquic_start_client_cnx(test_ctx->cnx_client)) == 0) {
ret = tls_api_connection_loop(test_ctx, &loss_mask, 0, &simulated_time);
}
}

/* Verify the timer negotiation */
if (ret == 0) {
if (test_ctx->cnx_client->local_parameters.idle_timeout != client_timeout) {
DBG_PRINTF("Idle timeout test %d. Client parameter set to %" PRIu64 " instead of %" PRIu64 "\n",
test_id, test_ctx->cnx_client->local_parameters.idle_timeout, client_timeout);
ret = -1;
}
if (test_ctx->cnx_server->local_parameters.idle_timeout != server_timeout) {
DBG_PRINTF("Idle timeout test %d. Server parameter set to %" PRIu64 " instead of %" PRIu64 "\n",
test_id, test_ctx->cnx_server->local_parameters.idle_timeout, server_timeout);
ret = -1;
}
if (test_ctx->cnx_client->idle_timeout != expected_timeout) {
DBG_PRINTF("Idle timeout test %d. Client negotiated %" PRIu64 " instead of %" PRIu64 "\n",
test_id, test_ctx->cnx_client->idle_timeout, expected_timeout);
ret = -1;
}
if (test_ctx->cnx_server->idle_timeout != expected_timeout) {
DBG_PRINTF("Idle timeout test %d. Server negotiated %" PRIu64 " instead of %" PRIu64 "\n",
test_id, test_ctx->cnx_server->idle_timeout, expected_timeout);
ret = -1;
}
}

if (ret == 0) {
/* Wait for half time. Expectation: connections are still up */
ret = tls_api_wait_for_timeout(test_ctx, &simulated_time, half_time);
if (ret != 0 || !((TEST_CLIENT_READY && TEST_SERVER_READY))) {
DBG_PRINTF("Idle timeout test %d. Broke early, time = %" PRIu64 "\n", test_id, simulated_time);
ret = -1;
}
}

if (ret == 0) {
/* Wait for full time. Expectation: connections are down, unless timeout == 0 */
ret = tls_api_wait_for_timeout(test_ctx, &simulated_time, full_time);

if (ret == 0){
if (TEST_CLIENT_READY && TEST_SERVER_READY) {
if (expected_timeout != UINT64_MAX) {
DBG_PRINTF("Idle timeout test %d. Waited too long, time = %" PRIu64 "\n", test_id, simulated_time);
ret = -1;
}
}
else {
if (expected_timeout == UINT64_MAX) {
DBG_PRINTF("Idle timeout test %d. Broke early, time = %" PRIu64 "\n", test_id, simulated_time);
ret = -1;
}
}
}
}

if (test_ctx != NULL) {
tls_api_delete_ctx(test_ctx);
test_ctx = NULL;
}

return ret;
}

int idle_timeout_test()
{
int ret = 0;

if ((ret = idle_timeout_test_one(1, 30000, 30000, 30000000)) == 0 &&
(ret = idle_timeout_test_one(2, 60000, 20000, 20000000)) == 0 &&
(ret = idle_timeout_test_one(3, 20000, 60000, 20000000)) == 0 &&
(ret = idle_timeout_test_one(4, 5000, 300000, 5000000)) == 0 &&
(ret = idle_timeout_test_one(5, 300000, 5000, 5000000)) == 0 &&
(ret = idle_timeout_test_one(6, 0, 5000, 5000000)) == 0 &&
(ret = idle_timeout_test_one(7, 0, 60000, 60000000)) == 0 &&
(ret = idle_timeout_test_one(8, 5000, 0, 5000000)) == 0 &&
(ret = idle_timeout_test_one(9, 60000, 0, 60000000)) == 0 &&
(ret = idle_timeout_test_one(10, 0, 0, UINT64_MAX)) == 0) {
DBG_PRINTF("All idle timeout tests pass.\n");
}
return ret;
}
1 change: 1 addition & 0 deletions picoquictest/picoquictest.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ int ecf1_final_loss_test();
int ec5c_silly_cid_test();
int ec9a_preemptive_amok_test();
int error_reason_test();
int idle_timeout_test();
int ready_to_send_test();
int ready_to_skip_test();
int ready_to_zero_test();
Expand Down

0 comments on commit 55a9ea1

Please sign in to comment.