test_ackparse_gquic_be.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <sys/queue.h> 7#ifndef WIN32 8#include <sys/time.h> 9#else 10#include "vc_compat.h" 11#endif 12 13#include "lsquic_types.h" 14#include "lsquic_parse.h" 15#include "lsquic_rechist.h" 16#include "lsquic_util.h" 17#include "lsquic.h" 18#include "lsquic_hash.h" 19#include "lsquic_conn.h" 20 21static struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0); 22 23static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_043); 24 25 26static lsquic_packno_t 27n_acked (const struct ack_info *acki) 28{ 29 lsquic_packno_t n = 0; 30 unsigned i; 31 for (i = 0; i < acki->n_ranges; ++i) 32 n += acki->ranges[i].high - acki->ranges[i].low + 1; 33 return n; 34} 35 36 37static void 38test1 (void) 39{ 40 /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 41 unsigned char ack_buf[] = { 42 0x45, 43 0x12, 0x34, /* Largest acked */ 44 0x00, 0x00, /* Delta time */ 45 0x12, 0x34, /* Block length */ 46 0x00, /* Number of timestamps */ 47 }; 48 49 struct ack_info acki; 50 memset(&acki, 0xF1, sizeof(acki)); 51 52 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 53 assert(("Parsed length is correct (8)", len == sizeof(ack_buf))); 54 assert(("Number of ranges is 1", acki.n_ranges == 1)); 55 assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 56 assert(("Lowest acked is 1", acki.ranges[0].low == 1)); 57 unsigned n = n_acked(&acki); 58 assert(("Number of acked packets is 0x1234", n == 0x1234)); 59 60 { 61 size_t sz; 62 for (sz = 1; sz < sizeof(ack_buf); ++sz) 63 { 64 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 65 assert(("Parsing truncated frame failed", len < 0)); 66 } 67 } 68} 69 70 71static void 72test2 (void) 73{ 74 /* Test taken from quic_framer_test.cc -- NewAckFrameOneAckBlock */ 75 unsigned char ack_buf[] = { 76 0x65, 77 0x12, 0x34, /* Largest acked */ 78 0x00, 0x00, /* Zero delta time. */ 79 0x04, /* Num ack blocks ranges. */ 80 0x00, 0x01, /* First ack block length. */ 81 0x01, /* Gap to next block. */ 82 0x0e, 0xaf, /* Ack block length. */ 83 0xff, /* Gap to next block. */ 84 0x00, 0x00, /* Ack block length. */ 85 0x91, /* Gap to next block. */ 86 0x01, 0xea, /* Ack block length. */ 87 0x05, /* Gap to next block. */ 88 0x00, 0x04, /* Ack block length. */ 89 0x02, /* Number of timestamps. */ 90 0x01, /* Delta from largest observed. */ 91 0x10, 0x32, 0x54, 0x76, /* Delta time. */ /* XXX do we use this at all? */ 92 0x02, /* Delta from largest observed. */ 93 0x10, 0x32, /* Delta time. */ 94 }; 95 96 /* We should get the following array of ranges: 97 * high low 98 * 0x1234 0x1234 99 * 0x1232 0x384 100 * 0x1F3 0xA 101 * 0x4 0x1 102 */ 103 static const struct { unsigned high, low; } ranges[] = { 104 { 0x1234, 0x1234 }, 105 { 0x1232, 0x384 }, 106 { 0x1F3, 0xA }, 107 { 0x4, 0x1 }, 108 }; 109 110 struct ack_info acki; 111 memset(&acki, 0xF1, sizeof(acki)); 112 113 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 114 assert(("Parsed length is correct (29)", len == sizeof(ack_buf))); 115 assert(("Number of ranges is 4", acki.n_ranges == 4)); 116 assert(("Largest acked is 0x1234", acki.ranges[0].high == 0x1234)); 117 unsigned n = n_acked(&acki); 118 assert(("Number of acked packets is 4254", n == 4254)); 119 120 for (n = 0; n < 4; ++n) 121 assert(("Range checks out", ranges[n].high == acki.ranges[n].high 122 && ranges[n].low == acki.ranges[n].low)); 123 124 { 125 size_t sz; 126 for (sz = 1; sz < sizeof(ack_buf); ++sz) 127 { 128 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 129 assert(("Parsing truncated frame failed", len < 0)); 130 } 131 } 132} 133 134 135static void 136test3 (void) 137{ 138 /* Generated by our own code, but failed to parse... */ 139 unsigned char ack_buf[] = { 140 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 141 0x06, /* Largest ACKed */ 142 0x00, 0x00, /* Delta time */ 143 0x01, /* Num ACK block ranges */ 144 0x01, /* First ACK block length */ 145 0x02, /* Gap to next block */ 146 0x03, /* Ack block length */ 147 0x00 /* Number of timestamps */ 148 }; 149 150 /* We should get the following array of ranges: 151 * high low 152 * 6 6 153 * 3 1 154 */ 155 static const struct { unsigned high, low; } ranges[] = { 156 { 6, 6, }, 157 { 3, 1, }, 158 }; 159 160 struct ack_info acki; 161 memset(&acki, 0xF1, sizeof(acki)); 162 163 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 164 assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 165 assert(("Number of ranges is 2", acki.n_ranges == 2)); 166 assert(("Largest acked is 6", acki.ranges[0].high == 6)); 167 unsigned n = n_acked(&acki); 168 assert(("Number of acked packets is 4", n == 4)); 169 170 for (n = 0; n < 2; ++n) 171 assert(("Range checks out", ranges[n].high == acki.ranges[n].high 172 && ranges[n].low == acki.ranges[n].low)); 173 174 { 175 size_t sz; 176 for (sz = 1; sz < sizeof(ack_buf); ++sz) 177 { 178 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 179 assert(("Parsing truncated frame failed", len < 0)); 180 } 181 } 182} 183 184 185static void 186test4 (void) 187{ 188 unsigned char ack_buf[] = { 189 0x60, /* More than one ack block, 1 byte largest observed, 1 byte block length */ 190 0x03, /* Largest ACKed */ 191 0x23, 0x00, /* Delta time */ 192 0x01, /* Num ACK block ranges */ 193 0x01, /* First ack block length */ 194 0x01, /* Gap */ 195 0x01, /* Ack block length */ 196 0x00, /* Number of timestamps */ 197 }; 198 199 /* We should get the following array of ranges: 200 * high low 201 * 6 6 202 * 3 1 203 */ 204 static const struct { unsigned high, low; } ranges[] = { 205 { 3, 3, }, 206 { 1, 1, }, 207 }; 208 209 struct ack_info acki; 210 memset(&acki, 0xF1, sizeof(acki)); 211 212 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 213 assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 214 assert(("Number of ranges is 2", acki.n_ranges == 2)); 215 assert(("Largest acked is 3", acki.ranges[0].high == 3)); 216 unsigned n = n_acked(&acki); 217 assert(("Number of acked packets is 2", n == 2)); 218 219 for (n = 0; n < 2; ++n) 220 assert(("Range checks out", ranges[n].high == acki.ranges[n].high 221 && ranges[n].low == acki.ranges[n].low)); 222 223 { 224 size_t sz; 225 for (sz = 1; sz < sizeof(ack_buf); ++sz) 226 { 227 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 228 assert(("Parsing truncated frame failed", len < 0)); 229 } 230 } 231} 232 233 234/* Four-byte packet numbers */ 235static void 236test5 (void) 237{ 238 unsigned char ack_buf[] = { 239 0x60 240 | (2 << 2) /* Four-byte largest acked */ 241 | (2 << 0) /* Four-byte ACK block length */ 242 , 243 0x23, 0x45, 0x67, 0x89, 244 0x00, 0x00, /* Zero delta time. */ 245 0x01, /* Num ack blocks ranges. */ 246 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 247 33 - 1, /* Gap to next block. */ 248 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 249 0x00, /* Number of timestamps. */ 250 }; 251 252 /* We should get the following array of ranges: 253 * high low 254 * 6 6 255 * 3 1 256 */ 257 static const struct { unsigned high, low; } ranges[] = { 258 { 0x23456789, 0x23456789, }, 259 { 0x23456768, 1, }, 260 }; 261 262 struct ack_info acki; 263 memset(&acki, 0xF1, sizeof(acki)); 264 265 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 266 assert(("Parsed length is correct (9)", len == sizeof(ack_buf))); 267 assert(("Number of ranges is 2", acki.n_ranges == 2)); 268 assert(("Largest acked is 0x23456789", acki.ranges[0].high == 0x23456789)); 269 lsquic_packno_t n = n_acked(&acki); 270 assert(("Number of acked packets is correct", n == 0x23456768 + 1)); 271 272 for (n = 0; n < 2; ++n) 273 assert(("Range checks out", ranges[n].high == acki.ranges[n].high 274 && ranges[n].low == acki.ranges[n].low)); 275 276 { 277 size_t sz; 278 for (sz = 1; sz < sizeof(ack_buf); ++sz) 279 { 280 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 281 assert(("Parsing truncated frame failed", len < 0)); 282 } 283 } 284} 285 286 287/* Six-byte packet numbers */ 288static void 289test6 (void) 290{ 291 unsigned char ack_buf[] = { 292 0x60 293 | (3 << 2) /* Six-byte largest acked */ 294 | (3 << 0) /* Six-byte ACK block length */ 295 , 296 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x89, 297 0x00, 0x00, /* Zero delta time. */ 298 0x01, /* Num ack blocks ranges. */ 299 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* First ack block length. */ 300 33 - 1, /* Gap to next block. */ 301 0xAB, 0xCD, 0x23, 0x45, 0x67, 0x68, /* Ack block length. */ 302 0x00, /* Number of timestamps. */ 303 }; 304 305 static const struct { lsquic_packno_t high, low; } ranges[] = { 306 { 0xABCD23456789, 0xABCD23456789, }, 307 { 0xABCD23456768, 1, }, 308 }; 309 310 struct ack_info acki; 311 memset(&acki, 0xF1, sizeof(acki)); 312 313 int len = pf->pf_parse_ack_frame(ack_buf, sizeof(ack_buf), &acki, 0); 314 assert(("Parsed length is correct", len == sizeof(ack_buf))); 315 assert(("Number of ranges is 2", acki.n_ranges == 2)); 316 assert(("Largest acked is 0xABCD23456789", acki.ranges[0].high == 0xABCD23456789)); 317 lsquic_packno_t n = n_acked(&acki); 318 assert(("Number of acked packets is correct", n == 0xABCD23456768 + 1)); 319 320 for (n = 0; n < 2; ++n) 321 assert(("Range checks out", ranges[n].high == acki.ranges[n].high 322 && ranges[n].low == acki.ranges[n].low)); 323 324 { 325 size_t sz; 326 for (sz = 1; sz < sizeof(ack_buf); ++sz) 327 { 328 len = pf->pf_parse_ack_frame(ack_buf, sz, &acki, 0); 329 assert(("Parsing truncated frame failed", len < 0)); 330 } 331 } 332} 333 334 335static void 336test_max_ack (void) 337{ 338 lsquic_rechist_t rechist; 339 lsquic_time_t now; 340 unsigned i; 341 int has_missing, sz[2]; 342 const struct lsquic_packno_range *range; 343 unsigned char buf[1500]; 344 struct ack_info acki; 345 346 lsquic_rechist_init(&rechist, 0, 0); 347 now = lsquic_time_now(); 348 349 for (i = 1; i <= 300; ++i) 350 { 351 lsquic_rechist_received(&rechist, i * 10, now); 352 now += i * 1000; 353 } 354 355 memset(buf, 0xAA, sizeof(buf)); 356 357 lsquic_packno_t largest = 0; 358 sz[0] = pf->pf_gen_ack_frame(buf, sizeof(buf), 359 (gaf_rechist_first_f) lsquic_rechist_first, 360 (gaf_rechist_next_f) lsquic_rechist_next, 361 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 362 &rechist, now, &has_missing, &largest, NULL); 363 assert(sz[0] > 0); 364 assert(sz[0] <= (int) sizeof(buf)); 365 assert(has_missing); 366 367 assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 368 assert(0xAA == buf[ sz[0] ]); 369 370 sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 371 assert(sz[1] == sz[0]); 372 assert(256 == acki.n_ranges); 373 374 for (range = lsquic_rechist_first(&rechist), i = 0; 375 range && i < acki.n_ranges; 376 range = lsquic_rechist_next(&rechist), ++i) 377 { 378 assert(range->high == acki.ranges[i].high); 379 assert(range->low == acki.ranges[i].low); 380 } 381 assert(i == 256); 382 383 lsquic_rechist_cleanup(&rechist); 384} 385 386 387static void 388test_ack_truncation (void) 389{ 390 lsquic_rechist_t rechist; 391 lsquic_time_t now; 392 unsigned i; 393 int has_missing, sz[2]; 394 const struct lsquic_packno_range *range; 395 unsigned char buf[1500]; 396 struct ack_info acki; 397 size_t bufsz; 398 399 lsquic_rechist_init(&rechist, 0, 0); 400 now = lsquic_time_now(); 401 402 for (i = 1; i <= 300; ++i) 403 { 404 lsquic_rechist_received(&rechist, i * 10, now); 405 now += i * 1000; 406 } 407 408 for (bufsz = 200; bufsz < 210; ++bufsz) 409 { 410 memset(buf, 0xAA, sizeof(buf)); 411 lsquic_packno_t largest = 0; 412 sz[0] = pf->pf_gen_ack_frame(buf, bufsz, 413 (gaf_rechist_first_f) lsquic_rechist_first, 414 (gaf_rechist_next_f) lsquic_rechist_next, 415 (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv, 416 &rechist, now, &has_missing, &largest, NULL); 417 assert(sz[0] > 0); 418 assert(sz[0] <= (int) bufsz); 419 assert(has_missing); 420 421 assert(0 == buf[ sz[0] - 1 ]); /* Number of timestamps */ 422 assert(0xAA == buf[ sz[0] ]); 423 424 sz[1] = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 425 assert(sz[1] == sz[0]); 426 assert(acki.n_ranges < 256); 427 428 for (range = lsquic_rechist_first(&rechist), i = 0; 429 range && i < acki.n_ranges; 430 range = lsquic_rechist_next(&rechist), ++i) 431 { 432 assert(range->high == acki.ranges[i].high); 433 assert(range->low == acki.ranges[i].low); 434 } 435 } 436 437 lsquic_rechist_cleanup(&rechist); 438} 439 440 441static void 442test_empty_ack (void) 443{ 444 int len; 445 unsigned char buf[] = { 0x40, 0x00, 0xFF, 0xFF, 0x00, 0x00, 446 /* fluff: */ 0x12, 0x23, 0x34, 0x45, }; 447 struct ack_info acki; 448 449 len = pf->pf_parse_ack_frame(buf, sizeof(buf), &acki, 0); 450 assert(6 == len); 451 assert(empty_ack_frame(&acki)); 452} 453 454 455int 456main (void) 457{ 458 lsquic_global_init(LSQUIC_GLOBAL_SERVER); 459 test1(); 460 test2(); 461 test3(); 462 test4(); 463 test5(); 464 test6(); 465 test_max_ack(); 466 test_ack_truncation(); 467 test_empty_ack(); 468 return 0; 469} 470