test_ackparse_gquic_be.c revision fb3e20e0
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#ifndef WIN32
7#include <sys/time.h>
8#else
9#include "vc_compat.h"
10#endif
11
12#include "lsquic_types.h"
13#include "lsquic_parse.h"
14#include "lsquic_rechist.h"
15#include "lsquic_util.h"
16#include "lsquic.h"
17#include "lsquic_hash.h"
18#include "lsquic_conn.h"
19
20static struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0);
21
22static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043);
23
24
25static lsquic_packno_t
26n_acked (const struct ack_info *acki)
27{
28    lsquic_packno_t n = 0;
29    unsigned i;
30    for (i = 0; i < acki->n_ranges; ++i)
31        n += acki->ranges[i].high - acki->ranges[i].low + 1;
32    return n;
33}
34
35
36static void
37test1 (void)
38{
39    /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */
40    unsigned char ack_buf[] = {
41        0x45,
42        0x12, 0x34,             /* Largest acked */
43        0x00, 0x00,             /* Delta time */
44        0x12, 0x34,             /* Block length */
45        0x00,                   /* Number of timestamps */
46    };
47
48    struct ack_info acki;
49    memset(&acki, 0xF1, sizeof(acki));
50
51    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
52    assert(("Parsed length is correct (8)", len == sizeof(ack_buf)));
53    assert(("Number of ranges is 1", acki.n_ranges == 1));
54    assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234));
55    assert(("Lowest acked is 1", acki.ranges[0].low == 1));
56    unsigned n = n_acked(&acki);
57    assert(("Number of acked packets is 0x1234", n == 0x1234));
58
59    {
60        size_t sz;
61        for (sz = 1; sz < sizeof(ack_buf); ++sz)
62        {
63            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
64            assert(("Parsing truncated frame failed", len < 0));
65        }
66    }
67}
68
69
70static void
71test2 (void)
72{
73    /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */
74    unsigned char ack_buf[] = {
75        0x65,
76        0x12, 0x34,                 /* Largest acked */
77        0x00, 0x00,                 /* Zero delta time. */
78        0x04,                       /* Num ack blocks ranges. */
79        0x00, 0x01,                 /* First ack block length. */
80        0x01,                       /* Gap to next block. */
81        0x0e, 0xaf,                 /* Ack block length. */
82        0xff,                       /* Gap to next block. */
83        0x00, 0x00,                 /* Ack block length. */
84        0x91,                       /* Gap to next block. */
85        0x01, 0xea,                 /* Ack block length. */
86        0x05,                       /* Gap to next block. */
87        0x00, 0x04,                 /* Ack block length. */
88        0x02,                       /* Number of timestamps. */
89        0x01,                       /* Delta from largest observed. */
90        0x10, 0x32, 0x54, 0x76,     /* Delta time. */   /* XXX do we use this at all? */
91        0x02,                       /* Delta from largest observed. */
92        0x10, 0x32,                 /* Delta time. */
93    };
94
95    /* We should get the following array of ranges:
96     *    high      low
97     *    0x1234    0x1234
98     *    0x1232    0x384
99     *    0x1F3     0xA
100     *    0x4       0x1
101     */
102    static const struct { unsigned high, low; } ranges[] = {
103        {   0x1234, 0x1234 },
104        {   0x1232, 0x384 },
105        {   0x1F3,  0xA },
106        {   0x4,    0x1 },
107    };
108
109    struct ack_info acki;
110    memset(&acki, 0xF1, sizeof(acki));
111
112    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
113    assert(("Parsed length is correct (29)", len == sizeof(ack_buf)));
114    assert(("Number of ranges is 4", acki.n_ranges == 4));
115    assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234));
116    unsigned n = n_acked(&acki);
117    assert(("Number of acked packets is 4254", n == 4254));
118
119    for (n = 0; n < 4; ++n)
120        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
121                                &&  ranges[n].low  == acki.ranges[n].low));
122
123    {
124        size_t sz;
125        for (sz = 1; sz < sizeof(ack_buf); ++sz)
126        {
127            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
128            assert(("Parsing truncated frame failed", len < 0));
129        }
130    }
131}
132
133
134static void
135test3 (void)
136{
137    /* Generated by our own code, but failed to parse... */
138    unsigned char ack_buf[] = {
139        0x60,         /* More than one ack block, 1 byte largest observed, 1 byte block length */
140        0x06,         /* Largest ACKed */
141        0x00, 0x00,   /* Delta time */
142        0x01,         /* Num ACK block ranges */
143        0x01,         /* First ACK block length */
144        0x02,         /* Gap to next block */
145        0x03,         /* Ack block length */
146        0x00          /* Number of timestamps */
147    };
148
149    /* We should get the following array of ranges:
150     *    high      low
151     *    6         6
152     *    3         1
153     */
154    static const struct { unsigned high, low; } ranges[] = {
155        {   6,      6, },
156        {   3,      1, },
157    };
158
159    struct ack_info acki;
160    memset(&acki, 0xF1, sizeof(acki));
161
162    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
163    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
164    assert(("Number of ranges is 2", acki.n_ranges == 2));
165    assert(("Largest acked is 6", acki.ranges[0].high == 6));
166    unsigned n = n_acked(&acki);
167    assert(("Number of acked packets is 4", n == 4));
168
169    for (n = 0; n < 2; ++n)
170        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
171                                &&  ranges[n].low  == acki.ranges[n].low));
172
173    {
174        size_t sz;
175        for (sz = 1; sz < sizeof(ack_buf); ++sz)
176        {
177            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
178            assert(("Parsing truncated frame failed", len < 0));
179        }
180    }
181}
182
183
184static void
185test4 (void)
186{
187    unsigned char ack_buf[] = {
188        0x60,       /* More than one ack block, 1 byte largest observed, 1 byte block length */
189        0x03,       /* Largest ACKed */
190        0x23, 0x00, /* Delta time */
191        0x01,       /* Num ACK block ranges */
192        0x01,       /* First ack block length */
193        0x01,       /* Gap */
194        0x01,       /* Ack block length */
195        0x00,       /* Number of timestamps */
196    };
197
198    /* We should get the following array of ranges:
199     *    high      low
200     *    6         6
201     *    3         1
202     */
203    static const struct { unsigned high, low; } ranges[] = {
204        {   3,      3, },
205        {   1,      1, },
206    };
207
208    struct ack_info acki;
209    memset(&acki, 0xF1, sizeof(acki));
210
211    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
212    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
213    assert(("Number of ranges is 2", acki.n_ranges == 2));
214    assert(("Largest acked is 3", acki.ranges[0].high == 3));
215    unsigned n = n_acked(&acki);
216    assert(("Number of acked packets is 2", n == 2));
217
218    for (n = 0; n < 2; ++n)
219        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
220                                &&  ranges[n].low  == acki.ranges[n].low));
221
222    {
223        size_t sz;
224        for (sz = 1; sz < sizeof(ack_buf); ++sz)
225        {
226            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
227            assert(("Parsing truncated frame failed", len < 0));
228        }
229    }
230}
231
232
233/* Four-byte packet numbers */
234static void
235test5 (void)
236{
237    unsigned char ack_buf[] = {
238        0x60
239            | (2 << 2)  /* Four-byte largest acked */
240            | (2 << 0)  /* Four-byte ACK block length */
241        ,
242        0x23, 0x45, 0x67, 0x89,
243        0x00, 0x00,                 /* Zero delta time. */
244        0x01,                       /* Num ack blocks ranges. */
245        0x00, 0x00, 0x00, 0x01,     /* First ack block length. */
246        33 - 1,                     /* Gap to next block. */
247        0x23, 0x45, 0x67, 0x68,     /* Ack block length. */
248        0x00,                       /* Number of timestamps. */
249    };
250
251    /* We should get the following array of ranges:
252     *    high      low
253     *    6         6
254     *    3         1
255     */
256    static const struct { unsigned high, low; } ranges[] = {
257        {   0x23456789,      0x23456789, },
258        {   0x23456768,      1, },
259    };
260
261    struct ack_info acki;
262    memset(&acki, 0xF1, sizeof(acki));
263
264    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
265    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
266    assert(("Number of ranges is 2", acki.n_ranges == 2));
267    assert(("Largest acked is 0x23456789", acki.ranges[0].high == 0x23456789));
268    lsquic_packno_t n = n_acked(&acki);
269    assert(("Number of acked packets is correct", n == 0x23456768 + 1));
270
271    for (n = 0; n < 2; ++n)
272        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
273                                &&  ranges[n].low  == acki.ranges[n].low));
274
275    {
276        size_t sz;
277        for (sz = 1; sz < sizeof(ack_buf); ++sz)
278        {
279            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
280            assert(("Parsing truncated frame failed", len < 0));
281        }
282    }
283}
284
285
286/* Six-byte packet numbers */
287static void
288test6 (void)
289{
290    unsigned char ack_buf[] = {
291        0x60
292            | (3 << 2)  /* Six-byte largest acked */
293            | (3 << 0)  /* Six-byte ACK block length */
294        ,
295        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89,
296        0x00, 0x00,                 /* Zero delta time. */
297        0x01,                       /* Num ack blocks ranges. */
298        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */
299        33 - 1,                     /* Gap to next block. */
300        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */
301        0x00,                       /* Number of timestamps. */
302    };
303
304    static const struct { lsquic_packno_t high, low; } ranges[] = {
305        {   0xABCD23456789,      0xABCD23456789, },
306        {   0xABCD23456768,      1, },
307    };
308
309    struct ack_info acki;
310    memset(&acki, 0xF1, sizeof(acki));
311
312    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
313    assert(("Parsed length is correct", len == sizeof(ack_buf)));
314    assert(("Number of ranges is 2", acki.n_ranges == 2));
315    assert(("Largest acked is 0xABCD23456789", acki.ranges[0].high == 0xABCD23456789));
316    lsquic_packno_t n = n_acked(&acki);
317    assert(("Number of acked packets is correct", n == 0xABCD23456768 + 1));
318
319    for (n = 0; n < 2; ++n)
320        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
321                                &&  ranges[n].low  == acki.ranges[n].low));
322
323    {
324        size_t sz;
325        for (sz = 1; sz < sizeof(ack_buf); ++sz)
326        {
327            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
328            assert(("Parsing truncated frame failed", len < 0));
329        }
330    }
331}
332
333
334static void
335test_max_ack (void)
336{
337    lsquic_rechist_t rechist;
338    lsquic_time_t now;
339    unsigned i;
340    int has_missing, sz[2];
341    const struct lsquic_packno_range *range;
342    unsigned char buf[1500];
343    struct ack_info acki;
344
345    lsquic_rechist_init(&rechist, &lconn, 0);
346    now = lsquic_time_now();
347
348    for (i = 1; i <= 300; ++i)
349    {
350        lsquic_rechist_received(&rechist, i * 10, now);
351        now += i * 1000;
352    }
353
354    memset(buf, 0xAA, sizeof(buf));
355
356    lsquic_packno_t largest = 0;
357    sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf),
358        (gaf_rechist_first_f)        lsquic_rechist_first,
359        (gaf_rechist_next_f)         lsquic_rechist_next,
360        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
361        &rechist, now, &has_missing, &largest, NULL);
362    assert(sz[0] > 0);
363    assert(sz[0] <= (int) sizeof(buf));
364    assert(has_missing);
365
366    assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
367    assert(0xAA == buf[ sz[0] ]);
368
369    sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
370    assert(sz[1] == sz[0]);
371    assert(256 == acki.n_ranges);
372
373    for (range = lsquic_rechist_first(&rechist), i = 0;
374                        range && i < acki.n_ranges;
375                                    range = lsquic_rechist_next(&rechist), ++i)
376    {
377        assert(range->high == acki.ranges[i].high);
378        assert(range->low  == acki.ranges[i].low);
379    }
380    assert(i == 256);
381
382    lsquic_rechist_cleanup(&rechist);
383}
384
385
386static void
387test_ack_truncation (void)
388{
389    lsquic_rechist_t rechist;
390    lsquic_time_t now;
391    unsigned i;
392    int has_missing, sz[2];
393    const struct lsquic_packno_range *range;
394    unsigned char buf[1500];
395    struct ack_info acki;
396    size_t bufsz;
397
398    lsquic_rechist_init(&rechist, &lconn, 0);
399    now = lsquic_time_now();
400
401    for (i = 1; i <= 300; ++i)
402    {
403        lsquic_rechist_received(&rechist, i * 10, now);
404        now += i * 1000;
405    }
406
407    for (bufsz = 200; bufsz < 210; ++bufsz)
408    {
409        memset(buf, 0xAA, sizeof(buf));
410        lsquic_packno_t largest = 0;
411        sz[0] = pf->pf_gen_ack_frame(buf, bufsz,
412            (gaf_rechist_first_f)        lsquic_rechist_first,
413            (gaf_rechist_next_f)         lsquic_rechist_next,
414            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
415            &rechist, now, &has_missing, &largest, NULL);
416        assert(sz[0] > 0);
417        assert(sz[0] <= (int) bufsz);
418        assert(has_missing);
419
420        assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
421        assert(0xAA == buf[ sz[0] ]);
422
423        sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
424        assert(sz[1] == sz[0]);
425        assert(acki.n_ranges < 256);
426
427        for (range = lsquic_rechist_first(&rechist), i = 0;
428                            range && i < acki.n_ranges;
429                                        range = lsquic_rechist_next(&rechist), ++i)
430        {
431            assert(range->high == acki.ranges[i].high);
432            assert(range->low  == acki.ranges[i].low);
433        }
434    }
435
436    lsquic_rechist_cleanup(&rechist);
437}
438
439
440static void
441test_empty_ack (void)
442{
443    int len;
444    unsigned char buf[] = { 0x40, 0x00, 0xFF, 0xFF, 0x00, 0x00,
445                            /* fluff: */ 0x12, 0x23, 0x34, 0x45, };
446    struct ack_info acki;
447
448    len = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
449    assert(6 == len);
450    assert(empty_ack_frame(&acki));
451}
452
453
454int
455main (void)
456{
457    lsquic_global_init(LSQUIC_GLOBAL_SERVER);
458    test1();
459    test2();
460    test3();
461    test4();
462    test5();
463    test6();
464    test_max_ack();
465    test_ack_truncation();
466    test_empty_ack();
467    return 0;
468}
469