test_ackgen_gquic_be.c revision a74702c6
1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2/* 3 * Test how ACK frame is encoded. Receive history module is tested by a 4 * separate unit test. 5 */ 6 7#include <assert.h> 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11 12#ifdef WIN32 13#include "vc_compat.h" 14#endif 15 16#include "lsquic_types.h" 17#include "lsquic_int_types.h" 18#include "lsquic_rechist.h" 19#include "lsquic_parse.h" 20#include "lsquic_util.h" 21#include "lsquic_logger.h" 22#include "lsquic.h" 23 24//static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043); // will not work on MSVC 25#define pf ((const struct parse_funcs *const)select_pf_by_ver(LSQVER_043)) 26 27static void 28test1 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock */ 29{ 30 lsquic_rechist_t rechist; 31 lsquic_time_t now = lsquic_time_now(); 32 lsquic_packno_t largest = 0; 33 34 lsquic_rechist_init(&rechist, 0, 0); 35 36 unsigned i; 37 for (i = 1; i <= 0x1234; ++i) 38 (void) lsquic_rechist_received(&rechist, i, now); 39 40 const unsigned char expected_ack_frame[] = { 41 0x45, 42 0x12, 0x34, /* Largest acked */ 43 0x87, 0xFF, /* Delta time */ 44 0x12, 0x34, /* Block length */ 45 0x00, /* Number of timestamps */ 46 }; 47 unsigned char outbuf[0x100]; 48 49 int has_missing = -1; 50 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 51 (gaf_rechist_first_f) lsquic_rechist_first, 52 (gaf_rechist_next_f) lsquic_rechist_next, 53 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 54 &rechist, now + 0x7FF8000, &has_missing, &largest, NULL); 55 assert(("ACK frame generation successful", w > 0)); 56 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 57 assert(("ACK frame contents are as expected", 58 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 59 assert(("ACK frame has no missing packets", has_missing == 0)); 60 assert(largest == 0x1234); 61 62 lsquic_rechist_cleanup(&rechist); 63} 64 65static void 66test2 (void) /* Inverse of quic_framer_test.cc -- NewAckFrameOneAckBlock, minus 67 * delta times. 68 */ 69{ 70 lsquic_rechist_t rechist; 71 lsquic_time_t now = lsquic_time_now(); 72 73 lsquic_rechist_init(&rechist, 0, 0); 74 75 /* Encode the following ranges: 76 * high low 77 * 0x1234 0x1234 78 * 0x1232 0x384 79 * 0x1F3 0xA 80 * 0x4 0x1 81 */ 82 unsigned i; 83 for (i = 4; i >= 1; --i) 84 (void) lsquic_rechist_received(&rechist, i, now); 85 (void) lsquic_rechist_received(&rechist, 0x1234, now); 86 for (i = 0xA; i <= 0x1F3; ++i) 87 (void) lsquic_rechist_received(&rechist, i, now); 88 for (i = 0x1232; i >= 0x384; --i) 89 (void) lsquic_rechist_received(&rechist, i, now); 90 91 const unsigned char expected_ack_frame[] = { 92 0x65, 93 0x12, 0x34, /* Largest acked */ 94 0x00, 0x00, /* Zero delta time. */ 95 0x04, /* Num ack blocks ranges. */ 96 0x00, 0x01, /* First ack block length. */ 97 0x01, /* Gap to next block. */ 98 0x0e, 0xaf, /* Ack block length. */ 99 0xff, /* Gap to next block. */ 100 0x00, 0x00, /* Ack block length. */ 101 0x91, /* Gap to next block. */ 102 0x01, 0xea, /* Ack block length. */ 103 0x05, /* Gap to next block. */ 104 0x00, 0x04, /* Ack block length. */ 105 0x00, /* Number of timestamps. */ 106 }; 107 unsigned char outbuf[0x100]; 108 109 int has_missing = -1; 110 lsquic_packno_t largest = 0; 111 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 112 (gaf_rechist_first_f) lsquic_rechist_first, 113 (gaf_rechist_next_f) lsquic_rechist_next, 114 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 115 &rechist, now, &has_missing, &largest, NULL); 116 assert(("ACK frame generation successful", w > 0)); 117 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 118 assert(("ACK frame contents are as expected", 119 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 120 assert(("ACK frame has missing packets", has_missing > 0)); 121 assert(largest == 0x1234); 122 123 lsquic_rechist_cleanup(&rechist); 124} 125 126static void 127test3 (void) 128{ 129 lsquic_rechist_t rechist; 130 lsquic_time_t now = lsquic_time_now(); 131 132 lsquic_rechist_init(&rechist, 0, 0); 133 134 /* Encode the following ranges: 135 * high low 136 * 3 3 137 * 1 1 138 */ 139 (void) lsquic_rechist_received(&rechist, 1, now); 140 (void) lsquic_rechist_received(&rechist, 3, now); 141 142 const unsigned char expected_ack_frame[] = { 143 0x60, 144 0x03, 145 0x00, 0x00, /* Zero delta time. */ 146 0x01, /* Num ack blocks ranges. */ 147 0x01, /* First ack block length. */ 148 0x01, /* Gap to next block. */ 149 0x01, /* Ack block length. */ 150 0x00, /* Number of timestamps. */ 151 }; 152 unsigned char outbuf[0x100]; 153 154 int has_missing = -1; 155 lsquic_packno_t largest = 0; 156 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 157 (gaf_rechist_first_f) lsquic_rechist_first, 158 (gaf_rechist_next_f) lsquic_rechist_next, 159 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 160 &rechist, now, &has_missing, &largest, NULL); 161 assert(("ACK frame generation successful", w > 0)); 162 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 163 assert(("ACK frame contents are as expected", 164 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 165 assert(("ACK frame has missing packets", has_missing > 0)); 166 assert(largest == 0x03); 167 168 lsquic_rechist_cleanup(&rechist); 169} 170 171 172static void 173test4 (void) 174{ 175 lsquic_rechist_t rechist; 176 int i; 177 178 lsquic_rechist_init(&rechist, 0, 0); 179 180 lsquic_time_t now = lsquic_time_now(); 181 lsquic_rechist_received(&rechist, 1, now); 182 183 { 184 const unsigned char expected_ack_frame[] = { 185 0x40, 186 0x01, /* Largest acked */ 187 0x00, 0x00, /* Delta time */ 188 0x01, /* Block length */ 189 0x00, /* Number of timestamps */ 190 }; 191 unsigned char outbuf[0x100]; 192 int has_missing = -1; 193 lsquic_packno_t largest = 0; 194 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 195 (gaf_rechist_first_f) lsquic_rechist_first, 196 (gaf_rechist_next_f) lsquic_rechist_next, 197 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 198 &rechist, now, &has_missing, &largest, NULL); 199 assert(("ACK frame generation successful", w > 0)); 200 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 201 assert(("ACK frame contents are as expected", 202 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 203 assert(("ACK frame has no missing packets", has_missing == 0)); 204 assert(largest == 1); 205 } 206 207 for (i = 3; i <= 5; ++i) 208 lsquic_rechist_received(&rechist, i, now); 209 210 { 211 const unsigned char expected_ack_frame[] = { 212 0x60, 213 0x05, /* Largest acked */ 214 0x00, 0x00, /* Delta time */ 215 0x01, /* Num ack blocks */ 216 0x03, /* First block length [3, 5] */ 217 0x01, /* Gap to next block */ 218 0x01, /* Second block length [1, 1] */ 219 0x00, /* Number of timestamps */ 220 }; 221 unsigned char outbuf[0x100]; 222 int has_missing = -1; 223 lsquic_packno_t largest = 0; 224 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 225 (gaf_rechist_first_f) lsquic_rechist_first, 226 (gaf_rechist_next_f) lsquic_rechist_next, 227 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 228 &rechist, now, &has_missing, &largest, NULL); 229 assert(("ACK frame generation successful", w > 0)); 230 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 231 assert(("ACK frame contents are as expected", 232 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 233 assert(("ACK frame has missing packets", has_missing > 0)); 234 assert(largest == 5); 235 } 236 237 lsquic_rechist_cleanup(&rechist); 238} 239 240 241static void 242test_4byte_packnos (void) 243{ 244 lsquic_packno_t packno; 245 lsquic_rechist_t rechist; 246 lsquic_time_t now = lsquic_time_now(); 247 248 lsquic_rechist_init(&rechist, 0, 0); 249 250 packno = 0x23456789; 251 (void) lsquic_rechist_received(&rechist, packno - 33, now); 252 (void) lsquic_rechist_received(&rechist, packno, now); 253 254 /* Adjust: */ 255 rechist.rh_elems[0].re_low = 1; 256 rechist.rh_elems[0].re_count = packno - 33; 257 258 const unsigned char expected_ack_frame[] = { 259 0x60 260 | (2 << 2) /* Four-byte largest acked */ 261 | (2 << 0) /* Four-byte ACK block length */ 262 , 263 0x23, 0x45, 0x67, 0x89, 264 0x00, 0x00, /* Zero delta time. */ 265 0x01, /* Num ack blocks ranges. */ 266 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 267 33 - 1, /* Gap to next block. */ 268 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 269 0x00, /* Number of timestamps. */ 270 }; 271 unsigned char outbuf[0x100]; 272 273 int has_missing = -1; 274 lsquic_packno_t largest = 0; 275 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 276 (gaf_rechist_first_f) lsquic_rechist_first, 277 (gaf_rechist_next_f) lsquic_rechist_next, 278 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 279 &rechist, now, &has_missing, &largest, NULL); 280 assert(("ACK frame generation successful", w > 0)); 281 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 282 assert(("ACK frame contents are as expected", 283 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 284 assert(("ACK frame has missing packets", has_missing > 0)); 285 assert(largest == 0x23456789); 286 287 lsquic_rechist_cleanup(&rechist); 288} 289 290 291/* lsquic_rechist no longer supports ranges that require integers 292 * wider than four bytes -- modify the test to use a custom receive 293 * history. 294 */ 295static const struct lsquic_packno_range test_6byte_ranges[] = { 296 { .high = 0xABCD23456789, .low = 0xABCD23456789, }, 297 { .high = 0xABCD23456789 - 33, .low = 1, }, 298}; 299 300 301static const struct lsquic_packno_range * 302test_6byte_rechist_first (void *rechist) 303{ 304 int *next = rechist; 305 *next = 1; 306 return &test_6byte_ranges[0]; 307}; 308 309 310static const struct lsquic_packno_range * 311test_6byte_rechist_next (void *rechist) 312{ 313 int *next = rechist; 314 if (*next == 1) 315 { 316 ++*next; 317 return &test_6byte_ranges[1]; 318 } 319 else 320 return NULL; 321} 322 323 324static lsquic_time_t s_test_6byte_now; 325static lsquic_time_t 326test_6byte_rechist_largest_recv (void *rechist) 327{ 328 return s_test_6byte_now; 329} 330 331 332static void 333test_6byte_packnos (void) 334{ 335 int rechist = 0; 336 s_test_6byte_now = lsquic_time_now(); 337 338 const unsigned char expected_ack_frame[] = { 339 0x60 340 | (3 << 2) /* Six-byte largest acked */ 341 | (3 << 0) /* Six-byte ACK block length */ 342 , 343 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89, 344 0x00, 0x00, /* Zero delta time. */ 345 0x01, /* Num ack blocks ranges. */ 346 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 347 33 - 1, /* Gap to next block. */ 348 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 349 0x00, /* Number of timestamps. */ 350 }; 351 unsigned char outbuf[0x100]; 352 353 int has_missing = -1; 354 lsquic_packno_t largest = 0; 355 int w = pf->pf_gen_ack_frame(outbuf, sizeof(outbuf), 356 test_6byte_rechist_first, 357 test_6byte_rechist_next, 358 test_6byte_rechist_largest_recv, 359 &rechist, s_test_6byte_now, &has_missing, &largest, NULL); 360 assert(("ACK frame generation successful", w > 0)); 361 assert(("ACK frame length is correct", w == sizeof(expected_ack_frame))); 362 assert(("ACK frame contents are as expected", 363 0 == memcmp(outbuf, expected_ack_frame, sizeof(expected_ack_frame)))); 364 assert(("ACK frame has missing packets", has_missing > 0)); 365 assert(largest == 0xABCD23456789ULL); 366} 367 368 369int 370main (void) 371{ 372 lsquic_global_init(LSQUIC_GLOBAL_SERVER); 373 lsquic_log_to_fstream(stderr, 0); 374 lsq_log_levels[LSQLM_PARSE] = LSQ_LOG_DEBUG; 375 376 test1(); 377 378 test2(); 379 380 test3(); 381 382 test4(); 383 384 test_4byte_packnos(); 385 386 test_6byte_packnos(); 387 388 return 0; 389} 390