1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2767cf611SDmitri Tikhonov#include <assert.h> 3767cf611SDmitri Tikhonov#include <stdio.h> 4767cf611SDmitri Tikhonov#include <stdlib.h> 5767cf611SDmitri Tikhonov#include <string.h> 6b62ec17fSDmitri Tikhonov#include <sys/queue.h> 7767cf611SDmitri Tikhonov#ifndef WIN32 8767cf611SDmitri Tikhonov#include <sys/time.h> 9fb3e20e0SDmitri Tikhonov#else 10fb3e20e0SDmitri Tikhonov#include "vc_compat.h" 11767cf611SDmitri Tikhonov#endif 12767cf611SDmitri Tikhonov 13767cf611SDmitri Tikhonov#include "lsquic_types.h" 14767cf611SDmitri Tikhonov#include "lsquic_parse.h" 15767cf611SDmitri Tikhonov#include "lsquic_rechist.h" 16767cf611SDmitri Tikhonov#include "lsquic_util.h" 17767cf611SDmitri Tikhonov#include "lsquic.h" 18767cf611SDmitri Tikhonov#include "lsquic_hash.h" 19767cf611SDmitri Tikhonov#include "lsquic_conn.h" 20767cf611SDmitri Tikhonov 21767cf611SDmitri Tikhonovstatic struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0); 22767cf611SDmitri Tikhonov 23f07b3eaeSTyler Young//static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_ID27); // will not work on MSVC 24f07b3eaeSTyler Young#define pf ((const struct parse_funcs *const)select_pf_by_ver(LSQVER_ID27)) 25767cf611SDmitri Tikhonov 26767cf611SDmitri Tikhonov 27767cf611SDmitri Tikhonovstatic void 28767cf611SDmitri Tikhonovtest_max_ack (void) 29767cf611SDmitri Tikhonov{ 30767cf611SDmitri Tikhonov lsquic_rechist_t rechist; 31767cf611SDmitri Tikhonov lsquic_time_t now; 32767cf611SDmitri Tikhonov unsigned i; 33767cf611SDmitri Tikhonov int has_missing, sz[2]; 34767cf611SDmitri Tikhonov const struct lsquic_packno_range *range; 35767cf611SDmitri Tikhonov unsigned char buf[1500]; 36767cf611SDmitri Tikhonov struct ack_info acki; 37767cf611SDmitri Tikhonov 38f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 39767cf611SDmitri Tikhonov now = lsquic_time_now(); 40767cf611SDmitri Tikhonov 41767cf611SDmitri Tikhonov for (i = 1; i <= 300; ++i) 42767cf611SDmitri Tikhonov { 43767cf611SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 44767cf611SDmitri Tikhonov now += i * 1000; 45767cf611SDmitri Tikhonov } 46767cf611SDmitri Tikhonov 47767cf611SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 48767cf611SDmitri Tikhonov 49767cf611SDmitri Tikhonov lsquic_packno_t largest = 0; 50767cf611SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf), 51767cf611SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 52767cf611SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 53767cf611SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 54767cf611SDmitri Tikhonov &rechist, now, &has_missing, &largest, NULL); 55767cf611SDmitri Tikhonov assert(sz[0] > 0); 56767cf611SDmitri Tikhonov assert(sz[0] <= (int) sizeof(buf)); 57767cf611SDmitri Tikhonov assert(has_missing); 58767cf611SDmitri Tikhonov 59767cf611SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 60767cf611SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 61767cf611SDmitri Tikhonov 62767cf611SDmitri Tikhonov sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 63767cf611SDmitri Tikhonov assert(sz[1] == sz[0]); 64767cf611SDmitri Tikhonov assert(256 == acki.n_ranges); 65767cf611SDmitri Tikhonov 66767cf611SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 67767cf611SDmitri Tikhonov range && i < acki.n_ranges; 68767cf611SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 69767cf611SDmitri Tikhonov { 70767cf611SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 71767cf611SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 72767cf611SDmitri Tikhonov } 73767cf611SDmitri Tikhonov assert(i == 256); 74767cf611SDmitri Tikhonov 75767cf611SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 76767cf611SDmitri Tikhonov} 77767cf611SDmitri Tikhonov 78767cf611SDmitri Tikhonov 79767cf611SDmitri Tikhonovstatic void 80767cf611SDmitri Tikhonovtest_ack_truncation (void) 81767cf611SDmitri Tikhonov{ 82767cf611SDmitri Tikhonov lsquic_rechist_t rechist; 83767cf611SDmitri Tikhonov lsquic_time_t now; 84767cf611SDmitri Tikhonov unsigned i; 85767cf611SDmitri Tikhonov int has_missing, sz[2]; 86767cf611SDmitri Tikhonov const struct lsquic_packno_range *range; 87767cf611SDmitri Tikhonov unsigned char buf[1500]; 88767cf611SDmitri Tikhonov struct ack_info acki; 89767cf611SDmitri Tikhonov size_t bufsz; 90767cf611SDmitri Tikhonov 91f38b395aSDmitri Tikhonov lsquic_rechist_init(&rechist, 0, 0); 92767cf611SDmitri Tikhonov now = lsquic_time_now(); 93767cf611SDmitri Tikhonov 94767cf611SDmitri Tikhonov for (i = 1; i <= 300; ++i) 95767cf611SDmitri Tikhonov { 96767cf611SDmitri Tikhonov lsquic_rechist_received(&rechist, i * 10, now); 97767cf611SDmitri Tikhonov now += i * 1000; 98767cf611SDmitri Tikhonov } 99767cf611SDmitri Tikhonov 100767cf611SDmitri Tikhonov for (bufsz = 200; bufsz < 210; ++bufsz) 101767cf611SDmitri Tikhonov { 102767cf611SDmitri Tikhonov memset(buf, 0xAA, sizeof(buf)); 103767cf611SDmitri Tikhonov lsquic_packno_t largest = 0; 104767cf611SDmitri Tikhonov sz[0] = pf->pf_gen_ack_frame(buf, bufsz, 105767cf611SDmitri Tikhonov (gaf_rechist_first_f) lsquic_rechist_first, 106767cf611SDmitri Tikhonov (gaf_rechist_next_f) lsquic_rechist_next, 107767cf611SDmitri Tikhonov (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 108767cf611SDmitri Tikhonov &rechist, now, &has_missing, &largest, NULL); 109767cf611SDmitri Tikhonov assert(sz[0] > 0); 110767cf611SDmitri Tikhonov assert(sz[0] <= (int) bufsz); 111767cf611SDmitri Tikhonov assert(has_missing); 112767cf611SDmitri Tikhonov 113767cf611SDmitri Tikhonov assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 114767cf611SDmitri Tikhonov assert(0xAA == buf[ sz[0] ]); 115767cf611SDmitri Tikhonov 116767cf611SDmitri Tikhonov sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 117767cf611SDmitri Tikhonov assert(sz[1] == sz[0]); 118767cf611SDmitri Tikhonov assert(acki.n_ranges < 256); 119767cf611SDmitri Tikhonov 120767cf611SDmitri Tikhonov for (range = lsquic_rechist_first(&rechist), i = 0; 121767cf611SDmitri Tikhonov range && i < acki.n_ranges; 122767cf611SDmitri Tikhonov range = lsquic_rechist_next(&rechist), ++i) 123767cf611SDmitri Tikhonov { 124767cf611SDmitri Tikhonov assert(range->high == acki.ranges[i].high); 125767cf611SDmitri Tikhonov assert(range->low == acki.ranges[i].low); 126767cf611SDmitri Tikhonov } 127767cf611SDmitri Tikhonov } 128767cf611SDmitri Tikhonov 129767cf611SDmitri Tikhonov lsquic_rechist_cleanup(&rechist); 130767cf611SDmitri Tikhonov} 131767cf611SDmitri Tikhonov 132767cf611SDmitri Tikhonov 133767cf611SDmitri Tikhonovint 134767cf611SDmitri Tikhonovmain (void) 135767cf611SDmitri Tikhonov{ 136767cf611SDmitri Tikhonov lsquic_global_init(LSQUIC_GLOBAL_SERVER); 137767cf611SDmitri Tikhonov test_max_ack(); 138767cf611SDmitri Tikhonov test_ack_truncation(); 139767cf611SDmitri Tikhonov return 0; 140767cf611SDmitri Tikhonov} 141