@@ -8189,12 +8189,35 @@ int stream_id_max_test()
8189
8189
* Test whether padding policy is correctly applied, and whether the corresponding
8190
8190
* connection succeeds.
8191
8191
*/
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
+ }
8192
8211
8193
- int padding_test ( )
8212
+ int padding_test_one ( uint32_t padding_multiple , uint32_t padding_min_size )
8194
8213
{
8195
8214
uint64_t simulated_time = 0 ;
8215
+ uint64_t loss_mask = 0 ;
8196
8216
picoquic_test_tls_api_ctx_t * test_ctx = NULL ;
8197
8217
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 );
8198
8221
8199
8222
if (ret == 0 && test_ctx == NULL ) {
8200
8223
ret = -1 ;
@@ -8203,16 +8226,128 @@ int padding_test()
8203
8226
/* Set the padding policy in the server context and in the client connection
8204
8227
*/
8205
8228
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
+ }
8208
8233
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
+ }
8211
8238
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 ));
8214
8343
}
8215
8344
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
+
8216
8351
/* And then free the resource
8217
8352
*/
8218
8353
@@ -8224,6 +8359,22 @@ int padding_test()
8224
8359
return ret ;
8225
8360
}
8226
8361
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
+
8227
8378
/*
8228
8379
* Test whether the server correctly processes coalesced packets when one of the segments does not decrypt correctly
8229
8380
*/
0 commit comments