1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech/* 35392f7a3SLiteSpeed Tech * test_trapa.c -- Test transport parameters. 45392f7a3SLiteSpeed Tech */ 55392f7a3SLiteSpeed Tech 65392f7a3SLiteSpeed Tech#include <assert.h> 75392f7a3SLiteSpeed Tech 85392f7a3SLiteSpeed Tech#include <stddef.h> 95392f7a3SLiteSpeed Tech#include <stdint.h> 105392f7a3SLiteSpeed Tech#include <stdio.h> 115392f7a3SLiteSpeed Tech#include <stdlib.h> 125392f7a3SLiteSpeed Tech#include <string.h> 13fb3e20e0SDmitri Tikhonov#ifndef WIN32 145392f7a3SLiteSpeed Tech#include <unistd.h> 15fb3e20e0SDmitri Tikhonov#else 16fb3e20e0SDmitri Tikhonov#include "getopt.h" 17fb3e20e0SDmitri Tikhonov#endif 185392f7a3SLiteSpeed Tech 195392f7a3SLiteSpeed Tech#include "lsquic.h" 205392f7a3SLiteSpeed Tech#include "lsquic_types.h" 215392f7a3SLiteSpeed Tech#include "lsquic_sizes.h" 225392f7a3SLiteSpeed Tech#include "lsquic_logger.h" 235392f7a3SLiteSpeed Tech#include "lsquic_trans_params.h" 245392f7a3SLiteSpeed Tech 255392f7a3SLiteSpeed Tech#define ENC_BUF_SZ 0x1000 265392f7a3SLiteSpeed Tech 275392f7a3SLiteSpeed Techstruct trapa_test 285392f7a3SLiteSpeed Tech{ 295392f7a3SLiteSpeed Tech int line; 305392f7a3SLiteSpeed Tech enum { 315392f7a3SLiteSpeed Tech TEST_ENCODE = 1 << 0, 325392f7a3SLiteSpeed Tech TEST_DECODE = 1 << 1, 335392f7a3SLiteSpeed Tech } flags; 345392f7a3SLiteSpeed Tech struct transport_params params; 355392f7a3SLiteSpeed Tech size_t enc_len, dec_len; 361bdb91d1SDmitri Tikhonov unsigned addl_set; 371bdb91d1SDmitri Tikhonov int is_server; 385392f7a3SLiteSpeed Tech int expect_decode_err; 395392f7a3SLiteSpeed Tech unsigned char encoded[ENC_BUF_SZ]; 405392f7a3SLiteSpeed Tech}; 415392f7a3SLiteSpeed Tech 425392f7a3SLiteSpeed Techstatic const struct trapa_test tests[] = 435392f7a3SLiteSpeed Tech{ 445392f7a3SLiteSpeed Tech 455392f7a3SLiteSpeed Tech { 465392f7a3SLiteSpeed Tech .line = __LINE__, 475392f7a3SLiteSpeed Tech .flags = TEST_ENCODE | TEST_DECODE, 485392f7a3SLiteSpeed Tech .params = { 495392f7a3SLiteSpeed Tech TP_DEFAULT_VALUES, 505392f7a3SLiteSpeed Tech }, 51bc520ef7SDmitri Tikhonov .enc_len = 0, 525392f7a3SLiteSpeed Tech .encoded = 535392f7a3SLiteSpeed Tech /* Trailer to make the end easily visible in gdb: */ 545392f7a3SLiteSpeed Tech "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 555392f7a3SLiteSpeed Tech }, 565392f7a3SLiteSpeed Tech 575392f7a3SLiteSpeed Tech { 585392f7a3SLiteSpeed Tech .line = __LINE__, 595392f7a3SLiteSpeed Tech .flags = TEST_ENCODE | TEST_DECODE, 605392f7a3SLiteSpeed Tech .params = { 611bdb91d1SDmitri Tikhonov .tp_set = (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL) 621bdb91d1SDmitri Tikhonov | (1 << TPI_INIT_MAX_DATA) 631bdb91d1SDmitri Tikhonov | (1 << TPI_MAX_IDLE_TIMEOUT) 641bdb91d1SDmitri Tikhonov | (1 << TPI_MAX_ACK_DELAY) 65fb73393fSDmitri Tikhonov | (1 << TPI_MAX_UDP_PAYLOAD_SIZE) 661bdb91d1SDmitri Tikhonov | (1 << TPI_ACK_DELAY_EXPONENT) 67fb73393fSDmitri Tikhonov | (1 << TPI_INITIAL_SOURCE_CID) 681bdb91d1SDmitri Tikhonov | (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT), 695392f7a3SLiteSpeed Tech .tp_init_max_stream_data_bidi_local = 0x12348877, 705392f7a3SLiteSpeed Tech .tp_init_max_data = 0xAABB, 71fb73393fSDmitri Tikhonov .tp_max_udp_payload_size = 1213, 729fc12041SDmitri Tikhonov .tp_max_idle_timeout = 10 * 1000, 735392f7a3SLiteSpeed Tech .tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY, 745392f7a3SLiteSpeed Tech .tp_active_connection_id_limit = 7, 75fb73393fSDmitri Tikhonov .tp_initial_source_cid = { .len = 8, .u_cid.id = 0x0807060504030201ull, }, 765392f7a3SLiteSpeed Tech }, 771bdb91d1SDmitri Tikhonov .is_server = 0, 78fb73393fSDmitri Tikhonov .enc_len = 36, 795392f7a3SLiteSpeed Tech .encoded = 80bc520ef7SDmitri Tikhonov /* Idle timeout */ "\x01\x02\x67\x10" 8177a28812SDmitri Tikhonov /* Packet size */ "\x03\x02\x44\xBD" 82bc520ef7SDmitri Tikhonov /* Max data */ "\x04\x04\x80\x00\xAA\xBB" 83bc520ef7SDmitri Tikhonov /* Bidi local */ "\x05\x04\x92\x34\x88\x77" 84bc520ef7SDmitri Tikhonov /* Ack delay exp */ "\x0A\x01\x00" 85bc520ef7SDmitri Tikhonov /* Active CID limit */ "\x0E\x01\x07" 86fb73393fSDmitri Tikhonov /* Initial SCID */ "\x0F\x08\x01\x02\x03\x04\x05\x06\x07\x08" 875392f7a3SLiteSpeed Tech /* Trailer to make the end easily visible in gdb: */ 885392f7a3SLiteSpeed Tech "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 895392f7a3SLiteSpeed Tech }, 905392f7a3SLiteSpeed Tech 915392f7a3SLiteSpeed Tech { 925392f7a3SLiteSpeed Tech .line = __LINE__, 935392f7a3SLiteSpeed Tech .flags = TEST_DECODE, 945392f7a3SLiteSpeed Tech .dec_len = 1, 955392f7a3SLiteSpeed Tech .expect_decode_err = 1, 965392f7a3SLiteSpeed Tech }, 975392f7a3SLiteSpeed Tech 985392f7a3SLiteSpeed Tech { 995392f7a3SLiteSpeed Tech .line = __LINE__, 1005392f7a3SLiteSpeed Tech .flags = TEST_DECODE, 1015392f7a3SLiteSpeed Tech .dec_len = 3, 1025392f7a3SLiteSpeed Tech .expect_decode_err = 1, 1035392f7a3SLiteSpeed Tech .encoded = "\x00\x04", 1045392f7a3SLiteSpeed Tech }, 1055392f7a3SLiteSpeed Tech 1065392f7a3SLiteSpeed Tech 1075392f7a3SLiteSpeed Tech { 1085392f7a3SLiteSpeed Tech .line = __LINE__, 1095392f7a3SLiteSpeed Tech .flags = TEST_ENCODE | TEST_DECODE, 1105392f7a3SLiteSpeed Tech .params = { 1115392f7a3SLiteSpeed Tech TP_DEFAULT_VALUES, 1125392f7a3SLiteSpeed Tech .tp_init_max_data = 0x123456, 1135392f7a3SLiteSpeed Tech .tp_init_max_stream_data_bidi_local = 0xABCDEF88, 114fb73393fSDmitri Tikhonov .tp_max_udp_payload_size = 0x555, 1155392f7a3SLiteSpeed Tech }, 1161bdb91d1SDmitri Tikhonov .is_server = 1, 1171bdb91d1SDmitri Tikhonov .addl_set = 1 << TPI_DISABLE_ACTIVE_MIGRATION, 118bc520ef7SDmitri Tikhonov .enc_len = 22, 1195392f7a3SLiteSpeed Tech .encoded = 12077a28812SDmitri Tikhonov /* Packet size */ "\x03\x02\x45\x55" 121bc520ef7SDmitri Tikhonov /* Max data */ "\x04\x04\x80\x12\x34\x56" 122bc520ef7SDmitri Tikhonov /* Bidi local */ "\x05\x08\xC0\x00\x00\x00\xAB\xCD\xEF\x88" 123bc520ef7SDmitri Tikhonov /* Migration */ "\x0C\x00" 1245392f7a3SLiteSpeed Tech /* Trailer to make the end easily visible in gdb: */ 1255392f7a3SLiteSpeed Tech "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 1265392f7a3SLiteSpeed Tech }, 1275392f7a3SLiteSpeed Tech 1285392f7a3SLiteSpeed Tech /* Test server preferred address. */ 1295392f7a3SLiteSpeed Tech { 1305392f7a3SLiteSpeed Tech .line = __LINE__, 1315392f7a3SLiteSpeed Tech .flags = TEST_DECODE, 1325392f7a3SLiteSpeed Tech .params = { 1335392f7a3SLiteSpeed Tech TP_DEFAULT_VALUES, 1345392f7a3SLiteSpeed Tech .tp_max_ack_delay = 25, 135fb73393fSDmitri Tikhonov .tp_max_udp_payload_size = 0x555, 1365392f7a3SLiteSpeed Tech .tp_preferred_address = { 1375392f7a3SLiteSpeed Tech .ipv4_addr = "\x01\x02\x03\x04", 1385392f7a3SLiteSpeed Tech .ipv4_port = 0x1234, 1395392f7a3SLiteSpeed Tech .ipv6_addr = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 1405392f7a3SLiteSpeed Tech .ipv6_port = 0x9001, 1415392f7a3SLiteSpeed Tech .cid = { .len = 11, .idbuf = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A", }, 1425392f7a3SLiteSpeed Tech .srst = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F", 1435392f7a3SLiteSpeed Tech }, 1445392f7a3SLiteSpeed Tech }, 1451bdb91d1SDmitri Tikhonov .is_server = 1, 1461bdb91d1SDmitri Tikhonov .addl_set = 1 << TPI_PREFERRED_ADDRESS, 147bc520ef7SDmitri Tikhonov .enc_len = 0x3A, 148bc520ef7SDmitri Tikhonov .dec_len = 0x3A, 1495392f7a3SLiteSpeed Tech .encoded = 150bc520ef7SDmitri Tikhonov /* Preferred Address */"\x0D" 151bc520ef7SDmitri Tikhonov "\x34" 1525392f7a3SLiteSpeed Tech "\x01\x02\x03\x04" 1535392f7a3SLiteSpeed Tech "\x12\x34" 1545392f7a3SLiteSpeed Tech "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" 1555392f7a3SLiteSpeed Tech "\x90\x01" 1565392f7a3SLiteSpeed Tech "\x0B" /* CID len */ 1575392f7a3SLiteSpeed Tech "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A" 1585392f7a3SLiteSpeed Tech "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" 15977a28812SDmitri Tikhonov /* Packet size */ "\x03\x02\x45\x55" 1605392f7a3SLiteSpeed Tech /* Trailer to make the end easily visible in gdb: */ 1615392f7a3SLiteSpeed Tech "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" 1625392f7a3SLiteSpeed Tech }, 1635392f7a3SLiteSpeed Tech 1645392f7a3SLiteSpeed Tech}; 1655392f7a3SLiteSpeed Tech 1665392f7a3SLiteSpeed Tech 1675392f7a3SLiteSpeed Techstatic int 1685392f7a3SLiteSpeed Techparams_are_equal (const struct transport_params *a, 1695392f7a3SLiteSpeed Tech const struct transport_params *b) 1705392f7a3SLiteSpeed Tech{ 1715392f7a3SLiteSpeed Tech#define MCMP(f) 0 == memcmp(&a->f, &b->f, sizeof(a->f)) 1721bdb91d1SDmitri Tikhonov return MCMP(tp_numerics) 1731bdb91d1SDmitri Tikhonov && MCMP(tp_set) 1745392f7a3SLiteSpeed Tech && MCMP(tp_stateless_reset_token) 1755392f7a3SLiteSpeed Tech && MCMP(tp_preferred_address.ipv4_addr) 1765392f7a3SLiteSpeed Tech && MCMP(tp_preferred_address.ipv6_addr) 1775392f7a3SLiteSpeed Tech && MCMP(tp_preferred_address.srst) 1785392f7a3SLiteSpeed Tech && MCMP(tp_preferred_address.cid.idbuf) 1795392f7a3SLiteSpeed Tech && a->tp_preferred_address.ipv4_port == b->tp_preferred_address.ipv4_port 1805392f7a3SLiteSpeed Tech && a->tp_preferred_address.ipv6_port == b->tp_preferred_address.ipv6_port 1815392f7a3SLiteSpeed Tech && a->tp_preferred_address.cid.len == b->tp_preferred_address.cid.len 182fb73393fSDmitri Tikhonov && MCMP(tp_original_dest_cid.idbuf) 183fb73393fSDmitri Tikhonov && a->tp_original_dest_cid.len == b->tp_original_dest_cid.len 1845392f7a3SLiteSpeed Tech ; 1855392f7a3SLiteSpeed Tech#undef MCMP 1865392f7a3SLiteSpeed Tech} 1875392f7a3SLiteSpeed Tech 1885392f7a3SLiteSpeed Tech 1895392f7a3SLiteSpeed Techstatic void 1905392f7a3SLiteSpeed Techrun_test (const struct trapa_test *test) 1915392f7a3SLiteSpeed Tech{ 1921bdb91d1SDmitri Tikhonov struct transport_params source_params; 1935392f7a3SLiteSpeed Tech struct transport_params decoded_params; 1945392f7a3SLiteSpeed Tech size_t dec_len; 1955392f7a3SLiteSpeed Tech int s; 1965392f7a3SLiteSpeed Tech unsigned char buf[ENC_BUF_SZ]; 1975392f7a3SLiteSpeed Tech 1981bdb91d1SDmitri Tikhonov source_params = test->params; 1991bdb91d1SDmitri Tikhonov source_params.tp_set |= test->addl_set; 2001bdb91d1SDmitri Tikhonov 2015392f7a3SLiteSpeed Tech if (test->flags & TEST_ENCODE) 2025392f7a3SLiteSpeed Tech { 2031bdb91d1SDmitri Tikhonov s = lsquic_tp_encode(&source_params, test->is_server, buf, sizeof(buf)); 204bc520ef7SDmitri Tikhonov assert(s >= 0); 2055392f7a3SLiteSpeed Tech assert((size_t) s == test->enc_len); 2065392f7a3SLiteSpeed Tech assert(0 == memcmp(test->encoded, buf, s)); 2075392f7a3SLiteSpeed Tech } 2085392f7a3SLiteSpeed Tech 2095392f7a3SLiteSpeed Tech if (test->flags & TEST_DECODE) 2105392f7a3SLiteSpeed Tech { 2115392f7a3SLiteSpeed Tech if (test->dec_len) 2125392f7a3SLiteSpeed Tech dec_len = test->dec_len; 2135392f7a3SLiteSpeed Tech else 214bc520ef7SDmitri Tikhonov dec_len = test->enc_len; 2155392f7a3SLiteSpeed Tech s = lsquic_tp_decode(test->encoded, dec_len, 2161bdb91d1SDmitri Tikhonov test->is_server, &decoded_params); 2175392f7a3SLiteSpeed Tech if (!test->expect_decode_err) 2185392f7a3SLiteSpeed Tech { 219bc520ef7SDmitri Tikhonov assert(s >= 0); 2205392f7a3SLiteSpeed Tech assert((size_t) s == test->enc_len); 2211bdb91d1SDmitri Tikhonov /* The decoder initializes all default values, so set the flag 2221bdb91d1SDmitri Tikhonov * accordingly: 2231bdb91d1SDmitri Tikhonov */ 2241bdb91d1SDmitri Tikhonov source_params.tp_set |= ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1); 2251bdb91d1SDmitri Tikhonov s = params_are_equal(&source_params, &decoded_params); 2265392f7a3SLiteSpeed Tech assert(s); 2275392f7a3SLiteSpeed Tech } 2285392f7a3SLiteSpeed Tech else 2295392f7a3SLiteSpeed Tech assert(s < 0); 2305392f7a3SLiteSpeed Tech } 2315392f7a3SLiteSpeed Tech} 2325392f7a3SLiteSpeed Tech 2335392f7a3SLiteSpeed Tech 2345392f7a3SLiteSpeed Techstatic void 2355392f7a3SLiteSpeed Techdecode_file (const char *name) 2365392f7a3SLiteSpeed Tech{ 2375392f7a3SLiteSpeed Tech FILE *file; 2385392f7a3SLiteSpeed Tech size_t nread; 2395392f7a3SLiteSpeed Tech int s; 2405392f7a3SLiteSpeed Tech struct transport_params params; 2415392f7a3SLiteSpeed Tech unsigned char buf[0x1000]; 2425392f7a3SLiteSpeed Tech 2435392f7a3SLiteSpeed Tech file = fopen(name, "rb"); 2445392f7a3SLiteSpeed Tech if (!file) 2455392f7a3SLiteSpeed Tech { 2465392f7a3SLiteSpeed Tech perror("fopen"); 2475392f7a3SLiteSpeed Tech exit(1); 2485392f7a3SLiteSpeed Tech } 2495392f7a3SLiteSpeed Tech 2505392f7a3SLiteSpeed Tech nread = fread(buf, 1, sizeof(buf), file); 2515392f7a3SLiteSpeed Tech 2525392f7a3SLiteSpeed Tech s = lsquic_tp_decode(buf, nread, 0, ¶ms); 2535392f7a3SLiteSpeed Tech 2545392f7a3SLiteSpeed Tech fclose(file); 2555392f7a3SLiteSpeed Tech 2565392f7a3SLiteSpeed Tech printf("decoded params from %s: %d (%s)\n", name, s, s > 0 ? "OK" : "FAIL"); 2575392f7a3SLiteSpeed Tech} 2585392f7a3SLiteSpeed Tech 2595392f7a3SLiteSpeed Tech 2605392f7a3SLiteSpeed Techint 2615392f7a3SLiteSpeed Techmain (int argc, char **argv) 2625392f7a3SLiteSpeed Tech{ 2635392f7a3SLiteSpeed Tech unsigned i; 2645392f7a3SLiteSpeed Tech int opt; 2655392f7a3SLiteSpeed Tech 2665392f7a3SLiteSpeed Tech while (-1 != (opt = getopt(argc, argv, "d:l:"))) 2675392f7a3SLiteSpeed Tech { 2685392f7a3SLiteSpeed Tech switch (opt) 2695392f7a3SLiteSpeed Tech { 2705392f7a3SLiteSpeed Tech case 'd': 2715392f7a3SLiteSpeed Tech decode_file(optarg); 2725392f7a3SLiteSpeed Tech return 0; 2735392f7a3SLiteSpeed Tech case 'l': 2745392f7a3SLiteSpeed Tech lsquic_log_to_fstream(stderr, 0); 2755392f7a3SLiteSpeed Tech lsquic_logger_lopt(optarg); 2765392f7a3SLiteSpeed Tech break; 2775392f7a3SLiteSpeed Tech default: 2785392f7a3SLiteSpeed Tech exit(1); 2795392f7a3SLiteSpeed Tech } 2805392f7a3SLiteSpeed Tech } 2815392f7a3SLiteSpeed Tech 2825392f7a3SLiteSpeed Tech for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) 2835392f7a3SLiteSpeed Tech run_test(&tests[i]); 2845392f7a3SLiteSpeed Tech 2855392f7a3SLiteSpeed Tech return 0; 2865392f7a3SLiteSpeed Tech} 287