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