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