xref: /freebsd/crypto/openssl/test/quic_stream_test.c (revision dece5b05f577fc4c6b89af7ad48dfbdf7cc4945c)
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