test_trapa.c revision fb73393f
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 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>
135392f7a3SLiteSpeed Tech#include <unistd.h>
145392f7a3SLiteSpeed Tech
155392f7a3SLiteSpeed Tech#include "lsquic.h"
165392f7a3SLiteSpeed Tech#include "lsquic_types.h"
175392f7a3SLiteSpeed Tech#include "lsquic_sizes.h"
185392f7a3SLiteSpeed Tech#include "lsquic_logger.h"
195392f7a3SLiteSpeed Tech#include "lsquic_trans_params.h"
205392f7a3SLiteSpeed Tech
215392f7a3SLiteSpeed Tech#define ENC_BUF_SZ 0x1000
225392f7a3SLiteSpeed Tech
235392f7a3SLiteSpeed Techstruct trapa_test
245392f7a3SLiteSpeed Tech{
255392f7a3SLiteSpeed Tech    int                         line;
265392f7a3SLiteSpeed Tech    enum {
275392f7a3SLiteSpeed Tech        TEST_ENCODE = 1 << 0,
285392f7a3SLiteSpeed Tech        TEST_DECODE = 1 << 1,
295392f7a3SLiteSpeed Tech    }                           flags;
305392f7a3SLiteSpeed Tech    struct transport_params     params;
315392f7a3SLiteSpeed Tech    size_t                      enc_len, dec_len;
321bdb91d1SDmitri Tikhonov    unsigned                    addl_set;
331bdb91d1SDmitri Tikhonov    int                         is_server;
345392f7a3SLiteSpeed Tech    int                         expect_decode_err;
355392f7a3SLiteSpeed Tech    unsigned char               encoded[ENC_BUF_SZ];
365392f7a3SLiteSpeed Tech};
375392f7a3SLiteSpeed Tech
385392f7a3SLiteSpeed Techstatic const struct trapa_test tests[] =
395392f7a3SLiteSpeed Tech{
405392f7a3SLiteSpeed Tech
415392f7a3SLiteSpeed Tech    {
425392f7a3SLiteSpeed Tech        .line   = __LINE__,
435392f7a3SLiteSpeed Tech        .flags  = TEST_ENCODE | TEST_DECODE,
445392f7a3SLiteSpeed Tech        .params = {
455392f7a3SLiteSpeed Tech            TP_DEFAULT_VALUES,
465392f7a3SLiteSpeed Tech        },
47bc520ef7SDmitri Tikhonov        .enc_len = 0,
485392f7a3SLiteSpeed Tech        .encoded =
495392f7a3SLiteSpeed Tech    /* Trailer to make the end easily visible in gdb: */
505392f7a3SLiteSpeed Tech    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
515392f7a3SLiteSpeed Tech    },
525392f7a3SLiteSpeed Tech
535392f7a3SLiteSpeed Tech    {
545392f7a3SLiteSpeed Tech        .line   = __LINE__,
555392f7a3SLiteSpeed Tech        .flags  = TEST_ENCODE | TEST_DECODE,
565392f7a3SLiteSpeed Tech        .params = {
571bdb91d1SDmitri Tikhonov            .tp_set = (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)
581bdb91d1SDmitri Tikhonov                    | (1 << TPI_INIT_MAX_DATA)
591bdb91d1SDmitri Tikhonov                    | (1 << TPI_MAX_IDLE_TIMEOUT)
601bdb91d1SDmitri Tikhonov                    | (1 << TPI_MAX_ACK_DELAY)
61fb73393fSDmitri Tikhonov                    | (1 << TPI_MAX_UDP_PAYLOAD_SIZE)
621bdb91d1SDmitri Tikhonov                    | (1 << TPI_ACK_DELAY_EXPONENT)
63fb73393fSDmitri Tikhonov                    | (1 << TPI_INITIAL_SOURCE_CID)
641bdb91d1SDmitri Tikhonov                    | (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT),
655392f7a3SLiteSpeed Tech            .tp_init_max_stream_data_bidi_local = 0x12348877,
665392f7a3SLiteSpeed Tech            .tp_init_max_data = 0xAABB,
67fb73393fSDmitri Tikhonov            .tp_max_udp_payload_size = 1213,
689fc12041SDmitri Tikhonov            .tp_max_idle_timeout = 10 * 1000,
695392f7a3SLiteSpeed Tech            .tp_max_ack_delay = TP_DEF_MAX_ACK_DELAY,
705392f7a3SLiteSpeed Tech            .tp_active_connection_id_limit = 7,
71fb73393fSDmitri Tikhonov            .tp_initial_source_cid = { .len = 8, .u_cid.id = 0x0807060504030201ull, },
725392f7a3SLiteSpeed Tech        },
731bdb91d1SDmitri Tikhonov        .is_server = 0,
74fb73393fSDmitri Tikhonov        .enc_len = 36,
755392f7a3SLiteSpeed Tech        .encoded =
76bc520ef7SDmitri Tikhonov     /* Idle timeout */     "\x01\x02\x67\x10"
7777a28812SDmitri Tikhonov     /* Packet size */      "\x03\x02\x44\xBD"
78bc520ef7SDmitri Tikhonov     /* Max data */         "\x04\x04\x80\x00\xAA\xBB"
79bc520ef7SDmitri Tikhonov     /* Bidi local */       "\x05\x04\x92\x34\x88\x77"
80bc520ef7SDmitri Tikhonov     /* Ack delay exp */    "\x0A\x01\x00"
81bc520ef7SDmitri Tikhonov     /* Active CID limit */ "\x0E\x01\x07"
82fb73393fSDmitri Tikhonov     /* Initial SCID */     "\x0F\x08\x01\x02\x03\x04\x05\x06\x07\x08"
835392f7a3SLiteSpeed Tech    /* Trailer to make the end easily visible in gdb: */
845392f7a3SLiteSpeed Tech    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
855392f7a3SLiteSpeed Tech    },
865392f7a3SLiteSpeed Tech
875392f7a3SLiteSpeed Tech    {
885392f7a3SLiteSpeed Tech        .line   = __LINE__,
895392f7a3SLiteSpeed Tech        .flags  = TEST_DECODE,
905392f7a3SLiteSpeed Tech        .dec_len = 1,
915392f7a3SLiteSpeed Tech        .expect_decode_err = 1,
925392f7a3SLiteSpeed Tech    },
935392f7a3SLiteSpeed Tech
945392f7a3SLiteSpeed Tech    {
955392f7a3SLiteSpeed Tech        .line   = __LINE__,
965392f7a3SLiteSpeed Tech        .flags  = TEST_DECODE,
975392f7a3SLiteSpeed Tech        .dec_len = 3,
985392f7a3SLiteSpeed Tech        .expect_decode_err = 1,
995392f7a3SLiteSpeed Tech        .encoded = "\x00\x04",
1005392f7a3SLiteSpeed Tech    },
1015392f7a3SLiteSpeed Tech
1025392f7a3SLiteSpeed Tech
1035392f7a3SLiteSpeed Tech    {
1045392f7a3SLiteSpeed Tech        .line   = __LINE__,
1055392f7a3SLiteSpeed Tech        .flags  = TEST_ENCODE | TEST_DECODE,
1065392f7a3SLiteSpeed Tech        .params = {
1075392f7a3SLiteSpeed Tech            TP_DEFAULT_VALUES,
1085392f7a3SLiteSpeed Tech            .tp_init_max_data = 0x123456,
1095392f7a3SLiteSpeed Tech            .tp_init_max_stream_data_bidi_local = 0xABCDEF88,
110fb73393fSDmitri Tikhonov            .tp_max_udp_payload_size = 0x555,
1115392f7a3SLiteSpeed Tech        },
1121bdb91d1SDmitri Tikhonov        .is_server = 1,
1131bdb91d1SDmitri Tikhonov        .addl_set = 1 << TPI_DISABLE_ACTIVE_MIGRATION,
114bc520ef7SDmitri Tikhonov        .enc_len = 22,
1155392f7a3SLiteSpeed Tech        .encoded =
11677a28812SDmitri Tikhonov     /* Packet size */      "\x03\x02\x45\x55"
117bc520ef7SDmitri Tikhonov     /* Max data */         "\x04\x04\x80\x12\x34\x56"
118bc520ef7SDmitri Tikhonov     /* Bidi local */       "\x05\x08\xC0\x00\x00\x00\xAB\xCD\xEF\x88"
119bc520ef7SDmitri Tikhonov     /* Migration */        "\x0C\x00"
1205392f7a3SLiteSpeed Tech    /* Trailer to make the end easily visible in gdb: */
1215392f7a3SLiteSpeed Tech    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
1225392f7a3SLiteSpeed Tech    },
1235392f7a3SLiteSpeed Tech
1245392f7a3SLiteSpeed Tech    /* Test server preferred address. */
1255392f7a3SLiteSpeed Tech    {
1265392f7a3SLiteSpeed Tech        .line   = __LINE__,
1275392f7a3SLiteSpeed Tech        .flags  = TEST_DECODE,
1285392f7a3SLiteSpeed Tech        .params = {
1295392f7a3SLiteSpeed Tech            TP_DEFAULT_VALUES,
1305392f7a3SLiteSpeed Tech            .tp_max_ack_delay = 25,
131fb73393fSDmitri Tikhonov            .tp_max_udp_payload_size = 0x555,
1325392f7a3SLiteSpeed Tech            .tp_preferred_address = {
1335392f7a3SLiteSpeed Tech                .ipv4_addr = "\x01\x02\x03\x04",
1345392f7a3SLiteSpeed Tech                .ipv4_port = 0x1234,
1355392f7a3SLiteSpeed Tech                .ipv6_addr = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
1365392f7a3SLiteSpeed Tech                .ipv6_port = 0x9001,
1375392f7a3SLiteSpeed Tech                .cid = { .len = 11, .idbuf = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A", },
1385392f7a3SLiteSpeed Tech                .srst = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F",
1395392f7a3SLiteSpeed Tech            },
1405392f7a3SLiteSpeed Tech        },
1411bdb91d1SDmitri Tikhonov        .is_server = 1,
1421bdb91d1SDmitri Tikhonov        .addl_set = 1 << TPI_PREFERRED_ADDRESS,
143bc520ef7SDmitri Tikhonov        .enc_len = 0x3A,
144bc520ef7SDmitri Tikhonov        .dec_len = 0x3A,
1455392f7a3SLiteSpeed Tech        .encoded =
146bc520ef7SDmitri Tikhonov     /* Preferred Address */"\x0D"
147bc520ef7SDmitri Tikhonov                            "\x34"
1485392f7a3SLiteSpeed Tech                            "\x01\x02\x03\x04"
1495392f7a3SLiteSpeed Tech                            "\x12\x34"
1505392f7a3SLiteSpeed Tech                            "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
1515392f7a3SLiteSpeed Tech                            "\x90\x01"
1525392f7a3SLiteSpeed Tech                            "\x0B"  /* CID len */
1535392f7a3SLiteSpeed Tech                            "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A"
1545392f7a3SLiteSpeed Tech                            "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
15577a28812SDmitri Tikhonov     /* Packet size */      "\x03\x02\x45\x55"
1565392f7a3SLiteSpeed Tech    /* Trailer to make the end easily visible in gdb: */
1575392f7a3SLiteSpeed Tech    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
1585392f7a3SLiteSpeed Tech    },
1595392f7a3SLiteSpeed Tech
1605392f7a3SLiteSpeed Tech};
1615392f7a3SLiteSpeed Tech
1625392f7a3SLiteSpeed Tech
1635392f7a3SLiteSpeed Techstatic int
1645392f7a3SLiteSpeed Techparams_are_equal (const struct transport_params *a,
1655392f7a3SLiteSpeed Tech                  const struct transport_params *b)
1665392f7a3SLiteSpeed Tech{
1675392f7a3SLiteSpeed Tech#define MCMP(f) 0 == memcmp(&a->f, &b->f, sizeof(a->f))
1681bdb91d1SDmitri Tikhonov    return MCMP(tp_numerics)
1691bdb91d1SDmitri Tikhonov        && MCMP(tp_set)
1705392f7a3SLiteSpeed Tech        && MCMP(tp_stateless_reset_token)
1715392f7a3SLiteSpeed Tech        && MCMP(tp_preferred_address.ipv4_addr)
1725392f7a3SLiteSpeed Tech        && MCMP(tp_preferred_address.ipv6_addr)
1735392f7a3SLiteSpeed Tech        && MCMP(tp_preferred_address.srst)
1745392f7a3SLiteSpeed Tech        && MCMP(tp_preferred_address.cid.idbuf)
1755392f7a3SLiteSpeed Tech        && a->tp_preferred_address.ipv4_port == b->tp_preferred_address.ipv4_port
1765392f7a3SLiteSpeed Tech        && a->tp_preferred_address.ipv6_port == b->tp_preferred_address.ipv6_port
1775392f7a3SLiteSpeed Tech        && a->tp_preferred_address.cid.len == b->tp_preferred_address.cid.len
178fb73393fSDmitri Tikhonov        && MCMP(tp_original_dest_cid.idbuf)
179fb73393fSDmitri Tikhonov        && a->tp_original_dest_cid.len == b->tp_original_dest_cid.len
1805392f7a3SLiteSpeed Tech        ;
1815392f7a3SLiteSpeed Tech#undef MCMP
1825392f7a3SLiteSpeed Tech}
1835392f7a3SLiteSpeed Tech
1845392f7a3SLiteSpeed Tech
1855392f7a3SLiteSpeed Techstatic void
1865392f7a3SLiteSpeed Techrun_test (const struct trapa_test *test)
1875392f7a3SLiteSpeed Tech{
1881bdb91d1SDmitri Tikhonov    struct transport_params source_params;
1895392f7a3SLiteSpeed Tech    struct transport_params decoded_params;
1905392f7a3SLiteSpeed Tech    size_t dec_len;
1915392f7a3SLiteSpeed Tech    int s;
1925392f7a3SLiteSpeed Tech    unsigned char buf[ENC_BUF_SZ];
1935392f7a3SLiteSpeed Tech
1941bdb91d1SDmitri Tikhonov    source_params = test->params;
1951bdb91d1SDmitri Tikhonov    source_params.tp_set |= test->addl_set;
1961bdb91d1SDmitri Tikhonov
1975392f7a3SLiteSpeed Tech    if (test->flags & TEST_ENCODE)
1985392f7a3SLiteSpeed Tech    {
1991bdb91d1SDmitri Tikhonov        s = lsquic_tp_encode(&source_params, test->is_server, buf, sizeof(buf));
200bc520ef7SDmitri Tikhonov        assert(s >= 0);
2015392f7a3SLiteSpeed Tech        assert((size_t) s == test->enc_len);
2025392f7a3SLiteSpeed Tech        assert(0 == memcmp(test->encoded, buf, s));
2035392f7a3SLiteSpeed Tech    }
2045392f7a3SLiteSpeed Tech
2055392f7a3SLiteSpeed Tech    if (test->flags & TEST_DECODE)
2065392f7a3SLiteSpeed Tech    {
2075392f7a3SLiteSpeed Tech        if (test->dec_len)
2085392f7a3SLiteSpeed Tech            dec_len = test->dec_len;
2095392f7a3SLiteSpeed Tech        else
210bc520ef7SDmitri Tikhonov            dec_len = test->enc_len;
2115392f7a3SLiteSpeed Tech        s = lsquic_tp_decode(test->encoded, dec_len,
2121bdb91d1SDmitri Tikhonov                     test->is_server, &decoded_params);
2135392f7a3SLiteSpeed Tech        if (!test->expect_decode_err)
2145392f7a3SLiteSpeed Tech        {
215bc520ef7SDmitri Tikhonov            assert(s >= 0);
2165392f7a3SLiteSpeed Tech            assert((size_t) s == test->enc_len);
2171bdb91d1SDmitri Tikhonov            /* The decoder initializes all default values, so set the flag
2181bdb91d1SDmitri Tikhonov             * accordingly:
2191bdb91d1SDmitri Tikhonov             */
2201bdb91d1SDmitri Tikhonov            source_params.tp_set |= ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1);
2211bdb91d1SDmitri Tikhonov            s = params_are_equal(&source_params, &decoded_params);
2225392f7a3SLiteSpeed Tech            assert(s);
2235392f7a3SLiteSpeed Tech        }
2245392f7a3SLiteSpeed Tech        else
2255392f7a3SLiteSpeed Tech            assert(s < 0);
2265392f7a3SLiteSpeed Tech    }
2275392f7a3SLiteSpeed Tech}
2285392f7a3SLiteSpeed Tech
2295392f7a3SLiteSpeed Tech
2305392f7a3SLiteSpeed Techstatic void
2315392f7a3SLiteSpeed Techdecode_file (const char *name)
2325392f7a3SLiteSpeed Tech{
2335392f7a3SLiteSpeed Tech    FILE *file;
2345392f7a3SLiteSpeed Tech    size_t nread;
2355392f7a3SLiteSpeed Tech    int s;
2365392f7a3SLiteSpeed Tech    struct transport_params params;
2375392f7a3SLiteSpeed Tech    unsigned char buf[0x1000];
2385392f7a3SLiteSpeed Tech
2395392f7a3SLiteSpeed Tech    file = fopen(name, "rb");
2405392f7a3SLiteSpeed Tech    if (!file)
2415392f7a3SLiteSpeed Tech    {
2425392f7a3SLiteSpeed Tech        perror("fopen");
2435392f7a3SLiteSpeed Tech        exit(1);
2445392f7a3SLiteSpeed Tech    }
2455392f7a3SLiteSpeed Tech
2465392f7a3SLiteSpeed Tech    nread = fread(buf, 1, sizeof(buf), file);
2475392f7a3SLiteSpeed Tech
2485392f7a3SLiteSpeed Tech    s = lsquic_tp_decode(buf, nread, 0, &params);
2495392f7a3SLiteSpeed Tech
2505392f7a3SLiteSpeed Tech    fclose(file);
2515392f7a3SLiteSpeed Tech
2525392f7a3SLiteSpeed Tech    printf("decoded params from %s: %d (%s)\n", name, s, s > 0 ? "OK" : "FAIL");
2535392f7a3SLiteSpeed Tech}
2545392f7a3SLiteSpeed Tech
2555392f7a3SLiteSpeed Tech
2565392f7a3SLiteSpeed Techint
2575392f7a3SLiteSpeed Techmain (int argc, char **argv)
2585392f7a3SLiteSpeed Tech{
2595392f7a3SLiteSpeed Tech    unsigned i;
2605392f7a3SLiteSpeed Tech    int opt;
2615392f7a3SLiteSpeed Tech
2625392f7a3SLiteSpeed Tech    while (-1 != (opt = getopt(argc, argv, "d:l:")))
2635392f7a3SLiteSpeed Tech    {
2645392f7a3SLiteSpeed Tech        switch (opt)
2655392f7a3SLiteSpeed Tech        {
2665392f7a3SLiteSpeed Tech        case 'd':
2675392f7a3SLiteSpeed Tech            decode_file(optarg);
2685392f7a3SLiteSpeed Tech            return 0;
2695392f7a3SLiteSpeed Tech        case 'l':
2705392f7a3SLiteSpeed Tech            lsquic_log_to_fstream(stderr, 0);
2715392f7a3SLiteSpeed Tech            lsquic_logger_lopt(optarg);
2725392f7a3SLiteSpeed Tech            break;
2735392f7a3SLiteSpeed Tech        default:
2745392f7a3SLiteSpeed Tech            exit(1);
2755392f7a3SLiteSpeed Tech        }
2765392f7a3SLiteSpeed Tech    }
2775392f7a3SLiteSpeed Tech
2785392f7a3SLiteSpeed Tech    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
2795392f7a3SLiteSpeed Tech        run_test(&tests[i]);
2805392f7a3SLiteSpeed Tech
2815392f7a3SLiteSpeed Tech    return 0;
2825392f7a3SLiteSpeed Tech}
283