test_ackgen_gquic_be.c revision fb3e20e0
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * Test how ACK frame is encoded.  Receive history module is tested by a
450aadb33SDmitri Tikhonov * separate unit test.
550aadb33SDmitri Tikhonov */
650aadb33SDmitri Tikhonov
750aadb33SDmitri Tikhonov#include <assert.h>
850aadb33SDmitri Tikhonov#include <stdio.h>
950aadb33SDmitri Tikhonov#include <stdlib.h>
1050aadb33SDmitri Tikhonov#include <string.h>
1150aadb33SDmitri Tikhonov
12fb3e20e0SDmitri Tikhonov#ifdef WIN32
13fb3e20e0SDmitri Tikhonov#include "vc_compat.h"
14fb3e20e0SDmitri Tikhonov#endif
15fb3e20e0SDmitri Tikhonov
1650aadb33SDmitri Tikhonov#include "lsquic_types.h"
1750aadb33SDmitri Tikhonov#include "lsquic_int_types.h"
1850aadb33SDmitri Tikhonov#include "lsquic_rechist.h"
1950aadb33SDmitri Tikhonov#include "lsquic_parse.h"
2050aadb33SDmitri Tikhonov#include "lsquic_util.h"
2150aadb33SDmitri Tikhonov#include "lsquic_logger.h"
2250aadb33SDmitri Tikhonov#include "lsquic.h"
2350aadb33SDmitri Tikhonov
24fb96f4ddSDmitri Tikhonovstatic const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043);
2550aadb33SDmitri Tikhonov
2650aadb33SDmitri Tikhonovstatic void
2750aadb33SDmitri Tikhonovtest1 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock */
2850aadb33SDmitri Tikhonov{
2950aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
3050aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
3116a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
3250aadb33SDmitri Tikhonov
335392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
3450aadb33SDmitri Tikhonov
3550aadb33SDmitri Tikhonov    unsigned i;
3650aadb33SDmitri Tikhonov    for (i = 1; i <= 0x1234; ++i)
3750aadb33SDmitri Tikhonov        (void) lsquic_rechist_received(&rechist, i, now);
3850aadb33SDmitri Tikhonov
3950aadb33SDmitri Tikhonov    const unsigned char expected_ack_frame[] = {
4050aadb33SDmitri Tikhonov        0x45,
4150aadb33SDmitri Tikhonov        0x12, 0x34,             /* Largest acked */
4250aadb33SDmitri Tikhonov        0x87, 0xFF,             /* Delta time */
4350aadb33SDmitri Tikhonov        0x12, 0x34,             /* Block length */
4450aadb33SDmitri Tikhonov        0x00,                   /* Number of timestamps */
4550aadb33SDmitri Tikhonov    };
4650aadb33SDmitri Tikhonov    unsigned char outbuf[0x100];
4750aadb33SDmitri Tikhonov
4850aadb33SDmitri Tikhonov    int has_missing = -1;
4950aadb33SDmitri Tikhonov    int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
5050aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
5150aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
5250aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
535392f7a3SLiteSpeed Tech        &rechist, now + 0x7FF8000, &has_missing, &largest, NULL);
5450aadb33SDmitri Tikhonov    assert(("ACK frame generation successful", w > 0));
5550aadb33SDmitri Tikhonov    assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
5650aadb33SDmitri Tikhonov    assert(("ACK frame contents are as expected",
5750aadb33SDmitri Tikhonov        0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
5850aadb33SDmitri Tikhonov    assert(("ACK frame has no missing packets", has_missing == 0));
5916a9b66aSDmitri Tikhonov    assert(largest == 0x1234);
6050aadb33SDmitri Tikhonov
6150aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
6250aadb33SDmitri Tikhonov}
6350aadb33SDmitri Tikhonov
6450aadb33SDmitri Tikhonovstatic void
6550aadb33SDmitri Tikhonovtest2 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock, minus
6650aadb33SDmitri Tikhonov              * delta times.
6750aadb33SDmitri Tikhonov              */
6850aadb33SDmitri Tikhonov{
6950aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
7050aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
7150aadb33SDmitri Tikhonov
725392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
7350aadb33SDmitri Tikhonov
7450aadb33SDmitri Tikhonov    /* Encode the following ranges:
7550aadb33SDmitri Tikhonov     *    high      low
7650aadb33SDmitri Tikhonov     *    0x1234    0x1234
7750aadb33SDmitri Tikhonov     *    0x1232    0x384
7850aadb33SDmitri Tikhonov     *    0x1F3     0xA
7950aadb33SDmitri Tikhonov     *    0x4       0x1
8050aadb33SDmitri Tikhonov     */
8150aadb33SDmitri Tikhonov    unsigned i;
8250aadb33SDmitri Tikhonov    for (i = 4; i >= 1; --i)
8350aadb33SDmitri Tikhonov        (void) lsquic_rechist_received(&rechist, i, now);
8450aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, 0x1234, now);
8550aadb33SDmitri Tikhonov    for (i = 0xA; i <= 0x1F3; ++i)
8650aadb33SDmitri Tikhonov        (void) lsquic_rechist_received(&rechist, i, now);
8750aadb33SDmitri Tikhonov    for (i = 0x1232; i >= 0x384; --i)
8850aadb33SDmitri Tikhonov        (void) lsquic_rechist_received(&rechist, i, now);
8950aadb33SDmitri Tikhonov
9050aadb33SDmitri Tikhonov    const unsigned char expected_ack_frame[] = {
9150aadb33SDmitri Tikhonov        0x65,
9250aadb33SDmitri Tikhonov        0x12, 0x34,                 /* Largest acked */
9350aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
9450aadb33SDmitri Tikhonov        0x04,                       /* Num ack blocks ranges. */
9550aadb33SDmitri Tikhonov        0x00, 0x01,                 /* First ack block length. */
9650aadb33SDmitri Tikhonov        0x01,                       /* Gap to next block. */
9750aadb33SDmitri Tikhonov        0x0e, 0xaf,                 /* Ack block length. */
9850aadb33SDmitri Tikhonov        0xff,                       /* Gap to next block. */
9950aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Ack block length. */
10050aadb33SDmitri Tikhonov        0x91,                       /* Gap to next block. */
10150aadb33SDmitri Tikhonov        0x01, 0xea,                 /* Ack block length. */
10250aadb33SDmitri Tikhonov        0x05,                       /* Gap to next block. */
10350aadb33SDmitri Tikhonov        0x00, 0x04,                 /* Ack block length. */
10450aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
10550aadb33SDmitri Tikhonov    };
10650aadb33SDmitri Tikhonov    unsigned char outbuf[0x100];
10750aadb33SDmitri Tikhonov
10850aadb33SDmitri Tikhonov    int has_missing = -1;
10916a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
11050aadb33SDmitri Tikhonov    int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
11150aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
11250aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
11350aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
1145392f7a3SLiteSpeed Tech        &rechist, now, &has_missing, &largest, NULL);
11550aadb33SDmitri Tikhonov    assert(("ACK frame generation successful", w > 0));
11650aadb33SDmitri Tikhonov    assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
11750aadb33SDmitri Tikhonov    assert(("ACK frame contents are as expected",
11850aadb33SDmitri Tikhonov        0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
11950aadb33SDmitri Tikhonov    assert(("ACK frame has missing packets", has_missing > 0));
12016a9b66aSDmitri Tikhonov    assert(largest == 0x1234);
12150aadb33SDmitri Tikhonov
12250aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
12350aadb33SDmitri Tikhonov}
12450aadb33SDmitri Tikhonov
12550aadb33SDmitri Tikhonovstatic void
12650aadb33SDmitri Tikhonovtest3 (void)
12750aadb33SDmitri Tikhonov{
12850aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
12950aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
13050aadb33SDmitri Tikhonov
1315392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
13250aadb33SDmitri Tikhonov
13350aadb33SDmitri Tikhonov    /* Encode the following ranges:
13450aadb33SDmitri Tikhonov     *    high      low
13550aadb33SDmitri Tikhonov     *    3         3
13650aadb33SDmitri Tikhonov     *    1         1
13750aadb33SDmitri Tikhonov     */
13850aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, 1, now);
13950aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, 3, now);
14050aadb33SDmitri Tikhonov
14150aadb33SDmitri Tikhonov    const unsigned char expected_ack_frame[] = {
14250aadb33SDmitri Tikhonov        0x60,
14350aadb33SDmitri Tikhonov        0x03,
14450aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
14550aadb33SDmitri Tikhonov        0x01,                       /* Num ack blocks ranges. */
14650aadb33SDmitri Tikhonov        0x01,                       /* First ack block length. */
14750aadb33SDmitri Tikhonov        0x01,                       /* Gap to next block. */
14850aadb33SDmitri Tikhonov        0x01,                       /* Ack block length. */
14950aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
15050aadb33SDmitri Tikhonov    };
15150aadb33SDmitri Tikhonov    unsigned char outbuf[0x100];
15250aadb33SDmitri Tikhonov
15350aadb33SDmitri Tikhonov    int has_missing = -1;
15416a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
15550aadb33SDmitri Tikhonov    int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
15650aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
15750aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
15850aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
1595392f7a3SLiteSpeed Tech        &rechist, now, &has_missing, &largest, NULL);
16050aadb33SDmitri Tikhonov    assert(("ACK frame generation successful", w > 0));
16150aadb33SDmitri Tikhonov    assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
16250aadb33SDmitri Tikhonov    assert(("ACK frame contents are as expected",
16350aadb33SDmitri Tikhonov        0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
16450aadb33SDmitri Tikhonov    assert(("ACK frame has missing packets", has_missing > 0));
16516a9b66aSDmitri Tikhonov    assert(largest == 0x03);
16650aadb33SDmitri Tikhonov
16750aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
16850aadb33SDmitri Tikhonov}
16950aadb33SDmitri Tikhonov
17050aadb33SDmitri Tikhonov
17150aadb33SDmitri Tikhonovstatic void
17250aadb33SDmitri Tikhonovtest4 (void)
17350aadb33SDmitri Tikhonov{
17450aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
17550aadb33SDmitri Tikhonov    int i;
17650aadb33SDmitri Tikhonov
1775392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
17850aadb33SDmitri Tikhonov
17950aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
18050aadb33SDmitri Tikhonov    lsquic_rechist_received(&rechist, 1, now);
18150aadb33SDmitri Tikhonov
18250aadb33SDmitri Tikhonov    {
18350aadb33SDmitri Tikhonov        const unsigned char expected_ack_frame[] = {
18450aadb33SDmitri Tikhonov            0x40,
18550aadb33SDmitri Tikhonov            0x01,                   /* Largest acked */
18650aadb33SDmitri Tikhonov            0x00, 0x00,             /* Delta time */
18750aadb33SDmitri Tikhonov            0x01,                   /* Block length */
18850aadb33SDmitri Tikhonov            0x00,                   /* Number of timestamps */
18950aadb33SDmitri Tikhonov        };
19050aadb33SDmitri Tikhonov        unsigned char outbuf[0x100];
19150aadb33SDmitri Tikhonov        int has_missing = -1;
19216a9b66aSDmitri Tikhonov        lsquic_packno_t largest = 0;
19350aadb33SDmitri Tikhonov        int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
19450aadb33SDmitri Tikhonov            (gaf_rechist_first_f)        lsquic_rechist_first,
19550aadb33SDmitri Tikhonov            (gaf_rechist_next_f)         lsquic_rechist_next,
19650aadb33SDmitri Tikhonov            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
1975392f7a3SLiteSpeed Tech            &rechist, now, &has_missing, &largest, NULL);
19850aadb33SDmitri Tikhonov        assert(("ACK frame generation successful", w > 0));
19950aadb33SDmitri Tikhonov        assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
20050aadb33SDmitri Tikhonov        assert(("ACK frame contents are as expected",
20150aadb33SDmitri Tikhonov            0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
20250aadb33SDmitri Tikhonov        assert(("ACK frame has no missing packets", has_missing == 0));
20316a9b66aSDmitri Tikhonov        assert(largest == 1);
20450aadb33SDmitri Tikhonov    }
20550aadb33SDmitri Tikhonov
20650aadb33SDmitri Tikhonov    for (i = 3; i <= 5; ++i)
20750aadb33SDmitri Tikhonov        lsquic_rechist_received(&rechist, i, now);
20850aadb33SDmitri Tikhonov
20950aadb33SDmitri Tikhonov    {
21050aadb33SDmitri Tikhonov        const unsigned char expected_ack_frame[] = {
21150aadb33SDmitri Tikhonov            0x60,
21250aadb33SDmitri Tikhonov            0x05,                   /* Largest acked */
21350aadb33SDmitri Tikhonov            0x00, 0x00,             /* Delta time */
21450aadb33SDmitri Tikhonov            0x01,                   /* Num ack blocks */
21550aadb33SDmitri Tikhonov            0x03,                   /* First block length [3, 5] */
21650aadb33SDmitri Tikhonov            0x01,                   /* Gap to next block */
21750aadb33SDmitri Tikhonov            0x01,                   /* Second block length [1, 1] */
21850aadb33SDmitri Tikhonov            0x00,                   /* Number of timestamps */
21950aadb33SDmitri Tikhonov        };
22050aadb33SDmitri Tikhonov        unsigned char outbuf[0x100];
22150aadb33SDmitri Tikhonov        int has_missing = -1;
22216a9b66aSDmitri Tikhonov        lsquic_packno_t largest = 0;
22350aadb33SDmitri Tikhonov        int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
22450aadb33SDmitri Tikhonov            (gaf_rechist_first_f)        lsquic_rechist_first,
22550aadb33SDmitri Tikhonov            (gaf_rechist_next_f)         lsquic_rechist_next,
22650aadb33SDmitri Tikhonov            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
2275392f7a3SLiteSpeed Tech            &rechist, now, &has_missing, &largest, NULL);
22850aadb33SDmitri Tikhonov        assert(("ACK frame generation successful", w > 0));
22950aadb33SDmitri Tikhonov        assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
23050aadb33SDmitri Tikhonov        assert(("ACK frame contents are as expected",
23150aadb33SDmitri Tikhonov            0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
23250aadb33SDmitri Tikhonov        assert(("ACK frame has missing packets", has_missing > 0));
23316a9b66aSDmitri Tikhonov        assert(largest == 5);
23450aadb33SDmitri Tikhonov    }
23550aadb33SDmitri Tikhonov
23650aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
23750aadb33SDmitri Tikhonov}
23850aadb33SDmitri Tikhonov
23950aadb33SDmitri Tikhonov
24050aadb33SDmitri Tikhonovstatic void
24150aadb33SDmitri Tikhonovtest_4byte_packnos (void)
24250aadb33SDmitri Tikhonov{
24350aadb33SDmitri Tikhonov    lsquic_packno_t packno;
24450aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
24550aadb33SDmitri Tikhonov    struct packet_interval *pint;
24650aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
24750aadb33SDmitri Tikhonov
2485392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
24950aadb33SDmitri Tikhonov
25050aadb33SDmitri Tikhonov    packno = 0x23456789;
25150aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, packno - 33, now);
25250aadb33SDmitri Tikhonov    pint = TAILQ_FIRST(&rechist.rh_pints.pk_intervals);
25350aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, packno, now);
25450aadb33SDmitri Tikhonov
25550aadb33SDmitri Tikhonov    /* Adjust: */
25650aadb33SDmitri Tikhonov    pint->range.low = 1;
25750aadb33SDmitri Tikhonov
25850aadb33SDmitri Tikhonov    const unsigned char expected_ack_frame[] = {
25950aadb33SDmitri Tikhonov        0x60
26050aadb33SDmitri Tikhonov            | (2 << 2)  /* Four-byte largest acked */
26150aadb33SDmitri Tikhonov            | (2 << 0)  /* Four-byte ACK block length */
26250aadb33SDmitri Tikhonov        ,
26350aadb33SDmitri Tikhonov        0x23, 0x45, 0x67, 0x89,
26450aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
26550aadb33SDmitri Tikhonov        0x01,                       /* Num ack blocks ranges. */
26650aadb33SDmitri Tikhonov        0x00, 0x00, 0x00, 0x01,     /* First ack block length. */
26750aadb33SDmitri Tikhonov        33 - 1,                     /* Gap to next block. */
26850aadb33SDmitri Tikhonov        0x23, 0x45, 0x67, 0x68,     /* Ack block length. */
26950aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
27050aadb33SDmitri Tikhonov    };
27150aadb33SDmitri Tikhonov    unsigned char outbuf[0x100];
27250aadb33SDmitri Tikhonov
27350aadb33SDmitri Tikhonov    int has_missing = -1;
27416a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
27550aadb33SDmitri Tikhonov    int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
27650aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
27750aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
27850aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
2795392f7a3SLiteSpeed Tech        &rechist, now, &has_missing, &largest, NULL);
28050aadb33SDmitri Tikhonov    assert(("ACK frame generation successful", w > 0));
28150aadb33SDmitri Tikhonov    assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
28250aadb33SDmitri Tikhonov    assert(("ACK frame contents are as expected",
28350aadb33SDmitri Tikhonov        0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
28450aadb33SDmitri Tikhonov    assert(("ACK frame has missing packets", has_missing > 0));
28516a9b66aSDmitri Tikhonov    assert(largest == 0x23456789);
28650aadb33SDmitri Tikhonov
28750aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
28850aadb33SDmitri Tikhonov}
28950aadb33SDmitri Tikhonov
29050aadb33SDmitri Tikhonov
29150aadb33SDmitri Tikhonovstatic void
29250aadb33SDmitri Tikhonovtest_6byte_packnos (void)
29350aadb33SDmitri Tikhonov{
29450aadb33SDmitri Tikhonov    lsquic_packno_t packno;
29550aadb33SDmitri Tikhonov    lsquic_rechist_t rechist;
29650aadb33SDmitri Tikhonov    struct packet_interval *pint;
29750aadb33SDmitri Tikhonov    lsquic_time_t now = lsquic_time_now();
29850aadb33SDmitri Tikhonov
2995392f7a3SLiteSpeed Tech    lsquic_rechist_init(&rechist, 0, 0);
30050aadb33SDmitri Tikhonov
30150aadb33SDmitri Tikhonov    packno = 0xABCD23456789;
30250aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, packno - 33, now);
30350aadb33SDmitri Tikhonov    pint = TAILQ_FIRST(&rechist.rh_pints.pk_intervals);
30450aadb33SDmitri Tikhonov    (void) lsquic_rechist_received(&rechist, packno, now);
30550aadb33SDmitri Tikhonov
30650aadb33SDmitri Tikhonov    /* Adjust: */
30750aadb33SDmitri Tikhonov    pint->range.low = 1;
30850aadb33SDmitri Tikhonov
30950aadb33SDmitri Tikhonov    const unsigned char expected_ack_frame[] = {
31050aadb33SDmitri Tikhonov        0x60
31150aadb33SDmitri Tikhonov            | (3 << 2)  /* Six-byte largest acked */
31250aadb33SDmitri Tikhonov            | (3 << 0)  /* Six-byte ACK block length */
31350aadb33SDmitri Tikhonov        ,
31450aadb33SDmitri Tikhonov        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89,
31550aadb33SDmitri Tikhonov        0x00, 0x00,                 /* Zero delta time. */
31650aadb33SDmitri Tikhonov        0x01,                       /* Num ack blocks ranges. */
31750aadb33SDmitri Tikhonov        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */
31850aadb33SDmitri Tikhonov        33 - 1,                     /* Gap to next block. */
31950aadb33SDmitri Tikhonov        0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */
32050aadb33SDmitri Tikhonov        0x00,                       /* Number of timestamps. */
32150aadb33SDmitri Tikhonov    };
32250aadb33SDmitri Tikhonov    unsigned char outbuf[0x100];
32350aadb33SDmitri Tikhonov
32450aadb33SDmitri Tikhonov    int has_missing = -1;
32516a9b66aSDmitri Tikhonov    lsquic_packno_t largest = 0;
32650aadb33SDmitri Tikhonov    int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf),
32750aadb33SDmitri Tikhonov        (gaf_rechist_first_f)        lsquic_rechist_first,
32850aadb33SDmitri Tikhonov        (gaf_rechist_next_f)         lsquic_rechist_next,
32950aadb33SDmitri Tikhonov        (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
3305392f7a3SLiteSpeed Tech        &rechist, now, &has_missing, &largest, NULL);
33150aadb33SDmitri Tikhonov    assert(("ACK frame generation successful", w > 0));
33250aadb33SDmitri Tikhonov    assert(("ACK frame length is correct", w == sizeof(expected_ack_frame)));
33350aadb33SDmitri Tikhonov    assert(("ACK frame contents are as expected",
33450aadb33SDmitri Tikhonov        0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame))));
33550aadb33SDmitri Tikhonov    assert(("ACK frame has missing packets", has_missing > 0));
33616a9b66aSDmitri Tikhonov    assert(largest == 0xABCD23456789ULL);
33750aadb33SDmitri Tikhonov
33850aadb33SDmitri Tikhonov    lsquic_rechist_cleanup(&rechist);
33950aadb33SDmitri Tikhonov}
34050aadb33SDmitri Tikhonov
34150aadb33SDmitri Tikhonov
34250aadb33SDmitri Tikhonovint
34350aadb33SDmitri Tikhonovmain (void)
34450aadb33SDmitri Tikhonov{
345c51ce338SDmitri Tikhonov    lsquic_global_init(LSQUIC_GLOBAL_SERVER);
34650aadb33SDmitri Tikhonov    lsquic_log_to_fstream(stderr, 0);
34750aadb33SDmitri Tikhonov    lsq_log_levels[LSQLM_PARSE]   = LSQ_LOG_DEBUG;
34850aadb33SDmitri Tikhonov
34950aadb33SDmitri Tikhonov    test1();
35050aadb33SDmitri Tikhonov
35150aadb33SDmitri Tikhonov    test2();
35250aadb33SDmitri Tikhonov
35350aadb33SDmitri Tikhonov    test3();
35450aadb33SDmitri Tikhonov
35550aadb33SDmitri Tikhonov    test4();
35650aadb33SDmitri Tikhonov
35750aadb33SDmitri Tikhonov    test_4byte_packnos();
35850aadb33SDmitri Tikhonov
35950aadb33SDmitri Tikhonov    test_6byte_packnos();
36050aadb33SDmitri Tikhonov
36150aadb33SDmitri Tikhonov    return 0;
36250aadb33SDmitri Tikhonov}
363