test_ackparse_ietf.c revision fb3e20e0
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#ifndef WIN32 7#include <sys/time.h> 8#else 9#include "vc_compat.h" 10#endif 11 12#include "lsquic_types.h" 13#include "lsquic_parse.h" 14#include "lsquic_rechist.h" 15#include "lsquic_util.h" 16#include "lsquic.h" 17#include "lsquic_hash.h" 18#include "lsquic_conn.h" 19 20static struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0); 21 22static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_ID27); 23 24 25static void 26test_max_ack (void) 27{ 28 lsquic_rechist_t rechist; 29 lsquic_time_t now; 30 unsigned i; 31 int has_missing, sz[2]; 32 const struct lsquic_packno_range *range; 33 unsigned char buf[1500]; 34 struct ack_info acki; 35 36 lsquic_rechist_init(&rechist, &lconn, 0); 37 now = lsquic_time_now(); 38 39 for (i = 1; i <= 300; ++i) 40 { 41 lsquic_rechist_received(&rechist, i * 10, now); 42 now += i * 1000; 43 } 44 45 memset(buf, 0xAA, sizeof(buf)); 46 47 lsquic_packno_t largest = 0; 48 sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf), 49 (gaf_rechist_first_f) lsquic_rechist_first, 50 (gaf_rechist_next_f) lsquic_rechist_next, 51 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 52 &rechist, now, &has_missing, &largest, NULL); 53 assert(sz[0] > 0); 54 assert(sz[0] <= (int) sizeof(buf)); 55 assert(has_missing); 56 57 assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 58 assert(0xAA == buf[ sz[0] ]); 59 60 sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 61 assert(sz[1] == sz[0]); 62 assert(256 == acki.n_ranges); 63 64 for (range = lsquic_rechist_first(&rechist), i = 0; 65 range && i < acki.n_ranges; 66 range = lsquic_rechist_next(&rechist), ++i) 67 { 68 assert(range->high == acki.ranges[i].high); 69 assert(range->low == acki.ranges[i].low); 70 } 71 assert(i == 256); 72 73 lsquic_rechist_cleanup(&rechist); 74} 75 76 77static void 78test_ack_truncation (void) 79{ 80 lsquic_rechist_t rechist; 81 lsquic_time_t now; 82 unsigned i; 83 int has_missing, sz[2]; 84 const struct lsquic_packno_range *range; 85 unsigned char buf[1500]; 86 struct ack_info acki; 87 size_t bufsz; 88 89 lsquic_rechist_init(&rechist, &lconn, 0); 90 now = lsquic_time_now(); 91 92 for (i = 1; i <= 300; ++i) 93 { 94 lsquic_rechist_received(&rechist, i * 10, now); 95 now += i * 1000; 96 } 97 98 for (bufsz = 200; bufsz < 210; ++bufsz) 99 { 100 memset(buf, 0xAA, sizeof(buf)); 101 lsquic_packno_t largest = 0; 102 sz[0] = pf->pf_gen_ack_frame(buf, bufsz, 103 (gaf_rechist_first_f) lsquic_rechist_first, 104 (gaf_rechist_next_f) lsquic_rechist_next, 105 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 106 &rechist, now, &has_missing, &largest, NULL); 107 assert(sz[0] > 0); 108 assert(sz[0] <= (int) bufsz); 109 assert(has_missing); 110 111 assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 112 assert(0xAA == buf[ sz[0] ]); 113 114 sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 115 assert(sz[1] == sz[0]); 116 assert(acki.n_ranges < 256); 117 118 for (range = lsquic_rechist_first(&rechist), i = 0; 119 range && i < acki.n_ranges; 120 range = lsquic_rechist_next(&rechist), ++i) 121 { 122 assert(range->high == acki.ranges[i].high); 123 assert(range->low == acki.ranges[i].low); 124 } 125 } 126 127 lsquic_rechist_cleanup(&rechist); 128} 129 130 131int 132main (void) 133{ 134 lsquic_global_init(LSQUIC_GLOBAL_SERVER); 135 test_max_ack(); 136 test_ack_truncation(); 137 return 0; 138} 139