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