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