1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#ifndef WIN32
7#include <sys/time.h>
8#endif
9#include <sys/queue.h>
10
11#include "lsquic_types.h"
12#include "lsquic.h"
13#include "lsquic_int_types.h"
14#include "lsquic_packet_common.h"
15#include "lsquic_packet_out.h"
16#include "lsquic_hash.h"
17#include "lsquic_conn.h"
18#include "lsquic_parse.h"
19
20struct test {
21    /* Inputs. */
22    const struct parse_funcs
23                   *pf;
24    size_t          bufsz;
25    uint64_t        cid;    /* Zero means connection ID is not specified */
26    const char     *nonce;
27    lsquic_packno_t packno;
28    enum packno_bits
29                    bits;   /* The test has been retrofitted by adding bits parameter.  The test can
30                             * be made more complicated by calculating packet number length based on
31                             * some other inputs.  However, this is tested elsewhere.
32                             */
33    union {
34        unsigned char   buf[4];
35        lsquic_ver_tag_t    val;
36    }               ver;
37
38    /* Outputs */
39    int             len;            /* Retval */
40    char            out[0x100];     /* Contents */
41};
42
43
44static void
45run_test (const struct test *const test)
46{
47
48    struct lsquic_packet_out packet_out =
49    {
50        .po_flags = (test->cid ? PO_CONN_ID : 0)
51                  | (test->ver.val ? PO_VERSION : 0)
52                  | (test->nonce ? PO_NONCE: 0)
53                  ,
54        .po_nonce = (unsigned char *) test->nonce,
55        .po_ver_tag = test->ver.val,
56        .po_packno = test->packno,
57    };
58    lsquic_packet_out_set_packno_bits(&packet_out, test->bits);
59
60    lsquic_cid_t cid;
61    memset(&cid, 0, sizeof(cid));
62    cid.len = sizeof(test->cid);
63    memcpy(cid.idbuf, &test->cid, sizeof(test->cid));
64
65    struct lsquic_conn lconn = LSCONN_INITIALIZER_CID(lconn, cid);
66
67    unsigned char out[GQUIC_MAX_PUBHDR_SZ];
68    int len = test->pf->pf_gen_reg_pkt_header(&lconn, &packet_out, out,
69                                                    sizeof(out), NULL, NULL);
70
71    assert(("Packet length is correct", len == test->len));
72
73    if (test->len > 0)
74        assert(("Packet contents are correct",
75            0 == memcmp(out, test->out, len)));
76}
77
78
79int
80main (void)
81{
82    const struct test tests[] = {
83        {
84            .pf     = select_pf_by_ver(LSQVER_043),
85            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
86            .cid    = 0x0102030405060708UL,
87            .nonce  = NULL,
88            .packno = 0x01020304,
89            .bits   = GQUIC_PACKNO_LEN_4,
90            .len    = 1 + 8 + 0 + 4,
91            .out    = {     (0 << 2)                                        /* Nonce present */
92                          | 0x08                                            /* Connection ID present */
93                          | 0x20                                            /* Packet number length */
94                          ,
95                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
96                          0x01, 0x02, 0x03, 0x04,                           /* Packet number */
97            },
98        },
99
100        {
101            .pf     = select_pf_by_ver(LSQVER_043),
102            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
103            .cid    = 0x0102030405060708UL,
104            .nonce  = NULL,
105            .packno = 0x00,
106            .bits   = GQUIC_PACKNO_LEN_1,
107            .len    = 1 + 8 + 0 + 1,
108            .out    = {     (0 << 2)                                        /* Nonce present */
109                          | 0x08                                            /* Connection ID present */
110                          | 0x00                                            /* Packet number length */
111                          ,
112                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
113                          0x00,                                             /* Packet number */
114            },
115        },
116
117        {
118            .pf     = select_pf_by_ver(LSQVER_043),
119            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
120            .cid    = 0x0102030405060708UL,
121            .nonce  = NULL,
122            .packno = 0x09,
123            .bits   = GQUIC_PACKNO_LEN_1,
124            .ver.buf= { 'Q', '0', '4', '3', },
125            .len    = 1 + 8 + 4 + 0 + 1,
126            .out    = {     (0 << 2)                                        /* Nonce present */
127                          | 0x01                                            /* Version present */
128                          | 0x08                                            /* Connection ID present */
129                          | 0x00                                            /* Packet number length */
130                          ,
131                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
132                          'Q', '0', '4', '3',
133                          0x09,                                             /* Packet number */
134            },
135        },
136
137    #define NONCENSE "0123456789abcdefghijklmnopqrstuv"
138    #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'
139
140        {
141            .pf     = select_pf_by_ver(LSQVER_043),
142            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
143            .cid    = 0x0102030405060708UL,
144            .nonce  = NONCENSE,
145            .packno = 0x00,
146            .bits   = GQUIC_PACKNO_LEN_1,
147            .len    = 1 + 8 + 32 + 1,
148            .out    = {     (1 << 2)                                        /* Nonce present */
149                          | 0x08                                            /* Connection ID present */
150                          | 0x00                                            /* Packet number length */
151                          ,
152                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
153                          NONCENSE_BYTES,
154                          0x00,                                             /* Packet number */
155            },
156        },
157
158        {
159            .pf     = select_pf_by_ver(LSQVER_043),
160            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
161            .cid    = 0,    /* Do not set connection ID */
162            .nonce  = NONCENSE,
163            .packno = 0x00,
164            .bits   = GQUIC_PACKNO_LEN_1,
165            .len    = 1 + 0 + 32 + 1,
166            .out    = {     (1 << 2)                                        /* Nonce present */
167                          | 0x00                                            /* Packet number length */
168                          ,
169                          NONCENSE_BYTES,
170                          0x00,                                             /* Packet number */
171            },
172        },
173
174        {
175            .pf     = select_pf_by_ver(LSQVER_043),
176            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
177            .cid    = 0x0102030405060708UL,
178            .nonce  = NONCENSE,
179            .packno = 0x00,
180            .bits   = GQUIC_PACKNO_LEN_1,
181            .ver.buf= { 'Q', '0', '4', '3', },
182            .len    = 1 + 8 + 4 + 32 + 1,
183            .out    = {     (1 << 2)                                        /* Nonce present */
184                          | 0x01                                            /* Version present */
185                          | 0x08                                            /* Connection ID present */
186                          | 0x00                                            /* Packet number length */
187                          ,
188                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
189                          'Q', '0', '4', '3',
190                          NONCENSE_BYTES,
191                          0x00,                                             /* Packet number */
192            },
193        },
194
195        {
196            .pf     = select_pf_by_ver(LSQVER_043),
197            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
198            .cid    = 0x0102030405060708UL,
199            .nonce  = NONCENSE,
200            .packno = 0xA0A1A2A3A4A5A6A7UL,
201            .bits   = GQUIC_PACKNO_LEN_6,
202            .len    = 1 + 8 + 32 + 6,
203            .out    = {     (1 << 2)                                        /* Nonce present */
204                          | 0x08                                            /* Connection ID present */
205                          | 0x30                                            /* Packet number length */
206                          ,
207                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
208                          NONCENSE_BYTES,
209                          0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
210            },
211        },
212
213        {
214            .pf     = select_pf_by_ver(LSQVER_043),
215            .bufsz  = GQUIC_MAX_PUBHDR_SZ,
216            .cid    = 0x0102030405060708UL,
217            .nonce  = NONCENSE,
218            .packno = 0xA0A1A2A3A4A5A6A7UL,
219            .bits   = GQUIC_PACKNO_LEN_6,
220            .len    = 1 + 8 + 32 + 6,
221            .out    = {     (1 << 2)                                        /* Nonce present */
222                          | 0x08                                            /* Connection ID present */
223                          | 0x30                                            /* Packet number length */
224                          ,
225                          0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
226                          NONCENSE_BYTES,
227                          0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
228            },
229        },
230
231    };
232
233    unsigned i;
234    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
235        run_test(&tests[i]);
236    return 0;
237}
238