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