1 /* 2 * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 #include <string.h> 10 11 #include "internal/packet.h" 12 #include "internal/quic_record_rx.h" 13 #include "internal/quic_stream.h" 14 #include "../ssl/quic/quic_record_rx_local.h" 15 #include "../ssl/quic/quic_channel_local.h" 16 #include "internal/nelem.h" 17 #include "testutil.h" 18 19 /* 20 * A received packet as the stream code sees it, without a QRX behind it. 21 * The reference the caller keeps is never released by the stream code, so 22 * the reference count never reaches zero and the packet is never recycled 23 * through the QRX it does not have. It is freed with pkt_test_free() once 24 * the test is done with it. 25 */ 26 static OSSL_QRX_PKT *pkt_test_new(size_t datagram_len) 27 { 28 RXE *rxe = OPENSSL_zalloc(sizeof(*rxe)); 29 30 if (rxe == NULL) 31 return NULL; 32 33 rxe->refcount = 1; 34 rxe->datagram_len = datagram_len; 35 rxe->pkt.datagram_len = datagram_len; 36 return &rxe->pkt; 37 } 38 39 /* The number of references held on a packet, including the caller's own. */ 40 static size_t pkt_test_refcount(const OSSL_QRX_PKT *pkt) 41 { 42 return ((const RXE *)pkt)->refcount; 43 } 44 45 static void pkt_test_free(OSSL_QRX_PKT *pkt) 46 { 47 OPENSSL_free((RXE *)pkt); 48 } 49 50 static int compare_iov(const unsigned char *ref, size_t ref_len, 51 const OSSL_QTX_IOVEC *iov, size_t iov_len) 52 { 53 size_t i, total_len = 0; 54 const unsigned char *cur = ref; 55 56 for (i = 0; i < iov_len; ++i) 57 total_len += iov[i].buf_len; 58 59 if (ref_len != total_len) 60 return 0; 61 62 for (i = 0; i < iov_len; ++i) { 63 if (memcmp(cur, iov[i].buf, iov[i].buf_len)) 64 return 0; 65 66 cur += iov[i].buf_len; 67 } 68 69 return 1; 70 } 71 72 static const unsigned char data_1[] = { 73 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 74 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f 75 }; 76 77 static int test_sstream_simple(void) 78 { 79 int testresult = 0; 80 QUIC_SSTREAM *sstream = NULL; 81 OSSL_QUIC_FRAME_STREAM hdr; 82 OSSL_QTX_IOVEC iov[2]; 83 size_t num_iov = 0, wr = 0, i, init_size = 8192; 84 85 if (!TEST_ptr(sstream = ossl_quic_sstream_new(init_size))) 86 goto err; 87 88 /* A stream with nothing yet appended is totally acked */ 89 if (!TEST_true(ossl_quic_sstream_is_totally_acked(sstream))) 90 goto err; 91 92 /* Should not have any data yet */ 93 num_iov = OSSL_NELEM(iov); 94 if (!TEST_false(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 95 &num_iov))) 96 goto err; 97 98 /* Append data */ 99 if (!TEST_true(ossl_quic_sstream_append(sstream, data_1, sizeof(data_1), 100 &wr)) 101 || !TEST_size_t_eq(wr, sizeof(data_1))) 102 goto err; 103 104 /* No longer totally acked */ 105 if (!TEST_false(ossl_quic_sstream_is_totally_acked(sstream))) 106 goto err; 107 108 /* Read data */ 109 num_iov = OSSL_NELEM(iov); 110 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 111 &num_iov)) 112 || !TEST_size_t_gt(num_iov, 0) 113 || !TEST_uint64_t_eq(hdr.offset, 0) 114 || !TEST_uint64_t_eq(hdr.len, sizeof(data_1)) 115 || !TEST_false(hdr.is_fin)) 116 goto err; 117 118 if (!TEST_true(compare_iov(data_1, sizeof(data_1), iov, num_iov))) 119 goto err; 120 121 /* Mark data as half transmitted */ 122 if (!TEST_true(ossl_quic_sstream_mark_transmitted(sstream, 0, 7))) 123 goto err; 124 125 /* Read data */ 126 num_iov = OSSL_NELEM(iov); 127 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 128 &num_iov)) 129 || !TEST_size_t_gt(num_iov, 0) 130 || !TEST_uint64_t_eq(hdr.offset, 8) 131 || !TEST_uint64_t_eq(hdr.len, sizeof(data_1) - 8) 132 || !TEST_false(hdr.is_fin)) 133 goto err; 134 135 if (!TEST_true(compare_iov(data_1 + 8, sizeof(data_1) - 8, iov, num_iov))) 136 goto err; 137 138 if (!TEST_true(ossl_quic_sstream_mark_transmitted(sstream, 8, 15))) 139 goto err; 140 141 /* Read more data; should not be any more */ 142 num_iov = OSSL_NELEM(iov); 143 if (!TEST_false(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 144 &num_iov))) 145 goto err; 146 147 /* Now we have lost bytes 4-6 */ 148 if (!TEST_true(ossl_quic_sstream_mark_lost(sstream, 4, 6))) 149 goto err; 150 151 /* Should be able to read them */ 152 num_iov = OSSL_NELEM(iov); 153 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 154 &num_iov)) 155 || !TEST_size_t_gt(num_iov, 0) 156 || !TEST_uint64_t_eq(hdr.offset, 4) 157 || !TEST_uint64_t_eq(hdr.len, 3) 158 || !TEST_false(hdr.is_fin)) 159 goto err; 160 161 if (!TEST_true(compare_iov(data_1 + 4, 3, iov, num_iov))) 162 goto err; 163 164 /* Retransmit */ 165 if (!TEST_true(ossl_quic_sstream_mark_transmitted(sstream, 4, 6))) 166 goto err; 167 168 /* Read more data; should not be any more */ 169 num_iov = OSSL_NELEM(iov); 170 if (!TEST_false(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 171 &num_iov))) 172 goto err; 173 174 if (!TEST_size_t_eq(ossl_quic_sstream_get_buffer_used(sstream), 16)) 175 goto err; 176 177 /* Data has been acknowledged, space should be not be freed yet */ 178 if (!TEST_true(ossl_quic_sstream_mark_acked(sstream, 1, 7)) 179 || !TEST_size_t_eq(ossl_quic_sstream_get_buffer_used(sstream), 16)) 180 goto err; 181 182 /* Now data should be freed */ 183 if (!TEST_true(ossl_quic_sstream_mark_acked(sstream, 0, 0)) 184 || !TEST_size_t_eq(ossl_quic_sstream_get_buffer_used(sstream), 8)) 185 goto err; 186 187 if (!TEST_true(ossl_quic_sstream_mark_acked(sstream, 0, 15)) 188 || !TEST_size_t_eq(ossl_quic_sstream_get_buffer_used(sstream), 0)) 189 goto err; 190 191 /* Now FIN */ 192 ossl_quic_sstream_fin(sstream); 193 194 /* Get FIN frame */ 195 for (i = 0; i < 2; ++i) { 196 num_iov = OSSL_NELEM(iov); 197 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 198 &num_iov)) 199 || !TEST_uint64_t_eq(hdr.offset, 16) 200 || !TEST_uint64_t_eq(hdr.len, 0) 201 || !TEST_true(hdr.is_fin) 202 || !TEST_size_t_eq(num_iov, 0)) 203 goto err; 204 } 205 206 if (!TEST_true(ossl_quic_sstream_mark_transmitted_fin(sstream, 16))) 207 goto err; 208 209 /* Read more data; FIN should not be returned any more */ 210 num_iov = OSSL_NELEM(iov); 211 if (!TEST_false(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 212 &num_iov))) 213 goto err; 214 215 /* Lose FIN frame */ 216 if (!TEST_true(ossl_quic_sstream_mark_lost_fin(sstream))) 217 goto err; 218 219 /* Get FIN frame */ 220 for (i = 0; i < 2; ++i) { 221 num_iov = OSSL_NELEM(iov); 222 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 223 &num_iov)) 224 || !TEST_uint64_t_eq(hdr.offset, 16) 225 || !TEST_uint64_t_eq(hdr.len, 0) 226 || !TEST_true(hdr.is_fin) 227 || !TEST_size_t_eq(num_iov, 0)) 228 goto err; 229 } 230 231 if (!TEST_true(ossl_quic_sstream_mark_transmitted_fin(sstream, 16))) 232 goto err; 233 234 /* Read more data; FIN should not be returned any more */ 235 num_iov = OSSL_NELEM(iov); 236 if (!TEST_false(ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, 237 &num_iov))) 238 goto err; 239 240 /* Acknowledge fin. */ 241 if (!TEST_true(ossl_quic_sstream_mark_acked_fin(sstream))) 242 goto err; 243 244 if (!TEST_true(ossl_quic_sstream_is_totally_acked(sstream))) 245 goto err; 246 247 testresult = 1; 248 err: 249 ossl_quic_sstream_free(sstream); 250 return testresult; 251 } 252 253 static int test_sstream_bulk(int idx) 254 { 255 int testresult = 0; 256 QUIC_SSTREAM *sstream = NULL; 257 OSSL_QUIC_FRAME_STREAM hdr; 258 OSSL_QTX_IOVEC iov[2]; 259 size_t i, j, num_iov = 0, init_size = 8192, l; 260 size_t consumed = 0, total_written = 0, rd, cur_rd, expected = 0, start_at; 261 unsigned char *src_buf = NULL, *dst_buf = NULL; 262 unsigned char *ref_src_buf = NULL, *ref_dst_buf = NULL; 263 unsigned char *ref_dst_cur, *ref_src_cur, *dst_cur; 264 265 if (!TEST_ptr(sstream = ossl_quic_sstream_new(init_size))) 266 goto err; 267 268 if (!TEST_size_t_eq(ossl_quic_sstream_get_buffer_size(sstream), init_size)) 269 goto err; 270 271 if (!TEST_ptr(src_buf = OPENSSL_zalloc(init_size))) 272 goto err; 273 274 if (!TEST_ptr(dst_buf = OPENSSL_malloc(init_size))) 275 goto err; 276 277 if (!TEST_ptr(ref_src_buf = OPENSSL_malloc(init_size))) 278 goto err; 279 280 if (!TEST_ptr(ref_dst_buf = OPENSSL_malloc(init_size))) 281 goto err; 282 283 /* 284 * Append a preliminary buffer to allow later code to exercise wraparound. 285 */ 286 if (!TEST_true(ossl_quic_sstream_append(sstream, src_buf, init_size / 2, 287 &consumed)) 288 || !TEST_size_t_eq(consumed, init_size / 2) 289 || !TEST_true(ossl_quic_sstream_mark_transmitted(sstream, 0, 290 init_size / 2 - 1)) 291 || !TEST_true(ossl_quic_sstream_mark_acked(sstream, 0, 292 init_size / 2 - 1))) 293 goto err; 294 295 start_at = init_size / 2; 296 297 /* Generate a random buffer. */ 298 for (i = 0; i < init_size; ++i) 299 src_buf[i] = (unsigned char)(test_random() & 0xFF); 300 301 /* Append bytes into the buffer in chunks of random length. */ 302 ref_src_cur = ref_src_buf; 303 do { 304 l = (test_random() % init_size) + 1; 305 if (!TEST_true(ossl_quic_sstream_append(sstream, src_buf, l, &consumed))) 306 goto err; 307 308 memcpy(ref_src_cur, src_buf, consumed); 309 ref_src_cur += consumed; 310 total_written += consumed; 311 } while (consumed > 0); 312 313 if (!TEST_size_t_eq(ossl_quic_sstream_get_buffer_used(sstream), init_size) 314 || !TEST_size_t_eq(ossl_quic_sstream_get_buffer_avail(sstream), 0)) 315 goto err; 316 317 /* 318 * Randomly select bytes out of the buffer by marking them as transmitted. 319 * Record the remaining bytes, which should be the sequence of bytes 320 * returned. 321 */ 322 ref_src_cur = ref_src_buf; 323 ref_dst_cur = ref_dst_buf; 324 for (i = 0; i < total_written; ++i) { 325 if ((test_random() & 1) != 0) { 326 *ref_dst_cur++ = *ref_src_cur; 327 ++expected; 328 } else if (!TEST_true(ossl_quic_sstream_mark_transmitted(sstream, 329 start_at + i, 330 start_at + i))) 331 goto err; 332 333 ++ref_src_cur; 334 } 335 336 /* Exercise resize. */ 337 if (!TEST_true(ossl_quic_sstream_set_buffer_size(sstream, init_size * 2)) 338 || !TEST_true(ossl_quic_sstream_set_buffer_size(sstream, init_size))) 339 goto err; 340 341 /* Readout and verification. */ 342 dst_cur = dst_buf; 343 for (i = 0, rd = 0; rd < expected; ++i) { 344 num_iov = OSSL_NELEM(iov); 345 if (!TEST_true(ossl_quic_sstream_get_stream_frame(sstream, i, &hdr, iov, 346 &num_iov))) 347 goto err; 348 349 cur_rd = 0; 350 for (j = 0; j < num_iov; ++j) { 351 if (!TEST_size_t_le(iov[j].buf_len + rd, expected)) 352 goto err; 353 354 memcpy(dst_cur, iov[j].buf, iov[j].buf_len); 355 dst_cur += iov[j].buf_len; 356 cur_rd += iov[j].buf_len; 357 } 358 359 if (!TEST_uint64_t_eq(cur_rd, hdr.len)) 360 goto err; 361 362 rd += cur_rd; 363 } 364 365 if (!TEST_mem_eq(dst_buf, rd, ref_dst_buf, expected)) 366 goto err; 367 368 testresult = 1; 369 err: 370 OPENSSL_free(src_buf); 371 OPENSSL_free(dst_buf); 372 OPENSSL_free(ref_src_buf); 373 OPENSSL_free(ref_dst_buf); 374 ossl_quic_sstream_free(sstream); 375 return testresult; 376 } 377 378 static int test_single_copy_read(QUIC_RSTREAM *qrs, 379 unsigned char *buf, size_t size, 380 size_t *readbytes, int *fin) 381 { 382 const unsigned char *record; 383 size_t rec_len; 384 385 *readbytes = 0; 386 387 for (;;) { 388 if (!ossl_quic_rstream_get_record(qrs, &record, &rec_len, fin)) 389 return 0; 390 if (rec_len == 0) 391 break; 392 if (rec_len > size) { 393 rec_len = size; 394 *fin = 0; 395 } 396 memcpy(buf, record, rec_len); 397 size -= rec_len; 398 *readbytes += rec_len; 399 buf += rec_len; 400 401 if (!ossl_quic_rstream_release_record(qrs, rec_len)) 402 return 0; 403 if (*fin || size == 0) 404 break; 405 } 406 407 return 1; 408 } 409 410 static const unsigned char simple_data[] = "Hello world! And thank you for all the fish!"; 411 412 /* 413 * Walks the basic sequential contract of the receive stream: a gap at 414 * the head reads zero bytes without signalling the end of stream even 415 * when FIN is already known, duplicate FIN frames with a matching final 416 * size are accepted, available() reports the final size together with 417 * FIN, partial reads flip the FIN flag exactly with the last byte and 418 * reading at the end of stream stays successful. Runs once with the 419 * plain read and once with the single copy record path. 420 */ 421 static int test_rstream_simple(int idx) 422 { 423 QUIC_RSTREAM *rstream = NULL; 424 QUIC_CHANNEL *ch = NULL; 425 QUIC_RSTREAM_QPARM *rsqp = NULL; 426 OSSL_QRX_PKT *pkt[8] = { NULL }; 427 int ret = 0; 428 unsigned char buf[sizeof(simple_data)]; 429 size_t readbytes = 0, avail = 0, i; 430 int fin = 0; 431 int use_sc = (idx & 1) != 0; 432 int (*read_fn)(QUIC_RSTREAM *, unsigned char *, size_t, size_t *, 433 int *) 434 = use_sc ? test_single_copy_read 435 : ossl_quic_rstream_read; 436 437 /* every frame arrives in a packet, as it does in production */ 438 for (i = 0; i < OSSL_NELEM(pkt); ++i) 439 if (!TEST_ptr(pkt[i] = pkt_test_new(1200))) 440 goto err; 441 442 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 443 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 444 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 445 goto err; 446 447 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[0], 5, 448 simple_data + 5, 10, 0)) 449 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[1], 450 sizeof(simple_data) - 1, 451 simple_data + sizeof(simple_data) - 1, 452 1, 1)) 453 || !TEST_true(ossl_quic_rstream_peek(rstream, buf, sizeof(buf), 454 &readbytes, &fin)) 455 || !TEST_false(fin) 456 || !TEST_size_t_eq(readbytes, 0) 457 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[2], 458 sizeof(simple_data) - 10, 459 simple_data + sizeof(simple_data) - 10, 460 10, 1)) 461 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[3], 0, 462 simple_data, 1, 0)) 463 || !TEST_true(ossl_quic_rstream_peek(rstream, buf, sizeof(buf), 464 &readbytes, &fin)) 465 || !TEST_false(fin) 466 || !TEST_size_t_eq(readbytes, 1) 467 || !TEST_mem_eq(buf, 1, simple_data, 1) 468 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[4], 469 0, simple_data, 470 10, 0)) 471 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[5], 472 sizeof(simple_data), 473 NULL, 474 0, 1)) 475 || !TEST_true(ossl_quic_rstream_peek(rstream, buf, sizeof(buf), 476 &readbytes, &fin)) 477 || !TEST_false(fin) 478 || !TEST_size_t_eq(readbytes, 15) 479 || !TEST_mem_eq(buf, 15, simple_data, 15) 480 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[6], 481 15, 482 simple_data + 15, 483 sizeof(simple_data) - 15, 1)) 484 || !TEST_true(ossl_quic_rstream_available(rstream, &avail, &fin)) 485 || !TEST_true(fin) 486 || !TEST_size_t_eq(avail, sizeof(simple_data)) 487 || !TEST_true(read_fn(rstream, buf, 2, &readbytes, &fin)) 488 || !TEST_false(fin) 489 || !TEST_size_t_eq(readbytes, 2) 490 || !TEST_mem_eq(buf, 2, simple_data, 2) 491 || !TEST_true(read_fn(rstream, buf + 2, 12, &readbytes, &fin)) 492 || !TEST_false(fin) 493 || !TEST_size_t_eq(readbytes, 12) 494 || !TEST_mem_eq(buf + 2, 12, simple_data + 2, 12) 495 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[7], 496 sizeof(simple_data), 497 NULL, 498 0, 1)) 499 || !TEST_true(read_fn(rstream, buf + 14, 5, &readbytes, &fin)) 500 || !TEST_false(fin) 501 || !TEST_size_t_eq(readbytes, 5) 502 || !TEST_mem_eq(buf, 14 + 5, simple_data, 14 + 5) 503 || !TEST_true(read_fn(rstream, buf + 14 + 5, sizeof(buf) - 14 - 5, 504 &readbytes, &fin)) 505 || !TEST_true(fin) 506 || !TEST_size_t_eq(readbytes, sizeof(buf) - 14 - 5) 507 || !TEST_mem_eq(buf, sizeof(buf), simple_data, sizeof(simple_data)) 508 || !TEST_true(read_fn(rstream, buf, sizeof(buf), &readbytes, &fin)) 509 || !TEST_true(fin) 510 || !TEST_size_t_eq(readbytes, 0)) 511 goto err; 512 513 if (!TEST_int_eq(ch->protocol_error, 0)) 514 goto err; 515 516 ret = 1; 517 518 err: 519 ossl_quic_rstream_free(rstream); 520 /* All the references held by the stream must have been released */ 521 for (i = 0; i < OSSL_NELEM(pkt); ++i) { 522 if (pkt[i] != NULL 523 && !TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 524 ret = 0; 525 pkt_test_free(pkt[i]); 526 } 527 ossl_quic_rstream_qparm_destroy(rsqp); 528 ossl_quic_channel_free(ch); 529 return ret; 530 } 531 532 static int test_rstream_random(int idx) 533 { 534 unsigned char *bulk_data = NULL; 535 unsigned char *read_buf = NULL; 536 QUIC_RSTREAM *rstream = NULL; 537 QUIC_CHANNEL *ch = NULL; 538 OSSL_QRX_PKT **pkts = NULL; 539 QUIC_RSTREAM_QPARM *rsqp = NULL; 540 size_t i, read_off, queued_min, queued_max, num_pkts = 0; 541 const size_t data_size = 10000; 542 /* At most two frames are queued per each of the 100 * 10 iterations */ 543 const size_t max_pkts = 100 * 10 * 2; 544 int r, s, fin = 0, fin_set = 0; 545 int ret = 0; 546 size_t readbytes = 0; 547 548 if (!TEST_ptr(bulk_data = OPENSSL_malloc(data_size)) 549 || !TEST_ptr(read_buf = OPENSSL_malloc(data_size)) 550 || !TEST_ptr(pkts = OPENSSL_zalloc(sizeof(*pkts) * max_pkts)) 551 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 552 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 553 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 554 goto err; 555 556 if (idx % 3 == 0) 557 ossl_quic_rstream_set_cleanse(rstream, 1); 558 559 for (i = 0; i < data_size; ++i) 560 bulk_data[i] = (unsigned char)(test_random() & 0xFF); 561 562 read_off = queued_min = queued_max = 0; 563 for (r = 0; r < 100; ++r) { 564 for (s = 0; s < 10; ++s) { 565 size_t off = (r * 10 + s) * 10, size = 10; 566 OSSL_QRX_PKT *pkt = NULL; 567 568 if (test_random() % 10 == 0) 569 /* drop packet */ 570 continue; 571 572 if (off <= queued_min && off + size > queued_min) 573 queued_min = off + size; 574 575 /* each frame arrives in its own packet */ 576 if (!TEST_ptr(pkt = pkt_test_new(1200))) 577 goto err; 578 pkts[num_pkts++] = pkt; 579 580 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, 581 bulk_data + off, 582 size, 0))) 583 goto err; 584 if (queued_max < off + size) 585 queued_max = off + size; 586 587 if (test_random() % 5 != 0) 588 continue; 589 590 /* random overlapping retransmit */ 591 off = read_off + test_random() % 50; 592 if (off > 50) 593 off -= 50; 594 size = test_random() % 100 + 1; 595 if (off + size > data_size) 596 off = data_size - size; 597 if (off <= queued_min && off + size > queued_min) 598 queued_min = off + size; 599 600 /* a retransmit arrives in its own packet */ 601 if (!TEST_ptr(pkt = pkt_test_new(1200))) 602 goto err; 603 pkts[num_pkts++] = pkt; 604 605 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, 606 bulk_data + off, 607 size, 0))) 608 goto err; 609 if (queued_max < off + size) 610 queued_max = off + size; 611 } 612 if (idx % 2 == 0) { 613 if (!TEST_true(test_single_copy_read(rstream, read_buf, data_size, 614 &readbytes, &fin))) 615 goto err; 616 } else if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 617 data_size, 618 &readbytes, &fin))) { 619 goto err; 620 } 621 if (!TEST_size_t_ge(readbytes, queued_min - read_off) 622 || !TEST_size_t_le(readbytes + read_off, data_size) 623 || (idx % 3 != 0 624 && !TEST_mem_eq(read_buf, readbytes, bulk_data + read_off, 625 readbytes))) 626 goto err; 627 read_off += readbytes; 628 queued_min = read_off; 629 if (!fin_set && queued_max >= data_size - test_random() % 200) { 630 fin_set = 1; 631 /* Queue empty fin frame */ 632 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, data_size, 633 NULL, 0, 1))) 634 goto err; 635 } 636 } 637 638 TEST_info("Total read bytes: %zu Fin rcvd: %d", read_off, fin); 639 640 if (idx % 3 == 0) 641 for (i = 0; i < read_off; i++) 642 if (!TEST_uchar_eq(bulk_data[i], 0)) 643 goto err; 644 645 if (read_off == data_size && fin_set && !fin) { 646 /* We might still receive the final empty frame */ 647 if (idx % 2 == 0) { 648 if (!TEST_true(test_single_copy_read(rstream, read_buf, data_size, 649 &readbytes, &fin))) 650 goto err; 651 } else if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 652 data_size, 653 &readbytes, &fin))) { 654 goto err; 655 } 656 if (!TEST_size_t_eq(readbytes, 0) || !TEST_true(fin)) 657 goto err; 658 } 659 660 if (!TEST_int_eq(ch->protocol_error, 0)) 661 goto err; 662 663 ret = 1; 664 665 err: 666 ossl_quic_rstream_free(rstream); 667 if (pkts != NULL) { 668 /* All the references held by the stream must have been released */ 669 for (i = 0; i < num_pkts; ++i) { 670 if (!TEST_size_t_eq(pkt_test_refcount(pkts[i]), 1)) 671 ret = 0; 672 pkt_test_free(pkts[i]); 673 } 674 OPENSSL_free(pkts); 675 } 676 ossl_quic_rstream_qparm_destroy(rsqp); 677 OPENSSL_free(bulk_data); 678 OPENSSL_free(read_buf); 679 ossl_quic_channel_free(ch); 680 return ret; 681 } 682 683 /* 684 * Verify the reference counting of packets pinned by buffered stream 685 * chunks and the cleansing of packet backed chunks. 686 */ 687 static int test_rstream_pkt(void) 688 { 689 QUIC_RSTREAM *rstream = NULL; 690 QUIC_CHANNEL *ch = NULL; 691 QUIC_RSTREAM_QPARM *rsqp = NULL; 692 OSSL_QRX_PKT *pkt_a = NULL, *pkt_b = NULL, *pkt_c = NULL; 693 unsigned char pdata[64], cbuf[64], buf[64]; 694 size_t readbytes = 0, avail = 0, i; 695 int fin = 0; 696 int ret = 0; 697 698 for (i = 0; i < sizeof(pdata); ++i) 699 pdata[i] = (unsigned char)(0x40 + i); 700 701 if (!TEST_ptr(pkt_a = pkt_test_new(1200)) 702 || !TEST_ptr(pkt_b = pkt_test_new(1200)) 703 || !TEST_ptr(pkt_c = pkt_test_new(1200)) 704 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 705 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 706 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 707 goto err; 708 709 /* A buffered frame holds a reference to its packet */ 710 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, 711 pdata, 10, 0)) 712 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2)) 713 goto err; 714 715 /* Two frames from the same packet hold two references */ 716 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 20, 717 pdata + 20, 10, 0)) 718 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 3)) 719 goto err; 720 721 /* A frame contained in already buffered data takes no reference */ 722 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_b, 2, 723 pdata + 2, 6, 0)) 724 || !TEST_size_t_eq(pkt_test_refcount(pkt_b), 1)) 725 goto err; 726 727 /* 728 * An overlapping frame drops the frames it covers and releases 729 * their references 730 */ 731 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_c, 0, 732 pdata, 15, 0)) 733 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 3) 734 || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 2)) 735 goto err; 736 737 /* Reading past a frame releases its reference */ 738 if (!TEST_true(ossl_quic_rstream_available(rstream, &avail, &fin)) 739 || !TEST_size_t_eq(avail, 15) 740 || !TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), 741 &readbytes, &fin)) 742 || !TEST_size_t_eq(readbytes, 15) 743 || !TEST_mem_eq(buf, 15, pdata, 15) 744 || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 1) 745 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2)) 746 goto err; 747 748 /* Moving frames to the ring buffer releases their references */ 749 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_b, 15, 750 pdata + 15, 5, 0)) 751 || !TEST_size_t_eq(pkt_test_refcount(pkt_b), 2) 752 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2)) 753 goto err; 754 755 /* The moved data is still readable from the ring buffer */ 756 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), 757 &readbytes, &fin)) 758 || !TEST_size_t_eq(readbytes, 15) 759 || !TEST_mem_eq(buf, 15, pdata + 15, 15)) 760 goto err; 761 762 /* Freeing the stream releases the references of buffered frames */ 763 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_c, 30, 764 pdata + 30, 10, 0)) 765 || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 2)) 766 goto err; 767 ossl_quic_rstream_free(rstream); 768 rstream = NULL; 769 if (!TEST_size_t_eq(pkt_test_refcount(pkt_c), 1)) 770 goto err; 771 772 /* 773 * Cleansing a consumed packet backed chunk wipes exactly the chunk 774 * data, leaving the surrounding bytes intact. 775 */ 776 memset(cbuf, 0xAA, sizeof(cbuf)); 777 if (!TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 778 goto err; 779 ossl_quic_rstream_set_cleanse(rstream, 1); 780 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, 781 cbuf + 8, 48, 0)) 782 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2) 783 || !TEST_true(ossl_quic_rstream_read(rstream, buf, 48, 784 &readbytes, &fin)) 785 || !TEST_size_t_eq(readbytes, 48) 786 || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 1)) 787 goto err; 788 for (i = 0; i < sizeof(cbuf); ++i) 789 if (!TEST_uchar_eq(cbuf[i], i >= 8 && i < 56 ? 0 : 0xAA)) 790 goto err; 791 792 if (!TEST_int_eq(ch->protocol_error, 0)) 793 goto err; 794 795 ret = 1; 796 797 err: 798 ossl_quic_rstream_free(rstream); 799 ossl_quic_rstream_qparm_destroy(rsqp); 800 pkt_test_free(pkt_a); 801 pkt_test_free(pkt_b); 802 pkt_test_free(pkt_c); 803 ossl_quic_channel_free(ch); 804 return ret; 805 } 806 807 /* 808 * Many small contiguous frames, each pinning its own packet while the reader 809 * lags behind, so a large number of packets are held at once and released only 810 * as the data is finally consumed. Every byte must still read back in order and 811 * every packet reference must end up released. 812 */ 813 static int test_rstream_pkt_overhead(void) 814 { 815 QUIC_RSTREAM *rstream = NULL; 816 OSSL_QRX_PKT **pkt = NULL; 817 QUIC_RSTREAM_QPARM *rsqp = NULL; 818 QUIC_CHANNEL *ch = NULL; 819 unsigned char *data = NULL, *buf = NULL; 820 const size_t framesz = 8; 821 const size_t nframes = 4096; /* far past a 64 KiB overhead limit */ 822 const size_t total = framesz * nframes; 823 const size_t read_lag = 200; /* read only after this many arrive */ 824 size_t i, got = 0, readbytes = 0; 825 int fin = 0, ret = 0; 826 827 if (!TEST_ptr(data = OPENSSL_malloc(total)) 828 || !TEST_ptr(buf = OPENSSL_malloc(total)) 829 || !TEST_ptr(pkt = OPENSSL_zalloc(nframes * sizeof(*pkt))) 830 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 831 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 832 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 833 goto err; 834 835 for (i = 0; i < total; ++i) 836 data[i] = (unsigned char)(i & 0xff); 837 838 for (i = 0; i < nframes; ++i) { 839 if (!TEST_ptr(pkt[i] = pkt_test_new(1200))) 840 goto err; 841 842 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 843 i * framesz, data + i * framesz, framesz, 844 i == nframes - 1))) 845 goto err; 846 847 /* let the reader fall behind, then drain what has become available */ 848 if (i % read_lag == read_lag - 1) 849 while (got < total 850 && TEST_true(ossl_quic_rstream_read(rstream, buf + got, 851 total - got, &readbytes, &fin)) 852 && readbytes > 0) 853 got += readbytes; 854 } 855 856 /* drain whatever is left and check every byte survived in order */ 857 while (got < total 858 && TEST_true(ossl_quic_rstream_read(rstream, buf + got, total - got, 859 &readbytes, &fin)) 860 && readbytes > 0) 861 got += readbytes; 862 863 if (!TEST_size_t_eq(got, total) 864 || !TEST_true(fin) 865 || !TEST_mem_eq(buf, got, data, total)) 866 goto err; 867 868 /* every consumed frame has released the reference it held on its packet */ 869 for (i = 0; i < nframes; ++i) 870 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 871 goto err; 872 873 if (!TEST_int_eq(ch->protocol_error, 0)) 874 goto err; 875 876 ret = 1; 877 878 err: 879 ossl_quic_rstream_free(rstream); 880 if (pkt != NULL) 881 for (i = 0; i < nframes; ++i) 882 pkt_test_free(pkt[i]); 883 ossl_quic_rstream_qparm_destroy(rsqp); 884 OPENSSL_free(pkt); 885 OPENSSL_free(data); 886 OPENSSL_free(buf); 887 ossl_quic_channel_free(ch); 888 return ret; 889 } 890 891 /* 892 * Reassemble a buffer delivered as small frames in a random order with 893 * overlapping retransmits, each frame carrying its own copy of its bytes on 894 * its own packet as a real one would. The random order drives insertion at the 895 * head, the tail and the middle of the reassembly, and the frame size is swept 896 * across the boundary where a design may switch how it stores a chunk, so short 897 * frames and their overlaps are merged in every combination. The read back must 898 * match what was sent whether or not the data is cleansed, since each frame's 899 * own copy is what gets wiped, never the reference. 900 */ 901 static int test_rstream_reorder(int idx) 902 { 903 unsigned char *data = NULL, *buf = NULL, *arena = NULL, *ap; 904 QUIC_RSTREAM *rstream = NULL; 905 QUIC_CHANNEL *ch = NULL; 906 OSSL_QRX_PKT **pkts = NULL; 907 QUIC_RSTREAM_QPARM *rsqp = NULL; 908 const size_t data_size = 4096; 909 const size_t framesz = 1 + (size_t)(idx % 17); 910 const int cleanse = (idx & 1); 911 const size_t nframes = (data_size + framesz - 1) / framesz; 912 size_t *order = NULL; 913 size_t i, num_pkts = 0, got = 0, readbytes = 0; 914 int fin = 0, ret = 0; 915 916 if (!TEST_ptr(data = OPENSSL_malloc(data_size)) 917 || !TEST_ptr(buf = OPENSSL_malloc(data_size)) 918 || !TEST_ptr(arena = OPENSSL_malloc(3 * data_size)) 919 || !TEST_ptr(order = OPENSSL_malloc(nframes * sizeof(*order))) 920 || !TEST_ptr(pkts = OPENSSL_zalloc(2 * nframes * sizeof(*pkts))) 921 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 922 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 923 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 924 goto err; 925 926 if (cleanse) 927 ossl_quic_rstream_set_cleanse(rstream, 1); 928 929 for (i = 0; i < data_size; ++i) 930 data[i] = (unsigned char)(test_random() & 0xFF); 931 932 for (i = 0; i < nframes; ++i) 933 order[i] = i; 934 for (i = nframes; i > 1; --i) { 935 size_t j = (size_t)(test_random() % i); 936 size_t tmp = order[i - 1]; 937 938 order[i - 1] = order[j]; 939 order[j] = tmp; 940 } 941 942 ap = arena; 943 for (i = 0; i < nframes; ++i) { 944 size_t off = order[i] * framesz; 945 size_t size = off + framesz > data_size ? data_size - off : framesz; 946 OSSL_QRX_PKT *pkt; 947 948 if (!TEST_ptr(pkt = pkt_test_new(1200))) 949 goto err; 950 pkts[num_pkts++] = pkt; 951 memcpy(ap, data + off, size); 952 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, ap, 953 size, 0))) 954 goto err; 955 ap += size; 956 957 /* an overlapping retransmit straddling this frame and the next */ 958 if (off + framesz + framesz / 2 <= data_size 959 && test_random() % 3 == 0) { 960 size_t roff = off + framesz / 2; 961 OSSL_QRX_PKT *rpkt; 962 963 if (!TEST_ptr(rpkt = pkt_test_new(1200))) 964 goto err; 965 pkts[num_pkts++] = rpkt; 966 memcpy(ap, data + roff, framesz); 967 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, rpkt, roff, ap, 968 framesz, 0))) 969 goto err; 970 ap += framesz; 971 } 972 } 973 974 /* final empty fin frame past the last byte */ 975 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, data_size, NULL, 976 0, 1))) 977 goto err; 978 979 while (got < data_size) { 980 if (!TEST_true(ossl_quic_rstream_read(rstream, buf + got, 981 data_size - got, &readbytes, &fin))) 982 goto err; 983 if (readbytes == 0) 984 break; 985 got += readbytes; 986 } 987 988 if (!TEST_size_t_eq(got, data_size) 989 || !TEST_mem_eq(buf, got, data, data_size)) 990 goto err; 991 992 if (!TEST_int_eq(ch->protocol_error, 0)) 993 goto err; 994 995 ret = 1; 996 997 err: 998 ossl_quic_rstream_free(rstream); 999 if (pkts != NULL) { 1000 for (i = 0; i < num_pkts; ++i) { 1001 if (!TEST_size_t_eq(pkt_test_refcount(pkts[i]), 1)) 1002 ret = 0; 1003 pkt_test_free(pkts[i]); 1004 } 1005 OPENSSL_free(pkts); 1006 } 1007 ossl_quic_rstream_qparm_destroy(rsqp); 1008 OPENSSL_free(order); 1009 OPENSSL_free(arena); 1010 OPENSSL_free(data); 1011 OPENSSL_free(buf); 1012 ossl_quic_channel_free(ch); 1013 return ret; 1014 } 1015 1016 /* 1017 * A zero length read is a successful no-op returning zero read bytes, 1018 * and releasing a record without consuming any bytes succeeds likewise. 1019 * Neither may fail once at least one byte has been consumed, otherwise 1020 * quic_read_actual() turns the failed read into a fatal SSL error for 1021 * SSL_read_ex() called with a zero length buffer. 1022 */ 1023 static int test_rstream_zero_length_read(void) 1024 { 1025 QUIC_RSTREAM *rstream = NULL; 1026 QUIC_CHANNEL *ch = NULL; 1027 QUIC_RSTREAM_QPARM *rsqp = NULL; 1028 OSSL_QRX_PKT *pkt = NULL; 1029 unsigned char pdata[10], buf[10]; 1030 const unsigned char *record = NULL; 1031 size_t readbytes = 0, rec_len = 0, i; 1032 int fin = 0; 1033 int ret = 0; 1034 1035 for (i = 0; i < sizeof(pdata); ++i) 1036 pdata[i] = (unsigned char)(0x40 + i); 1037 1038 if (!TEST_ptr(pkt = pkt_test_new(1200)) 1039 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 1040 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 1041 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 1042 goto err; 1043 1044 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, 0, 1045 pdata, sizeof(pdata), 0))) 1046 goto err; 1047 1048 /* a zero length read before anything is consumed */ 1049 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, 0, &readbytes, &fin)) 1050 || !TEST_size_t_eq(readbytes, 0)) 1051 goto err; 1052 1053 /* consume some bytes so the stream offset is not zero */ 1054 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, 5, &readbytes, &fin)) 1055 || !TEST_size_t_eq(readbytes, 5) 1056 || !TEST_mem_eq(buf, 5, pdata, 5)) 1057 goto err; 1058 1059 /* a zero length read with data pending at a nonzero offset */ 1060 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, 0, &readbytes, &fin)) 1061 || !TEST_size_t_eq(readbytes, 0)) 1062 goto err; 1063 1064 /* releasing a record without consuming anything succeeds too */ 1065 if (!TEST_true(ossl_quic_rstream_get_record(rstream, &record, &rec_len, 1066 &fin)) 1067 || !TEST_size_t_eq(rec_len, 5) 1068 || !TEST_true(ossl_quic_rstream_release_record(rstream, 0))) 1069 goto err; 1070 1071 /* the remaining bytes are intact and still readable */ 1072 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), 1073 &readbytes, &fin)) 1074 || !TEST_size_t_eq(readbytes, 5) 1075 || !TEST_mem_eq(buf, 5, pdata + 5, 5)) 1076 goto err; 1077 1078 if (!TEST_int_eq(ch->protocol_error, 0)) 1079 goto err; 1080 1081 ret = 1; 1082 1083 err: 1084 ossl_quic_rstream_free(rstream); 1085 ossl_quic_rstream_qparm_destroy(rsqp); 1086 pkt_test_free(pkt); 1087 ossl_quic_channel_free(ch); 1088 return ret; 1089 } 1090 1091 /* 1092 * A short retransmit which starts below an existing range and ends past its 1093 * direct storage tail chunk is small enough to slip past the full overlap 1094 * guard in try_dstorage(), whose append path then treats every byte below 1095 * the tail chunk end as duplicate. The genuinely new bytes below the range 1096 * start must not be dropped when the insert reports success, otherwise the 1097 * frame is acked, never retransmitted and the gap in the stream is permanent. 1098 */ 1099 static int test_rstream_dstorage_two_sided_overlap(void) 1100 { 1101 QUIC_RSTREAM *rstream = NULL; 1102 QUIC_CHANNEL *ch = NULL; 1103 QUIC_RSTREAM_QPARM *rsqp = NULL; 1104 OSSL_QRX_PKT *pkts[59] = { NULL }; 1105 unsigned char pdata[64], buf[64], fill = 0xFF; 1106 size_t num_pkts = 0, readbytes = 0, avail = 0, i; 1107 int fin = 0; 1108 int ret = 0; 1109 1110 for (i = 0; i < sizeof(pdata); ++i) 1111 pdata[i] = (unsigned char)(0x40 + i); 1112 1113 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 1114 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 1115 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 1116 goto err; 1117 1118 for (i = 0; i < OSSL_NELEM(pkts); ++i) 1119 if (!TEST_ptr(pkts[num_pkts++] = pkt_test_new(1200))) 1120 goto err; 1121 1122 /* a packet backed chunk [10, 11) while below the overhead limit */ 1123 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[0], 10, 1124 pdata + 10, 1, 0)) 1125 || !TEST_size_t_eq(pkt_test_refcount(pkts[0]), 2)) 1126 goto err; 1127 1128 /* 1129 * disjoint 1-byte frames on 1200 byte datagrams, each accounting 1130 * 1199 bytes of overhead, take the stream past the 64kB overhead 1131 * limit so that short chunks switch to direct storage 1132 */ 1133 for (i = 0; i < 55; ++i) 1134 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[1 + i], 1135 100 + 2 * i, &fill, 1, 0))) 1136 goto err; 1137 1138 /* 1139 * [11, 12) goes to the direct storage of a new tail chunk appended 1140 * to the range, holding no reference to its packet 1141 */ 1142 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[56], 11, 1143 pdata + 11, 1, 0)) 1144 || !TEST_size_t_eq(pkt_test_refcount(pkts[56]), 1)) 1145 goto err; 1146 1147 /* 1148 * a 6 byte retransmit [8, 14) starts below the range [10, 12) and 1149 * ends past its direct storage tail chunk, the bytes [8, 10) are 1150 * new and must be kept 1151 */ 1152 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[57], 8, 1153 pdata + 8, 6, 0))) 1154 goto err; 1155 1156 /* deliver the head [0, 8) so everything up to 14 is contiguous */ 1157 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[58], 0, 1158 pdata, 8, 0))) 1159 goto err; 1160 1161 if (!TEST_true(ossl_quic_rstream_available(rstream, &avail, &fin)) 1162 || !TEST_size_t_eq(avail, 14) 1163 || !TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), 1164 &readbytes, &fin)) 1165 || !TEST_size_t_eq(readbytes, 14) 1166 || !TEST_mem_eq(buf, readbytes, pdata, 14)) 1167 goto err; 1168 1169 if (!TEST_int_eq(ch->protocol_error, 0)) 1170 goto err; 1171 1172 ret = 1; 1173 1174 err: 1175 ossl_quic_rstream_free(rstream); 1176 ossl_quic_rstream_qparm_destroy(rsqp); 1177 for (i = 0; i < num_pkts; ++i) 1178 pkt_test_free(pkts[i]); 1179 ossl_quic_channel_free(ch); 1180 return ret; 1181 } 1182 1183 /* 1184 * A FIN must be rejected as a final size error when data is already 1185 * buffered past its offset, or when the application has consumed more 1186 * bytes than the final size claims. Otherwise the frames beyond the FIN 1187 * offset stay pinned unreadable until the stream is torn down, and a 1188 * FIN below the consumed offset is recorded but can never signal the 1189 * end of the stream to the application. 1190 */ 1191 static int test_rstream_fin_final_size(void) 1192 { 1193 QUIC_RSTREAM *rstream = NULL; 1194 QUIC_CHANNEL *ch = NULL; 1195 QUIC_RSTREAM_QPARM *rsqp = NULL; 1196 OSSL_QRX_PKT *pkt_a = NULL, *pkt_b = NULL; 1197 unsigned char pdata[16], buf[16]; 1198 size_t readbytes = 0, i; 1199 int fin = 0; 1200 int ret = 0; 1201 1202 for (i = 0; i < sizeof(pdata); ++i) 1203 pdata[i] = (unsigned char)(0x40 + i); 1204 1205 /* a FIN below data which is already buffered in a higher range */ 1206 if (!TEST_ptr(pkt_a = pkt_test_new(1200)) 1207 || !TEST_ptr(pkt_b = pkt_test_new(1200)) 1208 || !TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 1209 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 1210 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 1211 goto err; 1212 1213 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, 1214 pdata, 10, 0)) 1215 || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_b, 100, 1216 pdata, 10, 0))) 1217 goto err; 1218 1219 if (!TEST_false(ossl_quic_rstream_queue_data(rstream, NULL, 50, NULL, 1220 0, 1)) 1221 || !TEST_int_eq(ch->protocol_error, 1)) 1222 goto err; 1223 1224 ossl_quic_rstream_free(rstream); 1225 rstream = NULL; 1226 ossl_quic_rstream_qparm_destroy(rsqp); 1227 rsqp = NULL; 1228 ossl_quic_channel_free(ch); 1229 ch = NULL; 1230 1231 /* a FIN below the offset the application has consumed already */ 1232 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 1233 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 1234 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 1235 goto err; 1236 1237 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, 1238 pdata, 10, 0)) 1239 || !TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), 1240 &readbytes, &fin)) 1241 || !TEST_size_t_eq(readbytes, 10)) 1242 goto err; 1243 1244 if (!TEST_false(ossl_quic_rstream_queue_data(rstream, NULL, 3, NULL, 1245 0, 1)) 1246 || !TEST_int_eq(ch->protocol_error, 1)) 1247 goto err; 1248 1249 ret = 1; 1250 1251 err: 1252 ossl_quic_rstream_free(rstream); 1253 ossl_quic_rstream_qparm_destroy(rsqp); 1254 pkt_test_free(pkt_a); 1255 pkt_test_free(pkt_b); 1256 ossl_quic_channel_free(ch); 1257 return ret; 1258 } 1259 1260 static int cleanse_buf_check(const unsigned char *buf, size_t size, 1261 size_t data_start, size_t data_end) 1262 { 1263 size_t i; 1264 1265 for (i = 0; i < size; ++i) 1266 if (!TEST_uchar_eq(buf[i], 1267 i >= data_start && i < data_end ? 0x00 : 0xAA)) { 1268 TEST_info("byte %zu", i); 1269 return 0; 1270 } 1271 1272 return 1; 1273 } 1274 1275 /* 1276 * With cleansing enabled, every dropped duplicate byte of an incoming 1277 * frame must be wiped in its packet buffer: a retransmit reaching below 1278 * the consumed offset, a retransmit consumed entirely, a duplicate 1279 * contained in an existing range and the tail trimmed away when a short 1280 * frame is prepended to a direct storage chunk. Otherwise the plaintext 1281 * stays in the recycled packet buffer which nothing else cleanses. 1282 */ 1283 static int test_rstream_cleanse_dropped_bytes(void) 1284 { 1285 QUIC_RSTREAM *rstream = NULL; 1286 QUIC_CHANNEL *ch = NULL; 1287 QUIC_RSTREAM_QPARM *rsqp = NULL; 1288 OSSL_QRX_PKT *pkts[60] = { NULL }; 1289 unsigned char src_a[16], src_b[16], src_c[16], src_d[16], src_e[16]; 1290 unsigned char buf[16], fill = 0xFF; 1291 size_t num_pkts = 0, readbytes = 0, i; 1292 int fin = 0; 1293 int ret = 0; 1294 1295 memset(src_a, 0xAA, sizeof(src_a)); 1296 memset(src_b, 0xAA, sizeof(src_b)); 1297 memset(src_c, 0xAA, sizeof(src_c)); 1298 memset(src_d, 0xAA, sizeof(src_d)); 1299 memset(src_e, 0xAA, sizeof(src_e)); 1300 for (i = 0; i < 10; ++i) 1301 src_a[3 + i] = (unsigned char)(0x40 + i); 1302 1303 for (i = 0; i < OSSL_NELEM(pkts); ++i) 1304 if (!TEST_ptr(pkts[num_pkts++] = pkt_test_new(1200))) 1305 goto err; 1306 1307 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL))) 1308 || !TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch)) 1309 || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, rsqp))) 1310 goto err; 1311 ossl_quic_rstream_set_cleanse(rstream, 1); 1312 1313 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[0], 0, 1314 src_a + 3, 10, 0)) 1315 || !TEST_true(ossl_quic_rstream_read(rstream, buf, 5, &readbytes, 1316 &fin)) 1317 || !TEST_size_t_eq(readbytes, 5)) 1318 goto err; 1319 1320 /* a retransmit reaching below the consumed offset is wiped whole */ 1321 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[1], 0, 1322 src_b + 3, 10, 0)) 1323 || !TEST_size_t_eq(pkt_test_refcount(pkts[1]), 1) 1324 || !cleanse_buf_check(src_b, sizeof(src_b), 3, 13)) 1325 goto err; 1326 1327 if (!TEST_true(ossl_quic_rstream_read(rstream, buf, 5, &readbytes, &fin)) 1328 || !TEST_size_t_eq(readbytes, 5)) 1329 goto err; 1330 1331 /* a fully consumed retransmit is wiped whole */ 1332 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[2], 0, 1333 src_c + 3, 10, 0)) 1334 || !TEST_size_t_eq(pkt_test_refcount(pkts[2]), 1) 1335 || !cleanse_buf_check(src_c, sizeof(src_c), 3, 13)) 1336 goto err; 1337 1338 /* 1339 * disjoint 1-byte frames on 1200 byte datagrams take the stream 1340 * past the overhead limit so short chunks use direct storage 1341 */ 1342 for (i = 0; i < 55; ++i) 1343 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[3 + i], 1344 100 + 2 * i, &fill, 1, 0))) 1345 goto err; 1346 1347 /* the copied direct storage chunk has its source wiped already */ 1348 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[58], 20, 1349 src_d + 3, 2, 0)) 1350 || !TEST_size_t_eq(pkt_test_refcount(pkts[58]), 1) 1351 || !cleanse_buf_check(src_d, sizeof(src_d), 3, 5)) 1352 goto err; 1353 1354 /* 1355 * [18, 21) prepends [18, 20) to the direct storage chunk [20, 22) 1356 * and drops the duplicate byte [20, 21), all three source bytes 1357 * must be wiped 1358 */ 1359 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkts[59], 18, 1360 src_e + 3, 3, 0)) 1361 || !TEST_size_t_eq(pkt_test_refcount(pkts[59]), 1) 1362 || !cleanse_buf_check(src_e, sizeof(src_e), 3, 6)) 1363 goto err; 1364 1365 if (!TEST_int_eq(ch->protocol_error, 0)) 1366 goto err; 1367 1368 ret = 1; 1369 1370 err: 1371 ossl_quic_rstream_free(rstream); 1372 ossl_quic_rstream_qparm_destroy(rsqp); 1373 for (i = 0; i < num_pkts; ++i) 1374 pkt_test_free(pkts[i]); 1375 ossl_quic_channel_free(ch); 1376 return ret; 1377 } 1378 1379 #define FILL_PATTERN "abcdefghijklmnopqrstuvwxyz0123456789" \ 1380 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 1381 1382 typedef struct test_stream_chunk { 1383 const unsigned char *tsc_data; 1384 uint64_t tsc_off; /* start == offset */ 1385 uint64_t tsc_len; /* end = offset + len */ 1386 int tsc_fin; 1387 size_t tsc_chunks_exp; 1388 size_t tsc_ranges_exp; 1389 } TEST_STREAM_CHUNK_T; 1390 1391 static int test_rstream_chunk_partial_overlap(void) 1392 { 1393 unsigned char data[4096]; 1394 unsigned char read_buf[4096]; 1395 TEST_STREAM_CHUNK_T tsc_buf[7]; 1396 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 1397 QUIC_RSTREAM_QPARM *rsqp = NULL; 1398 TEST_STREAM_CHUNK_T *tsc; 1399 QUIC_RSTREAM *rstream = NULL; 1400 QUIC_CHANNEL *ch = NULL; 1401 size_t readbytes; 1402 unsigned int i; 1403 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 1404 int fin = 0; 1405 int ok = 0; 1406 1407 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 1408 return 0; 1409 1410 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 1411 goto err; 1412 1413 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 1414 if (!TEST_ptr(rstream)) 1415 goto err; 1416 1417 for (i = 0; i < sizeof(data); i++) 1418 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 1419 1420 memset(tsc_buf, 0, sizeof(tsc_buf)); 1421 memset(read_buf, 0, sizeof(read_buf)); 1422 1423 /* 1424 * 1 range, (0, 120) with 5 stream chunks. there is a partial overlap 1425 * between chunks. 1426 */ 1427 tsc = &tsc_buf[0]; 1428 tsc->tsc_data = &data[0]; 1429 tsc->tsc_off = 0; 1430 tsc->tsc_len = 32; 1431 tsc->tsc_chunks_exp = 5; 1432 tsc->tsc_ranges_exp = 1; 1433 send_order[6] = 0; 1434 1435 tsc = &tsc_buf[1]; 1436 tsc->tsc_data = &data[24]; 1437 tsc->tsc_off = 24; 1438 tsc->tsc_len = 48; 1439 tsc->tsc_chunks_exp = 5; 1440 tsc->tsc_ranges_exp = 1; 1441 send_order[4] = 1; 1442 1443 tsc = &tsc_buf[2]; 1444 tsc->tsc_data = &data[44]; 1445 tsc->tsc_off = 44; 1446 tsc->tsc_len = 20; 1447 tsc->tsc_chunks_exp = 4; 1448 tsc->tsc_ranges_exp = 1; 1449 send_order[3] = 2; 1450 1451 tsc = &tsc_buf[3]; 1452 tsc->tsc_data = &data[55]; 1453 tsc->tsc_off = 55; 1454 tsc->tsc_len = 50; 1455 tsc->tsc_chunks_exp = 1; 1456 tsc->tsc_ranges_exp = 1; 1457 send_order[0] = 3; 1458 1459 tsc = &tsc_buf[4]; 1460 tsc->tsc_data = &data[100]; 1461 tsc->tsc_off = 100; 1462 tsc->tsc_len = 19; 1463 tsc->tsc_chunks_exp = 3; 1464 tsc->tsc_ranges_exp = 1; 1465 send_order[2] = 4; 1466 1467 tsc = &tsc_buf[5]; 1468 tsc->tsc_data = &data[119]; 1469 tsc->tsc_off = 119; 1470 tsc->tsc_len = 1; 1471 tsc->tsc_fin = 1; 1472 tsc->tsc_chunks_exp = 2; 1473 tsc->tsc_ranges_exp = 2; 1474 send_order[1] = 5; 1475 1476 /* 1477 * add duplicate chunk, the chunk range 48, 64 exists already 1478 * in the range, thus no additional stream chunk will be created. 1479 */ 1480 tsc = &tsc_buf[6]; 1481 tsc->tsc_data = &data[49]; 1482 tsc->tsc_off = 48; 1483 tsc->tsc_len = 16; 1484 tsc->tsc_chunks_exp = 5; 1485 tsc->tsc_ranges_exp = 1; 1486 send_order[5] = 6; 1487 1488 /* 1489 * send everything except offset 0. 1490 */ 1491 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 1492 for (i = 0; i < OSSL_NELEM(tsc_buf) - 1; i++) { 1493 pkt[i] = pkt_test_new(1200); 1494 if (!TEST_ptr(pkt[i])) 1495 goto err; 1496 tsc = &tsc_buf[send_order[i]]; 1497 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 1498 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) { 1499 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1500 goto err; 1501 } 1502 1503 /* 1504 * check our assumptions about about reassemble process internals. 1505 */ 1506 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 1507 tsc->tsc_ranges_exp)) { 1508 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1509 goto err; 1510 } 1511 1512 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 1513 tsc->tsc_chunks_exp)) { 1514 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1515 goto err; 1516 } 1517 1518 /* 1519 * the offset 0 chunk is not transmitted in loop here, 1520 * make sure the stream does not become readable. 1521 */ 1522 if (!TEST_true(ossl_quic_rstream_peek(rstream, read_buf, 1523 sizeof(read_buf), &readbytes, &fin))) { 1524 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1525 goto err; 1526 } 1527 1528 if (!TEST_false(fin)) { 1529 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1530 goto err; 1531 } 1532 1533 if (!TEST_size_t_eq(readbytes, 0)) { 1534 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1535 goto err; 1536 } 1537 } 1538 1539 /* 1540 * although 6 chunks were inserted, we expect to find only 5 chunks 1541 * in range, the last chunk was duplicate. 1542 */ 1543 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 5)) 1544 goto err; 1545 1546 /* 1547 * send offset 0 chunk, and try to read from stream. 1548 */ 1549 pkt[i] = pkt_test_new(1200); 1550 if (!TEST_ptr(pkt[i])) 1551 goto err; 1552 tsc = &tsc_buf[0]; 1553 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 1554 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 1555 goto err; 1556 1557 /* 1558 * writing chunk offset 0 makes stream readable 1559 */ 1560 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 1561 sizeof(read_buf), &readbytes, &fin))) 1562 goto err; 1563 1564 /* 1565 * we expect to read 120 bytes 1566 */ 1567 if (!TEST_uint64_t_eq(readbytes, 120)) 1568 goto err; 1569 1570 /* 1571 * the fin written by loop should be signaled too. 1572 */ 1573 if (!TEST_true(fin)) 1574 goto err; 1575 1576 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 1577 goto err; 1578 1579 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1580 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 1581 goto err; 1582 1583 if (!TEST_int_eq(ch->protocol_error, 0)) 1584 goto err; 1585 1586 ok = 1; 1587 err: 1588 ossl_quic_rstream_free(rstream); 1589 1590 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1591 pkt_test_free(pkt[i]); 1592 1593 ossl_quic_rstream_qparm_destroy(rsqp); 1594 ossl_quic_channel_free(ch); 1595 1596 return ok; 1597 } 1598 1599 /* 1600 * use 64kB as datagram size to force QUIC stack 1601 * to rach overhead threshold for all packets used 1602 * by test. So all data will be moved to stream buffers 1603 */ 1604 #define MOVE_TRESHOLD 65535 * 2 1605 1606 static int test_rstream_chunk_full_overlap(void) 1607 { 1608 unsigned char data[4096]; 1609 unsigned char read_buf[4096]; 1610 TEST_STREAM_CHUNK_T tsc_buf[5]; 1611 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 1612 QUIC_RSTREAM_QPARM *rsqp = NULL; 1613 TEST_STREAM_CHUNK_T *tsc; 1614 QUIC_RSTREAM *rstream = NULL; 1615 QUIC_CHANNEL *ch = NULL; 1616 size_t readbytes; 1617 unsigned int i; 1618 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 1619 int fin; 1620 int ok = 0; 1621 1622 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 1623 return 0; 1624 1625 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 1626 goto err; 1627 1628 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 1629 if (!TEST_ptr(rstream)) 1630 goto err; 1631 1632 for (i = 0; i < sizeof(data); i++) 1633 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 1634 1635 memset(tsc_buf, 0, sizeof(tsc_buf)); 1636 memset(read_buf, 0, sizeof(read_buf)); 1637 1638 /* 1639 * 1 range, (0, 256) with 5 stream chunks. 5 chunks overlap 1640 * partially, The last chunk we insert overlaps the whole range. 1641 */ 1642 tsc = &tsc_buf[0]; 1643 tsc->tsc_data = &data[0]; 1644 tsc->tsc_off = 0; 1645 tsc->tsc_len = 256; 1646 tsc->tsc_ranges_exp = 1; 1647 tsc->tsc_chunks_exp = 1; 1648 send_order[4] = 0; 1649 1650 tsc = &tsc_buf[1]; 1651 tsc->tsc_data = &data[24]; 1652 tsc->tsc_off = 24; 1653 tsc->tsc_len = 48; 1654 tsc->tsc_ranges_exp = 1; 1655 tsc->tsc_chunks_exp = 4; 1656 send_order[3] = 1; 1657 1658 tsc = &tsc_buf[2]; 1659 tsc->tsc_data = &data[44]; 1660 tsc->tsc_off = 44; 1661 tsc->tsc_len = 20; 1662 tsc->tsc_ranges_exp = 1; 1663 tsc->tsc_chunks_exp = 3; 1664 send_order[2] = 2; 1665 1666 tsc = &tsc_buf[3]; 1667 tsc->tsc_data = &data[55]; 1668 tsc->tsc_off = 55; 1669 tsc->tsc_len = 50; 1670 tsc->tsc_ranges_exp = 1; 1671 tsc->tsc_chunks_exp = 1; 1672 send_order[0] = 3; 1673 1674 tsc = &tsc_buf[4]; 1675 tsc->tsc_data = &data[100]; 1676 tsc->tsc_off = 100; 1677 tsc->tsc_len = 20; 1678 tsc->tsc_ranges_exp = 1; 1679 tsc->tsc_chunks_exp = 2; 1680 send_order[1] = 4; 1681 1682 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 1683 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) { 1684 pkt[i] = pkt_test_new(MOVE_TRESHOLD); 1685 if (!TEST_ptr(pkt[i])) 1686 goto err; 1687 tsc = &tsc_buf[send_order[i]]; 1688 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 1689 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, 0))) 1690 goto err; 1691 1692 /* 1693 * check our assumptions about about reassemble process internals. 1694 */ 1695 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 1696 tsc->tsc_ranges_exp)) { 1697 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1698 goto err; 1699 } 1700 1701 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 1702 tsc->tsc_chunks_exp)) { 1703 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1704 goto err; 1705 } 1706 } 1707 1708 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 1709 sizeof(read_buf), &readbytes, &fin))) 1710 goto err; 1711 1712 if (!TEST_false(fin)) 1713 goto err; 1714 1715 /* 1716 * we expect to read 256 bytes 1717 */ 1718 if (!TEST_uint64_t_eq(readbytes, 256)) 1719 goto err; 1720 1721 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 1722 goto err; 1723 1724 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1725 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 1726 goto err; 1727 1728 if (!TEST_int_eq(ch->protocol_error, 0)) 1729 goto err; 1730 1731 ok = 1; 1732 err: 1733 ossl_quic_rstream_free(rstream); 1734 1735 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1736 pkt_test_free(pkt[i]); 1737 1738 ossl_quic_rstream_qparm_destroy(rsqp); 1739 ossl_quic_channel_free(ch); 1740 1741 return ok; 1742 } 1743 1744 static int test_rstream_range_overlap(void) 1745 { 1746 unsigned char data[4096]; 1747 unsigned char read_buf[4096]; 1748 TEST_STREAM_CHUNK_T tsc_buf[9]; 1749 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 1750 QUIC_RSTREAM_QPARM *rsqp = NULL; 1751 TEST_STREAM_CHUNK_T *tsc; 1752 QUIC_RSTREAM *rstream = NULL; 1753 QUIC_CHANNEL *ch = NULL; 1754 size_t readbytes; 1755 unsigned int i; 1756 int fin; 1757 int ok = 0; 1758 1759 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 1760 return 0; 1761 1762 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 1763 goto err; 1764 1765 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 1766 if (!TEST_ptr(rstream)) 1767 goto err; 1768 1769 for (i = 0; i < sizeof(data); i++) 1770 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 1771 1772 memset(tsc_buf, 0, sizeof(tsc_buf)); 1773 memset(read_buf, 0, sizeof(read_buf)); 1774 1775 /* 1776 * start with 5 ranges, 1777 */ 1778 tsc = &tsc_buf[0]; 1779 tsc->tsc_data = &data[0]; 1780 tsc->tsc_off = 0; 1781 tsc->tsc_len = 64; 1782 tsc->tsc_ranges_exp = 1; 1783 tsc->tsc_chunks_exp = 1; 1784 1785 tsc = &tsc_buf[1]; 1786 tsc->tsc_data = &data[128]; 1787 tsc->tsc_off = 128; 1788 tsc->tsc_len = 64; 1789 tsc->tsc_ranges_exp = 2; 1790 tsc->tsc_chunks_exp = 2; 1791 1792 tsc = &tsc_buf[2]; 1793 tsc->tsc_data = &data[256]; 1794 tsc->tsc_off = 256; 1795 tsc->tsc_len = 64; 1796 tsc->tsc_ranges_exp = 3; 1797 tsc->tsc_chunks_exp = 3; 1798 1799 tsc = &tsc_buf[3]; 1800 tsc->tsc_data = &data[384]; 1801 tsc->tsc_off = 384; 1802 tsc->tsc_len = 64; 1803 tsc->tsc_ranges_exp = 4; 1804 tsc->tsc_chunks_exp = 4; 1805 1806 tsc = &tsc_buf[4]; 1807 tsc->tsc_data = &data[512]; 1808 tsc->tsc_off = 512; 1809 tsc->tsc_len = 64; 1810 tsc->tsc_ranges_exp = 5; 1811 tsc->tsc_chunks_exp = 5; 1812 1813 /* 1814 * chunk 6 appends data to last range 1815 */ 1816 tsc = &tsc_buf[5]; 1817 tsc->tsc_data = &data[548]; 1818 tsc->tsc_off = 548; 1819 tsc->tsc_len = 220; 1820 tsc->tsc_ranges_exp = 5; 1821 tsc->tsc_chunks_exp = 6; 1822 1823 /* 1824 * chunk 7 prepends data to last range 1825 */ 1826 tsc = &tsc_buf[6]; 1827 tsc->tsc_data = &data[480]; 1828 tsc->tsc_off = 480; 1829 tsc->tsc_len = 64; 1830 tsc->tsc_chunks_exp = 7; 1831 tsc->tsc_ranges_exp = 5; 1832 1833 /* 1834 * chunk 8 fully covers range 4 and partially 1835 * overlaps with 5 1836 */ 1837 tsc = &tsc_buf[7]; 1838 tsc->tsc_data = &data[364]; 1839 tsc->tsc_off = 364; 1840 tsc->tsc_len = 500; 1841 /* 1842 * note the expected number of chunks actually decreases!!! 1843 * here is what happened: 1844 * chunk [ 364, 864 ] is going to be inserted into range number 4 1845 * which spans over [ 384, 448 ]. After chunk is inserted the 1846 * 4th range looks as follows: 1847 * [ 364, 864 ], it contains 3 chunks: 1848 * [ 364, 384 ] 1849 * [ 384, 448 ] 1850 * [ 448, 864 ] 1851 * 1852 * however the 4th range now overlaps with 5th range [ 480, 768 ]. 1853 * the fifth range also contains 3 chunks: 1854 * [ 480, 768 ] 1855 * [ 480, 512 ] 1856 * [ 512, 576 ] 1857 * [ 576, 768 ] 1858 * as you can see there is a full overlap. The new range is going 1859 * to look as: 1860 * [ 364, 864 ] 1861 * [ 364, 384 ] 1862 * [ 384, 448 ] 1863 * [ 448, 864 ] 1864 * the 5th range is gone with all its ranges. the ranges 1, 2 and 3 1865 * where not touched so far, each of them contain one range, this 1866 * makes total 6 ranges. 1867 */ 1868 tsc->tsc_chunks_exp = 4; 1869 tsc->tsc_ranges_exp = 4; 1870 1871 /* 1872 * chunk 9 partially overlaps with the first and 1873 * the last range, 1874 */ 1875 tsc = &tsc_buf[8]; 1876 tsc->tsc_data = &data[32]; 1877 tsc->tsc_off = 32; 1878 tsc->tsc_len = 500; 1879 tsc->tsc_chunks_exp = 3; 1880 tsc->tsc_ranges_exp = 1; 1881 1882 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 1883 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) { 1884 pkt[i] = pkt_test_new(1200); 1885 if (!TEST_ptr(pkt[i])) 1886 goto err; 1887 tsc = &tsc_buf[i]; 1888 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 1889 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, 0))) 1890 goto err; 1891 1892 /* 1893 * check our assumptions about about reassemble process internals. 1894 */ 1895 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 1896 tsc->tsc_ranges_exp)) { 1897 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1898 goto err; 1899 } 1900 1901 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 1902 tsc->tsc_chunks_exp)) { 1903 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 1904 goto err; 1905 } 1906 } 1907 1908 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 1909 sizeof(read_buf), &readbytes, &fin))) 1910 goto err; 1911 1912 if (!TEST_false(fin)) 1913 goto err; 1914 1915 /* 1916 * we expect to read 864 bytes 1917 */ 1918 if (!TEST_uint64_t_eq(readbytes, 864)) 1919 goto err; 1920 1921 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 1922 goto err; 1923 1924 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1925 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 1926 goto err; 1927 1928 if (!TEST_int_eq(ch->protocol_error, 0)) 1929 goto err; 1930 1931 ok = 1; 1932 err: 1933 ossl_quic_rstream_free(rstream); 1934 1935 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 1936 pkt_test_free(pkt[i]); 1937 1938 ossl_quic_rstream_qparm_destroy(rsqp); 1939 ossl_quic_channel_free(ch); 1940 1941 return ok; 1942 } 1943 1944 static int test_rstream_prepend_byte_chunks(void) 1945 { 1946 unsigned char data[4096]; 1947 unsigned char read_buf[4096]; 1948 TEST_STREAM_CHUNK_T tsc_buf[6]; 1949 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 1950 QUIC_RSTREAM_QPARM *rsqp = NULL; 1951 TEST_STREAM_CHUNK_T *tsc; 1952 QUIC_RSTREAM *rstream = NULL; 1953 QUIC_CHANNEL *ch = NULL; 1954 size_t readbytes; 1955 unsigned int i; 1956 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 1957 int fin; 1958 int ok = 0; 1959 1960 if (sizeof(void *) != 8) { 1961 TEST_info("%s is implemented for 64-bit platforms only", OPENSSL_FUNC); 1962 return 1; 1963 } 1964 1965 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 1966 return 0; 1967 1968 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 1969 goto err; 1970 1971 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 1972 if (!TEST_ptr(rstream)) 1973 goto err; 1974 1975 for (i = 0; i < sizeof(data); i++) 1976 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 1977 1978 memset(tsc_buf, 0, sizeof(tsc_buf)); 1979 memset(read_buf, 0, sizeof(read_buf)); 1980 1981 /* 1982 * here we test one byte stream chunks. this test verifies 1983 * more short stream chunks are stored in single chunk buffer. 1984 */ 1985 tsc = &tsc_buf[0]; 1986 tsc->tsc_data = &data[0]; 1987 tsc->tsc_off = 0; 1988 tsc->tsc_len = 1; 1989 tsc->tsc_ranges_exp = 1; 1990 tsc->tsc_chunks_exp = 1; 1991 send_order[4] = 0; 1992 1993 tsc = &tsc_buf[1]; 1994 tsc->tsc_data = &data[1]; 1995 tsc->tsc_off = 1; 1996 tsc->tsc_len = 2; 1997 tsc->tsc_ranges_exp = 1; 1998 tsc->tsc_chunks_exp = 1; 1999 send_order[3] = 1; 2000 2001 tsc = &tsc_buf[2]; 2002 tsc->tsc_data = &data[3]; 2003 tsc->tsc_off = 3; 2004 tsc->tsc_len = 5; 2005 tsc->tsc_ranges_exp = 1; 2006 tsc->tsc_chunks_exp = 1; 2007 send_order[2] = 2; 2008 2009 tsc = &tsc_buf[3]; 2010 tsc->tsc_data = &data[8]; 2011 tsc->tsc_off = 8; 2012 tsc->tsc_len = 4; 2013 tsc->tsc_ranges_exp = 1; 2014 tsc->tsc_chunks_exp = 1; 2015 send_order[1] = 3; 2016 2017 tsc = &tsc_buf[4]; 2018 tsc->tsc_data = &data[12]; 2019 tsc->tsc_off = 12; 2020 tsc->tsc_len = 4; 2021 tsc->tsc_ranges_exp = 1; 2022 tsc->tsc_chunks_exp = 1; 2023 send_order[0] = 4; 2024 2025 tsc = &tsc_buf[5]; 2026 tsc->tsc_data = &data[12]; 2027 tsc->tsc_off = 12; 2028 tsc->tsc_len = 12; 2029 tsc->tsc_ranges_exp = 1; 2030 /* 2031 * this chunk partially overlaps. It does not fit to stream chunk buffer 2032 * created earlier, therefore a new stream chunk will be created. 2033 */ 2034 tsc->tsc_chunks_exp = 2; 2035 send_order[5] = 5; 2036 2037 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 2038 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) { 2039 pkt[i] = pkt_test_new(MOVE_TRESHOLD); 2040 if (!TEST_ptr(pkt[i])) 2041 goto err; 2042 tsc = &tsc_buf[send_order[i]]; 2043 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 2044 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, 0))) 2045 goto err; 2046 2047 /* 2048 * check our assumptions about about reassemble process internals. 2049 */ 2050 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2051 tsc->tsc_ranges_exp)) { 2052 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2053 goto err; 2054 } 2055 2056 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2057 tsc->tsc_chunks_exp)) { 2058 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2059 goto err; 2060 } 2061 } 2062 2063 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 2064 sizeof(read_buf), &readbytes, &fin))) 2065 goto err; 2066 2067 if (!TEST_false(fin)) 2068 goto err; 2069 2070 /* 2071 * we expect to read 24 bytes 2072 */ 2073 if (!TEST_uint64_t_eq(readbytes, 24)) 2074 goto err; 2075 2076 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 2077 goto err; 2078 2079 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2080 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 2081 goto err; 2082 2083 if (!TEST_int_eq(ch->protocol_error, 0)) 2084 goto err; 2085 2086 ok = 1; 2087 err: 2088 ossl_quic_rstream_free(rstream); 2089 2090 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2091 pkt_test_free(pkt[i]); 2092 2093 ossl_quic_rstream_qparm_destroy(rsqp); 2094 ossl_quic_channel_free(ch); 2095 2096 return ok; 2097 } 2098 2099 static int test_rstream_append_byte_chunks(void) 2100 { 2101 unsigned char data[4096]; 2102 unsigned char read_buf[4096]; 2103 TEST_STREAM_CHUNK_T tsc_buf[6]; 2104 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 2105 QUIC_RSTREAM_QPARM *rsqp = NULL; 2106 TEST_STREAM_CHUNK_T *tsc; 2107 QUIC_RSTREAM *rstream = NULL; 2108 QUIC_CHANNEL *ch = NULL; 2109 size_t readbytes; 2110 unsigned int i; 2111 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 2112 int fin; 2113 int ok = 0; 2114 2115 if (sizeof(void *) != 8) { 2116 TEST_info("%s is implemented for 64-bit platforms only", OPENSSL_FUNC); 2117 return 1; 2118 } 2119 2120 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 2121 return 0; 2122 2123 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 2124 goto err; 2125 2126 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 2127 if (!TEST_ptr(rstream)) 2128 goto err; 2129 2130 for (i = 0; i < sizeof(data); i++) 2131 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 2132 2133 memset(tsc_buf, 0, sizeof(tsc_buf)); 2134 memset(read_buf, 0, sizeof(read_buf)); 2135 2136 /* 2137 * here we test one byte stream chunks. this test verifies 2138 * more short stream chunks are stored in single chunk buffer. 2139 */ 2140 tsc = &tsc_buf[0]; 2141 tsc->tsc_data = &data[0]; 2142 tsc->tsc_off = 0; 2143 tsc->tsc_len = 1; 2144 tsc->tsc_ranges_exp = 1; 2145 tsc->tsc_chunks_exp = 1; 2146 send_order[0] = 0; 2147 2148 tsc = &tsc_buf[1]; 2149 tsc->tsc_data = &data[1]; 2150 tsc->tsc_off = 1; 2151 tsc->tsc_len = 2; 2152 tsc->tsc_ranges_exp = 1; 2153 tsc->tsc_chunks_exp = 1; 2154 send_order[1] = 1; 2155 2156 tsc = &tsc_buf[2]; 2157 tsc->tsc_data = &data[3]; 2158 tsc->tsc_off = 3; 2159 tsc->tsc_len = 5; 2160 tsc->tsc_ranges_exp = 1; 2161 tsc->tsc_chunks_exp = 1; 2162 send_order[2] = 2; 2163 2164 tsc = &tsc_buf[3]; 2165 tsc->tsc_data = &data[8]; 2166 tsc->tsc_off = 8; 2167 tsc->tsc_len = 4; 2168 tsc->tsc_ranges_exp = 1; 2169 tsc->tsc_chunks_exp = 1; 2170 send_order[3] = 3; 2171 2172 tsc = &tsc_buf[4]; 2173 tsc->tsc_data = &data[12]; 2174 tsc->tsc_off = 12; 2175 tsc->tsc_len = 4; 2176 tsc->tsc_ranges_exp = 1; 2177 tsc->tsc_chunks_exp = 1; 2178 send_order[4] = 4; 2179 2180 tsc = &tsc_buf[5]; 2181 tsc->tsc_data = &data[12]; 2182 tsc->tsc_off = 12; 2183 tsc->tsc_len = 12; 2184 /* 2185 * this chunk partially overlaps. It does not fit to stream chunk buffer 2186 * created by for() loop above, therefore a new stream chunk will be created. 2187 */ 2188 tsc->tsc_ranges_exp = 1; 2189 tsc->tsc_chunks_exp = 2; 2190 send_order[5] = 5; 2191 2192 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 2193 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) { 2194 pkt[i] = pkt_test_new(MOVE_TRESHOLD); 2195 if (!TEST_ptr(pkt[i])) 2196 goto err; 2197 tsc = &tsc_buf[send_order[i]]; 2198 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 2199 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, 0))) 2200 goto err; 2201 2202 /* 2203 * check our assumptions about about reassemble process internals. 2204 */ 2205 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2206 tsc->tsc_ranges_exp)) { 2207 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2208 goto err; 2209 } 2210 2211 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2212 tsc->tsc_chunks_exp)) { 2213 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2214 goto err; 2215 } 2216 } 2217 2218 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 2219 sizeof(read_buf), &readbytes, &fin))) 2220 goto err; 2221 2222 /* 2223 * we expect to read 24 bytes 2224 */ 2225 if (!TEST_uint64_t_eq(readbytes, 24)) 2226 goto err; 2227 2228 if (!TEST_false(fin)) 2229 goto err; 2230 2231 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 2232 goto err; 2233 2234 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2235 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 2236 goto err; 2237 2238 if (!TEST_int_eq(ch->protocol_error, 0)) 2239 goto err; 2240 2241 ok = 1; 2242 err: 2243 ossl_quic_rstream_free(rstream); 2244 2245 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2246 pkt_test_free(pkt[i]); 2247 2248 ossl_quic_rstream_qparm_destroy(rsqp); 2249 ossl_quic_channel_free(ch); 2250 2251 return ok; 2252 } 2253 2254 static int test_rstream_mix_chunks(void) 2255 { 2256 unsigned char data[4096]; 2257 unsigned char read_buf[4096]; 2258 TEST_STREAM_CHUNK_T tsc_buf[7]; 2259 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 2260 QUIC_RSTREAM_QPARM *rsqp = NULL; 2261 TEST_STREAM_CHUNK_T *tsc; 2262 QUIC_RSTREAM *rstream = NULL; 2263 QUIC_CHANNEL *ch = NULL; 2264 size_t readbytes; 2265 unsigned int i; 2266 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 2267 int fin; 2268 int ok = 0; 2269 2270 if (sizeof(void *) != 8) { 2271 TEST_info("%s is implemented for 64-bit platforms only", OPENSSL_FUNC); 2272 return 1; 2273 } 2274 2275 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 2276 return 0; 2277 2278 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 2279 goto err; 2280 2281 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 2282 if (!TEST_ptr(rstream)) 2283 goto err; 2284 2285 for (i = 0; i < sizeof(data); i++) 2286 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 2287 2288 memset(tsc_buf, 0, sizeof(tsc_buf)); 2289 memset(read_buf, 0, sizeof(read_buf)); 2290 2291 /* 2292 * we start with 4-byte nibble which at offset 8. 2293 */ 2294 tsc = &tsc_buf[0]; 2295 tsc->tsc_data = &data[8]; 2296 tsc->tsc_off = 8; 2297 tsc->tsc_len = 4; 2298 tsc->tsc_ranges_exp = 1; 2299 tsc->tsc_chunks_exp = 1; 2300 send_order[0] = 0; 2301 2302 /* 2303 * the next 3 byte nibble partially overlaps with 2304 * earlier one. it adds 1 byte. it is prepended 2305 */ 2306 tsc = &tsc_buf[1]; 2307 tsc->tsc_data = &data[7]; 2308 tsc->tsc_off = 7; 2309 tsc->tsc_len = 3; 2310 tsc->tsc_ranges_exp = 1; 2311 tsc->tsc_chunks_exp = 1; 2312 send_order[1] = 1; 2313 2314 /* 2315 * the next 3 byte nibble partially overlaps with 2316 * range. it effectively adds 1 byte to end. 2317 */ 2318 tsc = &tsc_buf[2]; 2319 tsc->tsc_data = &data[10]; 2320 tsc->tsc_off = 10; 2321 tsc->tsc_len = 3; 2322 tsc->tsc_ranges_exp = 1; 2323 tsc->tsc_chunks_exp = 1; 2324 send_order[2] = 2; 2325 2326 /* 2327 * append nibble that fully overlaps with range 2328 * (the new nibble is superset of existing range) 2329 * it effectively adds two bytes 2330 */ 2331 tsc = &tsc_buf[3]; 2332 tsc->tsc_data = &data[6]; 2333 tsc->tsc_off = 6; 2334 tsc->tsc_len = 8; 2335 tsc->tsc_ranges_exp = 1; 2336 tsc->tsc_chunks_exp = 1; 2337 send_order[3] = 3; 2338 2339 /* 2340 * prepend the nibble which starts yet another range. 2341 */ 2342 tsc = &tsc_buf[4]; 2343 tsc->tsc_data = &data[0]; 2344 tsc->tsc_off = 0; 2345 tsc->tsc_len = 1; 2346 tsc->tsc_ranges_exp = 2; 2347 tsc->tsc_chunks_exp = 2; 2348 send_order[4] = 4; 2349 2350 /* 2351 * nibble here appends bytes to right range. the range count and chunk 2352 * count must not change as new data still fit to dstorage. 2353 */ 2354 tsc = &tsc_buf[5]; 2355 tsc->tsc_data = &data[14]; 2356 tsc->tsc_off = 14; 2357 tsc->tsc_len = 3; 2358 tsc->tsc_ranges_exp = 2; 2359 tsc->tsc_chunks_exp = 2; 2360 send_order[5] = 5; 2361 2362 /* 2363 * send chunk that overlaps everything 2364 */ 2365 tsc = &tsc_buf[6]; 2366 tsc->tsc_data = &data[0]; 2367 tsc->tsc_off = 0; 2368 tsc->tsc_len = 24; 2369 tsc->tsc_ranges_exp = 1; 2370 tsc->tsc_chunks_exp = 2; 2371 send_order[6] = 6; 2372 2373 /* 2374 * all nibbles we've sent so far must fit to single range. 2375 */ 2376 assert(OSSL_NELEM(tsc_buf) == OSSL_NELEM(pkt)); 2377 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) { 2378 pkt[i] = pkt_test_new(MOVE_TRESHOLD); 2379 if (!TEST_ptr(pkt[i])) 2380 goto err; 2381 tsc = &tsc_buf[send_order[i]]; 2382 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 2383 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, 0))) 2384 goto err; 2385 2386 /* 2387 * check our assumptions about about reassemble process internals. 2388 */ 2389 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2390 tsc->tsc_ranges_exp)) { 2391 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2392 goto err; 2393 } 2394 2395 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2396 tsc->tsc_chunks_exp)) { 2397 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2398 goto err; 2399 } 2400 } 2401 2402 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 2403 sizeof(read_buf), &readbytes, &fin))) 2404 goto err; 2405 2406 if (!TEST_uint64_t_eq(readbytes, 24)) 2407 goto err; 2408 2409 if (!TEST_false(fin)) 2410 goto err; 2411 2412 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 2413 goto err; 2414 2415 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2416 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 2417 goto err; 2418 2419 if (!TEST_int_eq(ch->protocol_error, 0)) 2420 goto err; 2421 2422 ok = 1; 2423 err: 2424 ossl_quic_rstream_free(rstream); 2425 2426 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2427 pkt_test_free(pkt[i]); 2428 2429 ossl_quic_rstream_qparm_destroy(rsqp); 2430 ossl_quic_channel_free(ch); 2431 2432 return ok; 2433 } 2434 2435 static int test_final_size_violation_fin_first(void) 2436 { 2437 unsigned char data[4096]; 2438 unsigned char read_buf[4096]; 2439 TEST_STREAM_CHUNK_T tsc_buf[3]; 2440 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 2441 QUIC_RSTREAM_QPARM *rsqp = NULL; 2442 TEST_STREAM_CHUNK_T *tsc; 2443 QUIC_RSTREAM *rstream = NULL; 2444 QUIC_CHANNEL *ch = NULL; 2445 unsigned int i; 2446 unsigned int send_order[OSSL_NELEM(tsc_buf)]; 2447 int ok = 0; 2448 2449 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 2450 return 0; 2451 2452 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 2453 goto err; 2454 2455 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 2456 if (!TEST_ptr(rstream)) 2457 goto err; 2458 2459 for (i = 0; i < sizeof(data); i++) 2460 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 2461 2462 memset(tsc_buf, 0, sizeof(tsc_buf)); 2463 memset(read_buf, 0, sizeof(read_buf)); 2464 2465 /* 2466 * we start with 4-byte nibble which at offset 8. 2467 */ 2468 tsc = &tsc_buf[0]; 2469 tsc->tsc_data = &data[10]; 2470 tsc->tsc_off = 10; 2471 tsc->tsc_len = 10; 2472 tsc->tsc_fin = 1; 2473 tsc->tsc_ranges_exp = 1; 2474 tsc->tsc_chunks_exp = 1; 2475 send_order[0] = 0; 2476 2477 tsc = &tsc_buf[1]; 2478 tsc->tsc_data = &data[5]; 2479 tsc->tsc_off = 5; 2480 tsc->tsc_len = 5; 2481 tsc->tsc_fin = 0; 2482 tsc->tsc_ranges_exp = 1; 2483 tsc->tsc_chunks_exp = 2; 2484 send_order[1] = 1; 2485 2486 tsc = &tsc_buf[2]; 2487 tsc->tsc_data = &data[50]; 2488 tsc->tsc_off = 20; 2489 tsc->tsc_len = 10; 2490 tsc->tsc_fin = 0; 2491 tsc->tsc_ranges_exp = 1; 2492 tsc->tsc_chunks_exp = 2; 2493 send_order[2] = 2; 2494 2495 for (i = 0; i < OSSL_NELEM(tsc_buf) - 1; i++) { 2496 pkt[i] = pkt_test_new(1200); 2497 if (!TEST_ptr(pkt[i])) 2498 goto err; 2499 tsc = &tsc_buf[send_order[i]]; 2500 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], 2501 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2502 goto err; 2503 2504 /* 2505 * check our assumptions about about reassemble process internals. 2506 */ 2507 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2508 tsc->tsc_ranges_exp)) { 2509 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2510 goto err; 2511 } 2512 2513 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2514 tsc->tsc_chunks_exp)) { 2515 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2516 goto err; 2517 } 2518 } 2519 2520 pkt[i] = pkt_test_new(1200); 2521 if (!TEST_ptr(pkt[i])) 2522 goto err; 2523 tsc = &tsc_buf[send_order[i]]; 2524 if (!TEST_false(ossl_quic_rstream_queue_data(rstream, pkt[i], 2525 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2526 goto err; 2527 2528 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2529 tsc->tsc_ranges_exp)) { 2530 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2531 goto err; 2532 } 2533 2534 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2535 tsc->tsc_chunks_exp)) { 2536 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2537 goto err; 2538 } 2539 2540 for (i = 0; i < OSSL_NELEM(tsc_buf) - 1; i++) 2541 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 2)) 2542 goto err; 2543 2544 if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) 2545 goto err; 2546 2547 if (!TEST_int_eq(ch->protocol_error, 1)) 2548 goto err; 2549 2550 ok = 1; 2551 err: 2552 ossl_quic_rstream_free(rstream); 2553 2554 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2555 pkt_test_free(pkt[i]); 2556 2557 ossl_quic_rstream_qparm_destroy(rsqp); 2558 ossl_quic_channel_free(ch); 2559 2560 return ok; 2561 } 2562 2563 static int test_final_size_violation_data_first(void) 2564 { 2565 unsigned char data[4096]; 2566 unsigned char read_buf[4096]; 2567 TEST_STREAM_CHUNK_T tsc_buf[3]; 2568 OSSL_QRX_PKT *pkt[OSSL_NELEM(tsc_buf)] = { 0 }; 2569 QUIC_RSTREAM_QPARM *rsqp = NULL; 2570 TEST_STREAM_CHUNK_T *tsc; 2571 QUIC_RSTREAM *rstream = NULL; 2572 QUIC_CHANNEL *ch = NULL; 2573 unsigned int i; 2574 int ok = 0; 2575 2576 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 2577 return 0; 2578 2579 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 2580 goto err; 2581 2582 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 2583 if (!TEST_ptr(rstream)) 2584 goto err; 2585 2586 for (i = 0; i < sizeof(data); i++) 2587 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 2588 2589 memset(tsc_buf, 0, sizeof(tsc_buf)); 2590 memset(read_buf, 0, sizeof(read_buf)); 2591 2592 /* 2593 * we start with 4-byte nibble which at offset 8. 2594 */ 2595 tsc = &tsc_buf[0]; 2596 tsc->tsc_data = &data[10]; 2597 tsc->tsc_off = 10; 2598 tsc->tsc_len = 10; 2599 tsc->tsc_fin = 0; 2600 tsc->tsc_ranges_exp = 1; 2601 tsc->tsc_chunks_exp = 1; 2602 2603 tsc = &tsc_buf[1]; 2604 tsc->tsc_data = &data[5]; 2605 tsc->tsc_off = 5; 2606 tsc->tsc_len = 5; 2607 tsc->tsc_fin = 1; 2608 tsc->tsc_ranges_exp = 1; 2609 tsc->tsc_chunks_exp = 1; 2610 2611 pkt[0] = pkt_test_new(1200); 2612 if (!TEST_ptr(pkt[0])) 2613 goto err; 2614 tsc = &tsc_buf[0]; 2615 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[0], 2616 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2617 goto err; 2618 2619 /* 2620 * check our assumptions about about reassemble process internals. 2621 */ 2622 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2623 tsc->tsc_ranges_exp)) { 2624 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2625 goto err; 2626 } 2627 2628 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2629 tsc->tsc_chunks_exp)) { 2630 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2631 goto err; 2632 } 2633 2634 pkt[1] = pkt_test_new(1200); 2635 if (!TEST_ptr(pkt[1])) 2636 goto err; 2637 tsc = &tsc_buf[1]; 2638 if (!TEST_false(ossl_quic_rstream_queue_data(rstream, pkt[1], 2639 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2640 goto err; 2641 2642 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2643 tsc->tsc_ranges_exp)) { 2644 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2645 goto err; 2646 } 2647 2648 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2649 tsc->tsc_chunks_exp)) { 2650 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2651 goto err; 2652 } 2653 2654 if (!TEST_size_t_eq(pkt_test_refcount(pkt[0]), 2)) 2655 goto err; 2656 2657 if (!TEST_size_t_eq(pkt_test_refcount(pkt[1]), 1)) 2658 goto err; 2659 2660 if (!TEST_int_eq(ch->protocol_error, 1)) 2661 goto err; 2662 2663 ok = 1; 2664 err: 2665 ossl_quic_rstream_free(rstream); 2666 2667 for (i = 0; i < OSSL_NELEM(tsc_buf); i++) 2668 pkt_test_free(pkt[i]); 2669 2670 ossl_quic_rstream_qparm_destroy(rsqp); 2671 ossl_quic_channel_free(ch); 2672 2673 return ok; 2674 } 2675 2676 #define FILLERS 56 2677 2678 static int test_trim_right(void) 2679 { 2680 unsigned char data[4096]; 2681 unsigned char read_buf[4096]; 2682 size_t readbytes; 2683 TEST_STREAM_CHUNK_T tsc_buf[4]; 2684 OSSL_QRX_PKT *pkt[FILLERS + OSSL_NELEM(tsc_buf)] = { 0 }; 2685 unsigned char fill = 0xFF; 2686 QUIC_RSTREAM_QPARM *rsqp = NULL; 2687 TEST_STREAM_CHUNK_T *tsc; 2688 QUIC_RSTREAM *rstream = NULL; 2689 QUIC_CHANNEL *ch = NULL; 2690 int fin; 2691 unsigned int i, pktnum; 2692 int ok = 0; 2693 2694 if (!TEST_ptr(ch = OPENSSL_zalloc(sizeof(QUIC_CHANNEL)))) 2695 return 0; 2696 2697 if (!TEST_ptr(rsqp = ossl_quic_rstream_qparm_new(ch))) 2698 goto err; 2699 2700 rstream = ossl_quic_rstream_new(NULL, NULL, rsqp); 2701 if (!TEST_ptr(rstream)) 2702 goto err; 2703 2704 for (i = 0; i < sizeof(data); i++) 2705 data[i] = FILL_PATTERN[i % (sizeof(FILL_PATTERN) - 1)]; 2706 2707 memset(tsc_buf, 0, sizeof(tsc_buf)); 2708 memset(read_buf, 0, sizeof(read_buf)); 2709 2710 pktnum = 0; 2711 for (i = 0; i < FILLERS; i++) { 2712 pkt[pktnum] = pkt_test_new(1200); 2713 if (!TEST_ptr(pkt[pktnum])) 2714 goto err; 2715 2716 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[pktnum], 2717 1024 + 2 * i, &fill, 1, 0))) 2718 goto err; 2719 2720 pktnum++; 2721 } 2722 2723 /* 2724 * send three chunks. each 64 bytes long, 2725 * chunks create three ranges. 2726 */ 2727 tsc = &tsc_buf[0]; 2728 tsc->tsc_data = &data[0]; 2729 tsc->tsc_off = 0; 2730 tsc->tsc_len = 64; 2731 tsc->tsc_fin = 0; 2732 tsc->tsc_ranges_exp = FILLERS + 1; 2733 tsc->tsc_chunks_exp = FILLERS + 1; 2734 2735 tsc = &tsc_buf[1]; 2736 tsc->tsc_data = &data[128]; 2737 tsc->tsc_off = 128; 2738 tsc->tsc_len = 64; 2739 tsc->tsc_fin = 0; 2740 tsc->tsc_ranges_exp = FILLERS + 2; 2741 tsc->tsc_chunks_exp = FILLERS + 2; 2742 2743 tsc = &tsc_buf[2]; 2744 tsc->tsc_data = &data[256]; 2745 tsc->tsc_off = 256; 2746 tsc->tsc_len = 64; 2747 tsc->tsc_fin = 0; 2748 tsc->tsc_ranges_exp = FILLERS + 3; 2749 tsc->tsc_chunks_exp = FILLERS + 3; 2750 2751 for (i = 0; i < OSSL_NELEM(tsc_buf) - 1; i++) { 2752 pkt[pktnum] = pkt_test_new(1200); 2753 if (!TEST_ptr(pkt[pktnum])) 2754 goto err; 2755 tsc = &tsc_buf[i]; 2756 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[pktnum], 2757 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2758 goto err; 2759 2760 /* 2761 * check our assumptions about about reassemble process internals. 2762 */ 2763 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2764 tsc->tsc_ranges_exp)) { 2765 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2766 goto err; 2767 } 2768 2769 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2770 tsc->tsc_chunks_exp)) { 2771 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2772 goto err; 2773 } 2774 2775 /* 2776 * the packet reference should stay at 1, because _rstream_queue_data() 2777 * copies data to stream buffer instead of grabbing a reference to 2778 * packet (advancing the packet's ref counter) 2779 */ 2780 if (!TEST_size_t_eq(pkt_test_refcount(pkt[pktnum]), 1)) 2781 goto err; 2782 pktnum++; 2783 } 2784 2785 /* 2786 * do a partial read of 16 bytes. 2787 */ 2788 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 2789 16, &readbytes, &fin))) 2790 goto err; 2791 2792 if (!TEST_uint64_t_eq(readbytes, 16)) 2793 goto err; 2794 2795 if (!TEST_false(fin)) 2796 goto err; 2797 2798 if (!TEST_mem_eq(read_buf, readbytes, data, readbytes)) 2799 goto err; 2800 2801 /* 2802 * send chunk that glues three ranges together. 2803 */ 2804 tsc = &tsc_buf[3]; 2805 tsc->tsc_data = &data[63]; 2806 tsc->tsc_off = 63; 2807 tsc->tsc_len = 160; 2808 tsc->tsc_fin = 0; 2809 tsc->tsc_ranges_exp = FILLERS + 2; 2810 tsc->tsc_chunks_exp = FILLERS + 3; 2811 2812 pkt[pktnum] = pkt_test_new(1200); 2813 if (!TEST_ptr(pkt[pktnum])) 2814 goto err; 2815 if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[pktnum], 2816 tsc->tsc_off, tsc->tsc_data, tsc->tsc_len, tsc->tsc_fin))) 2817 goto err; 2818 2819 /* 2820 * check our assumptions about about reassemble process internals. 2821 */ 2822 if (!TEST_size_t_eq(ossl_quic_rstream_get_range_count(rstream), 2823 tsc->tsc_ranges_exp)) { 2824 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2825 goto err; 2826 } 2827 2828 if (!TEST_size_t_eq(ossl_quic_rstream_get_chunk_count(rstream), 2829 tsc->tsc_chunks_exp)) { 2830 TEST_info("%s failing iteration %u", OPENSSL_FUNC, i); 2831 goto err; 2832 } 2833 2834 if (!TEST_size_t_eq(pkt_test_refcount(pkt[pktnum]), 1)) 2835 goto err; 2836 pktnum++; 2837 2838 if (!TEST_true(ossl_quic_rstream_read(rstream, read_buf, 2839 4096, &readbytes, &fin))) 2840 goto err; 2841 2842 /* 2843 * the ranges are still dis-joint, only 207 bytes can be read 2844 */ 2845 if (!TEST_uint64_t_eq(readbytes, 207)) 2846 goto err; 2847 2848 if (!TEST_false(fin)) 2849 goto err; 2850 2851 if (!TEST_mem_eq(read_buf, readbytes, &data[16], readbytes)) 2852 goto err; 2853 2854 ok = 1; 2855 err: 2856 ossl_quic_rstream_free(rstream); 2857 2858 for (i = 0; i < OSSL_NELEM(pkt); i++) 2859 pkt_test_free(pkt[i]); 2860 2861 ossl_quic_rstream_qparm_destroy(rsqp); 2862 ossl_quic_channel_free(ch); 2863 2864 return ok; 2865 } 2866 2867 int setup_tests(void) 2868 { 2869 ADD_TEST(test_sstream_simple); 2870 ADD_ALL_TESTS(test_sstream_bulk, 100); 2871 ADD_ALL_TESTS(test_rstream_simple, 2); 2872 ADD_ALL_TESTS(test_rstream_random, 100); 2873 ADD_TEST(test_rstream_pkt); 2874 ADD_TEST(test_rstream_pkt_overhead); 2875 ADD_ALL_TESTS(test_rstream_reorder, 40); 2876 ADD_TEST(test_rstream_dstorage_two_sided_overlap); 2877 ADD_TEST(test_rstream_zero_length_read); 2878 ADD_TEST(test_rstream_fin_final_size); 2879 ADD_TEST(test_rstream_cleanse_dropped_bytes); 2880 ADD_TEST(test_rstream_chunk_partial_overlap); 2881 ADD_TEST(test_rstream_chunk_full_overlap); 2882 ADD_TEST(test_rstream_range_overlap); 2883 ADD_TEST(test_rstream_prepend_byte_chunks); 2884 ADD_TEST(test_rstream_append_byte_chunks); 2885 ADD_TEST(test_rstream_mix_chunks); 2886 ADD_TEST(test_final_size_violation_fin_first); 2887 ADD_TEST(test_final_size_violation_data_first); 2888 ADD_TEST(test_trim_right); 2889 2890 return 1; 2891 } 2892