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.h"
12#include "lsquic_types.h"
13#include "lsquic_parse.h"
14#include "lsquic_packet_common.h"
15#include "lsquic_packet_in.h"
16
17struct test {
18    const char     *name;
19    int             lineno;
20    const struct parse_funcs *
21                    pf;
22    const unsigned char
23                    buf[0x100];    /* Large enough for our needs */
24    size_t          buf_sz;        /* # of stream frame bytes in `buf' */
25    size_t          rem_packet_sz; /* # of bytes remaining in the packet,
26                                    * starting at the beginning of the
27                                    * stream frame.
28                                    */
29    stream_frame_t  frame;         /* Expected values */
30    int             should_succeed;
31};
32
33static void
34run_test (const struct test *test)
35{
36    stream_frame_t frame;
37    memset(&frame, 0x7A, sizeof(frame));
38
39    int len = test->pf->pf_parse_stream_frame(test->buf, test->rem_packet_sz, &frame);
40
41    if (test->should_succeed) {
42        /* Check parser operation */
43        assert(("Parsed correct number of bytes", (size_t) len == test->buf_sz + test->frame.data_frame.df_size));
44        assert(("Stream ID is correct", frame.stream_id == test->frame.stream_id));
45        assert(("Data length is correct", frame.data_frame.df_size == test->frame.data_frame.df_size));
46        assert(("Offset is correct", frame.data_frame.df_offset == test->frame.data_frame.df_offset));
47        assert(("FIN is correct", frame.data_frame.df_fin == test->frame.data_frame.df_fin));
48
49        /* Check that initialization of other fields occurred correctly: */
50        assert(0 == frame.packet_in);
51        assert(0 == frame.data_frame.df_read_off);
52    }
53    else
54    {
55        assert(("This test should fail", len < 0));
56    }
57}
58
59
60int
61main (void)
62{
63
64    const struct test tests[] = {
65
66        /*
67         * Big-endian tests
68         */
69        {   "Balls to the wall: every possible bit is set",
70            __LINE__,
71            select_pf_by_ver(LSQVER_043),
72          /*  1      f      d      ooo    ss            1fdoooss */
73          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
74            { 0x80 | 0x40 | 0x20 | 0x1C | 0x3,
75              0x00, 0x00, 0x02, 0x10,                           /* Stream ID */
76              0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Offset */
77              0x01, 0xC4,                                       /* Data length */
78            },
79              1           + 2    + 8    + 4,
80            0x200,
81            {   .data_frame.df_offset      = 0x0807060504030201UL,
82                .stream_id   = 0x210,
83                .data_frame.df_size = 0x1C4,
84                .data_frame.df_fin         = 1,
85            },
86            1,
87        },
88
89        {   "Balls to the wall #2: every possible bit is set, except FIN",
90            __LINE__,
91            select_pf_by_ver(LSQVER_043),
92          /*  1      f      d      ooo    ss            1fdoooss */
93          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
94            { 0x80 | 0x00 | 0x20 | 0x1C | 0x3,
95              0x00, 0x00, 0x02, 0x10,                           /* Stream ID */
96              0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Offset */
97              0x01, 0xC4,                                       /* Data length */
98            },
99              1           + 2    + 8    + 4,
100            0x200,
101            {   .data_frame.df_offset      = 0x0807060504030201UL,
102                .stream_id   = 0x210,
103                .data_frame.df_size = 0x1C4,
104                .data_frame.df_fin         = 0,
105            },
106            1,
107        },
108
109        {   "Data length is zero",
110            __LINE__,
111            select_pf_by_ver(LSQVER_043),
112          /*  1      f      d      ooo    ss            1fdoooss */
113          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
114            { 0x80 | 0x40 | 0x00 | 0x1C | 0x3,
115              0x00, 0x00, 0x02, 0x10,                           /* Stream ID */
116              0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Offset */
117              0xC4, 0x01,                                       /* Data length: note this does not matter */
118            },
119              1           + 0    + 8    + 4,
120            0x200,
121            {   .data_frame.df_offset      = 0x0807060504030201UL,
122                .stream_id   = 0x210,
123                .data_frame.df_size = 0x200 - (1 + 8 + 4),
124                .data_frame.df_fin         = 1,
125            },
126            1,
127        },
128
129        {   "Stream ID length is 1",
130            __LINE__,
131            select_pf_by_ver(LSQVER_043),
132          /*  1      f      d      ooo    ss            1fdoooss */
133          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
134            { 0x80 | 0x40 | 0x20 | 0x1C | 0x0,
135              0xF0,                                             /* Stream ID */
136              0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Offset */
137              0x01, 0xC4,                                       /* Data length */
138            },
139              1           + 2    + 8    + 1,
140            0x200,
141            {   .data_frame.df_offset      = 0x0807060504030201UL,
142                .stream_id   = 0xF0,
143                .data_frame.df_size = 0x1C4,
144                .data_frame.df_fin         = 1,
145            },
146            1,
147        },
148
149        {   "All bits are zero save offset length",
150            __LINE__,
151            select_pf_by_ver(LSQVER_043),
152          /*  1      f      d      ooo    ss            1fdoooss */
153          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
154            { 0x80 | 0x00 | 0x00 | 0x04 | 0x0,
155              0xF0,                                             /* Stream ID */
156              0x02, 0x55, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   /* Offset */
157              0xC4, 0x01,                                       /* Data length */
158            },
159              1           + 0    + 2    + 1,
160            0x200,
161            {   .data_frame.df_offset      = 0x255,
162                .stream_id   = 0xF0,
163                .data_frame.df_size = 0x200 - 4,
164                .data_frame.df_fin         = 0,
165            },
166            1,
167        },
168
169        {   "Sanity check: either FIN must be set or data length is not zero #1",
170            __LINE__,
171            select_pf_by_ver(LSQVER_043),
172          /*  1      f      d      ooo    ss            1fdoooss */
173          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
174            { 0x80 | 0x00 | 0x00 | 0x04 | 0x0,
175              0xF0,                                             /* Stream ID */
176              0x02, 0x55,                                       /* Offset */
177            },
178              1           + 0    + 2    + 1,
179              4,    /* Same as buffer size: in the absense of explicit data
180                     * length in the header, this would mean that data
181                     * length is zero.
182                     */
183            {   .data_frame.df_offset      = 0x255,
184                .stream_id   = 0xF0,
185                .data_frame.df_size = 0x200 - 4,
186                .data_frame.df_fin         = 0,
187            },
188            0,
189        },
190
191        {   "Sanity check: either FIN must be set or data length is not zero #2",
192            __LINE__,
193            select_pf_by_ver(LSQVER_043),
194          /*  1      f      d      ooo    ss            1fdoooss */
195          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
196            { 0x80 | 0x00 | 0x20 | 0x04 | 0x0,
197              0xF0,                                             /* Stream ID */
198              0x02, 0x55,                                       /* Offset */
199              0x00, 0x00,
200            },
201              1           + 2    + 2    + 1,
202              200,
203            {   .data_frame.df_offset      = 0x255,
204                .stream_id   = 0xF0,
205                .data_frame.df_size = 0x200 - 4,
206                .data_frame.df_fin         = 0,
207            },
208            0,
209        },
210
211        {   "Sanity check: either FIN must be set or data length is not zero #3",
212            __LINE__,
213            select_pf_by_ver(LSQVER_043),
214          /*  1      f      d      ooo    ss            1fdoooss */
215          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
216            { 0x80 | 0x40 | 0x20 | 0x04 | 0x0,
217              0xF0,                                             /* Stream ID */
218              0x02, 0x55,                                       /* Offset */
219              0x00, 0x00,
220            },
221              1           + 2    + 2    + 1,
222              200,
223            {   .data_frame.df_offset      = 0x255,
224                .stream_id   = 0xF0,
225                .data_frame.df_size = 0x0,
226                .data_frame.df_fin         = 1,
227            },
228            1,
229        },
230
231        {   "Check data bounds #1",
232            __LINE__,
233            select_pf_by_ver(LSQVER_043),
234          /*  1      f      d      ooo    ss            1fdoooss */
235          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
236            { 0x80 | 0x00 | 0x20 | 0x04 | 0x0,
237              0xF0,                                             /* Stream ID */
238              0x02, 0x55,                                       /* Offset */
239              0x01, 0xFA,                                       /* Data length */
240            },
241              1           + 2    + 2    + 1,
242              0x200,
243            {   .data_frame.df_offset      = 0x255,
244                .stream_id   = 0xF0,
245                .data_frame.df_size = 0x1FA,
246                .data_frame.df_fin         = 0,
247            },
248            1,
249        },
250
251        {   "Check data bounds #2",
252            __LINE__,
253            select_pf_by_ver(LSQVER_043),
254          /*  1      f      d      ooo    ss            1fdoooss */
255          /*  TYPE   FIN    DLEN   OLEN   SLEN  */
256            { 0x80 | 0x00 | 0x20 | 0x04 | 0x0,
257              0xF0,                                             /* Stream ID */
258              0x02, 0x55,                                       /* Offset */
259              0x01, 0xFB,    /* <---   One byte too many */
260            },
261              1           + 2    + 2    + 1,
262              0x200,
263            {   .data_frame.df_offset      = 0x255,
264                .stream_id   = 0xF0,
265                .data_frame.df_size = 0x1FA,
266                .data_frame.df_fin         = 0,
267            },
268            0,
269        },
270
271        /*
272         * IETF QUIC Internet-Draft 14 Tests.
273         */
274
275        {   "Balls to the wall: every possible bit is set",
276            __LINE__,
277            select_pf_by_ver(LSQVER_ID27),
278          /*  TYPE   OFF    DLEN   FIN   */
279            { 0x10 | 1<<2 | 1<<1 | 1<<0,
280              0x41, 0x23,                                       /* Stream ID */
281              0x08,                                             /* Offset */
282              0x41, 0xC4,                                       /* Data length */
283            },
284              1           + 2    + 1    + 2,
285            0x200,
286            {   .data_frame.df_offset       = 0x08,
287                .stream_id                  = 0x123,
288                .data_frame.df_size         = 0x1C4,
289                .data_frame.df_fin          = 1,
290            },
291            1,
292        },
293
294        {   "Balls to the wall #2: every possible bit is set except FIN",
295            __LINE__,
296            select_pf_by_ver(LSQVER_ID27),
297          /*  TYPE   OFF    DLEN   FIN   */
298            { 0x10 | 1<<2 | 1<<1 | 0<<0,
299              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
300              0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,   /* Offset */
301              0x41, 0xC4,                                       /* Data length */
302            },
303              1           + 4    + 8    + 2,
304            0x200,
305            {   .data_frame.df_offset       = 0x301234567890ABCDull,
306                .stream_id                  = 0x12300E4,
307                .data_frame.df_size         = 0x1C4,
308                .data_frame.df_fin          = 0,
309            },
310            1,
311        },
312
313        {   "Data length is zero",
314            __LINE__,
315            select_pf_by_ver(LSQVER_ID27),
316          /*  TYPE   OFF    DLEN   FIN   */
317            { 0x10 | 1<<2 | 0<<1 | 0<<0,
318              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
319              0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,   /* Offset */
320            },
321              1           + 4    + 8    + 0,
322            0x200,
323            {   .data_frame.df_offset       = 0x301234567890ABCDull,
324                .stream_id                  = 0x12300E4,
325                .data_frame.df_size         = 0x200 - 1 - 4 - 8,
326                .data_frame.df_fin          = 0,
327            },
328            1,
329        },
330
331        {   "Sanity check: what happens when data length is zero #1",
332            __LINE__,
333            select_pf_by_ver(LSQVER_ID27),
334          /*  TYPE   OFF    DLEN   FIN   */
335            { 0x10 | 1<<2 | 1<<1 | 0<<0,
336              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
337              0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD,   /* Offset */
338              0x40, 0x00,                                       /* Data length */
339            },
340              1           + 4    + 8    + 2,
341            0x200,
342            {   .data_frame.df_offset       = 0x301234567890ABCDull,
343                .stream_id                  = 0x12300E4,
344                .data_frame.df_size         = 0,
345                .data_frame.df_fin          = 0,
346            },
347            1,
348        },
349
350        {   "Sanity check: what happens when data length is zero #2",
351            __LINE__,
352            select_pf_by_ver(LSQVER_ID27),
353          /*  TYPE   OFF    DLEN   FIN   */
354            { 0x10 | 1<<2 | 1<<1 | 0<<0,
355              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
356              0x00,                                             /* Offset */
357              0x40, 0x00,                                       /* Data length */
358            },
359              1           + 4    + 1    + 2,
360            0x200,
361            {   .data_frame.df_offset       = 0,
362                .stream_id                  = 0x12300E4,
363                .data_frame.df_size         = 0,
364                .data_frame.df_fin          = 0,
365            },
366            1,
367        },
368
369        {   "Sanity check: what happens when data length is zero #3",
370            __LINE__,
371            select_pf_by_ver(LSQVER_ID27),
372          /*  TYPE   OFF    DLEN   FIN   */
373            { 0x10 | 0<<2 | 1<<1 | 0<<0,
374              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
375              0x40, 0x00,                                       /* Data length */
376            },
377              1           + 4    + 0    + 2,
378            0x200,
379            {   .data_frame.df_offset       = 0,
380                .stream_id                  = 0x12300E4,
381                .data_frame.df_size         = 0,
382                .data_frame.df_fin          = 0,
383            },
384            1,
385        },
386
387        {   "Sanity check: what happens when data length is zero #3",
388            __LINE__,
389            select_pf_by_ver(LSQVER_ID27),
390          /*  TYPE   OFF    DLEN   FIN   */
391            { 0x10 | 1<<2 | 1<<1 | 1<<0,
392              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
393              0x12,                                             /* Offset */
394              0x00,                                             /* Data length */
395            },
396              1           + 4    + 1    + 1,
397            0x200,
398            {   .data_frame.df_offset       = 0x12,
399                .stream_id                  = 0x12300E4,
400                .data_frame.df_size         = 0,
401                .data_frame.df_fin          = 1,
402            },
403            1,
404        },
405
406        {   "Check data bounds #1",
407            __LINE__,
408            select_pf_by_ver(LSQVER_ID27),
409          /*  TYPE   OFF    DLEN   FIN   */
410            { 0x10 | 1<<2 | 1<<1 | 1<<0,
411              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
412              0x12,                                             /* Offset */
413              0x41, 0xF8,                                       /* Data length */
414            },
415              1           + 4    + 1    + 2,
416            0x200,
417            {   .data_frame.df_offset       = 0x12,
418                .stream_id                  = 0x12300E4,
419                .data_frame.df_size         = 0x200 - 1 - 4 - 1 - 2,
420                .data_frame.df_fin          = 1,
421            },
422            1,
423        },
424
425        {   "Check data bounds #2",
426            __LINE__,
427            select_pf_by_ver(LSQVER_ID27),
428          /*  TYPE   OFF    DLEN   FIN   */
429            { 0x10 | 1<<2 | 1<<1 | 1<<0,
430              0x81, 0x23, 0x00, 0xE4,                           /* Stream ID */
431              0x12,                                             /* Offset */
432              0x41, 0xF9,                                       /* Data length */
433            },
434              1           + 4    + 1    + 2,
435            0x200,
436            {   .data_frame.df_offset       = 0x12,
437                .stream_id                  = 0x12300E4,
438                .data_frame.df_size         = 0x200 - 1 - 4 - 1 - 2,
439                .data_frame.df_fin          = 1,
440            },
441            0,
442        },
443
444    };
445
446    unsigned i;
447    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
448        run_test(&tests[i]);
449    return 0;
450}
451