test_ackparse_ietf.c revision fb3e20e0
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2767cf611SDmitri Tikhonov#include <assert.h>
3767cf611SDmitri Tikhonov#include <stdio.h>
4767cf611SDmitri Tikhonov#include <stdlib.h>
5767cf611SDmitri Tikhonov#include <string.h>
6767cf611SDmitri Tikhonov#ifndef WIN32
7767cf611SDmitri Tikhonov#include <sys/time.h>
8fb3e20e0SDmitri Tikhonov#else
9fb3e20e0SDmitri Tikhonov#include "vc_compat.h"
10767cf611SDmitri Tikhonov#endif
11767cf611SDmitri Tikhonov
12767cf611SDmitri Tikhonov#include "lsquic_types.h"
13767cf611SDmitri Tikhonov#include "lsquic_parse.h"
14767cf611SDmitri Tikhonov#include "lsquic_rechist.h"
15767cf611SDmitri Tikhonov#include "lsquic_util.h"
16767cf611SDmitri Tikhonov#include "lsquic.h"
17767cf611SDmitri Tikhonov#include "lsquic_hash.h"
18767cf611SDmitri Tikhonov#include "lsquic_conn.h"
19767cf611SDmitri Tikhonov
20767cf611SDmitri Tikhonovstatic struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0);
21767cf611SDmitri Tikhonov
22fb73393fSDmitri Tikhonovstatic const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_ID27);
23767cf611SDmitri Tikhonov
24767cf611SDmitri Tikhonov
25767cf611SDmitri Tikhonovstatic void
26767cf611SDmitri Tikhonovtest_max_ack (void)
27767cf611SDmitri Tikhonov{
28767cf611SDmitri Tikhonov    lsquic_rechist_t rechist;
29767cf611SDmitri Tikhonov    lsquic_time_t now;
30767cf611SDmitri Tikhonov    unsigned i;
31767cf611SDmitri Tikhonov    int has_missing, sz[2];
32767cf611SDmitri Tikhonov    const struct lsquic_packno_range *range;
33767cf611SDmitri Tikhonov    unsigned char buf[1500];
34767cf611SDmitri Tikhonov    struct ack_info acki;
35767cf611SDmitri Tikhonov
36767cf611SDmitri Tikhonov    lsquic_rechist_init(&rechist, &lconn, 0);
37767cf611SDmitri Tikhonov    now = lsquic_time_now();
38767cf611SDmitri Tikhonov
39767cf611SDmitri Tikhonov    for (i = 1; i <= 300; ++i)
40767cf611SDmitri Tikhonov    {
41767cf611SDmitri Tikhonov        lsquic_rechist_received(&rechist, i * 10, now);
42767cf611SDmitri Tikhonov        now += i * 1000;
43767cf611SDmitri Tikhonov    }
44767cf611SDmitri Tikhonov
45767cf611SDmitri Tikhonov    memset(buf, 0xAA, sizeof(buf));
46767cf611SDmitri Tikhonov
47767cf611SDmitri Tikhonov    lsquic_packno_t largest = 0;
48767cf611SDmitri Tikhonov    sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf),
49767cf611SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
50767cf611SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
51767cf611SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
52767cf611SDmitri Tikhonov        &rechist, now, &has_missing, &largest, NULL);
53767cf611SDmitri Tikhonov    assert(sz[0] > 0);
54767cf611SDmitri Tikhonov    assert(sz[0] <= (int) sizeof(buf));
55767cf611SDmitri Tikhonov    assert(has_missing);
56767cf611SDmitri Tikhonov
57767cf611SDmitri Tikhonov    assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
58767cf611SDmitri Tikhonov    assert(0xAA == buf[ sz[0] ]);
59767cf611SDmitri Tikhonov
60767cf611SDmitri Tikhonov    sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
61767cf611SDmitri Tikhonov    assert(sz[1] == sz[0]);
62767cf611SDmitri Tikhonov    assert(256 == acki.n_ranges);
63767cf611SDmitri Tikhonov
64767cf611SDmitri Tikhonov    for (range = lsquic_rechist_first(&rechist), i = 0;
65767cf611SDmitri Tikhonov                        range && i < acki.n_ranges;
66767cf611SDmitri Tikhonov                                    range = lsquic_rechist_next(&rechist), ++i)
67767cf611SDmitri Tikhonov    {
68767cf611SDmitri Tikhonov        assert(range->high == acki.ranges[i].high);
69767cf611SDmitri Tikhonov        assert(range->low  == acki.ranges[i].low);
70767cf611SDmitri Tikhonov    }
71767cf611SDmitri Tikhonov    assert(i == 256);
72767cf611SDmitri Tikhonov
73767cf611SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
74767cf611SDmitri Tikhonov}
75767cf611SDmitri Tikhonov
76767cf611SDmitri Tikhonov
77767cf611SDmitri Tikhonovstatic void
78767cf611SDmitri Tikhonovtest_ack_truncation (void)
79767cf611SDmitri Tikhonov{
80767cf611SDmitri Tikhonov    lsquic_rechist_t rechist;
81767cf611SDmitri Tikhonov    lsquic_time_t now;
82767cf611SDmitri Tikhonov    unsigned i;
83767cf611SDmitri Tikhonov    int has_missing, sz[2];
84767cf611SDmitri Tikhonov    const struct lsquic_packno_range *range;
85767cf611SDmitri Tikhonov    unsigned char buf[1500];
86767cf611SDmitri Tikhonov    struct ack_info acki;
87767cf611SDmitri Tikhonov    size_t bufsz;
88767cf611SDmitri Tikhonov
89767cf611SDmitri Tikhonov    lsquic_rechist_init(&rechist, &lconn, 0);
90767cf611SDmitri Tikhonov    now = lsquic_time_now();
91767cf611SDmitri Tikhonov
92767cf611SDmitri Tikhonov    for (i = 1; i <= 300; ++i)
93767cf611SDmitri Tikhonov    {
94767cf611SDmitri Tikhonov        lsquic_rechist_received(&rechist, i * 10, now);
95767cf611SDmitri Tikhonov        now += i * 1000;
96767cf611SDmitri Tikhonov    }
97767cf611SDmitri Tikhonov
98767cf611SDmitri Tikhonov    for (bufsz = 200; bufsz < 210; ++bufsz)
99767cf611SDmitri Tikhonov    {
100767cf611SDmitri Tikhonov        memset(buf, 0xAA, sizeof(buf));
101767cf611SDmitri Tikhonov        lsquic_packno_t largest = 0;
102767cf611SDmitri Tikhonov        sz[0] = pf->pf_gen_ack_frame(buf, bufsz,
103767cf611SDmitri Tikhonov            (gaf_rechist_first_f)        lsquic_rechist_first,
104767cf611SDmitri Tikhonov            (gaf_rechist_next_f)         lsquic_rechist_next,
105767cf611SDmitri Tikhonov            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
106767cf611SDmitri Tikhonov            &rechist, now, &has_missing, &largest, NULL);
107767cf611SDmitri Tikhonov        assert(sz[0] > 0);
108767cf611SDmitri Tikhonov        assert(sz[0] <= (int) bufsz);
109767cf611SDmitri Tikhonov        assert(has_missing);
110767cf611SDmitri Tikhonov
111767cf611SDmitri Tikhonov        assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
112767cf611SDmitri Tikhonov        assert(0xAA == buf[ sz[0] ]);
113767cf611SDmitri Tikhonov
114767cf611SDmitri Tikhonov        sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
115767cf611SDmitri Tikhonov        assert(sz[1] == sz[0]);
116767cf611SDmitri Tikhonov        assert(acki.n_ranges < 256);
117767cf611SDmitri Tikhonov
118767cf611SDmitri Tikhonov        for (range = lsquic_rechist_first(&rechist), i = 0;
119767cf611SDmitri Tikhonov                            range && i < acki.n_ranges;
120767cf611SDmitri Tikhonov                                        range = lsquic_rechist_next(&rechist), ++i)
121767cf611SDmitri Tikhonov        {
122767cf611SDmitri Tikhonov            assert(range->high == acki.ranges[i].high);
123767cf611SDmitri Tikhonov            assert(range->low  == acki.ranges[i].low);
124767cf611SDmitri Tikhonov        }
125767cf611SDmitri Tikhonov    }
126767cf611SDmitri Tikhonov
127767cf611SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
128767cf611SDmitri Tikhonov}
129767cf611SDmitri Tikhonov
130767cf611SDmitri Tikhonov
131767cf611SDmitri Tikhonovint
132767cf611SDmitri Tikhonovmain (void)
133767cf611SDmitri Tikhonov{
134767cf611SDmitri Tikhonov    lsquic_global_init(LSQUIC_GLOBAL_SERVER);
135767cf611SDmitri Tikhonov    test_max_ack();
136767cf611SDmitri Tikhonov    test_ack_truncation();
137767cf611SDmitri Tikhonov    return 0;
138767cf611SDmitri Tikhonov}
139