1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 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 23f07b3eaeSTyler Young//static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043); // will not work on MSVC 24f07b3eaeSTyler Young#define pf ((const struct parse_funcs *const)select_pf_by_ver(LSQVER_043)) 2550aadb33SDmitri Tikhonov 2650aadb33SDmitri Tikhonov 2750aadb33SDmitri Tikhonovstatic lsquic_packno_t 285392f7a3SLiteSpeed Techn_acked (const struct ack_info *acki) 2950aadb33SDmitri Tikhonov{ 3050aadb33SDmitri Tikhonov lsquic_packno_t n = 0; 3150aadb33SDmitri Tikhonov unsigned i; 3250aadb33SDmitri Tikhonov for (i = 0; i < acki->n_ranges; ++i) 3350aadb33SDmitri Tikhonov n += acki->ranges[i].high - acki->ranges[i].low + 1; 3450aadb33SDmitri Tikhonov return n; 3550aadb33SDmitri Tikhonov} 3650aadb33SDmitri Tikhonov 3750aadb33SDmitri Tikhonov 3850aadb33SDmitri Tikhonovstatic void 3950aadb33SDmitri Tikhonovtest1 (void) 4050aadb33SDmitri Tikhonov{ 4150aadb33SDmitri Tikhonov /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 4250aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 4350aadb33SDmitri Tikhonov 0x45, 4450aadb33SDmitri Tikhonov 0x12, 0x34, /* Largest acked */ 4550aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 4650aadb33SDmitri Tikhonov 0x12, 0x34, /* Block length */ 4750aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 4850aadb33SDmitri Tikhonov }; 4950aadb33SDmitri Tikhonov 505392f7a3SLiteSpeed Tech struct ack_info acki; 5150aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 5250aadb33SDmitri Tikhonov 535392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 5450aadb33SDmitri Tikhonov assert(("Parsed length is correct (8)", len == sizeof(ack_buf))); 5550aadb33SDmitri Tikhonov assert(("Number of ranges is 1", acki.n_ranges == 1)); 5650aadb33SDmitri Tikhonov assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 5750aadb33SDmitri Tikhonov assert(("Lowest acked is 1", acki.ranges[0].low == 1)); 5850aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 5950aadb33SDmitri Tikhonov assert(("Number of acked packets is 0x1234", n == 0x1234)); 6050aadb33SDmitri Tikhonov 6150aadb33SDmitri Tikhonov { 6250aadb33SDmitri Tikhonov size_t sz; 6350aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 6450aadb33SDmitri Tikhonov { 655392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 6650aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 6750aadb33SDmitri Tikhonov } 6850aadb33SDmitri Tikhonov } 6950aadb33SDmitri Tikhonov} 7050aadb33SDmitri Tikhonov 7150aadb33SDmitri Tikhonov 7250aadb33SDmitri Tikhonovstatic void 7350aadb33SDmitri Tikhonovtest2 (void) 7450aadb33SDmitri Tikhonov{ 7550aadb33SDmitri Tikhonov /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 7650aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 7750aadb33SDmitri Tikhonov 0x65, 7850aadb33SDmitri Tikhonov 0x12, 0x34, /* Largest acked */ 7950aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 8050aadb33SDmitri Tikhonov 0x04, /* Num ack blocks ranges. */ 8150aadb33SDmitri Tikhonov 0x00, 0x01, /* First ack block length. */ 8250aadb33SDmitri Tikhonov 0x01, /* Gap to next block. */ 8350aadb33SDmitri Tikhonov 0x0e, 0xaf, /* Ack block length. */ 8450aadb33SDmitri Tikhonov 0xff, /* Gap to next block. */ 8550aadb33SDmitri Tikhonov 0x00, 0x00, /* Ack block length. */ 8650aadb33SDmitri Tikhonov 0x91, /* Gap to next block. */ 8750aadb33SDmitri Tikhonov 0x01, 0xea, /* Ack block length. */ 8850aadb33SDmitri Tikhonov 0x05, /* Gap to next block. */ 8950aadb33SDmitri Tikhonov 0x00, 0x04, /* Ack block length. */ 9050aadb33SDmitri Tikhonov 0x02, /* Number of timestamps. */ 9150aadb33SDmitri Tikhonov 0x01, /* Delta from largest observed. */ 9250aadb33SDmitri Tikhonov 0x10, 0x32, 0x54, 0x76, /* Delta time. */ /* XXX do we use this at all? */ 9350aadb33SDmitri Tikhonov 0x02, /* Delta from largest observed. */ 9450aadb33SDmitri Tikhonov 0x10, 0x32, /* Delta time. */ 9550aadb33SDmitri Tikhonov }; 9650aadb33SDmitri Tikhonov 9750aadb33SDmitri Tikhonov /* We should get the following array of ranges: 9850aadb33SDmitri Tikhonov * high low 9950aadb33SDmitri Tikhonov * 0x1234 0x1234 10050aadb33SDmitri Tikhonov * 0x1232 0x384 10150aadb33SDmitri Tikhonov * 0x1F3 0xA 10250aadb33SDmitri Tikhonov * 0x4 0x1 10350aadb33SDmitri Tikhonov */ 10450aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 10550aadb33SDmitri Tikhonov { 0x1234, 0x1234 }, 10650aadb33SDmitri Tikhonov { 0x1232, 0x384 }, 10750aadb33SDmitri Tikhonov { 0x1F3, 0xA }, 10850aadb33SDmitri Tikhonov { 0x4, 0x1 }, 10950aadb33SDmitri Tikhonov }; 11050aadb33SDmitri Tikhonov 1115392f7a3SLiteSpeed Tech struct ack_info acki; 11250aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 11350aadb33SDmitri Tikhonov 1145392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 11550aadb33SDmitri Tikhonov assert(("Parsed length is correct (29)", len == sizeof(ack_buf))); 11650aadb33SDmitri Tikhonov assert(("Number of ranges is 4", acki.n_ranges == 4)); 11750aadb33SDmitri Tikhonov assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 11850aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 11950aadb33SDmitri Tikhonov assert(("Number of acked packets is 4254", n == 4254)); 12050aadb33SDmitri Tikhonov 12150aadb33SDmitri Tikhonov for (n = 0; n < 4; ++n) 12250aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 12350aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 12450aadb33SDmitri Tikhonov 12550aadb33SDmitri Tikhonov { 12650aadb33SDmitri Tikhonov size_t sz; 12750aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 12850aadb33SDmitri Tikhonov { 1295392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 13050aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 13150aadb33SDmitri Tikhonov } 13250aadb33SDmitri Tikhonov } 13350aadb33SDmitri Tikhonov} 13450aadb33SDmitri Tikhonov 13550aadb33SDmitri Tikhonov 13650aadb33SDmitri Tikhonovstatic void 13750aadb33SDmitri Tikhonovtest3 (void) 13850aadb33SDmitri Tikhonov{ 13950aadb33SDmitri Tikhonov /* Generated by our own code, but failed to parse... */ 14050aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 14150aadb33SDmitri Tikhonov 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 14250aadb33SDmitri Tikhonov 0x06, /* Largest ACKed */ 14350aadb33SDmitri Tikhonov 0x00, 0x00, /* Delta time */ 14450aadb33SDmitri Tikhonov 0x01, /* Num ACK block ranges */ 14550aadb33SDmitri Tikhonov 0x01, /* First ACK block length */ 14650aadb33SDmitri Tikhonov 0x02, /* Gap to next block */ 14750aadb33SDmitri Tikhonov 0x03, /* Ack block length */ 14850aadb33SDmitri Tikhonov 0x00 /* Number of timestamps */ 14950aadb33SDmitri Tikhonov }; 15050aadb33SDmitri Tikhonov 15150aadb33SDmitri Tikhonov /* We should get the following array of ranges: 15250aadb33SDmitri Tikhonov * high low 15350aadb33SDmitri Tikhonov * 6 6 15450aadb33SDmitri Tikhonov * 3 1 15550aadb33SDmitri Tikhonov */ 15650aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 15750aadb33SDmitri Tikhonov { 6, 6, }, 15850aadb33SDmitri Tikhonov { 3, 1, }, 15950aadb33SDmitri Tikhonov }; 16050aadb33SDmitri Tikhonov 1615392f7a3SLiteSpeed Tech struct ack_info acki; 16250aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 16350aadb33SDmitri Tikhonov 1645392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 16550aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 16650aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 16750aadb33SDmitri Tikhonov assert(("Largest acked is 6", acki.ranges[0].high == 6)); 16850aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 16950aadb33SDmitri Tikhonov assert(("Number of acked packets is 4", n == 4)); 17050aadb33SDmitri Tikhonov 17150aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 17250aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 17350aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 17450aadb33SDmitri Tikhonov 17550aadb33SDmitri Tikhonov { 17650aadb33SDmitri Tikhonov size_t sz; 17750aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 17850aadb33SDmitri Tikhonov { 1795392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 18050aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 18150aadb33SDmitri Tikhonov } 18250aadb33SDmitri Tikhonov } 18350aadb33SDmitri Tikhonov} 18450aadb33SDmitri Tikhonov 18550aadb33SDmitri Tikhonov 18650aadb33SDmitri Tikhonovstatic void 18750aadb33SDmitri Tikhonovtest4 (void) 18850aadb33SDmitri Tikhonov{ 18950aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 19050aadb33SDmitri Tikhonov 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 19150aadb33SDmitri Tikhonov 0x03, /* Largest ACKed */ 19250aadb33SDmitri Tikhonov 0x23, 0x00, /* Delta time */ 19350aadb33SDmitri Tikhonov 0x01, /* Num ACK block ranges */ 19450aadb33SDmitri Tikhonov 0x01, /* First ack block length */ 19550aadb33SDmitri Tikhonov 0x01, /* Gap */ 19650aadb33SDmitri Tikhonov 0x01, /* Ack block length */ 19750aadb33SDmitri Tikhonov 0x00, /* Number of timestamps */ 19850aadb33SDmitri Tikhonov }; 19950aadb33SDmitri Tikhonov 20050aadb33SDmitri Tikhonov /* We should get the following array of ranges: 20150aadb33SDmitri Tikhonov * high low 20250aadb33SDmitri Tikhonov * 6 6 20350aadb33SDmitri Tikhonov * 3 1 20450aadb33SDmitri Tikhonov */ 20550aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 20650aadb33SDmitri Tikhonov { 3, 3, }, 20750aadb33SDmitri Tikhonov { 1, 1, }, 20850aadb33SDmitri Tikhonov }; 20950aadb33SDmitri Tikhonov 2105392f7a3SLiteSpeed Tech struct ack_info acki; 21150aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 21250aadb33SDmitri Tikhonov 2135392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 21450aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 21550aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 21650aadb33SDmitri Tikhonov assert(("Largest acked is 3", acki.ranges[0].high == 3)); 21750aadb33SDmitri Tikhonov unsigned n = n_acked(&acki); 21850aadb33SDmitri Tikhonov assert(("Number of acked packets is 2", n == 2)); 21950aadb33SDmitri Tikhonov 22050aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 22150aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 22250aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 22350aadb33SDmitri Tikhonov 22450aadb33SDmitri Tikhonov { 22550aadb33SDmitri Tikhonov size_t sz; 22650aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 22750aadb33SDmitri Tikhonov { 2285392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 22950aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 23050aadb33SDmitri Tikhonov } 23150aadb33SDmitri Tikhonov } 23250aadb33SDmitri Tikhonov} 23350aadb33SDmitri Tikhonov 23450aadb33SDmitri Tikhonov 23550aadb33SDmitri Tikhonov/* Four-byte packet numbers */ 23650aadb33SDmitri Tikhonovstatic void 23750aadb33SDmitri Tikhonovtest5 (void) 23850aadb33SDmitri Tikhonov{ 23950aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 24050aadb33SDmitri Tikhonov 0x60 24150aadb33SDmitri Tikhonov | (2 << 2) /* Four-byte largest acked */ 24250aadb33SDmitri Tikhonov | (2 << 0) /* Four-byte ACK block length */ 24350aadb33SDmitri Tikhonov , 24450aadb33SDmitri Tikhonov 0x23, 0x45, 0x67, 0x89, 24550aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 24650aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 24750aadb33SDmitri Tikhonov 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 24850aadb33SDmitri Tikhonov 33 - 1, /* Gap to next block. */ 24950aadb33SDmitri Tikhonov 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 25050aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 25150aadb33SDmitri Tikhonov }; 25250aadb33SDmitri Tikhonov 25350aadb33SDmitri Tikhonov /* We should get the following array of ranges: 25450aadb33SDmitri Tikhonov * high low 25550aadb33SDmitri Tikhonov * 6 6 25650aadb33SDmitri Tikhonov * 3 1 25750aadb33SDmitri Tikhonov */ 25850aadb33SDmitri Tikhonov static const struct { unsigned high, low; } ranges[] = { 25950aadb33SDmitri Tikhonov { 0x23456789, 0x23456789, }, 26050aadb33SDmitri Tikhonov { 0x23456768, 1, }, 26150aadb33SDmitri Tikhonov }; 26250aadb33SDmitri Tikhonov 2635392f7a3SLiteSpeed Tech struct ack_info acki; 26450aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 26550aadb33SDmitri Tikhonov 2665392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 26750aadb33SDmitri Tikhonov assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 26850aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 26950aadb33SDmitri Tikhonov assert(("Largest acked is 0x23456789", acki.ranges[0].high == 0x23456789)); 27050aadb33SDmitri Tikhonov lsquic_packno_t n = n_acked(&acki); 27150aadb33SDmitri Tikhonov assert(("Number of acked packets is correct", n == 0x23456768 + 1)); 27250aadb33SDmitri Tikhonov 27350aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 27450aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 27550aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 27650aadb33SDmitri Tikhonov 27750aadb33SDmitri Tikhonov { 27850aadb33SDmitri Tikhonov size_t sz; 27950aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 28050aadb33SDmitri Tikhonov { 2815392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 28250aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 28350aadb33SDmitri Tikhonov } 28450aadb33SDmitri Tikhonov } 28550aadb33SDmitri Tikhonov} 28650aadb33SDmitri Tikhonov 28750aadb33SDmitri Tikhonov 28850aadb33SDmitri Tikhonov/* Six-byte packet numbers */ 28950aadb33SDmitri Tikhonovstatic void 29050aadb33SDmitri Tikhonovtest6 (void) 29150aadb33SDmitri Tikhonov{ 29250aadb33SDmitri Tikhonov unsigned char ack_buf[] = { 29350aadb33SDmitri Tikhonov 0x60 29450aadb33SDmitri Tikhonov | (3 << 2) /* Six-byte largest acked */ 29550aadb33SDmitri Tikhonov | (3 << 0) /* Six-byte ACK block length */ 29650aadb33SDmitri Tikhonov , 29750aadb33SDmitri Tikhonov 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89, 29850aadb33SDmitri Tikhonov 0x00, 0x00, /* Zero delta time. */ 29950aadb33SDmitri Tikhonov 0x01, /* Num ack blocks ranges. */ 30050aadb33SDmitri Tikhonov 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 30150aadb33SDmitri Tikhonov 33 - 1, /* Gap to next block. */ 30250aadb33SDmitri Tikhonov 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 30350aadb33SDmitri Tikhonov 0x00, /* Number of timestamps. */ 30450aadb33SDmitri Tikhonov }; 30550aadb33SDmitri Tikhonov 30650aadb33SDmitri Tikhonov static const struct { lsquic_packno_t high, low; } ranges[] = { 30750aadb33SDmitri Tikhonov { 0xABCD23456789, 0xABCD23456789, }, 30850aadb33SDmitri Tikhonov { 0xABCD23456768, 1, }, 30950aadb33SDmitri Tikhonov }; 31050aadb33SDmitri Tikhonov 3115392f7a3SLiteSpeed Tech struct ack_info acki; 31250aadb33SDmitri Tikhonov memset(&acki, 0xF1, sizeof(acki)); 31350aadb33SDmitri Tikhonov 3145392f7a3SLiteSpeed Tech int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 31550aadb33SDmitri Tikhonov assert(("Parsed length is correct", len == sizeof(ack_buf))); 31650aadb33SDmitri Tikhonov assert(("Number of ranges is 2", acki.n_ranges == 2)); 31750aadb33SDmitri Tikhonov assert(("Largest acked is 0xABCD23456789", acki.ranges[0].high == 0xABCD23456789)); 31850aadb33SDmitri Tikhonov lsquic_packno_t n = n_acked(&acki); 31950aadb33SDmitri Tikhonov assert(("Number of acked packets is correct", n == 0xABCD23456768 + 1)); 32050aadb33SDmitri Tikhonov 32150aadb33SDmitri Tikhonov for (n = 0; n < 2; ++n) 32250aadb33SDmitri Tikhonov assert(("Range checks out", ranges[n].high == acki.ranges[n].high 32350aadb33SDmitri Tikhonov && ranges[n].low == acki.ranges[n].low)); 32450aadb33SDmitri Tikhonov 32550aadb33SDmitri Tikhonov { 32650aadb33SDmitri Tikhonov size_t sz; 32750aadb33SDmitri Tikhonov for (sz = 1; sz < sizeof(ack_buf); ++sz) 32850aadb33SDmitri Tikhonov { 3295392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 33050aadb33SDmitri Tikhonov assert(("Parsing truncated frame failed", len < 0)); 33150aadb33SDmitri Tikhonov } 33250aadb33SDmitri Tikhonov } 33350aadb33SDmitri Tikhonov} 33450aadb33SDmitri Tikhonov 33550aadb33SDmitri Tikhonov 33650aadb33SDmitri Tikhonovstatic void 33750aadb33SDmitri Tikhonovtest_max_ack (void) 33850aadb33SDmitri Tikhonov{ 33950aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 34050aadb33SDmitri Tikhonov lsquic_time_t now; 34150aadb33SDmitri Tikhonov unsigned i; 34250aadb33SDmitri Tikhonov int has_missing, sz[2]; 34350aadb33SDmitri Tikhonov const struct lsquic_packno_range *range; 34450aadb33SDmitri Tikhonov unsigned char buf[1500]; 34550aadb33SDmitri Tikhonov struct ack_info acki; 34650aadb33SDmitri Tikhonov 347f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 34850aadb33SDmitri Tikhonov now = lsquic_time_now(); 34950aadb33SDmitri Tikhonov 35050aadb33SDmitri Tikhonov for (i = 1; i <= 300; ++i) 35150aadb33SDmitri Tikhonov { 35250aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 35350aadb33SDmitri Tikhonov now += i * 1000; 35450aadb33SDmitri Tikhonov } 35550aadb33SDmitri Tikhonov 35650aadb33SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 35750aadb33SDmitri Tikhonov 35816a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 35950aadb33SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf), 36050aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 36150aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 36250aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 3635392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 36450aadb33SDmitri Tikhonov assert(sz[0] > 0); 36550aadb33SDmitri Tikhonov assert(sz[0] <= (int) sizeof(buf)); 36650aadb33SDmitri Tikhonov assert(has_missing); 36750aadb33SDmitri Tikhonov 36850aadb33SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 36950aadb33SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 37050aadb33SDmitri Tikhonov 3715392f7a3SLiteSpeed Tech sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 37250aadb33SDmitri Tikhonov assert(sz[1] == sz[0]); 37350aadb33SDmitri Tikhonov assert(256 == acki.n_ranges); 37450aadb33SDmitri Tikhonov 37550aadb33SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 37650aadb33SDmitri Tikhonov range && i < acki.n_ranges; 37750aadb33SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 37850aadb33SDmitri Tikhonov { 37950aadb33SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 38050aadb33SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 38150aadb33SDmitri Tikhonov } 38250aadb33SDmitri Tikhonov assert(i == 256); 38350aadb33SDmitri Tikhonov 38450aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 38550aadb33SDmitri Tikhonov} 38650aadb33SDmitri Tikhonov 38750aadb33SDmitri Tikhonov 38850aadb33SDmitri Tikhonovstatic void 38950aadb33SDmitri Tikhonovtest_ack_truncation (void) 39050aadb33SDmitri Tikhonov{ 39150aadb33SDmitri Tikhonov lsquic_rechist_t rechist; 39250aadb33SDmitri Tikhonov lsquic_time_t now; 39350aadb33SDmitri Tikhonov unsigned i; 39450aadb33SDmitri Tikhonov int has_missing, sz[2]; 39550aadb33SDmitri Tikhonov const struct lsquic_packno_range *range; 39650aadb33SDmitri Tikhonov unsigned char buf[1500]; 39750aadb33SDmitri Tikhonov struct ack_info acki; 39850aadb33SDmitri Tikhonov size_t bufsz; 39950aadb33SDmitri Tikhonov 400f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 40150aadb33SDmitri Tikhonov now = lsquic_time_now(); 40250aadb33SDmitri Tikhonov 40350aadb33SDmitri Tikhonov for (i = 1; i <= 300; ++i) 40450aadb33SDmitri Tikhonov { 40550aadb33SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 40650aadb33SDmitri Tikhonov now += i * 1000; 40750aadb33SDmitri Tikhonov } 40850aadb33SDmitri Tikhonov 40950aadb33SDmitri Tikhonov for (bufsz = 200; bufsz < 210; ++bufsz) 41050aadb33SDmitri Tikhonov { 41150aadb33SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 41216a9b66aSDmitri Tikhonov lsquic_packno_t largest = 0; 41350aadb33SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, bufsz, 41450aadb33SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 41550aadb33SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 41650aadb33SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 4175392f7a3SLiteSpeed Tech &rechist, now, &has_missing, &largest, NULL); 41850aadb33SDmitri Tikhonov assert(sz[0] > 0); 41950aadb33SDmitri Tikhonov assert(sz[0] <= (int) bufsz); 42050aadb33SDmitri Tikhonov assert(has_missing); 42150aadb33SDmitri Tikhonov 42250aadb33SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 42350aadb33SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 42450aadb33SDmitri Tikhonov 4255392f7a3SLiteSpeed Tech sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 42650aadb33SDmitri Tikhonov assert(sz[1] == sz[0]); 42750aadb33SDmitri Tikhonov assert(acki.n_ranges < 256); 42850aadb33SDmitri Tikhonov 42950aadb33SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 43050aadb33SDmitri Tikhonov range && i < acki.n_ranges; 43150aadb33SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 43250aadb33SDmitri Tikhonov { 43350aadb33SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 43450aadb33SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 43550aadb33SDmitri Tikhonov } 43650aadb33SDmitri Tikhonov } 43750aadb33SDmitri Tikhonov 43850aadb33SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 43950aadb33SDmitri Tikhonov} 44050aadb33SDmitri Tikhonov 44150aadb33SDmitri Tikhonov 4425392f7a3SLiteSpeed Techstatic void 4435392f7a3SLiteSpeed Techtest_empty_ack (void) 4445392f7a3SLiteSpeed Tech{ 4455392f7a3SLiteSpeed Tech int len; 4465392f7a3SLiteSpeed Tech unsigned char buf[] = { 0x40, 0x00, 0xFF, 0xFF, 0x00, 0x00, 4475392f7a3SLiteSpeed Tech /* fluff: */ 0x12, 0x23, 0x34, 0x45, }; 4485392f7a3SLiteSpeed Tech struct ack_info acki; 4495392f7a3SLiteSpeed Tech 4505392f7a3SLiteSpeed Tech len = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 4515392f7a3SLiteSpeed Tech assert(6 == len); 4525392f7a3SLiteSpeed Tech assert(empty_ack_frame(&acki)); 4535392f7a3SLiteSpeed Tech} 4545392f7a3SLiteSpeed Tech 4555392f7a3SLiteSpeed Tech 45650aadb33SDmitri Tikhonovint 45750aadb33SDmitri Tikhonovmain (void) 45850aadb33SDmitri Tikhonov{ 459c51ce338SDmitri Tikhonov lsquic_global_init(LSQUIC_GLOBAL_SERVER); 46050aadb33SDmitri Tikhonov test1(); 46150aadb33SDmitri Tikhonov test2(); 46250aadb33SDmitri Tikhonov test3(); 46350aadb33SDmitri Tikhonov test4(); 46450aadb33SDmitri Tikhonov test5(); 46550aadb33SDmitri Tikhonov test6(); 46650aadb33SDmitri Tikhonov test_max_ack(); 46750aadb33SDmitri Tikhonov test_ack_truncation(); 4685392f7a3SLiteSpeed Tech test_empty_ack(); 46950aadb33SDmitri Tikhonov return 0; 47050aadb33SDmitri Tikhonov} 471