test_streamparse.c revision a74702c6
1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#ifndef WIN32 7#include <sys/time.h> 8#endif 9#include <sys/queue.h> 10 11#include "lsquic.h" 12#include "lsquic_types.h" 13#include "lsquic_parse.h" 14#include "lsquic_packet_common.h" 15#include "lsquic_packet_in.h" 16 17struct test { 18 const char *name; 19 int lineno; 20 const struct parse_funcs * 21 pf; 22 const unsigned char 23 buf[0x100]; /* Large enough for our needs */ 24 size_t buf_sz; /* # of stream frame bytes in `buf' */ 25 size_t rem_packet_sz; /* # of bytes remaining in the packet, 26 * starting at the beginning of the 27 * stream frame. 28 */ 29 stream_frame_t frame; /* Expected values */ 30 int should_succeed; 31}; 32 33static void 34run_test (const struct test *test) 35{ 36 stream_frame_t frame; 37 memset(&frame, 0x7A, sizeof(frame)); 38 39 int len = test->pf->pf_parse_stream_frame(test->buf, test->rem_packet_sz, &frame); 40 41 if (test->should_succeed) { 42 /* Check parser operation */ 43 assert(("Parsed correct number of bytes", (size_t) len == test->buf_sz + test->frame.data_frame.df_size)); 44 assert(("Stream ID is correct", frame.stream_id == test->frame.stream_id)); 45 assert(("Data length is correct", frame.data_frame.df_size == test->frame.data_frame.df_size)); 46 assert(("Offset is correct", frame.data_frame.df_offset == test->frame.data_frame.df_offset)); 47 assert(("FIN is correct", frame.data_frame.df_fin == test->frame.data_frame.df_fin)); 48 49 /* Check that initialization of other fields occurred correctly: */ 50 assert(0 == frame.packet_in); 51 assert(0 == frame.data_frame.df_read_off); 52 } 53 else 54 { 55 assert(("This test should fail", len < 0)); 56 } 57} 58 59 60int 61main (void) 62{ 63 64 const struct test tests[] = { 65 66 /* 67 * Big-endian tests 68 */ 69 { "Balls to the wall: every possible bit is set", 70 __LINE__, 71 select_pf_by_ver(LSQVER_043), 72 /* 1 f d ooo ss 1fdoooss */ 73 /* TYPE FIN DLEN OLEN SLEN */ 74 { 0x80 | 0x40 | 0x20 | 0x1C | 0x3, 75 0x00, 0x00, 0x02, 0x10, /* Stream ID */ 76 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Offset */ 77 0x01, 0xC4, /* Data length */ 78 }, 79 1 + 2 + 8 + 4, 80 0x200, 81 { .data_frame.df_offset = 0x0807060504030201UL, 82 .stream_id = 0x210, 83 .data_frame.df_size = 0x1C4, 84 .data_frame.df_fin = 1, 85 }, 86 1, 87 }, 88 89 { "Balls to the wall #2: every possible bit is set, except FIN", 90 __LINE__, 91 select_pf_by_ver(LSQVER_043), 92 /* 1 f d ooo ss 1fdoooss */ 93 /* TYPE FIN DLEN OLEN SLEN */ 94 { 0x80 | 0x00 | 0x20 | 0x1C | 0x3, 95 0x00, 0x00, 0x02, 0x10, /* Stream ID */ 96 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Offset */ 97 0x01, 0xC4, /* Data length */ 98 }, 99 1 + 2 + 8 + 4, 100 0x200, 101 { .data_frame.df_offset = 0x0807060504030201UL, 102 .stream_id = 0x210, 103 .data_frame.df_size = 0x1C4, 104 .data_frame.df_fin = 0, 105 }, 106 1, 107 }, 108 109 { "Data length is zero", 110 __LINE__, 111 select_pf_by_ver(LSQVER_043), 112 /* 1 f d ooo ss 1fdoooss */ 113 /* TYPE FIN DLEN OLEN SLEN */ 114 { 0x80 | 0x40 | 0x00 | 0x1C | 0x3, 115 0x00, 0x00, 0x02, 0x10, /* Stream ID */ 116 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Offset */ 117 0xC4, 0x01, /* Data length: note this does not matter */ 118 }, 119 1 + 0 + 8 + 4, 120 0x200, 121 { .data_frame.df_offset = 0x0807060504030201UL, 122 .stream_id = 0x210, 123 .data_frame.df_size = 0x200 - (1 + 8 + 4), 124 .data_frame.df_fin = 1, 125 }, 126 1, 127 }, 128 129 { "Stream ID length is 1", 130 __LINE__, 131 select_pf_by_ver(LSQVER_043), 132 /* 1 f d ooo ss 1fdoooss */ 133 /* TYPE FIN DLEN OLEN SLEN */ 134 { 0x80 | 0x40 | 0x20 | 0x1C | 0x0, 135 0xF0, /* Stream ID */ 136 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, /* Offset */ 137 0x01, 0xC4, /* Data length */ 138 }, 139 1 + 2 + 8 + 1, 140 0x200, 141 { .data_frame.df_offset = 0x0807060504030201UL, 142 .stream_id = 0xF0, 143 .data_frame.df_size = 0x1C4, 144 .data_frame.df_fin = 1, 145 }, 146 1, 147 }, 148 149 { "All bits are zero save offset length", 150 __LINE__, 151 select_pf_by_ver(LSQVER_043), 152 /* 1 f d ooo ss 1fdoooss */ 153 /* TYPE FIN DLEN OLEN SLEN */ 154 { 0x80 | 0x00 | 0x00 | 0x04 | 0x0, 155 0xF0, /* Stream ID */ 156 0x02, 0x55, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, /* Offset */ 157 0xC4, 0x01, /* Data length */ 158 }, 159 1 + 0 + 2 + 1, 160 0x200, 161 { .data_frame.df_offset = 0x255, 162 .stream_id = 0xF0, 163 .data_frame.df_size = 0x200 - 4, 164 .data_frame.df_fin = 0, 165 }, 166 1, 167 }, 168 169 { "Sanity check: either FIN must be set or data length is not zero #1", 170 __LINE__, 171 select_pf_by_ver(LSQVER_043), 172 /* 1 f d ooo ss 1fdoooss */ 173 /* TYPE FIN DLEN OLEN SLEN */ 174 { 0x80 | 0x00 | 0x00 | 0x04 | 0x0, 175 0xF0, /* Stream ID */ 176 0x02, 0x55, /* Offset */ 177 }, 178 1 + 0 + 2 + 1, 179 4, /* Same as buffer size: in the absense of explicit data 180 * length in the header, this would mean that data 181 * length is zero. 182 */ 183 { .data_frame.df_offset = 0x255, 184 .stream_id = 0xF0, 185 .data_frame.df_size = 0x200 - 4, 186 .data_frame.df_fin = 0, 187 }, 188 0, 189 }, 190 191 { "Sanity check: either FIN must be set or data length is not zero #2", 192 __LINE__, 193 select_pf_by_ver(LSQVER_043), 194 /* 1 f d ooo ss 1fdoooss */ 195 /* TYPE FIN DLEN OLEN SLEN */ 196 { 0x80 | 0x00 | 0x20 | 0x04 | 0x0, 197 0xF0, /* Stream ID */ 198 0x02, 0x55, /* Offset */ 199 0x00, 0x00, 200 }, 201 1 + 2 + 2 + 1, 202 200, 203 { .data_frame.df_offset = 0x255, 204 .stream_id = 0xF0, 205 .data_frame.df_size = 0x200 - 4, 206 .data_frame.df_fin = 0, 207 }, 208 0, 209 }, 210 211 { "Sanity check: either FIN must be set or data length is not zero #3", 212 __LINE__, 213 select_pf_by_ver(LSQVER_043), 214 /* 1 f d ooo ss 1fdoooss */ 215 /* TYPE FIN DLEN OLEN SLEN */ 216 { 0x80 | 0x40 | 0x20 | 0x04 | 0x0, 217 0xF0, /* Stream ID */ 218 0x02, 0x55, /* Offset */ 219 0x00, 0x00, 220 }, 221 1 + 2 + 2 + 1, 222 200, 223 { .data_frame.df_offset = 0x255, 224 .stream_id = 0xF0, 225 .data_frame.df_size = 0x0, 226 .data_frame.df_fin = 1, 227 }, 228 1, 229 }, 230 231 { "Check data bounds #1", 232 __LINE__, 233 select_pf_by_ver(LSQVER_043), 234 /* 1 f d ooo ss 1fdoooss */ 235 /* TYPE FIN DLEN OLEN SLEN */ 236 { 0x80 | 0x00 | 0x20 | 0x04 | 0x0, 237 0xF0, /* Stream ID */ 238 0x02, 0x55, /* Offset */ 239 0x01, 0xFA, /* Data length */ 240 }, 241 1 + 2 + 2 + 1, 242 0x200, 243 { .data_frame.df_offset = 0x255, 244 .stream_id = 0xF0, 245 .data_frame.df_size = 0x1FA, 246 .data_frame.df_fin = 0, 247 }, 248 1, 249 }, 250 251 { "Check data bounds #2", 252 __LINE__, 253 select_pf_by_ver(LSQVER_043), 254 /* 1 f d ooo ss 1fdoooss */ 255 /* TYPE FIN DLEN OLEN SLEN */ 256 { 0x80 | 0x00 | 0x20 | 0x04 | 0x0, 257 0xF0, /* Stream ID */ 258 0x02, 0x55, /* Offset */ 259 0x01, 0xFB, /* <--- One byte too many */ 260 }, 261 1 + 2 + 2 + 1, 262 0x200, 263 { .data_frame.df_offset = 0x255, 264 .stream_id = 0xF0, 265 .data_frame.df_size = 0x1FA, 266 .data_frame.df_fin = 0, 267 }, 268 0, 269 }, 270 271 /* 272 * IETF QUIC Internet-Draft 14 Tests. 273 */ 274 275 { "Balls to the wall: every possible bit is set", 276 __LINE__, 277 select_pf_by_ver(LSQVER_ID27), 278 /* TYPE OFF DLEN FIN */ 279 { 0x10 | 1<<2 | 1<<1 | 1<<0, 280 0x41, 0x23, /* Stream ID */ 281 0x08, /* Offset */ 282 0x41, 0xC4, /* Data length */ 283 }, 284 1 + 2 + 1 + 2, 285 0x200, 286 { .data_frame.df_offset = 0x08, 287 .stream_id = 0x123, 288 .data_frame.df_size = 0x1C4, 289 .data_frame.df_fin = 1, 290 }, 291 1, 292 }, 293 294 { "Balls to the wall #2: every possible bit is set except FIN", 295 __LINE__, 296 select_pf_by_ver(LSQVER_ID27), 297 /* TYPE OFF DLEN FIN */ 298 { 0x10 | 1<<2 | 1<<1 | 0<<0, 299 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 300 0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, /* Offset */ 301 0x41, 0xC4, /* Data length */ 302 }, 303 1 + 4 + 8 + 2, 304 0x200, 305 { .data_frame.df_offset = 0x301234567890ABCDull, 306 .stream_id = 0x12300E4, 307 .data_frame.df_size = 0x1C4, 308 .data_frame.df_fin = 0, 309 }, 310 1, 311 }, 312 313 { "Data length is zero", 314 __LINE__, 315 select_pf_by_ver(LSQVER_ID27), 316 /* TYPE OFF DLEN FIN */ 317 { 0x10 | 1<<2 | 0<<1 | 0<<0, 318 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 319 0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, /* Offset */ 320 }, 321 1 + 4 + 8 + 0, 322 0x200, 323 { .data_frame.df_offset = 0x301234567890ABCDull, 324 .stream_id = 0x12300E4, 325 .data_frame.df_size = 0x200 - 1 - 4 - 8, 326 .data_frame.df_fin = 0, 327 }, 328 1, 329 }, 330 331 { "Sanity check: what happens when data length is zero #1", 332 __LINE__, 333 select_pf_by_ver(LSQVER_ID27), 334 /* TYPE OFF DLEN FIN */ 335 { 0x10 | 1<<2 | 1<<1 | 0<<0, 336 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 337 0xF0, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, /* Offset */ 338 0x40, 0x00, /* Data length */ 339 }, 340 1 + 4 + 8 + 2, 341 0x200, 342 { .data_frame.df_offset = 0x301234567890ABCDull, 343 .stream_id = 0x12300E4, 344 .data_frame.df_size = 0, 345 .data_frame.df_fin = 0, 346 }, 347 1, 348 }, 349 350 { "Sanity check: what happens when data length is zero #2", 351 __LINE__, 352 select_pf_by_ver(LSQVER_ID27), 353 /* TYPE OFF DLEN FIN */ 354 { 0x10 | 1<<2 | 1<<1 | 0<<0, 355 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 356 0x00, /* Offset */ 357 0x40, 0x00, /* Data length */ 358 }, 359 1 + 4 + 1 + 2, 360 0x200, 361 { .data_frame.df_offset = 0, 362 .stream_id = 0x12300E4, 363 .data_frame.df_size = 0, 364 .data_frame.df_fin = 0, 365 }, 366 1, 367 }, 368 369 { "Sanity check: what happens when data length is zero #3", 370 __LINE__, 371 select_pf_by_ver(LSQVER_ID27), 372 /* TYPE OFF DLEN FIN */ 373 { 0x10 | 0<<2 | 1<<1 | 0<<0, 374 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 375 0x40, 0x00, /* Data length */ 376 }, 377 1 + 4 + 0 + 2, 378 0x200, 379 { .data_frame.df_offset = 0, 380 .stream_id = 0x12300E4, 381 .data_frame.df_size = 0, 382 .data_frame.df_fin = 0, 383 }, 384 1, 385 }, 386 387 { "Sanity check: what happens when data length is zero #3", 388 __LINE__, 389 select_pf_by_ver(LSQVER_ID27), 390 /* TYPE OFF DLEN FIN */ 391 { 0x10 | 1<<2 | 1<<1 | 1<<0, 392 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 393 0x12, /* Offset */ 394 0x00, /* Data length */ 395 }, 396 1 + 4 + 1 + 1, 397 0x200, 398 { .data_frame.df_offset = 0x12, 399 .stream_id = 0x12300E4, 400 .data_frame.df_size = 0, 401 .data_frame.df_fin = 1, 402 }, 403 1, 404 }, 405 406 { "Check data bounds #1", 407 __LINE__, 408 select_pf_by_ver(LSQVER_ID27), 409 /* TYPE OFF DLEN FIN */ 410 { 0x10 | 1<<2 | 1<<1 | 1<<0, 411 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 412 0x12, /* Offset */ 413 0x41, 0xF8, /* Data length */ 414 }, 415 1 + 4 + 1 + 2, 416 0x200, 417 { .data_frame.df_offset = 0x12, 418 .stream_id = 0x12300E4, 419 .data_frame.df_size = 0x200 - 1 - 4 - 1 - 2, 420 .data_frame.df_fin = 1, 421 }, 422 1, 423 }, 424 425 { "Check data bounds #2", 426 __LINE__, 427 select_pf_by_ver(LSQVER_ID27), 428 /* TYPE OFF DLEN FIN */ 429 { 0x10 | 1<<2 | 1<<1 | 1<<0, 430 0x81, 0x23, 0x00, 0xE4, /* Stream ID */ 431 0x12, /* Offset */ 432 0x41, 0xF9, /* Data length */ 433 }, 434 1 + 4 + 1 + 2, 435 0x200, 436 { .data_frame.df_offset = 0x12, 437 .stream_id = 0x12300E4, 438 .data_frame.df_size = 0x200 - 1 - 4 - 1 - 2, 439 .data_frame.df_fin = 1, 440 }, 441 0, 442 }, 443 444 }; 445 446 unsigned i; 447 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) 448 run_test(&tests[i]); 449 return 0; 450} 451