test_ackparse_gquic_be.c revision 06b2a236
106b2a236SDmitri Tikhonov/* Copyright (c) 2017 - 2021 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