test_ackparse_ietf.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_ID27);
24
25
26static void
27test_max_ack (void)
28{
29    lsquic_rechist_t rechist;
30    lsquic_time_t now;
31    unsigned i;
32    int has_missing, sz[2];
33    const struct lsquic_packno_range *range;
34    unsigned char buf[1500];
35    struct ack_info acki;
36
37    lsquic_rechist_init(&rechist, 0, 0);
38    now = lsquic_time_now();
39
40    for (i = 1; i <= 300; ++i)
41    {
42        lsquic_rechist_received(&rechist, i * 10, now);
43        now += i * 1000;
44    }
45
46    memset(buf, 0xAA, sizeof(buf));
47
48    lsquic_packno_t largest = 0;
49    sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf),
50        (gaf_rechist_first_f)        lsquic_rechist_first,
51        (gaf_rechist_next_f)         lsquic_rechist_next,
52        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
53        &rechist, now, &has_missing, &largest, NULL);
54    assert(sz[0] > 0);
55    assert(sz[0] <= (int) sizeof(buf));
56    assert(has_missing);
57
58    assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
59    assert(0xAA == buf[ sz[0] ]);
60
61    sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
62    assert(sz[1] == sz[0]);
63    assert(256 == acki.n_ranges);
64
65    for (range = lsquic_rechist_first(&rechist), i = 0;
66                        range && i < acki.n_ranges;
67                                    range = lsquic_rechist_next(&rechist), ++i)
68    {
69        assert(range->high == acki.ranges[i].high);
70        assert(range->low  == acki.ranges[i].low);
71    }
72    assert(i == 256);
73
74    lsquic_rechist_cleanup(&rechist);
75}
76
77
78static void
79test_ack_truncation (void)
80{
81    lsquic_rechist_t rechist;
82    lsquic_time_t now;
83    unsigned i;
84    int has_missing, sz[2];
85    const struct lsquic_packno_range *range;
86    unsigned char buf[1500];
87    struct ack_info acki;
88    size_t bufsz;
89
90    lsquic_rechist_init(&rechist, 0, 0);
91    now = lsquic_time_now();
92
93    for (i = 1; i <= 300; ++i)
94    {
95        lsquic_rechist_received(&rechist, i * 10, now);
96        now += i * 1000;
97    }
98
99    for (bufsz = 200; bufsz < 210; ++bufsz)
100    {
101        memset(buf, 0xAA, sizeof(buf));
102        lsquic_packno_t largest = 0;
103        sz[0] = pf->pf_gen_ack_frame(buf, bufsz,
104            (gaf_rechist_first_f)        lsquic_rechist_first,
105            (gaf_rechist_next_f)         lsquic_rechist_next,
106            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
107            &rechist, now, &has_missing, &largest, NULL);
108        assert(sz[0] > 0);
109        assert(sz[0] <= (int) bufsz);
110        assert(has_missing);
111
112        assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
113        assert(0xAA == buf[ sz[0] ]);
114
115        sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
116        assert(sz[1] == sz[0]);
117        assert(acki.n_ranges < 256);
118
119        for (range = lsquic_rechist_first(&rechist), i = 0;
120                            range && i < acki.n_ranges;
121                                        range = lsquic_rechist_next(&rechist), ++i)
122        {
123            assert(range->high == acki.ranges[i].high);
124            assert(range->low  == acki.ranges[i].low);
125        }
126    }
127
128    lsquic_rechist_cleanup(&rechist);
129}
130
131
132int
133main (void)
134{
135    lsquic_global_init(LSQUIC_GLOBAL_SERVER);
136    test_max_ack();
137    test_ack_truncation();
138    return 0;
139}
140