test_streamparse.c revision f07b3eae
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 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