Skip to content

Commit 7d9ccc4

Browse files
authored
Merge pull request #1849 from private-octopus/unpadded-test
Add test of variations of padding policy
2 parents 93e06fa + 18d5351 commit 7d9ccc4

File tree

4 files changed

+176
-7
lines changed

4 files changed

+176
-7
lines changed

UnitTest1/unittest1.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,20 @@ namespace UnitTest1
17651765
Assert::AreEqual(ret, 0);
17661766
}
17671767

1768+
TEST_METHOD(padding_null)
1769+
{
1770+
int ret = padding_null_test();
1771+
1772+
Assert::AreEqual(ret, 0);
1773+
}
1774+
1775+
TEST_METHOD(padding_zero_min)
1776+
{
1777+
int ret = padding_zero_min_test();
1778+
1779+
Assert::AreEqual(ret, 0);
1780+
}
1781+
17681782
TEST_METHOD(packet_trace)
17691783
{
17701784
int ret = packet_trace_test();

picoquic_t/picoquic_t.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ static const picoquic_test_def_t test_table[] = {
294294
{ "short_initial_cid", short_initial_cid_test },
295295
{ "stream_id_max", stream_id_max_test },
296296
{ "padding_test", padding_test },
297+
{ "padding_null", padding_null_test },
298+
{ "padding_zero_min", padding_zero_min_test },
297299
{ "packet_trace", packet_trace_test },
298300
{ "qlog_auto", qlog_auto_test },
299301
{ "qlog_error", qlog_error_test },

picoquictest/picoquictest.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ int keylog_test();
234234
int short_initial_cid_test();
235235
int stream_id_max_test();
236236
int padding_test();
237+
int padding_null_test();
238+
int padding_zero_min_test();
237239
int packet_trace_test();
238240
int qlog_auto_test();
239241
int qlog_error_test();

picoquictest/tls_api_test.c

Lines changed: 158 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8189,12 +8189,35 @@ int stream_id_max_test()
81898189
* Test whether padding policy is correctly applied, and whether the corresponding
81908190
* connection succeeds.
81918191
*/
8192+
size_t padding_test_predict_pn_length(picoquic_packet_context_t * pkt_ctx)
8193+
{
8194+
/* Predict acceptable length of packet number */
8195+
size_t pn_l = 4;
8196+
int64_t delta = (pkt_ctx->send_sequence==0)?0: pkt_ctx->send_sequence-1;
8197+
if (pkt_ctx->pending_first != NULL) {
8198+
delta -= pkt_ctx->pending_first->sequence_number;
8199+
}
8200+
if (delta < 262144) {
8201+
pn_l = 3;
8202+
if (pkt_ctx->send_sequence < 1024) {
8203+
pn_l = 2;
8204+
if (pkt_ctx->send_sequence < 16) {
8205+
pn_l = 1;
8206+
}
8207+
}
8208+
}
8209+
return pn_l;
8210+
}
81928211

8193-
int padding_test()
8212+
int padding_test_one(uint32_t padding_multiple, uint32_t padding_min_size)
81948213
{
81958214
uint64_t simulated_time = 0;
8215+
uint64_t loss_mask = 0;
81968216
picoquic_test_tls_api_ctx_t* test_ctx = NULL;
81978217
int ret = tls_api_init_ctx(&test_ctx, PICOQUIC_INTERNAL_TEST_VERSION_1, PICOQUIC_TEST_SNI, PICOQUIC_TEST_ALPN, &simulated_time, NULL, NULL, 0, 1, 0);
8218+
uint8_t data[PICOQUIC_MAX_PACKET_SIZE];
8219+
const size_t test_sizes[] = { 1, 2, 3, 5, 8, 13, 21, 44, 65, 109, 174, 283, 457, 740, 1023 };
8220+
const size_t nb_test_sizes = sizeof(test_sizes) / sizeof(size_t);
81988221

81998222
if (ret == 0 && test_ctx == NULL) {
82008223
ret = -1;
@@ -8203,16 +8226,128 @@ int padding_test()
82038226
/* Set the padding policy in the server context and in the client connection
82048227
*/
82058228
if (ret == 0) {
8206-
picoquic_set_default_padding(test_ctx->qserver, 128, 64);
8207-
picoquic_cnx_set_padding_policy(test_ctx->cnx_client, 128, 64);
8229+
picoquic_set_default_padding(test_ctx->qserver, padding_multiple, padding_min_size);
8230+
picoquic_cnx_set_padding_policy(test_ctx->cnx_client, padding_multiple, padding_min_size);
8231+
ret = picoquic_start_client_cnx(test_ctx->cnx_client);
8232+
}
82088233

8209-
/* Run a basic test scenario
8210-
*/
8234+
/* start the connection */
8235+
if (ret == 0) {
8236+
ret = tls_api_connection_loop(test_ctx, &loss_mask, 0, &simulated_time);
8237+
}
82118238

8212-
ret = tls_api_one_scenario_body(test_ctx, &simulated_time,
8213-
test_scenario_many_streams, sizeof(test_scenario_many_streams), 0, 0, 0, 0, 250000);
8239+
if (ret == 0) {
8240+
size_t checksum_length = picoquic_get_checksum_length(test_ctx->cnx_client, picoquic_epoch_1rtt);
8241+
size_t pn_iv_length = picoquic_pn_iv_size(test_ctx->cnx_client->crypto_context[picoquic_epoch_1rtt].pn_enc);
8242+
8243+
for (size_t i = 0; ret == 0 && i < nb_test_sizes; i++) {
8244+
/* repeat: queue a packet of size X, wait until it is acknowledged.
8245+
* verify that the padding is as expected.
8246+
*/
8247+
int nb_trials = 0;
8248+
int nb_inactive = 0;
8249+
int is_queued = 0;
8250+
int is_success = 0;
8251+
8252+
memset(data, picoquic_frame_type_padding, test_sizes[i] - 1);
8253+
data[test_sizes[i] - 1] = picoquic_frame_type_ping;
8254+
8255+
while (ret == 0 && nb_trials < 256 && nb_inactive < 256 && TEST_CLIENT_READY && TEST_SERVER_READY) {
8256+
int was_active = 0;
8257+
int ack_is_queued = 0;
8258+
nb_trials++;
8259+
if ((picoquic_is_cnx_backlog_empty(test_ctx->cnx_client) && picoquic_is_cnx_backlog_empty(test_ctx->cnx_server) &&
8260+
test_ctx->c_to_s_link->first_packet == NULL && test_ctx->s_to_c_link->first_packet == NULL)) {
8261+
if (!is_queued) {
8262+
ret = picoquic_queue_misc_frame(test_ctx->cnx_client, data, test_sizes[i], 0, picoquic_packet_context_application);
8263+
is_queued = 1;
8264+
}
8265+
else {
8266+
is_success = 1;
8267+
break;
8268+
}
8269+
}
8270+
ret = tls_api_one_sim_round(test_ctx, &simulated_time, 0, &was_active);
8271+
8272+
if (ret == 0 && is_queued && test_ctx->c_to_s_link->first_packet != NULL) {
8273+
size_t length = test_ctx->c_to_s_link->first_packet->length;
8274+
uint8_t* bytes = test_ctx->c_to_s_link->first_packet->bytes;
8275+
size_t pn_offset = 1 + test_ctx->cnx_client->path[0]->p_remote_cnxid->cnx_id.id_len;
8276+
size_t pn_length = padding_test_predict_pn_length(&test_ctx->cnx_client->pkt_ctx[picoquic_packet_context_application]);
8277+
size_t raw_length = pn_offset + pn_length + test_sizes[i];
8278+
8279+
if (pn_length == 1 && raw_length + checksum_length > length) {
8280+
/* Too short for this length.
8281+
* The test depends on correct prediction of pn length, which is hard, so
8282+
* we only do it if the predicted pn_length is 1 */
8283+
ret = -1;
8284+
}
8285+
else if (pn_offset + 4 + pn_iv_length > length) {
8286+
/* Not enough length to fit the data */
8287+
ret = -1;
8288+
}
8289+
else if (padding_multiple == 0 && padding_min_size == 0) {
8290+
/* No padding. The size should be equal to either the natural size of the minimum valid,
8291+
* unless the stack queued an acknowledgement, which would add 5 or 6 bytes */
8292+
if (raw_length + checksum_length + 6 < length && pn_offset + 4 + pn_iv_length != length) {
8293+
ret = -1;
8294+
}
8295+
}
8296+
else if (padding_min_size != 0 && length < padding_min_size) {
8297+
/* Size should be at least min size */
8298+
ret = -1;
8299+
}
8300+
else if (padding_min_size != 0 &&
8301+
raw_length < padding_min_size &&
8302+
length != padding_min_size + checksum_length) {
8303+
/* too much padding */
8304+
ret = -1;
8305+
}
8306+
else if (padding_multiple != 0){
8307+
if ((length - padding_min_size - checksum_length) % padding_multiple != 0 &&
8308+
length != test_ctx->cnx_client->path[0]->send_mtu) {
8309+
/* padding does not match formula */
8310+
ret = -1;
8311+
}
8312+
else if (raw_length > padding_min_size &&
8313+
((length - checksum_length) - raw_length) >= padding_multiple) {
8314+
/* Too much padding */
8315+
ret = -1;
8316+
}
8317+
}
8318+
}
8319+
8320+
if (ret < 0)
8321+
{
8322+
break;
8323+
}
8324+
8325+
if (was_active) {
8326+
nb_inactive = 0;
8327+
}
8328+
else {
8329+
nb_inactive++;
8330+
}
8331+
}
8332+
8333+
if (ret == 0 && !is_success) {
8334+
ret = -1;
8335+
}
8336+
}
8337+
}
8338+
8339+
#if 0
8340+
/* Prepare to send data, setting a scenario that creates packets of multiple sizes. */
8341+
if (ret == 0) {
8342+
ret = test_api_init_send_recv_scenario(test_ctx, test_scenario_many_streams, sizeof(test_scenario_many_streams));
82148343
}
82158344

8345+
if (ret == 0) {
8346+
/* do the sending loop until everything is received. */
8347+
ret = tls_api_data_sending_loop(test_ctx, NULL, &simulated_time, 0);
8348+
}
8349+
#endif
8350+
82168351
/* And then free the resource
82178352
*/
82188353

@@ -8224,6 +8359,22 @@ int padding_test()
82248359
return ret;
82258360
}
82268361

8362+
int padding_test()
8363+
{
8364+
return padding_test_one(128, 64);
8365+
}
8366+
8367+
int padding_null_test()
8368+
{
8369+
return padding_test_one(0, 0);
8370+
}
8371+
8372+
int padding_zero_min_test()
8373+
{
8374+
return padding_test_one(128, 0);
8375+
}
8376+
8377+
82278378
/*
82288379
* Test whether the server correctly processes coalesced packets when one of the segments does not decrypt correctly
82298380
*/

0 commit comments

Comments
 (0)