test_ackparse_gquic_be.c revision f38b395a
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <stdio.h>
450aadb33SDmitri Tikhonov#include <stdlib.h>
550aadb33SDmitri Tikhonov#include <string.h>
6b62ec17fSDmitri Tikhonov#include <sys/queue.h>
7461e84d8SAmol Deshpande#ifndef WIN32
850aadb33SDmitri Tikhonov#include <sys/time.h>
9fb3e20e0SDmitri Tikhonov#else
10fb3e20e0SDmitri Tikhonov#include "vc_compat.h"
11461e84d8SAmol Deshpande#endif
1250aadb33SDmitri Tikhonov
1350aadb33SDmitri Tikhonov#include "lsquic_types.h"
1450aadb33SDmitri Tikhonov#include "lsquic_parse.h"
1550aadb33SDmitri Tikhonov#include "lsquic_rechist.h"
1650aadb33SDmitri Tikhonov#include "lsquic_util.h"
1750aadb33SDmitri Tikhonov#include "lsquic.h"
185392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
195392f7a3SLiteSpeed Tech#include "lsquic_conn.h"
205392f7a3SLiteSpeed Tech
215392f7a3SLiteSpeed Techstatic struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0);
2250aadb33SDmitri Tikhonov
23fb96f4ddSDmitri Tikhonovstatic const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043);
2450aadb33SDmitri Tikhonov
2550aadb33SDmitri Tikhonov
2650aadb33SDmitri Tikhonovstatic lsquic_packno_t
275392f7a3SLiteSpeed Techn_acked (const struct ack_info *acki)
2850aadb33SDmitri Tikhonov{
2950aadb33SDmitri Tikhonov    lsquic_packno_t n = 0;
3050aadb33SDmitri Tikhonov    unsigned i;
3150aadb33SDmitri Tikhonov    for (i = 0; i < acki->n_ranges; ++i)
3250aadb33SDmitri Tikhonov        n += acki->ranges[i].high - acki->ranges[i].low + 1;
3350aadb33SDmitri Tikhonov    return n;
3450aadb33SDmitri Tikhonov}
3550aadb33SDmitri Tikhonov
3650aadb33SDmitri Tikhonov
3750aadb33SDmitri Tikhonovstatic void
3850aadb33SDmitri Tikhonovtest1 (void)
3950aadb33SDmitri Tikhonov{
4050aadb33SDmitri Tikhonov    /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */
4150aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
4250aadb33SDmitri Tikhonov        0x45,
4350aadb33SDmitri Tikhonov        0x12, 0x34,             /* Largest acked */
4450aadb33SDmitri Tikhonov        0x00, 0x00,             /* Delta time */
4550aadb33SDmitri Tikhonov        0x12, 0x34,             /* Block length */
4650aadb33SDmitri Tikhonov        0x00,                   /* Number of timestamps */
4750aadb33SDmitri Tikhonov    };
4850aadb33SDmitri Tikhonov
495392f7a3SLiteSpeed Tech    struct ack_info acki;
5050aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
5150aadb33SDmitri Tikhonov
525392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
5350aadb33SDmitri Tikhonov    assert(("Parsed length is correct (8)", len == sizeof(ack_buf)));
5450aadb33SDmitri Tikhonov    assert(("Number of ranges is 1", acki.n_ranges == 1));
5550aadb33SDmitri Tikhonov    assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234));
5650aadb33SDmitri Tikhonov    assert(("Lowest acked is 1", acki.ranges[0].low == 1));
5750aadb33SDmitri Tikhonov    unsigned n = n_acked(&acki);
5850aadb33SDmitri Tikhonov    assert(("Number of acked packets is 0x1234", n == 0x1234));
5950aadb33SDmitri Tikhonov
6050aadb33SDmitri Tikhonov    {
6150aadb33SDmitri Tikhonov        size_t sz;
6250aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
6350aadb33SDmitri Tikhonov        {
645392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
6550aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
6650aadb33SDmitri Tikhonov        }
6750aadb33SDmitri Tikhonov    }
6850aadb33SDmitri Tikhonov}
6950aadb33SDmitri Tikhonov
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonovstatic void
7250aadb33SDmitri Tikhonovtest2 (void)
7350aadb33SDmitri Tikhonov{
7450aadb33SDmitri Tikhonov    /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */
7550aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
7650aadb33SDmitri Tikhonov        0x65,
7750aadb33SDmitri Tikhonov        0x12, 0x34,                 /* Largest acked */
7850aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
7950aadb33SDmitri Tikhonov        0x04,                       /* Num ack blocks ranges. */
8050aadb33SDmitri Tikhonov        0x00, 0x01,                 /* First ack block length. */
8150aadb33SDmitri Tikhonov        0x01,                       /* Gap to next block. */
8250aadb33SDmitri Tikhonov        0x0e, 0xaf,                 /* Ack block length. */
8350aadb33SDmitri Tikhonov        0xff,                       /* Gap to next block. */
8450aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Ack block length. */
8550aadb33SDmitri Tikhonov        0x91,                       /* Gap to next block. */
8650aadb33SDmitri Tikhonov        0x01, 0xea,                 /* Ack block length. */
8750aadb33SDmitri Tikhonov        0x05,                       /* Gap to next block. */
8850aadb33SDmitri Tikhonov        0x00, 0x04,                 /* Ack block length. */
8950aadb33SDmitri Tikhonov        0x02,                       /* Number of timestamps. */
9050aadb33SDmitri Tikhonov        0x01,                       /* Delta from largest observed. */
9150aadb33SDmitri Tikhonov        0x10, 0x32, 0x54, 0x76,     /* Delta time. */   /* XXX do we use this at all? */
9250aadb33SDmitri Tikhonov        0x02,                       /* Delta from largest observed. */
9350aadb33SDmitri Tikhonov        0x10, 0x32,                 /* Delta time. */
9450aadb33SDmitri Tikhonov    };
9550aadb33SDmitri Tikhonov
9650aadb33SDmitri Tikhonov    /* We should get the following array of ranges:
9750aadb33SDmitri Tikhonov     *    high      low
9850aadb33SDmitri Tikhonov     *    0x1234    0x1234
9950aadb33SDmitri Tikhonov     *    0x1232    0x384
10050aadb33SDmitri Tikhonov     *    0x1F3     0xA
10150aadb33SDmitri Tikhonov     *    0x4       0x1
10250aadb33SDmitri Tikhonov     */
10350aadb33SDmitri Tikhonov    static const struct { unsigned high, low; } ranges[] = {
10450aadb33SDmitri Tikhonov        {   0x1234, 0x1234 },
10550aadb33SDmitri Tikhonov        {   0x1232, 0x384 },
10650aadb33SDmitri Tikhonov        {   0x1F3,  0xA },
10750aadb33SDmitri Tikhonov        {   0x4,    0x1 },
10850aadb33SDmitri Tikhonov    };
10950aadb33SDmitri Tikhonov
1105392f7a3SLiteSpeed Tech    struct ack_info acki;
11150aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
11250aadb33SDmitri Tikhonov
1135392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
11450aadb33SDmitri Tikhonov    assert(("Parsed length is correct (29)", len == sizeof(ack_buf)));
11550aadb33SDmitri Tikhonov    assert(("Number of ranges is 4", acki.n_ranges == 4));
11650aadb33SDmitri Tikhonov    assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234));
11750aadb33SDmitri Tikhonov    unsigned n = n_acked(&acki);
11850aadb33SDmitri Tikhonov    assert(("Number of acked packets is 4254", n == 4254));
11950aadb33SDmitri Tikhonov
12050aadb33SDmitri Tikhonov    for (n = 0; n < 4; ++n)
12150aadb33SDmitri Tikhonov        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
12250aadb33SDmitri Tikhonov                                &&  ranges[n].low  == acki.ranges[n].low));
12350aadb33SDmitri Tikhonov
12450aadb33SDmitri Tikhonov    {
12550aadb33SDmitri Tikhonov        size_t sz;
12650aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
12750aadb33SDmitri Tikhonov        {
1285392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
12950aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
13050aadb33SDmitri Tikhonov        }
13150aadb33SDmitri Tikhonov    }
13250aadb33SDmitri Tikhonov}
13350aadb33SDmitri Tikhonov
13450aadb33SDmitri Tikhonov
13550aadb33SDmitri Tikhonovstatic void
13650aadb33SDmitri Tikhonovtest3 (void)
13750aadb33SDmitri Tikhonov{
13850aadb33SDmitri Tikhonov    /* Generated by our own code, but failed to parse... */
13950aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
14050aadb33SDmitri Tikhonov        0x60,         /* More than one ack block, 1 byte largest observed, 1 byte block length */
14150aadb33SDmitri Tikhonov        0x06,         /* Largest ACKed */
14250aadb33SDmitri Tikhonov        0x00, 0x00,   /* Delta time */
14350aadb33SDmitri Tikhonov        0x01,         /* Num ACK block ranges */
14450aadb33SDmitri Tikhonov        0x01,         /* First ACK block length */
14550aadb33SDmitri Tikhonov        0x02,         /* Gap to next block */
14650aadb33SDmitri Tikhonov        0x03,         /* Ack block length */
14750aadb33SDmitri Tikhonov        0x00          /* Number of timestamps */
14850aadb33SDmitri Tikhonov    };
14950aadb33SDmitri Tikhonov
15050aadb33SDmitri Tikhonov    /* We should get the following array of ranges:
15150aadb33SDmitri Tikhonov     *    high      low
15250aadb33SDmitri Tikhonov     *    6         6
15350aadb33SDmitri Tikhonov     *    3         1
15450aadb33SDmitri Tikhonov     */
15550aadb33SDmitri Tikhonov    static const struct { unsigned high, low; } ranges[] = {
15650aadb33SDmitri Tikhonov        {   6,      6, },
15750aadb33SDmitri Tikhonov        {   3,      1, },
15850aadb33SDmitri Tikhonov    };
15950aadb33SDmitri Tikhonov
1605392f7a3SLiteSpeed Tech    struct ack_info acki;
16150aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
16250aadb33SDmitri Tikhonov
1635392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
16450aadb33SDmitri Tikhonov    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
16550aadb33SDmitri Tikhonov    assert(("Number of ranges is 2", acki.n_ranges == 2));
16650aadb33SDmitri Tikhonov    assert(("Largest acked is 6", acki.ranges[0].high == 6));
16750aadb33SDmitri Tikhonov    unsigned n = n_acked(&acki);
16850aadb33SDmitri Tikhonov    assert(("Number of acked packets is 4", n == 4));
16950aadb33SDmitri Tikhonov
17050aadb33SDmitri Tikhonov    for (n = 0; n < 2; ++n)
17150aadb33SDmitri Tikhonov        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
17250aadb33SDmitri Tikhonov                                &&  ranges[n].low  == acki.ranges[n].low));
17350aadb33SDmitri Tikhonov
17450aadb33SDmitri Tikhonov    {
17550aadb33SDmitri Tikhonov        size_t sz;
17650aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
17750aadb33SDmitri Tikhonov        {
1785392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
17950aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
18050aadb33SDmitri Tikhonov        }
18150aadb33SDmitri Tikhonov    }
18250aadb33SDmitri Tikhonov}
18350aadb33SDmitri Tikhonov
18450aadb33SDmitri Tikhonov
18550aadb33SDmitri Tikhonovstatic void
18650aadb33SDmitri Tikhonovtest4 (void)
18750aadb33SDmitri Tikhonov{
18850aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
18950aadb33SDmitri Tikhonov        0x60,       /* More than one ack block, 1 byte largest observed, 1 byte block length */
19050aadb33SDmitri Tikhonov        0x03,       /* Largest ACKed */
19150aadb33SDmitri Tikhonov        0x23, 0x00, /* Delta time */
19250aadb33SDmitri Tikhonov        0x01,       /* Num ACK block ranges */
19350aadb33SDmitri Tikhonov        0x01,       /* First ack block length */
19450aadb33SDmitri Tikhonov        0x01,       /* Gap */
19550aadb33SDmitri Tikhonov        0x01,       /* Ack block length */
19650aadb33SDmitri Tikhonov        0x00,       /* Number of timestamps */
19750aadb33SDmitri Tikhonov    };
19850aadb33SDmitri Tikhonov
19950aadb33SDmitri Tikhonov    /* We should get the following array of ranges:
20050aadb33SDmitri Tikhonov     *    high      low
20150aadb33SDmitri Tikhonov     *    6         6
20250aadb33SDmitri Tikhonov     *    3         1
20350aadb33SDmitri Tikhonov     */
20450aadb33SDmitri Tikhonov    static const struct { unsigned high, low; } ranges[] = {
20550aadb33SDmitri Tikhonov        {   3,      3, },
20650aadb33SDmitri Tikhonov        {   1,      1, },
20750aadb33SDmitri Tikhonov    };
20850aadb33SDmitri Tikhonov
2095392f7a3SLiteSpeed Tech    struct ack_info acki;
21050aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
21150aadb33SDmitri Tikhonov
2125392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
21350aadb33SDmitri Tikhonov    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
21450aadb33SDmitri Tikhonov    assert(("Number of ranges is 2", acki.n_ranges == 2));
21550aadb33SDmitri Tikhonov    assert(("Largest acked is 3", acki.ranges[0].high == 3));
21650aadb33SDmitri Tikhonov    unsigned n = n_acked(&acki);
21750aadb33SDmitri Tikhonov    assert(("Number of acked packets is 2", n == 2));
21850aadb33SDmitri Tikhonov
21950aadb33SDmitri Tikhonov    for (n = 0; n < 2; ++n)
22050aadb33SDmitri Tikhonov        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
22150aadb33SDmitri Tikhonov                                &&  ranges[n].low  == acki.ranges[n].low));
22250aadb33SDmitri Tikhonov
22350aadb33SDmitri Tikhonov    {
22450aadb33SDmitri Tikhonov        size_t sz;
22550aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
22650aadb33SDmitri Tikhonov        {
2275392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
22850aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
22950aadb33SDmitri Tikhonov        }
23050aadb33SDmitri Tikhonov    }
23150aadb33SDmitri Tikhonov}
23250aadb33SDmitri Tikhonov
23350aadb33SDmitri Tikhonov
23450aadb33SDmitri Tikhonov/* Four-byte packet numbers */
23550aadb33SDmitri Tikhonovstatic void
23650aadb33SDmitri Tikhonovtest5 (void)
23750aadb33SDmitri Tikhonov{
23850aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
23950aadb33SDmitri Tikhonov        0x60
24050aadb33SDmitri Tikhonov            | (2 << 2)  /* Four-byte largest acked */
24150aadb33SDmitri Tikhonov            | (2 << 0)  /* Four-byte ACK block length */
24250aadb33SDmitri Tikhonov        ,
24350aadb33SDmitri Tikhonov        0x23, 0x45, 0x67, 0x89,
24450aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
24550aadb33SDmitri Tikhonov        0x01,                       /* Num ack blocks ranges. */
24650aadb33SDmitri Tikhonov        0x00, 0x00, 0x00, 0x01,     /* First ack block length. */
24750aadb33SDmitri Tikhonov        33 - 1,                     /* Gap to next block. */
24850aadb33SDmitri Tikhonov        0x23, 0x45, 0x67, 0x68,     /* Ack block length. */
24950aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
25050aadb33SDmitri Tikhonov    };
25150aadb33SDmitri Tikhonov
25250aadb33SDmitri Tikhonov    /* We should get the following array of ranges:
25350aadb33SDmitri Tikhonov     *    high      low
25450aadb33SDmitri Tikhonov     *    6         6
25550aadb33SDmitri Tikhonov     *    3         1
25650aadb33SDmitri Tikhonov     */
25750aadb33SDmitri Tikhonov    static const struct { unsigned high, low; } ranges[] = {
25850aadb33SDmitri Tikhonov        {   0x23456789,      0x23456789, },
25950aadb33SDmitri Tikhonov        {   0x23456768,      1, },
26050aadb33SDmitri Tikhonov    };
26150aadb33SDmitri Tikhonov
2625392f7a3SLiteSpeed Tech    struct ack_info acki;
26350aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
26450aadb33SDmitri Tikhonov
2655392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
26650aadb33SDmitri Tikhonov    assert(("Parsed length is correct (9)", len == sizeof(ack_buf)));
26750aadb33SDmitri Tikhonov    assert(("Number of ranges is 2", acki.n_ranges == 2));
26850aadb33SDmitri Tikhonov    assert(("Largest acked is 0x23456789", acki.ranges[0].high == 0x23456789));
26950aadb33SDmitri Tikhonov    lsquic_packno_t n = n_acked(&acki);
27050aadb33SDmitri Tikhonov    assert(("Number of acked packets is correct", n == 0x23456768 + 1));
27150aadb33SDmitri Tikhonov
27250aadb33SDmitri Tikhonov    for (n = 0; n < 2; ++n)
27350aadb33SDmitri Tikhonov        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
27450aadb33SDmitri Tikhonov                                &&  ranges[n].low  == acki.ranges[n].low));
27550aadb33SDmitri Tikhonov
27650aadb33SDmitri Tikhonov    {
27750aadb33SDmitri Tikhonov        size_t sz;
27850aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
27950aadb33SDmitri Tikhonov        {
2805392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
28150aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
28250aadb33SDmitri Tikhonov        }
28350aadb33SDmitri Tikhonov    }
28450aadb33SDmitri Tikhonov}
28550aadb33SDmitri Tikhonov
28650aadb33SDmitri Tikhonov
28750aadb33SDmitri Tikhonov/* Six-byte packet numbers */
28850aadb33SDmitri Tikhonovstatic void
28950aadb33SDmitri Tikhonovtest6 (void)
29050aadb33SDmitri Tikhonov{
29150aadb33SDmitri Tikhonov    unsigned char ack_buf[] = {
29250aadb33SDmitri Tikhonov        0x60
29350aadb33SDmitri Tikhonov            | (3 << 2)  /* Six-byte largest acked */
29450aadb33SDmitri Tikhonov            | (3 << 0)  /* Six-byte ACK block length */
29550aadb33SDmitri Tikhonov        ,
29650aadb33SDmitri Tikhonov        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89,
29750aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
29850aadb33SDmitri Tikhonov        0x01,                       /* Num ack blocks ranges. */
29950aadb33SDmitri Tikhonov        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */
30050aadb33SDmitri Tikhonov        33 - 1,                     /* Gap to next block. */
30150aadb33SDmitri Tikhonov        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */
30250aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
30350aadb33SDmitri Tikhonov    };
30450aadb33SDmitri Tikhonov
30550aadb33SDmitri Tikhonov    static const struct { lsquic_packno_t high, low; } ranges[] = {
30650aadb33SDmitri Tikhonov        {   0xABCD23456789,      0xABCD23456789, },
30750aadb33SDmitri Tikhonov        {   0xABCD23456768,      1, },
30850aadb33SDmitri Tikhonov    };
30950aadb33SDmitri Tikhonov
3105392f7a3SLiteSpeed Tech    struct ack_info acki;
31150aadb33SDmitri Tikhonov    memset(&acki, 0xF1, sizeof(acki));
31250aadb33SDmitri Tikhonov
3135392f7a3SLiteSpeed Tech    int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0);
31450aadb33SDmitri Tikhonov    assert(("Parsed length is correct", len == sizeof(ack_buf)));
31550aadb33SDmitri Tikhonov    assert(("Number of ranges is 2", acki.n_ranges == 2));
31650aadb33SDmitri Tikhonov    assert(("Largest acked is 0xABCD23456789", acki.ranges[0].high == 0xABCD23456789));
31750aadb33SDmitri Tikhonov    lsquic_packno_t n = n_acked(&acki);
31850aadb33SDmitri Tikhonov    assert(("Number of acked packets is correct", n == 0xABCD23456768 + 1));
31950aadb33SDmitri Tikhonov
32050aadb33SDmitri Tikhonov    for (n = 0; n < 2; ++n)
32150aadb33SDmitri Tikhonov        assert(("Range checks out", ranges[n].high == acki.ranges[n].high
32250aadb33SDmitri Tikhonov                                &&  ranges[n].low  == acki.ranges[n].low));
32350aadb33SDmitri Tikhonov
32450aadb33SDmitri Tikhonov    {
32550aadb33SDmitri Tikhonov        size_t sz;
32650aadb33SDmitri Tikhonov        for (sz = 1; sz < sizeof(ack_buf); ++sz)
32750aadb33SDmitri Tikhonov        {
3285392f7a3SLiteSpeed Tech            len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0);
32950aadb33SDmitri Tikhonov            assert(("Parsing truncated frame failed", len < 0));
33050aadb33SDmitri Tikhonov        }
33150aadb33SDmitri Tikhonov    }
33250aadb33SDmitri Tikhonov}
33350aadb33SDmitri Tikhonov
33450aadb33SDmitri Tikhonov
33550aadb33SDmitri Tikhonovstatic void
33650aadb33SDmitri Tikhonovtest_max_ack (void)
33750aadb33SDmitri Tikhonov{
33850aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
33950aadb33SDmitri Tikhonov    lsquic_time_t now;
34050aadb33SDmitri Tikhonov    unsigned i;
34150aadb33SDmitri Tikhonov    int has_missing, sz[2];
34250aadb33SDmitri Tikhonov    const struct lsquic_packno_range *range;
34350aadb33SDmitri Tikhonov    unsigned char buf[1500];
34450aadb33SDmitri Tikhonov    struct ack_info acki;
34550aadb33SDmitri Tikhonov
346f38b395aSDmitri Tikhonov    lsquic_rechist_init(&rechist, 0, 0);
34750aadb33SDmitri Tikhonov    now = lsquic_time_now();
34850aadb33SDmitri Tikhonov
34950aadb33SDmitri Tikhonov    for (i = 1; i <= 300; ++i)
35050aadb33SDmitri Tikhonov    {
35150aadb33SDmitri Tikhonov        lsquic_rechist_received(&rechist, i * 10, now);
35250aadb33SDmitri Tikhonov        now += i * 1000;
35350aadb33SDmitri Tikhonov    }
35450aadb33SDmitri Tikhonov
35550aadb33SDmitri Tikhonov    memset(buf, 0xAA, sizeof(buf));
35650aadb33SDmitri Tikhonov
35716a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
35850aadb33SDmitri Tikhonov    sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf),
35950aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
36050aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
36150aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
3625392f7a3SLiteSpeed Tech        &rechist, now, &has_missing, &largest, NULL);
36350aadb33SDmitri Tikhonov    assert(sz[0] > 0);
36450aadb33SDmitri Tikhonov    assert(sz[0] <= (int) sizeof(buf));
36550aadb33SDmitri Tikhonov    assert(has_missing);
36650aadb33SDmitri Tikhonov
36750aadb33SDmitri Tikhonov    assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
36850aadb33SDmitri Tikhonov    assert(0xAA == buf[ sz[0] ]);
36950aadb33SDmitri Tikhonov
3705392f7a3SLiteSpeed Tech    sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
37150aadb33SDmitri Tikhonov    assert(sz[1] == sz[0]);
37250aadb33SDmitri Tikhonov    assert(256 == acki.n_ranges);
37350aadb33SDmitri Tikhonov
37450aadb33SDmitri Tikhonov    for (range = lsquic_rechist_first(&rechist), i = 0;
37550aadb33SDmitri Tikhonov                        range && i < acki.n_ranges;
37650aadb33SDmitri Tikhonov                                    range = lsquic_rechist_next(&rechist), ++i)
37750aadb33SDmitri Tikhonov    {
37850aadb33SDmitri Tikhonov        assert(range->high == acki.ranges[i].high);
37950aadb33SDmitri Tikhonov        assert(range->low  == acki.ranges[i].low);
38050aadb33SDmitri Tikhonov    }
38150aadb33SDmitri Tikhonov    assert(i == 256);
38250aadb33SDmitri Tikhonov
38350aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
38450aadb33SDmitri Tikhonov}
38550aadb33SDmitri Tikhonov
38650aadb33SDmitri Tikhonov
38750aadb33SDmitri Tikhonovstatic void
38850aadb33SDmitri Tikhonovtest_ack_truncation (void)
38950aadb33SDmitri Tikhonov{
39050aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
39150aadb33SDmitri Tikhonov    lsquic_time_t now;
39250aadb33SDmitri Tikhonov    unsigned i;
39350aadb33SDmitri Tikhonov    int has_missing, sz[2];
39450aadb33SDmitri Tikhonov    const struct lsquic_packno_range *range;
39550aadb33SDmitri Tikhonov    unsigned char buf[1500];
39650aadb33SDmitri Tikhonov    struct ack_info acki;
39750aadb33SDmitri Tikhonov    size_t bufsz;
39850aadb33SDmitri Tikhonov
399f38b395aSDmitri Tikhonov    lsquic_rechist_init(&rechist, 0, 0);
40050aadb33SDmitri Tikhonov    now = lsquic_time_now();
40150aadb33SDmitri Tikhonov
40250aadb33SDmitri Tikhonov    for (i = 1; i <= 300; ++i)
40350aadb33SDmitri Tikhonov    {
40450aadb33SDmitri Tikhonov        lsquic_rechist_received(&rechist, i * 10, now);
40550aadb33SDmitri Tikhonov        now += i * 1000;
40650aadb33SDmitri Tikhonov    }
40750aadb33SDmitri Tikhonov
40850aadb33SDmitri Tikhonov    for (bufsz = 200; bufsz < 210; ++bufsz)
40950aadb33SDmitri Tikhonov    {
41050aadb33SDmitri Tikhonov        memset(buf, 0xAA, sizeof(buf));
41116a9b66aSDmitri Tikhonov        lsquic_packno_t largest = 0;
41250aadb33SDmitri Tikhonov        sz[0] = pf->pf_gen_ack_frame(buf, bufsz,
41350aadb33SDmitri Tikhonov            (gaf_rechist_first_f)        lsquic_rechist_first,
41450aadb33SDmitri Tikhonov            (gaf_rechist_next_f)         lsquic_rechist_next,
41550aadb33SDmitri Tikhonov            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
4165392f7a3SLiteSpeed Tech            &rechist, now, &has_missing, &largest, NULL);
41750aadb33SDmitri Tikhonov        assert(sz[0] > 0);
41850aadb33SDmitri Tikhonov        assert(sz[0] <= (int) bufsz);
41950aadb33SDmitri Tikhonov        assert(has_missing);
42050aadb33SDmitri Tikhonov
42150aadb33SDmitri Tikhonov        assert(0 == buf[ sz[0] - 1 ]);  /* Number of timestamps */
42250aadb33SDmitri Tikhonov        assert(0xAA == buf[ sz[0] ]);
42350aadb33SDmitri Tikhonov
4245392f7a3SLiteSpeed Tech        sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
42550aadb33SDmitri Tikhonov        assert(sz[1] == sz[0]);
42650aadb33SDmitri Tikhonov        assert(acki.n_ranges < 256);
42750aadb33SDmitri Tikhonov
42850aadb33SDmitri Tikhonov        for (range = lsquic_rechist_first(&rechist), i = 0;
42950aadb33SDmitri Tikhonov                            range && i < acki.n_ranges;
43050aadb33SDmitri Tikhonov                                        range = lsquic_rechist_next(&rechist), ++i)
43150aadb33SDmitri Tikhonov        {
43250aadb33SDmitri Tikhonov            assert(range->high == acki.ranges[i].high);
43350aadb33SDmitri Tikhonov            assert(range->low  == acki.ranges[i].low);
43450aadb33SDmitri Tikhonov        }
43550aadb33SDmitri Tikhonov    }
43650aadb33SDmitri Tikhonov
43750aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
43850aadb33SDmitri Tikhonov}
43950aadb33SDmitri Tikhonov
44050aadb33SDmitri Tikhonov
4415392f7a3SLiteSpeed Techstatic void
4425392f7a3SLiteSpeed Techtest_empty_ack (void)
4435392f7a3SLiteSpeed Tech{
4445392f7a3SLiteSpeed Tech    int len;
4455392f7a3SLiteSpeed Tech    unsigned char buf[] = { 0x40, 0x00, 0xFF, 0xFF, 0x00, 0x00,
4465392f7a3SLiteSpeed Tech                            /* fluff: */ 0x12, 0x23, 0x34, 0x45, };
4475392f7a3SLiteSpeed Tech    struct ack_info acki;
4485392f7a3SLiteSpeed Tech
4495392f7a3SLiteSpeed Tech    len = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0);
4505392f7a3SLiteSpeed Tech    assert(6 == len);
4515392f7a3SLiteSpeed Tech    assert(empty_ack_frame(&acki));
4525392f7a3SLiteSpeed Tech}
4535392f7a3SLiteSpeed Tech
4545392f7a3SLiteSpeed Tech
45550aadb33SDmitri Tikhonovint
45650aadb33SDmitri Tikhonovmain (void)
45750aadb33SDmitri Tikhonov{
458c51ce338SDmitri Tikhonov    lsquic_global_init(LSQUIC_GLOBAL_SERVER);
45950aadb33SDmitri Tikhonov    test1();
46050aadb33SDmitri Tikhonov    test2();
46150aadb33SDmitri Tikhonov    test3();
46250aadb33SDmitri Tikhonov    test4();
46350aadb33SDmitri Tikhonov    test5();
46450aadb33SDmitri Tikhonov    test6();
46550aadb33SDmitri Tikhonov    test_max_ack();
46650aadb33SDmitri Tikhonov    test_ack_truncation();
4675392f7a3SLiteSpeed Tech    test_empty_ack();
46850aadb33SDmitri Tikhonov    return 0;
46950aadb33SDmitri Tikhonov}
470