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