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