1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 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> 6461e84d8SAmol Deshpande#ifndef WIN32 750aadb33SDmitri Tikhonov#include <sys/time.h> 8461e84d8SAmol Deshpande#endif 950aadb33SDmitri Tikhonov 1050aadb33SDmitri Tikhonov#include "lsquic_types.h" 1150aadb33SDmitri Tikhonov#include "lsquic_parse.h" 1250aadb33SDmitri Tikhonov#include "lsquic_rechist.h" 1350aadb33SDmitri Tikhonov#include "lsquic_util.h" 1450aadb33SDmitri Tikhonov#include "lsquic.h" 1550aadb33SDmitri Tikhonov 16052a1c28SDmitri Tikhonovstatic const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_035); 1750aadb33SDmitri Tikhonov 1850aadb33SDmitri Tikhonovstatic lsquic_packno_t 1950aadb33SDmitri Tikhonovn_acked (const ack_info_t *acki) 2050aadb33SDmitri Tikhonov{ 2150aadb33SDmitri Tikhonov lsquic_packno_t n = 0; 2250aadb33SDmitri Tikhonov unsigned i; 2350aadb33SDmitri Tikhonov for (i = 0; i < acki->n_ranges; ++i) 2450aadb33SDmitri Tikhonov n += acki->ranges[i].high - acki->ranges[i].low + 1; 2550aadb33SDmitri Tikhonov return n; 2650aadb33SDmitri Tikhonov} 2750aadb33SDmitri Tikhonov 2850aadb33SDmitri Tikhonov 2950aadb33SDmitri Tikhonovstatic void 3050aadb33SDmitri Tikhonovtest1 (void) 3150aadb33SDmitri Tikhonov{ 3250aadb33SDmitri Tikhonov /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 3350aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 3450aadb33SDmitri Tikhonov 0x45, 3550aadb33SDmitri Tikhonov 0x34, 0x12, /* Largest acked */ 3650aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 3750aadb33SDmitri Tikhonov 0x34, 0x12, /* Block length */ 3850aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 3950aadb33SDmitri Tikhonov }; 4050aadb33SDmitri Tikhonov 4150aadb33SDmitri Tikhonov ack_info_t acki; 4250aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 4350aadb33SDmitri Tikhonov 4450aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 4550aadb33SDmitri Tikhonov assert(("Parsed length is correct (8)", len == sizeof(ack_buf))); 4650aadb33SDmitri Tikhonov assert(("Number of ranges is 1", acki.n_ranges == 1)); 4750aadb33SDmitri Tikhonov assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 4850aadb33SDmitri Tikhonov assert(("Lowest acked is 1", acki.ranges[0].low == 1)); 4950aadb33SDmitri Tikhonov assert(("Number of timestamps is 0", acki.n_timestamps == 0)); 5050aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 5150aadb33SDmitri Tikhonov assert(("Number of acked packets is 0x1234", n == 0x1234)); 5250aadb33SDmitri Tikhonov 5350aadb33SDmitri Tikhonov { 5450aadb33SDmitri Tikhonov size_t sz; 5550aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 5650aadb33SDmitri Tikhonov { 5750aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 5850aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 5950aadb33SDmitri Tikhonov } 6050aadb33SDmitri Tikhonov } 6150aadb33SDmitri Tikhonov} 6250aadb33SDmitri Tikhonov 6350aadb33SDmitri Tikhonov 6450aadb33SDmitri Tikhonovstatic void 6550aadb33SDmitri Tikhonovtest2 (void) 6650aadb33SDmitri Tikhonov{ 6750aadb33SDmitri Tikhonov /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 6850aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 6950aadb33SDmitri Tikhonov 0x65, 7050aadb33SDmitri Tikhonov 0x34, 0x12, /* Largest acked */ 7150aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 7250aadb33SDmitri Tikhonov 0x04, /* Num ack blocks ranges. */ 7350aadb33SDmitri Tikhonov 0x01, 0x00, /* First ack block length. */ 7450aadb33SDmitri Tikhonov 0x01, /* Gap to next block. */ 7550aadb33SDmitri Tikhonov 0xaf, 0x0e, /* Ack block length. */ 7650aadb33SDmitri Tikhonov 0xff, /* Gap to next block. */ 7750aadb33SDmitri Tikhonov 0x00, 0x00, /* Ack block length. */ 7850aadb33SDmitri Tikhonov 0x91, /* Gap to next block. */ 7950aadb33SDmitri Tikhonov 0xea, 0x01, /* Ack block length. */ 8050aadb33SDmitri Tikhonov 0x05, /* Gap to next block. */ 8150aadb33SDmitri Tikhonov 0x04, 0x00, /* Ack block length. */ 8250aadb33SDmitri Tikhonov 0x02, /* Number of timestamps. */ 8350aadb33SDmitri Tikhonov 0x01, /* Delta from largest observed. */ 8450aadb33SDmitri Tikhonov 0x10, 0x32, 0x54, 0x76, /* Delta time. */ 8550aadb33SDmitri Tikhonov 0x02, /* Delta from largest observed. */ 8650aadb33SDmitri Tikhonov 0x10, 0x32, /* Delta time. */ 8750aadb33SDmitri Tikhonov }; 8850aadb33SDmitri Tikhonov 8950aadb33SDmitri Tikhonov /* We should get the following array of ranges: 9050aadb33SDmitri Tikhonov * high low 9150aadb33SDmitri Tikhonov * 0x1234 0x1234 9250aadb33SDmitri Tikhonov * 0x1232 0x384 9350aadb33SDmitri Tikhonov * 0x1F3 0xA 9450aadb33SDmitri Tikhonov * 0x4 0x1 9550aadb33SDmitri Tikhonov */ 9650aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 9750aadb33SDmitri Tikhonov { 0x1234, 0x1234 }, 9850aadb33SDmitri Tikhonov { 0x1232, 0x384 }, 9950aadb33SDmitri Tikhonov { 0x1F3, 0xA }, 10050aadb33SDmitri Tikhonov { 0x4, 0x1 }, 10150aadb33SDmitri Tikhonov }; 10250aadb33SDmitri Tikhonov 10350aadb33SDmitri Tikhonov ack_info_t acki; 10450aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 10550aadb33SDmitri Tikhonov 10650aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 10750aadb33SDmitri Tikhonov assert(("Parsed length is correct (29)", len == sizeof(ack_buf))); 10850aadb33SDmitri Tikhonov assert(("Number of ranges is 4", acki.n_ranges == 4)); 10950aadb33SDmitri Tikhonov assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 11050aadb33SDmitri Tikhonov assert(("Number of timestamps is 2", acki.n_timestamps == 2)); 11150aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 11250aadb33SDmitri Tikhonov assert(("Number of acked packets is 4254", n == 4254)); 11350aadb33SDmitri Tikhonov 11450aadb33SDmitri Tikhonov for (n = 0; n < 4; ++n) 11550aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 11650aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 11750aadb33SDmitri Tikhonov 11850aadb33SDmitri Tikhonov { 11950aadb33SDmitri Tikhonov size_t sz; 12050aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 12150aadb33SDmitri Tikhonov { 12250aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 12350aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 12450aadb33SDmitri Tikhonov } 12550aadb33SDmitri Tikhonov } 12650aadb33SDmitri Tikhonov} 12750aadb33SDmitri Tikhonov 12850aadb33SDmitri Tikhonov 12950aadb33SDmitri Tikhonovstatic void 13050aadb33SDmitri Tikhonovtest3 (void) 13150aadb33SDmitri Tikhonov{ 13250aadb33SDmitri Tikhonov /* Generated by our own code, but failed to parse... */ 13350aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 13450aadb33SDmitri Tikhonov 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 13550aadb33SDmitri Tikhonov 0x06, /* Largest ACKed */ 13650aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 13750aadb33SDmitri Tikhonov 0x01, /* Num ACK block ranges */ 13850aadb33SDmitri Tikhonov 0x01, /* First ACK block length */ 13950aadb33SDmitri Tikhonov 0x02, /* Gap to next block */ 14050aadb33SDmitri Tikhonov 0x03, /* Ack block length */ 14150aadb33SDmitri Tikhonov 0x00 /* Number of timestamps */ 14250aadb33SDmitri Tikhonov }; 14350aadb33SDmitri Tikhonov 14450aadb33SDmitri Tikhonov /* We should get the following array of ranges: 14550aadb33SDmitri Tikhonov * high low 14650aadb33SDmitri Tikhonov * 6 6 14750aadb33SDmitri Tikhonov * 3 1 14850aadb33SDmitri Tikhonov */ 14950aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 15050aadb33SDmitri Tikhonov { 6, 6, }, 15150aadb33SDmitri Tikhonov { 3, 1, }, 15250aadb33SDmitri Tikhonov }; 15350aadb33SDmitri Tikhonov 15450aadb33SDmitri Tikhonov ack_info_t acki; 15550aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 15650aadb33SDmitri Tikhonov 15750aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 15850aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 15950aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 16050aadb33SDmitri Tikhonov assert(("Largest acked is 6", acki.ranges[0].high == 6)); 16150aadb33SDmitri Tikhonov assert(("Number of timestamps is 0", acki.n_timestamps == 0)); 16250aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 16350aadb33SDmitri Tikhonov assert(("Number of acked packets is 4", n == 4)); 16450aadb33SDmitri Tikhonov 16550aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 16650aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 16750aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 16850aadb33SDmitri Tikhonov 16950aadb33SDmitri Tikhonov { 17050aadb33SDmitri Tikhonov size_t sz; 17150aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 17250aadb33SDmitri Tikhonov { 17350aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 17450aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 17550aadb33SDmitri Tikhonov } 17650aadb33SDmitri Tikhonov } 17750aadb33SDmitri Tikhonov} 17850aadb33SDmitri Tikhonov 17950aadb33SDmitri Tikhonov 18050aadb33SDmitri Tikhonovstatic void 18150aadb33SDmitri Tikhonovtest4 (void) 18250aadb33SDmitri Tikhonov{ 18350aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 18450aadb33SDmitri Tikhonov 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 18550aadb33SDmitri Tikhonov 0x03, /* Largest ACKed */ 18650aadb33SDmitri Tikhonov 0x23, 0x00, /* Delta time */ 18750aadb33SDmitri Tikhonov 0x01, /* Num ACK block ranges */ 18850aadb33SDmitri Tikhonov 0x01, /* First ack block length */ 18950aadb33SDmitri Tikhonov 0x01, /* Gap */ 19050aadb33SDmitri Tikhonov 0x01, /* Ack block length */ 19150aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 19250aadb33SDmitri Tikhonov }; 19350aadb33SDmitri Tikhonov 19450aadb33SDmitri Tikhonov /* We should get the following array of ranges: 19550aadb33SDmitri Tikhonov * high low 19650aadb33SDmitri Tikhonov * 6 6 19750aadb33SDmitri Tikhonov * 3 1 19850aadb33SDmitri Tikhonov */ 19950aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 20050aadb33SDmitri Tikhonov { 3, 3, }, 20150aadb33SDmitri Tikhonov { 1, 1, }, 20250aadb33SDmitri Tikhonov }; 20350aadb33SDmitri Tikhonov 20450aadb33SDmitri Tikhonov ack_info_t acki; 20550aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 20650aadb33SDmitri Tikhonov 20750aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 20850aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 20950aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 21050aadb33SDmitri Tikhonov assert(("Largest acked is 3", acki.ranges[0].high == 3)); 21150aadb33SDmitri Tikhonov assert(("Number of timestamps is 0", acki.n_timestamps == 0)); 21250aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 21350aadb33SDmitri Tikhonov assert(("Number of acked packets is 2", n == 2)); 21450aadb33SDmitri Tikhonov 21550aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 21650aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 21750aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 21850aadb33SDmitri Tikhonov 21950aadb33SDmitri Tikhonov { 22050aadb33SDmitri Tikhonov size_t sz; 22150aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 22250aadb33SDmitri Tikhonov { 22350aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 22450aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 22550aadb33SDmitri Tikhonov } 22650aadb33SDmitri Tikhonov } 22750aadb33SDmitri Tikhonov} 22850aadb33SDmitri Tikhonov 22950aadb33SDmitri Tikhonov 23050aadb33SDmitri Tikhonov/* Four-byte packet numbers */ 23150aadb33SDmitri Tikhonovstatic void 23250aadb33SDmitri Tikhonovtest5 (void) 23350aadb33SDmitri Tikhonov{ 23450aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 23550aadb33SDmitri Tikhonov 0x60 23650aadb33SDmitri Tikhonov | (2 << 2) /* Four-byte largest acked */ 23750aadb33SDmitri Tikhonov | (2 << 0) /* Four-byte ACK block length */ 23850aadb33SDmitri Tikhonov , 23950aadb33SDmitri Tikhonov 0x89, 0x67, 0x45, 0x23, 24050aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 24150aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 24250aadb33SDmitri Tikhonov 0x01, 0x00, 0x00, 0x00, /* First ack block length. */ 24350aadb33SDmitri Tikhonov 33 - 1, /* Gap to next block. */ 24450aadb33SDmitri Tikhonov 0x68, 0x67, 0x45, 0x23, /* Ack block length. */ 24550aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 24650aadb33SDmitri Tikhonov }; 24750aadb33SDmitri Tikhonov 24850aadb33SDmitri Tikhonov /* We should get the following array of ranges: 24950aadb33SDmitri Tikhonov * high low 25050aadb33SDmitri Tikhonov * 6 6 25150aadb33SDmitri Tikhonov * 3 1 25250aadb33SDmitri Tikhonov */ 25350aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 25450aadb33SDmitri Tikhonov { 0x23456789, 0x23456789, }, 25550aadb33SDmitri Tikhonov { 0x23456768, 1, }, 25650aadb33SDmitri Tikhonov }; 25750aadb33SDmitri Tikhonov 25850aadb33SDmitri Tikhonov ack_info_t acki; 25950aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 26050aadb33SDmitri Tikhonov 26150aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 26250aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 26350aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 26450aadb33SDmitri Tikhonov assert(("Largest acked is 0x23456789", acki.ranges[0].high == 0x23456789)); 26550aadb33SDmitri Tikhonov assert(("Number of timestamps is 0", acki.n_timestamps == 0)); 26650aadb33SDmitri Tikhonov lsquic_packno_t n = n_acked(&acki); 26750aadb33SDmitri Tikhonov assert(("Number of acked packets is correct", n == 0x23456768 + 1)); 26850aadb33SDmitri Tikhonov 26950aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 27050aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 27150aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 27250aadb33SDmitri Tikhonov 27350aadb33SDmitri Tikhonov { 27450aadb33SDmitri Tikhonov size_t sz; 27550aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 27650aadb33SDmitri Tikhonov { 27750aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 27850aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 27950aadb33SDmitri Tikhonov } 28050aadb33SDmitri Tikhonov } 28150aadb33SDmitri Tikhonov} 28250aadb33SDmitri Tikhonov 28350aadb33SDmitri Tikhonov 28450aadb33SDmitri Tikhonov/* Six-byte packet numbers */ 28550aadb33SDmitri Tikhonovstatic void 28650aadb33SDmitri Tikhonovtest6 (void) 28750aadb33SDmitri Tikhonov{ 28850aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 28950aadb33SDmitri Tikhonov 0x60 29050aadb33SDmitri Tikhonov | (3 << 2) /* Six-byte largest acked */ 29150aadb33SDmitri Tikhonov | (3 << 0) /* Six-byte ACK block length */ 29250aadb33SDmitri Tikhonov , 29350aadb33SDmitri Tikhonov 0x89, 0x67, 0x45, 0x23, 0xCD, 0xAB, 29450aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 29550aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 29650aadb33SDmitri Tikhonov 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* First ack block length. */ 29750aadb33SDmitri Tikhonov 33 - 1, /* Gap to next block. */ 29850aadb33SDmitri Tikhonov 0x68, 0x67, 0x45, 0x23, 0xCD, 0xAB, /* Ack block length. */ 29950aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 30050aadb33SDmitri Tikhonov }; 30150aadb33SDmitri Tikhonov 30250aadb33SDmitri Tikhonov static const struct { lsquic_packno_t high, low; } ranges[] = { 30350aadb33SDmitri Tikhonov { 0xABCD23456789, 0xABCD23456789, }, 30450aadb33SDmitri Tikhonov { 0xABCD23456768, 1, }, 30550aadb33SDmitri Tikhonov }; 30650aadb33SDmitri Tikhonov 30750aadb33SDmitri Tikhonov ack_info_t acki; 30850aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 30950aadb33SDmitri Tikhonov 31050aadb33SDmitri Tikhonov int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki); 31150aadb33SDmitri Tikhonov assert(("Parsed length is correct", len == sizeof(ack_buf))); 31250aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 31350aadb33SDmitri Tikhonov assert(("Largest acked is 0xABCD23456789", acki.ranges[0].high == 0xABCD23456789)); 31450aadb33SDmitri Tikhonov assert(("Number of timestamps is 0", acki.n_timestamps == 0)); 31550aadb33SDmitri Tikhonov lsquic_packno_t n = n_acked(&acki); 31650aadb33SDmitri Tikhonov assert(("Number of acked packets is correct", n == 0xABCD23456768 + 1)); 31750aadb33SDmitri Tikhonov 31850aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 31950aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 32050aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 32150aadb33SDmitri Tikhonov 32250aadb33SDmitri Tikhonov { 32350aadb33SDmitri Tikhonov size_t sz; 32450aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 32550aadb33SDmitri Tikhonov { 32650aadb33SDmitri Tikhonov len = pf->pf_parse_ack_frame(ack_buf, sz, &acki); 32750aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 32850aadb33SDmitri Tikhonov } 32950aadb33SDmitri Tikhonov } 33050aadb33SDmitri Tikhonov} 33150aadb33SDmitri Tikhonov 33250aadb33SDmitri Tikhonov 33350aadb33SDmitri Tikhonovstatic void 33450aadb33SDmitri Tikhonovtest_max_ack (void) 33550aadb33SDmitri Tikhonov{ 33650aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 33750aadb33SDmitri Tikhonov lsquic_time_t now; 33850aadb33SDmitri Tikhonov unsigned i; 33950aadb33SDmitri Tikhonov int has_missing, sz[2]; 34050aadb33SDmitri Tikhonov const struct lsquic_packno_range *range; 34150aadb33SDmitri Tikhonov unsigned char buf[1500]; 34250aadb33SDmitri Tikhonov struct ack_info acki; 34350aadb33SDmitri Tikhonov 34450aadb33SDmitri Tikhonov lsquic_rechist_init(&rechist, 12345); 34550aadb33SDmitri Tikhonov now = lsquic_time_now(); 34650aadb33SDmitri Tikhonov 34750aadb33SDmitri Tikhonov for (i = 1; i <= 300; ++i) 34850aadb33SDmitri Tikhonov { 34950aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 35050aadb33SDmitri Tikhonov now += i * 1000; 35150aadb33SDmitri Tikhonov } 35250aadb33SDmitri Tikhonov 35350aadb33SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 35450aadb33SDmitri Tikhonov 35516a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 35650aadb33SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf), 35750aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 35850aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 35950aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 36016a9b66aSDmitri Tikhonov &rechist, now, &has_missing, &largest); 36150aadb33SDmitri Tikhonov assert(sz[0] > 0); 36250aadb33SDmitri Tikhonov assert(sz[0] <= (int) sizeof(buf)); 36350aadb33SDmitri Tikhonov assert(has_missing); 36450aadb33SDmitri Tikhonov 36550aadb33SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 36650aadb33SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 36750aadb33SDmitri Tikhonov 36850aadb33SDmitri Tikhonov sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki); 36950aadb33SDmitri Tikhonov assert(sz[1] == sz[0]); 37050aadb33SDmitri Tikhonov assert(256 == acki.n_ranges); 37150aadb33SDmitri Tikhonov 37250aadb33SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 37350aadb33SDmitri Tikhonov range && i < acki.n_ranges; 37450aadb33SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 37550aadb33SDmitri Tikhonov { 37650aadb33SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 37750aadb33SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 37850aadb33SDmitri Tikhonov } 37950aadb33SDmitri Tikhonov assert(i == 256); 38050aadb33SDmitri Tikhonov 38150aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 38250aadb33SDmitri Tikhonov} 38350aadb33SDmitri Tikhonov 38450aadb33SDmitri Tikhonov 38550aadb33SDmitri Tikhonovstatic void 38650aadb33SDmitri Tikhonovtest_ack_truncation (void) 38750aadb33SDmitri Tikhonov{ 38850aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 38950aadb33SDmitri Tikhonov lsquic_time_t now; 39050aadb33SDmitri Tikhonov unsigned i; 39150aadb33SDmitri Tikhonov int has_missing, sz[2]; 39250aadb33SDmitri Tikhonov const struct lsquic_packno_range *range; 39350aadb33SDmitri Tikhonov unsigned char buf[1500]; 39450aadb33SDmitri Tikhonov struct ack_info acki; 39550aadb33SDmitri Tikhonov size_t bufsz; 39650aadb33SDmitri Tikhonov 39750aadb33SDmitri Tikhonov lsquic_rechist_init(&rechist, 12345); 39850aadb33SDmitri Tikhonov now = lsquic_time_now(); 39950aadb33SDmitri Tikhonov 40050aadb33SDmitri Tikhonov for (i = 1; i <= 300; ++i) 40150aadb33SDmitri Tikhonov { 40250aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 40350aadb33SDmitri Tikhonov now += i * 1000; 40450aadb33SDmitri Tikhonov } 40550aadb33SDmitri Tikhonov 40650aadb33SDmitri Tikhonov for (bufsz = 200; bufsz < 210; ++bufsz) 40750aadb33SDmitri Tikhonov { 40850aadb33SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 40916a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 41050aadb33SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, bufsz, 41150aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 41250aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 41350aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 41416a9b66aSDmitri Tikhonov &rechist, now, &has_missing, &largest); 41550aadb33SDmitri Tikhonov assert(sz[0] > 0); 41650aadb33SDmitri Tikhonov assert(sz[0] <= (int) bufsz); 41750aadb33SDmitri Tikhonov assert(has_missing); 41850aadb33SDmitri Tikhonov 41950aadb33SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 42050aadb33SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 42150aadb33SDmitri Tikhonov 42250aadb33SDmitri Tikhonov sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki); 42350aadb33SDmitri Tikhonov assert(sz[1] == sz[0]); 42450aadb33SDmitri Tikhonov assert(acki.n_ranges < 256); 42550aadb33SDmitri Tikhonov 42650aadb33SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 42750aadb33SDmitri Tikhonov range && i < acki.n_ranges; 42850aadb33SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 42950aadb33SDmitri Tikhonov { 43050aadb33SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 43150aadb33SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 43250aadb33SDmitri Tikhonov } 43350aadb33SDmitri Tikhonov } 43450aadb33SDmitri Tikhonov 43550aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 43650aadb33SDmitri Tikhonov} 43750aadb33SDmitri Tikhonov 43850aadb33SDmitri Tikhonov 43950aadb33SDmitri Tikhonovint 44050aadb33SDmitri Tikhonovmain (void) 44150aadb33SDmitri Tikhonov{ 442c51ce338SDmitri Tikhonov lsquic_global_init(LSQUIC_GLOBAL_SERVER); 44350aadb33SDmitri Tikhonov test1(); 44450aadb33SDmitri Tikhonov test2(); 44550aadb33SDmitri Tikhonov test3(); 44650aadb33SDmitri Tikhonov test4(); 44750aadb33SDmitri Tikhonov test5(); 44850aadb33SDmitri Tikhonov test6(); 44950aadb33SDmitri Tikhonov test_max_ack(); 45050aadb33SDmitri Tikhonov test_ack_truncation(); 45150aadb33SDmitri Tikhonov return 0; 45250aadb33SDmitri Tikhonov} 453