1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 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 24f07b3eaeSTyler Young//static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043); // will not work on MSVC 25f07b3eaeSTyler Young#define pf ((const struct parse_funcs *const)select_pf_by_ver(LSQVER_043)) 2650aadb33SDmitri Tikhonov 2750aadb33SDmitri Tikhonovstatic void 2850aadb33SDmitri Tikhonovtest1 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock */ 2950aadb33SDmitri Tikhonov{ 3050aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 3150aadb33SDmitri Tikhonov lsquic_time_t now = lsquic_time_now(); 3216a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 3350aadb33SDmitri Tikhonov 34f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 3550aadb33SDmitri Tikhonov 3650aadb33SDmitri Tikhonov unsigned i; 3750aadb33SDmitri Tikhonov for (i = 1; i <= 0x1234; ++i) 3850aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, i, now); 3950aadb33SDmitri Tikhonov 4050aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 4150aadb33SDmitri Tikhonov 0x45, 4250aadb33SDmitri Tikhonov 0x12, 0x34, /* Largest acked */ 4350aadb33SDmitri Tikhonov 0x87, 0xFF, /* Delta time */ 4450aadb33SDmitri Tikhonov 0x12, 0x34, /* Block length */ 4550aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 4650aadb33SDmitri Tikhonov }; 4750aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 4850aadb33SDmitri Tikhonov 4950aadb33SDmitri Tikhonov int has_missing = -1; 5050aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 5150aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 5250aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 5350aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 545392f7a3SLiteSpeed Tech &rechist, now + 0x7FF8000, &has_missing, &largest, NULL); 5550aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 5650aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 5750aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 5850aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 5950aadb33SDmitri Tikhonov assert(("ACK frame has no missing packets", has_missing == 0)); 6016a9b66aSDmitri Tikhonov assert(largest == 0x1234); 6150aadb33SDmitri Tikhonov 6250aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 6350aadb33SDmitri Tikhonov} 6450aadb33SDmitri Tikhonov 6550aadb33SDmitri Tikhonovstatic void 6650aadb33SDmitri Tikhonovtest2 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock, minus 6750aadb33SDmitri Tikhonov * delta times. 6850aadb33SDmitri Tikhonov */ 6950aadb33SDmitri Tikhonov{ 7050aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 7150aadb33SDmitri Tikhonov lsquic_time_t now = lsquic_time_now(); 7250aadb33SDmitri Tikhonov 73f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 7450aadb33SDmitri Tikhonov 7550aadb33SDmitri Tikhonov /* Encode the following ranges: 7650aadb33SDmitri Tikhonov * high low 7750aadb33SDmitri Tikhonov * 0x1234 0x1234 7850aadb33SDmitri Tikhonov * 0x1232 0x384 7950aadb33SDmitri Tikhonov * 0x1F3 0xA 8050aadb33SDmitri Tikhonov * 0x4 0x1 8150aadb33SDmitri Tikhonov */ 8250aadb33SDmitri Tikhonov unsigned i; 8350aadb33SDmitri Tikhonov for (i = 4; i >= 1; --i) 8450aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, i, now); 8550aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, 0x1234, now); 8650aadb33SDmitri Tikhonov for (i = 0xA; i <= 0x1F3; ++i) 8750aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, i, now); 8850aadb33SDmitri Tikhonov for (i = 0x1232; i >= 0x384; --i) 8950aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, i, now); 9050aadb33SDmitri Tikhonov 9150aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 9250aadb33SDmitri Tikhonov 0x65, 9350aadb33SDmitri Tikhonov 0x12, 0x34, /* Largest acked */ 9450aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 9550aadb33SDmitri Tikhonov 0x04, /* Num ack blocks ranges. */ 9650aadb33SDmitri Tikhonov 0x00, 0x01, /* First ack block length. */ 9750aadb33SDmitri Tikhonov 0x01, /* Gap to next block. */ 9850aadb33SDmitri Tikhonov 0x0e, 0xaf, /* Ack block length. */ 9950aadb33SDmitri Tikhonov 0xff, /* Gap to next block. */ 10050aadb33SDmitri Tikhonov 0x00, 0x00, /* Ack block length. */ 10150aadb33SDmitri Tikhonov 0x91, /* Gap to next block. */ 10250aadb33SDmitri Tikhonov 0x01, 0xea, /* Ack block length. */ 10350aadb33SDmitri Tikhonov 0x05, /* Gap to next block. */ 10450aadb33SDmitri Tikhonov 0x00, 0x04, /* Ack block length. */ 10550aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 10650aadb33SDmitri Tikhonov }; 10750aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 10850aadb33SDmitri Tikhonov 10950aadb33SDmitri Tikhonov int has_missing = -1; 11016a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 11150aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 11250aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 11350aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 11450aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 1155392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 11650aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 11750aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 11850aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 11950aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 12050aadb33SDmitri Tikhonov assert(("ACK frame has missing packets", has_missing > 0)); 12116a9b66aSDmitri Tikhonov assert(largest == 0x1234); 12250aadb33SDmitri Tikhonov 12350aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 12450aadb33SDmitri Tikhonov} 12550aadb33SDmitri Tikhonov 12650aadb33SDmitri Tikhonovstatic void 12750aadb33SDmitri Tikhonovtest3 (void) 12850aadb33SDmitri Tikhonov{ 12950aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 13050aadb33SDmitri Tikhonov lsquic_time_t now = lsquic_time_now(); 13150aadb33SDmitri Tikhonov 132f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 13350aadb33SDmitri Tikhonov 13450aadb33SDmitri Tikhonov /* Encode the following ranges: 13550aadb33SDmitri Tikhonov * high low 13650aadb33SDmitri Tikhonov * 3 3 13750aadb33SDmitri Tikhonov * 1 1 13850aadb33SDmitri Tikhonov */ 13950aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, 1, now); 14050aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, 3, now); 14150aadb33SDmitri Tikhonov 14250aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 14350aadb33SDmitri Tikhonov 0x60, 14450aadb33SDmitri Tikhonov 0x03, 14550aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 14650aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 14750aadb33SDmitri Tikhonov 0x01, /* First ack block length. */ 14850aadb33SDmitri Tikhonov 0x01, /* Gap to next block. */ 14950aadb33SDmitri Tikhonov 0x01, /* Ack block length. */ 15050aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 15150aadb33SDmitri Tikhonov }; 15250aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 15350aadb33SDmitri Tikhonov 15450aadb33SDmitri Tikhonov int has_missing = -1; 15516a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 15650aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 15750aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 15850aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 15950aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 1605392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 16150aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 16250aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 16350aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 16450aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 16550aadb33SDmitri Tikhonov assert(("ACK frame has missing packets", has_missing > 0)); 16616a9b66aSDmitri Tikhonov assert(largest == 0x03); 16750aadb33SDmitri Tikhonov 16850aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 16950aadb33SDmitri Tikhonov} 17050aadb33SDmitri Tikhonov 17150aadb33SDmitri Tikhonov 17250aadb33SDmitri Tikhonovstatic void 17350aadb33SDmitri Tikhonovtest4 (void) 17450aadb33SDmitri Tikhonov{ 17550aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 17650aadb33SDmitri Tikhonov int i; 17750aadb33SDmitri Tikhonov 178f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 17950aadb33SDmitri Tikhonov 18050aadb33SDmitri Tikhonov lsquic_time_t now = lsquic_time_now(); 18150aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, 1, now); 18250aadb33SDmitri Tikhonov 18350aadb33SDmitri Tikhonov { 18450aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 18550aadb33SDmitri Tikhonov 0x40, 18650aadb33SDmitri Tikhonov 0x01, /* Largest acked */ 18750aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 18850aadb33SDmitri Tikhonov 0x01, /* Block length */ 18950aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 19050aadb33SDmitri Tikhonov }; 19150aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 19250aadb33SDmitri Tikhonov int has_missing = -1; 19316a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 19450aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 19550aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 19650aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 19750aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 1985392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 19950aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 20050aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 20150aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 20250aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 20350aadb33SDmitri Tikhonov assert(("ACK frame has no missing packets", has_missing == 0)); 20416a9b66aSDmitri Tikhonov assert(largest == 1); 20550aadb33SDmitri Tikhonov } 20650aadb33SDmitri Tikhonov 20750aadb33SDmitri Tikhonov for (i = 3; i <= 5; ++i) 20850aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, i, now); 20950aadb33SDmitri Tikhonov 21050aadb33SDmitri Tikhonov { 21150aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 21250aadb33SDmitri Tikhonov 0x60, 21350aadb33SDmitri Tikhonov 0x05, /* Largest acked */ 21450aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 21550aadb33SDmitri Tikhonov 0x01, /* Num ack blocks */ 21650aadb33SDmitri Tikhonov 0x03, /* First block length [3, 5] */ 21750aadb33SDmitri Tikhonov 0x01, /* Gap to next block */ 21850aadb33SDmitri Tikhonov 0x01, /* Second block length [1, 1] */ 21950aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 22050aadb33SDmitri Tikhonov }; 22150aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 22250aadb33SDmitri Tikhonov int has_missing = -1; 22316a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 22450aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 22550aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 22650aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 22750aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 2285392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 22950aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 23050aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 23150aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 23250aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 23350aadb33SDmitri Tikhonov assert(("ACK frame has missing packets", has_missing > 0)); 23416a9b66aSDmitri Tikhonov assert(largest == 5); 23550aadb33SDmitri Tikhonov } 23650aadb33SDmitri Tikhonov 23750aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 23850aadb33SDmitri Tikhonov} 23950aadb33SDmitri Tikhonov 24050aadb33SDmitri Tikhonov 24150aadb33SDmitri Tikhonovstatic void 24250aadb33SDmitri Tikhonovtest_4byte_packnos (void) 24350aadb33SDmitri Tikhonov{ 24450aadb33SDmitri Tikhonov lsquic_packno_t packno; 24550aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 24650aadb33SDmitri Tikhonov lsquic_time_t now = lsquic_time_now(); 24750aadb33SDmitri Tikhonov 248f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 24950aadb33SDmitri Tikhonov 25050aadb33SDmitri Tikhonov packno = 0x23456789; 25150aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, packno - 33, now); 25250aadb33SDmitri Tikhonov (void) lsquic_rechist_received(&rechist, packno, now); 25350aadb33SDmitri Tikhonov 25450aadb33SDmitri Tikhonov /* Adjust: */ 255b62ec17fSDmitri Tikhonov rechist.rh_elems[0].re_low = 1; 256b62ec17fSDmitri Tikhonov rechist.rh_elems[0].re_count = packno - 33; 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 291b62ec17fSDmitri Tikhonov/* lsquic_rechist no longer supports ranges that require integers 292b62ec17fSDmitri Tikhonov * wider than four bytes -- modify the test to use a custom receive 293b62ec17fSDmitri Tikhonov * history. 294b62ec17fSDmitri Tikhonov */ 295b62ec17fSDmitri Tikhonovstatic const struct lsquic_packno_range test_6byte_ranges[] = { 296b62ec17fSDmitri Tikhonov { .high = 0xABCD23456789, .low = 0xABCD23456789, }, 297b62ec17fSDmitri Tikhonov { .high = 0xABCD23456789 - 33, .low = 1, }, 298b62ec17fSDmitri Tikhonov}; 299b62ec17fSDmitri Tikhonov 300b62ec17fSDmitri Tikhonov 301b62ec17fSDmitri Tikhonovstatic const struct lsquic_packno_range * 302b62ec17fSDmitri Tikhonovtest_6byte_rechist_first (void *rechist) 30350aadb33SDmitri Tikhonov{ 304b62ec17fSDmitri Tikhonov int *next = rechist; 305b62ec17fSDmitri Tikhonov *next = 1; 306b62ec17fSDmitri Tikhonov return &test_6byte_ranges[0]; 307b62ec17fSDmitri Tikhonov}; 30850aadb33SDmitri Tikhonov 30950aadb33SDmitri Tikhonov 310b62ec17fSDmitri Tikhonovstatic const struct lsquic_packno_range * 311b62ec17fSDmitri Tikhonovtest_6byte_rechist_next (void *rechist) 312b62ec17fSDmitri Tikhonov{ 313b62ec17fSDmitri Tikhonov int *next = rechist; 314b62ec17fSDmitri Tikhonov if (*next == 1) 315b62ec17fSDmitri Tikhonov { 316b62ec17fSDmitri Tikhonov ++*next; 317b62ec17fSDmitri Tikhonov return &test_6byte_ranges[1]; 318b62ec17fSDmitri Tikhonov } 319b62ec17fSDmitri Tikhonov else 320b62ec17fSDmitri Tikhonov return NULL; 321b62ec17fSDmitri Tikhonov} 32250aadb33SDmitri Tikhonov 323b62ec17fSDmitri Tikhonov 324b62ec17fSDmitri Tikhonovstatic lsquic_time_t s_test_6byte_now; 325b62ec17fSDmitri Tikhonovstatic lsquic_time_t 326b62ec17fSDmitri Tikhonovtest_6byte_rechist_largest_recv (void *rechist) 327b62ec17fSDmitri Tikhonov{ 328b62ec17fSDmitri Tikhonov return s_test_6byte_now; 329b62ec17fSDmitri Tikhonov} 330b62ec17fSDmitri Tikhonov 331b62ec17fSDmitri Tikhonov 332b62ec17fSDmitri Tikhonovstatic void 333b62ec17fSDmitri Tikhonovtest_6byte_packnos (void) 334b62ec17fSDmitri Tikhonov{ 335b62ec17fSDmitri Tikhonov int rechist = 0; 336b62ec17fSDmitri Tikhonov s_test_6byte_now = lsquic_time_now(); 33750aadb33SDmitri Tikhonov 33850aadb33SDmitri Tikhonov const unsigned char expected_ack_frame[] = { 33950aadb33SDmitri Tikhonov 0x60 34050aadb33SDmitri Tikhonov | (3 << 2) /* Six-byte largest acked */ 34150aadb33SDmitri Tikhonov | (3 << 0) /* Six-byte ACK block length */ 34250aadb33SDmitri Tikhonov , 34350aadb33SDmitri Tikhonov 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89, 34450aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 34550aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 34650aadb33SDmitri Tikhonov 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 34750aadb33SDmitri Tikhonov 33 - 1, /* Gap to next block. */ 34850aadb33SDmitri Tikhonov 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 34950aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 35050aadb33SDmitri Tikhonov }; 35150aadb33SDmitri Tikhonov unsigned char outbuf[0x100]; 35250aadb33SDmitri Tikhonov 35350aadb33SDmitri Tikhonov int has_missing = -1; 35416a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 35550aadb33SDmitri Tikhonov int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 356b62ec17fSDmitri Tikhonov test_6byte_rechist_first, 357b62ec17fSDmitri Tikhonov test_6byte_rechist_next, 358b62ec17fSDmitri Tikhonov test_6byte_rechist_largest_recv, 359b62ec17fSDmitri Tikhonov &rechist, s_test_6byte_now, &has_missing, &largest, NULL); 36050aadb33SDmitri Tikhonov assert(("ACK frame generation successful", w > 0)); 36150aadb33SDmitri Tikhonov assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 36250aadb33SDmitri Tikhonov assert(("ACK frame contents are as expected", 36350aadb33SDmitri Tikhonov 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 36450aadb33SDmitri Tikhonov assert(("ACK frame has missing packets", has_missing > 0)); 36516a9b66aSDmitri Tikhonov assert(largest == 0xABCD23456789ULL); 36650aadb33SDmitri Tikhonov} 36750aadb33SDmitri Tikhonov 36850aadb33SDmitri Tikhonov 36950aadb33SDmitri Tikhonovint 37050aadb33SDmitri Tikhonovmain (void) 37150aadb33SDmitri Tikhonov{ 372c51ce338SDmitri Tikhonov lsquic_global_init(LSQUIC_GLOBAL_SERVER); 37350aadb33SDmitri Tikhonov lsquic_log_to_fstream(stderr, 0); 37450aadb33SDmitri Tikhonov lsq_log_levels[LSQLM_PARSE] = LSQ_LOG_DEBUG; 37550aadb33SDmitri Tikhonov 37650aadb33SDmitri Tikhonov test1(); 37750aadb33SDmitri Tikhonov 37850aadb33SDmitri Tikhonov test2(); 37950aadb33SDmitri Tikhonov 38050aadb33SDmitri Tikhonov test3(); 38150aadb33SDmitri Tikhonov 38250aadb33SDmitri Tikhonov test4(); 38350aadb33SDmitri Tikhonov 38450aadb33SDmitri Tikhonov test_4byte_packnos(); 38550aadb33SDmitri Tikhonov 38650aadb33SDmitri Tikhonov test_6byte_packnos(); 38750aadb33SDmitri Tikhonov 38850aadb33SDmitri Tikhonov return 0; 38950aadb33SDmitri Tikhonov} 390