1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <stdio.h>
450aadb33SDmitri Tikhonov#include <stdlib.h>
550aadb33SDmitri Tikhonov#include <string.h>
6461e84d8SAmol Deshpande#ifndef WIN32
750aadb33SDmitri Tikhonov#include <sys/time.h>
8461e84d8SAmol Deshpande#endif
95392f7a3SLiteSpeed Tech#include <sys/queue.h>
1050aadb33SDmitri Tikhonov
1150aadb33SDmitri Tikhonov#include "lsquic_types.h"
129626cfc2SDmitri Tikhonov#include "lsquic.h"
135392f7a3SLiteSpeed Tech#include "lsquic_int_types.h"
1450aadb33SDmitri Tikhonov#include "lsquic_packet_common.h"
159626cfc2SDmitri Tikhonov#include "lsquic_packet_out.h"
165392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
179626cfc2SDmitri Tikhonov#include "lsquic_conn.h"
1850aadb33SDmitri Tikhonov#include "lsquic_parse.h"
1950aadb33SDmitri Tikhonov
2050aadb33SDmitri Tikhonovstruct test {
2150aadb33SDmitri Tikhonov    /* Inputs. */
2250aadb33SDmitri Tikhonov    const struct parse_funcs
2350aadb33SDmitri Tikhonov                   *pf;
2450aadb33SDmitri Tikhonov    size_t          bufsz;
255392f7a3SLiteSpeed Tech    uint64_t        cid;    /* Zero means connection ID is not specified */
2650aadb33SDmitri Tikhonov    const char     *nonce;
2750aadb33SDmitri Tikhonov    lsquic_packno_t packno;
28c7d81ce1SDmitri Tikhonov    enum packno_bits
2950aadb33SDmitri Tikhonov                    bits;   /* The test has been retrofitted by adding bits parameter.  The test can
3050aadb33SDmitri Tikhonov                             * be made more complicated by calculating packet number length based on
3150aadb33SDmitri Tikhonov                             * some other inputs.  However, this is tested elsewhere.
3250aadb33SDmitri Tikhonov                             */
3350aadb33SDmitri Tikhonov    union {
3450aadb33SDmitri Tikhonov        unsigned char   buf[4];
3550aadb33SDmitri Tikhonov        lsquic_ver_tag_t    val;
3650aadb33SDmitri Tikhonov    }               ver;
3750aadb33SDmitri Tikhonov
3850aadb33SDmitri Tikhonov    /* Outputs */
3950aadb33SDmitri Tikhonov    int             len;            /* Retval */
4050aadb33SDmitri Tikhonov    char            out[0x100];     /* Contents */
4150aadb33SDmitri Tikhonov};
4250aadb33SDmitri Tikhonov
4350aadb33SDmitri Tikhonov
4450aadb33SDmitri Tikhonovstatic void
45f07b3eaeSTyler Youngrun_test (const struct test *const test)
4650aadb33SDmitri Tikhonov{
4750aadb33SDmitri Tikhonov
489626cfc2SDmitri Tikhonov    struct lsquic_packet_out packet_out =
499626cfc2SDmitri Tikhonov    {
509626cfc2SDmitri Tikhonov        .po_flags = (test->cid ? PO_CONN_ID : 0)
519626cfc2SDmitri Tikhonov                  | (test->ver.val ? PO_VERSION : 0)
529626cfc2SDmitri Tikhonov                  | (test->nonce ? PO_NONCE: 0)
539626cfc2SDmitri Tikhonov                  ,
549626cfc2SDmitri Tikhonov        .po_nonce = (unsigned char *) test->nonce,
559626cfc2SDmitri Tikhonov        .po_ver_tag = test->ver.val,
569626cfc2SDmitri Tikhonov        .po_packno = test->packno,
579626cfc2SDmitri Tikhonov    };
589626cfc2SDmitri Tikhonov    lsquic_packet_out_set_packno_bits(&packet_out, test->bits);
599626cfc2SDmitri Tikhonov
605392f7a3SLiteSpeed Tech    lsquic_cid_t cid;
615392f7a3SLiteSpeed Tech    memset(&cid, 0, sizeof(cid));
625392f7a3SLiteSpeed Tech    cid.len = sizeof(test->cid);
635392f7a3SLiteSpeed Tech    memcpy(cid.idbuf, &test->cid, sizeof(test->cid));
645392f7a3SLiteSpeed Tech
655392f7a3SLiteSpeed Tech    struct lsquic_conn lconn = LSCONN_INITIALIZER_CID(lconn, cid);
669626cfc2SDmitri Tikhonov
675392f7a3SLiteSpeed Tech    unsigned char out[GQUIC_MAX_PUBHDR_SZ];
689626cfc2SDmitri Tikhonov    int len = test->pf->pf_gen_reg_pkt_header(&lconn, &packet_out, out,
6949f1f4f6SDmitri Tikhonov                                                    sizeof(out), NULL, NULL);
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonov    assert(("Packet length is correct", len == test->len));
7250aadb33SDmitri Tikhonov
7350aadb33SDmitri Tikhonov    if (test->len > 0)
7450aadb33SDmitri Tikhonov        assert(("Packet contents are correct",
7550aadb33SDmitri Tikhonov            0 == memcmp(out, test->out, len)));
7650aadb33SDmitri Tikhonov}
7750aadb33SDmitri Tikhonov
7850aadb33SDmitri Tikhonov
7950aadb33SDmitri Tikhonovint
8050aadb33SDmitri Tikhonovmain (void)
8150aadb33SDmitri Tikhonov{
826ff1e9b8SGeorge Wang    const struct test tests[] = {
836ff1e9b8SGeorge Wang        {
846ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
856ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
866ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
876ff1e9b8SGeorge Wang            .nonce  = NULL,
886ff1e9b8SGeorge Wang            .packno = 0x01020304,
896ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_4,
906ff1e9b8SGeorge Wang            .len    = 1 + 8 + 0 + 4,
916ff1e9b8SGeorge Wang            .out    = {     (0 << 2)                                        /* Nonce present */
926ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
936ff1e9b8SGeorge Wang                          | 0x20                                            /* Packet number length */
946ff1e9b8SGeorge Wang                          ,
956ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
966ff1e9b8SGeorge Wang                          0x01, 0x02, 0x03, 0x04,                           /* Packet number */
976ff1e9b8SGeorge Wang            },
986ff1e9b8SGeorge Wang        },
996ff1e9b8SGeorge Wang
1006ff1e9b8SGeorge Wang        {
1016ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1026ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1036ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
1046ff1e9b8SGeorge Wang            .nonce  = NULL,
1056ff1e9b8SGeorge Wang            .packno = 0x00,
1066ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_1,
1076ff1e9b8SGeorge Wang            .len    = 1 + 8 + 0 + 1,
1086ff1e9b8SGeorge Wang            .out    = {     (0 << 2)                                        /* Nonce present */
1096ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
1106ff1e9b8SGeorge Wang                          | 0x00                                            /* Packet number length */
1116ff1e9b8SGeorge Wang                          ,
1126ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
1136ff1e9b8SGeorge Wang                          0x00,                                             /* Packet number */
1146ff1e9b8SGeorge Wang            },
1156ff1e9b8SGeorge Wang        },
1166ff1e9b8SGeorge Wang
1176ff1e9b8SGeorge Wang        {
1186ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1196ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1206ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
1216ff1e9b8SGeorge Wang            .nonce  = NULL,
1226ff1e9b8SGeorge Wang            .packno = 0x09,
1236ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_1,
1246ff1e9b8SGeorge Wang            .ver.buf= { 'Q', '0', '4', '3', },
1256ff1e9b8SGeorge Wang            .len    = 1 + 8 + 4 + 0 + 1,
1266ff1e9b8SGeorge Wang            .out    = {     (0 << 2)                                        /* Nonce present */
1276ff1e9b8SGeorge Wang                          | 0x01                                            /* Version present */
1286ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
1296ff1e9b8SGeorge Wang                          | 0x00                                            /* Packet number length */
1306ff1e9b8SGeorge Wang                          ,
1316ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
1326ff1e9b8SGeorge Wang                          'Q', '0', '4', '3',
1336ff1e9b8SGeorge Wang                          0x09,                                             /* Packet number */
1346ff1e9b8SGeorge Wang            },
1356ff1e9b8SGeorge Wang        },
1366ff1e9b8SGeorge Wang
1376ff1e9b8SGeorge Wang    #define NONCENSE "0123456789abcdefghijklmnopqrstuv"
1386ff1e9b8SGeorge Wang    #define NONCENSE_BYTES '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v'
1396ff1e9b8SGeorge Wang
1406ff1e9b8SGeorge Wang        {
1416ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1426ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1436ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
1446ff1e9b8SGeorge Wang            .nonce  = NONCENSE,
1456ff1e9b8SGeorge Wang            .packno = 0x00,
1466ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_1,
1476ff1e9b8SGeorge Wang            .len    = 1 + 8 + 32 + 1,
1486ff1e9b8SGeorge Wang            .out    = {     (1 << 2)                                        /* Nonce present */
1496ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
1506ff1e9b8SGeorge Wang                          | 0x00                                            /* Packet number length */
1516ff1e9b8SGeorge Wang                          ,
1526ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
1536ff1e9b8SGeorge Wang                          NONCENSE_BYTES,
1546ff1e9b8SGeorge Wang                          0x00,                                             /* Packet number */
1556ff1e9b8SGeorge Wang            },
1566ff1e9b8SGeorge Wang        },
1576ff1e9b8SGeorge Wang
1586ff1e9b8SGeorge Wang        {
1596ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1606ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1616ff1e9b8SGeorge Wang            .cid    = 0,    /* Do not set connection ID */
1626ff1e9b8SGeorge Wang            .nonce  = NONCENSE,
1636ff1e9b8SGeorge Wang            .packno = 0x00,
1646ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_1,
1656ff1e9b8SGeorge Wang            .len    = 1 + 0 + 32 + 1,
1666ff1e9b8SGeorge Wang            .out    = {     (1 << 2)                                        /* Nonce present */
1676ff1e9b8SGeorge Wang                          | 0x00                                            /* Packet number length */
1686ff1e9b8SGeorge Wang                          ,
1696ff1e9b8SGeorge Wang                          NONCENSE_BYTES,
1706ff1e9b8SGeorge Wang                          0x00,                                             /* Packet number */
1716ff1e9b8SGeorge Wang            },
1726ff1e9b8SGeorge Wang        },
1736ff1e9b8SGeorge Wang
1746ff1e9b8SGeorge Wang        {
1756ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1766ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1776ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
1786ff1e9b8SGeorge Wang            .nonce  = NONCENSE,
1796ff1e9b8SGeorge Wang            .packno = 0x00,
1806ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_1,
1816ff1e9b8SGeorge Wang            .ver.buf= { 'Q', '0', '4', '3', },
1826ff1e9b8SGeorge Wang            .len    = 1 + 8 + 4 + 32 + 1,
1836ff1e9b8SGeorge Wang            .out    = {     (1 << 2)                                        /* Nonce present */
1846ff1e9b8SGeorge Wang                          | 0x01                                            /* Version present */
1856ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
1866ff1e9b8SGeorge Wang                          | 0x00                                            /* Packet number length */
1876ff1e9b8SGeorge Wang                          ,
1886ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
1896ff1e9b8SGeorge Wang                          'Q', '0', '4', '3',
1906ff1e9b8SGeorge Wang                          NONCENSE_BYTES,
1916ff1e9b8SGeorge Wang                          0x00,                                             /* Packet number */
1926ff1e9b8SGeorge Wang            },
1936ff1e9b8SGeorge Wang        },
1946ff1e9b8SGeorge Wang
1956ff1e9b8SGeorge Wang        {
1966ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
1976ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
1986ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
1996ff1e9b8SGeorge Wang            .nonce  = NONCENSE,
2006ff1e9b8SGeorge Wang            .packno = 0xA0A1A2A3A4A5A6A7UL,
2016ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_6,
2026ff1e9b8SGeorge Wang            .len    = 1 + 8 + 32 + 6,
2036ff1e9b8SGeorge Wang            .out    = {     (1 << 2)                                        /* Nonce present */
2046ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
2056ff1e9b8SGeorge Wang                          | 0x30                                            /* Packet number length */
2066ff1e9b8SGeorge Wang                          ,
2076ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
2086ff1e9b8SGeorge Wang                          NONCENSE_BYTES,
2096ff1e9b8SGeorge Wang                          0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
2106ff1e9b8SGeorge Wang            },
2116ff1e9b8SGeorge Wang        },
2126ff1e9b8SGeorge Wang
2136ff1e9b8SGeorge Wang        {
2146ff1e9b8SGeorge Wang            .pf     = select_pf_by_ver(LSQVER_043),
2156ff1e9b8SGeorge Wang            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
2166ff1e9b8SGeorge Wang            .cid    = 0x0102030405060708UL,
2176ff1e9b8SGeorge Wang            .nonce  = NONCENSE,
2186ff1e9b8SGeorge Wang            .packno = 0xA0A1A2A3A4A5A6A7UL,
2196ff1e9b8SGeorge Wang            .bits   = GQUIC_PACKNO_LEN_6,
2206ff1e9b8SGeorge Wang            .len    = 1 + 8 + 32 + 6,
2216ff1e9b8SGeorge Wang            .out    = {     (1 << 2)                                        /* Nonce present */
2226ff1e9b8SGeorge Wang                          | 0x08                                            /* Connection ID present */
2236ff1e9b8SGeorge Wang                          | 0x30                                            /* Packet number length */
2246ff1e9b8SGeorge Wang                          ,
2256ff1e9b8SGeorge Wang                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
2266ff1e9b8SGeorge Wang                          NONCENSE_BYTES,
2276ff1e9b8SGeorge Wang                          0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
2286ff1e9b8SGeorge Wang            },
2296ff1e9b8SGeorge Wang        },
2306ff1e9b8SGeorge Wang
2316ff1e9b8SGeorge Wang    };
232f07b3eaeSTyler Young
23350aadb33SDmitri Tikhonov    unsigned i;
23450aadb33SDmitri Tikhonov    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
235f07b3eaeSTyler Young        run_test(&tests[i]);
23650aadb33SDmitri Tikhonov    return 0;
23750aadb33SDmitri Tikhonov}
238