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