test_goaway_gquic_be.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
10#include "lsquic.h"
11#include "lsquic_types.h"
12#include "lsquic_parse.h"
13
14static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043);
15
16
17struct goaway_parse_test {
18    int             lineno;
19    unsigned char   buf[0x100];
20    size_t          buf_len;
21    uint32_t        error_code;
22    lsquic_stream_id_t        last_stream_id;
23    uint16_t        reason_len;
24    const char     *reason;
25    int             retval;
26};
27
28static const struct goaway_parse_test parse_tests[] = {
29
30    {
31        .lineno         = __LINE__,
32        .buf            = { 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x12, 0x34, 0x00, 0x05, 'D', 'u', 'd', 'e', '!', },
33        .buf_len        = 0x100,
34        .error_code     = 0x31,
35        .last_stream_id = 0x1234,
36        .reason_len     = 0x05,
37        .reason         = "Dude!",
38        .retval         = 11 + 5,
39    },
40
41    {
42        .lineno         = __LINE__,
43        .buf            = { 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x12, 0x34, 0x00, 0x05, 'D', 'u', 'd', 'e', '!', },
44        .buf_len        = 8,    /* Too short #1 */
45        .error_code     = 0x31,
46        .last_stream_id = 0x1234,
47        .reason_len     = 0x05,
48        .reason         = "Dude!",
49        .retval         = -1,
50    },
51
52    {
53        .lineno         = __LINE__,
54        .buf            = { 0x03, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x12, 0x34, 0x00, 0x05, 'D', 'u', 'd', 'e', '!', },
55        .buf_len        = 12,    /* Too short #2 */
56        .error_code     = 0x31,
57        .last_stream_id = 0x1234,
58        .reason_len     = 0x05,
59        .reason         = "Dude!",
60        .retval         = -2,
61    },
62
63    {   .buf            = { 0 },    }
64};
65
66
67struct goaway_gen_test {
68    int             lineno;
69    uint32_t        error_code;
70    lsquic_stream_id_t        last_stream_id;
71    const char     *reason;
72    int             retval;
73    unsigned char   buf[0x100];
74    size_t          buf_len;
75};
76
77
78static const struct goaway_gen_test gen_tests[] = {
79
80    {
81        .lineno         = __LINE__,
82        .error_code     = 0x12345678,
83        .last_stream_id = 0x1234,
84        .reason         = "Dude, where is my car?",
85        .retval         = 11 + sizeof("Dude, where is my car?") - 1,
86        .buf_len        = 0x100,
87        .buf            = {
88            0x03,
89            0x12, 0x34, 0x56, 0x78,
90            0x00, 0x00, 0x12, 0x34,
91            0x00, sizeof("Dude, where is my car?") - 1,
92            'D', 'u', 'd', 'e', ',', ' ', 'w', 'h', 'e', 'r', 'e', ' ', 'i', 's', ' ', 'm', 'y', ' ', 'c', 'a', 'r', '?',
93        },
94    },
95
96    {
97        .lineno         = __LINE__,
98        .error_code     = 0x12345678,
99        .last_stream_id = 0x2345,
100        .reason         = NULL,
101        .retval         = 11,
102        .buf_len        = 0x100,
103        .buf            = {
104            0x02,
105            0x12, 0x34, 0x56, 0x78,
106            0x00, 0x00, 0x23, 0x45,
107            0x00, 0x00, /* Zero-sized string */
108        },
109    },
110
111    {
112        .lineno         = __LINE__,
113        .error_code     = 0x12345678,
114        .last_stream_id = 0x2345,
115        .reason         = "Dude, where is my car?",
116        .retval         = -1,   /* Too short */
117        .buf_len        = 0x10,
118    },
119
120    {   .buf            = { 0 },    }
121
122};
123
124
125static void
126run_parse_tests (void)
127{
128    const struct goaway_parse_test *test;
129    for (test = parse_tests; test->buf[0]; ++test)
130    {
131        uint32_t error_code = ~0;
132        lsquic_stream_id_t last_stream_id = ~0;
133        uint16_t reason_len = ~0;
134        const char *reason;
135        int sz = pf->pf_parse_goaway_frame(test->buf, test->buf_len,
136                    &error_code, &last_stream_id, &reason_len, &reason);
137        assert(sz == test->retval);
138        if (0 == sz)
139        {
140            assert(test->error_code == error_code);
141            assert(test->last_stream_id == last_stream_id);
142            assert(test->reason_len == reason_len);
143            assert(0 == memcmp(test->reason, reason, reason_len));
144        }
145    }
146}
147
148
149static void
150run_gen_tests (void)
151{
152    const struct goaway_gen_test *test;
153    for (test = gen_tests; test->buf[0]; ++test)
154    {
155        unsigned char buf[0x100];
156        int sz = pf->pf_gen_goaway_frame(buf, sizeof(buf),
157                    test->error_code, test->last_stream_id, test->reason,
158                    test->reason ? strlen(test->reason) : 0);
159        assert(sz == test->retval);
160        if (0 == sz)
161            assert(0 == memcmp(test->buf, buf, sz));
162    }
163}
164
165
166int
167main (void)
168{
169    run_parse_tests();
170    run_gen_tests();
171    return 0;
172}
173