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