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