test_ver_nego.c revision 9a690580
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/queue.h>
7#ifndef WIN32
8#include <sys/time.h>
9#endif
10
11#include "lsquic.h"
12#include "lsquic_types.h"
13#include "lsquic_packet_common.h"
14#include "lsquic_parse.h"
15#include "lsquic_parse_common.h"
16#include "lsquic_mm.h"
17#include "lsquic_packet_in.h"
18#include "lsquic_engine_public.h"
19#include "lsquic_version.h"
20
21
22/* The struct is used to test both generation and parsing of version
23 * negotiation packet.
24 */
25struct gen_ver_nego_test {
26    int             gvnt_lineno;
27    /* Generate: inputs; parse: outputs */
28    enum lsquic_version
29                    gvnt_gen_ver;
30    uint64_t        gvnt_cid;
31    unsigned        gvnt_versions;
32    size_t          gvnt_bufsz;
33    /* Generate: outputs; parse: inputs */
34    int             gvnt_len;            /* Retval */
35    char            gvnt_buf[0x40];      /* Contents */
36};
37
38
39static const struct gen_ver_nego_test tests[] = {
40
41    {   .gvnt_lineno    = __LINE__,
42        .gvnt_cid       = 0x0102030405060708UL,
43        .gvnt_versions  = (1 << LSQVER_043),
44        .gvnt_gen_ver   = LSQVER_043,
45        .gvnt_bufsz     = 12,
46        .gvnt_len       = -1,       /* Buffer size is too small */
47    },
48
49    {   .gvnt_lineno    = __LINE__,
50        .gvnt_cid       = 0x0102030405060708UL,
51        .gvnt_versions  = (1 << LSQVER_043) | (1 << N_LSQVER),
52        .gvnt_gen_ver   = LSQVER_043,
53        .gvnt_bufsz     = 20,
54        .gvnt_len       = -1,       /* Invalid version specified in the bitmask */
55    },
56
57    {   .gvnt_lineno    = __LINE__,
58        .gvnt_cid       = 0x0102030405060708UL,
59        .gvnt_versions  = (1 << LSQVER_043) | (1 << LSQVER_046),
60        .gvnt_gen_ver   = LSQVER_043,
61        .gvnt_bufsz     = 17,
62        .gvnt_len       = 17,
63        .gvnt_buf       = {
64            PACKET_PUBLIC_FLAGS_VERSION|
65            PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID,
66            0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,   /* Connection ID */
67            'Q', '0', '4', '3',
68            'Q', '0', '4', '6',
69        },
70    },
71
72};
73
74
75static void
76test_parsing_ver_nego (const struct gen_ver_nego_test *gvnt)
77{
78    int s;
79    lsquic_packet_in_t *packet_in;
80    struct lsquic_mm mm;
81    struct ver_iter vi;
82    lsquic_ver_tag_t ver_tag;
83    enum lsquic_version version;
84    struct packin_parse_state ppstate;
85    unsigned version_bitmask = gvnt->gvnt_versions;
86
87    lsquic_mm_init(&mm);
88    packet_in = lsquic_mm_get_packet_in(&mm);
89    packet_in->pi_data = lsquic_mm_get_packet_in_buf(&mm, 1370);
90    packet_in->pi_flags |= PI_OWN_DATA;
91    memcpy(packet_in->pi_data, gvnt->gvnt_buf, gvnt->gvnt_len);
92    s = lsquic_parse_packet_in_begin(packet_in, gvnt->gvnt_len, 0, GQUIC_CID_LEN, &ppstate);
93    assert(s == 0);
94
95    for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
96                     s = lsquic_packet_in_ver_next(&vi, &ver_tag))
97    {
98        version = lsquic_tag2ver(ver_tag);
99        assert(version < N_LSQVER);
100        assert(version_bitmask & (1 << version));
101        version_bitmask &= ~(1 << version);
102    }
103
104    assert(0 == version_bitmask);
105
106    lsquic_mm_put_packet_in(&mm, packet_in);
107    lsquic_mm_cleanup(&mm);
108}
109
110
111static void
112run_gvnt (int i)
113{
114    const struct gen_ver_nego_test *const gvnt = &tests[i];
115    lsquic_cid_t scid, dcid;
116    int len;
117
118    memset(&dcid, 0, sizeof(dcid));
119    dcid.len = sizeof(gvnt->gvnt_cid);
120    memcpy(dcid.idbuf, &gvnt->gvnt_cid, sizeof(gvnt->gvnt_cid));
121
122    unsigned char out[0x40];
123    assert(sizeof(out) <= sizeof(gvnt->gvnt_buf));  /* Internal sanity check */
124
125    if ((1 << gvnt->gvnt_gen_ver) & LSQUIC_GQUIC_HEADER_VERSIONS)
126        len = lsquic_gquic_gen_ver_nego_pkt(out, gvnt->gvnt_bufsz, &dcid,
127                                                    gvnt->gvnt_versions);
128    else
129    {
130        /* XXX this is never executed, as there is no test case for this */
131        scid = (lsquic_cid_t) { .len = 0, };
132        len = lsquic_Q046_gen_ver_nego_pkt(out, gvnt->gvnt_bufsz, &dcid,
133                    &scid, gvnt->gvnt_versions, ((unsigned char) rand()) & 0xF);
134    }
135    assert(("Packet length is correct", len == gvnt->gvnt_len));
136
137    if (gvnt->gvnt_len > 0)
138    {
139        if ((1 << gvnt->gvnt_gen_ver) & LSQUIC_GQUIC_HEADER_VERSIONS)
140            assert(("Packet contents are correct",
141                0 == memcmp(out, gvnt->gvnt_buf, gvnt->gvnt_len)));
142        else
143        {
144            assert(("Packet contents are correct",
145                0 == memcmp(out + 1, gvnt->gvnt_buf + 1, gvnt->gvnt_len - 1)));
146            assert(out[0] & 0x80);  /* Other 7 bits are random */
147        }
148        test_parsing_ver_nego(gvnt);
149    }
150}
151
152
153int
154main (void)
155{
156    unsigned i;
157    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
158        run_gvnt(i);
159    return 0;
160}
161