Coverage Report

Created: 2026-05-24 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/ssl/quic/quic_stream_map.c
Line
Count
Source
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
10
#include "internal/quic_stream_map.h"
11
#include "internal/nelem.h"
12
#include "internal/quic_channel.h"
13
14
/*
15
 * QUIC Stream Map
16
 * ===============
17
 */
18
DEFINE_LHASH_OF_EX(QUIC_STREAM);
19
20
static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs);
21
22
/* Circular list management. */
23
static void list_insert_tail(QUIC_STREAM_LIST_NODE *l,
24
    QUIC_STREAM_LIST_NODE *n)
25
172k
{
26
    /* Must not be in list. */
27
172k
    assert(n->prev == NULL && n->next == NULL
28
172k
        && l->prev != NULL && l->next != NULL);
29
30
172k
    n->prev = l->prev;
31
172k
    n->prev->next = n;
32
172k
    l->prev = n;
33
172k
    n->next = l;
34
172k
}
35
36
static void list_remove(QUIC_STREAM_LIST_NODE *l,
37
    QUIC_STREAM_LIST_NODE *n)
38
172k
{
39
172k
    assert(n->prev != NULL && n->next != NULL
40
172k
        && n->prev != n && n->next != n);
41
42
172k
    n->prev->next = n->next;
43
172k
    n->next->prev = n->prev;
44
172k
    n->next = n->prev = NULL;
45
172k
}
46
47
static QUIC_STREAM *list_next(QUIC_STREAM_LIST_NODE *l, QUIC_STREAM_LIST_NODE *n,
48
    size_t off)
49
78.8M
{
50
78.8M
    assert(n->prev != NULL && n->next != NULL
51
78.8M
        && (n == l || (n->prev != n && n->next != n))
52
78.8M
        && l->prev != NULL && l->next != NULL);
53
54
78.8M
    n = n->next;
55
56
78.8M
    if (n == l)
57
78.8M
        n = n->next;
58
78.8M
    if (n == l)
59
78.8M
        return NULL;
60
61
78.8M
    assert(n != NULL);
62
63
43.7k
    return (QUIC_STREAM *)(((char *)n) - off);
64
43.7k
}
65
66
43.2k
#define active_next(l, s) list_next((l), &(s)->active_node, \
67
43.2k
    offsetof(QUIC_STREAM, active_node))
68
0
#define accept_next(l, s) list_next((l), &(s)->accept_node, \
69
0
    offsetof(QUIC_STREAM, accept_node))
70
504
#define accept_head(l) list_next((l), (l), \
71
504
    offsetof(QUIC_STREAM, accept_node))
72
78.8M
#define ready_for_gc_head(l) list_next((l), (l), \
73
78.8M
    offsetof(QUIC_STREAM, ready_for_gc_node))
74
75
static unsigned long hash_stream(const QUIC_STREAM *s)
76
15.7M
{
77
15.7M
    return (unsigned long)s->id;
78
15.7M
}
79
80
static int cmp_stream(const QUIC_STREAM *a, const QUIC_STREAM *b)
81
349k
{
82
349k
    if (a->id < b->id)
83
0
        return -1;
84
349k
    if (a->id > b->id)
85
0
        return 1;
86
349k
    return 0;
87
349k
}
88
89
int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm,
90
    uint64_t (*get_stream_limit_cb)(int uni, void *arg),
91
    void *get_stream_limit_cb_arg,
92
    QUIC_RXFC *max_streams_bidi_rxfc,
93
    QUIC_RXFC *max_streams_uni_rxfc,
94
    QUIC_CHANNEL *ch)
95
42.4k
{
96
42.4k
    qsm->map = lh_QUIC_STREAM_new(hash_stream, cmp_stream);
97
42.4k
    qsm->active_list.prev = qsm->active_list.next = &qsm->active_list;
98
42.4k
    qsm->accept_list.prev = qsm->accept_list.next = &qsm->accept_list;
99
42.4k
    qsm->ready_for_gc_list.prev = qsm->ready_for_gc_list.next
100
42.4k
        = &qsm->ready_for_gc_list;
101
42.4k
    qsm->rr_stepping = 1;
102
42.4k
    qsm->rr_counter = 0;
103
42.4k
    qsm->rr_cur = NULL;
104
105
42.4k
    qsm->num_accept_bidi = 0;
106
42.4k
    qsm->num_accept_uni = 0;
107
42.4k
    qsm->num_shutdown_flush = 0;
108
109
42.4k
    qsm->get_stream_limit_cb = get_stream_limit_cb;
110
42.4k
    qsm->get_stream_limit_cb_arg = get_stream_limit_cb_arg;
111
42.4k
    qsm->max_streams_bidi_rxfc = max_streams_bidi_rxfc;
112
42.4k
    qsm->max_streams_uni_rxfc = max_streams_uni_rxfc;
113
42.4k
    qsm->ch = ch;
114
42.4k
    return 1;
115
42.4k
}
116
117
static void release_each(QUIC_STREAM *stream, void *arg)
118
153k
{
119
153k
    QUIC_STREAM_MAP *qsm = arg;
120
121
153k
    ossl_quic_stream_map_release(qsm, stream);
122
153k
}
123
124
void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm)
125
42.4k
{
126
42.4k
    lh_QUIC_STREAM_set_down_load(qsm->map, 0);
127
42.4k
    ossl_quic_stream_map_visit(qsm, release_each, qsm);
128
129
42.4k
    lh_QUIC_STREAM_free(qsm->map);
130
42.4k
    qsm->map = NULL;
131
42.4k
}
132
133
void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm,
134
    void (*visit_cb)(QUIC_STREAM *stream, void *arg),
135
    void *visit_cb_arg)
136
213k
{
137
213k
    lh_QUIC_STREAM_doall_arg(qsm->map, visit_cb, visit_cb_arg);
138
213k
}
139
140
QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm,
141
    uint64_t stream_id,
142
    int type)
143
153k
{
144
153k
    QUIC_STREAM *s;
145
153k
    QUIC_STREAM key;
146
147
153k
    key.id = stream_id;
148
149
153k
    s = lh_QUIC_STREAM_retrieve(qsm->map, &key);
150
153k
    if (s != NULL)
151
0
        return NULL;
152
153
153k
    s = OPENSSL_zalloc(sizeof(*s));
154
153k
    if (s == NULL)
155
0
        return NULL;
156
157
153k
    s->id = stream_id;
158
153k
    s->type = type;
159
153k
    s->as_server = ossl_quic_channel_is_server(qsm->ch);
160
153k
    s->send_state = (ossl_quic_stream_is_local_init(s)
161
148k
                        || ossl_quic_stream_is_bidi(s))
162
153k
        ? QUIC_SSTREAM_STATE_READY
163
153k
        : QUIC_SSTREAM_STATE_NONE;
164
153k
    s->recv_state = (!ossl_quic_stream_is_local_init(s)
165
5.11k
                        || ossl_quic_stream_is_bidi(s))
166
153k
        ? QUIC_RSTREAM_STATE_RECV
167
153k
        : QUIC_RSTREAM_STATE_NONE;
168
169
153k
    s->send_final_size = UINT64_MAX;
170
171
153k
    lh_QUIC_STREAM_insert(qsm->map, s);
172
153k
    return s;
173
153k
}
174
175
void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream)
176
160k
{
177
160k
    if (stream == NULL)
178
7.06k
        return;
179
180
153k
    if (stream->active_node.next != NULL)
181
12.8k
        list_remove(&qsm->active_list, &stream->active_node);
182
153k
    if (stream->accept_node.next != NULL)
183
140k
        list_remove(&qsm->accept_list, &stream->accept_node);
184
153k
    if (stream->ready_for_gc_node.next != NULL)
185
0
        list_remove(&qsm->ready_for_gc_list, &stream->ready_for_gc_node);
186
187
153k
    ossl_quic_sstream_free(stream->sstream);
188
153k
    stream->sstream = NULL;
189
190
153k
    ossl_quic_rstream_free(stream->rstream);
191
153k
    stream->rstream = NULL;
192
193
153k
    lh_QUIC_STREAM_delete(qsm->map, stream);
194
153k
    OPENSSL_free(stream);
195
153k
}
196
197
QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm,
198
    uint64_t stream_id)
199
15.2M
{
200
15.2M
    QUIC_STREAM key;
201
202
15.2M
    key.id = stream_id;
203
204
15.2M
    return lh_QUIC_STREAM_retrieve(qsm->map, &key);
205
15.2M
}
206
207
static void stream_map_mark_active(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s)
208
99.6k
{
209
99.6k
    if (s->active)
210
75.0k
        return;
211
212
24.5k
    list_insert_tail(&qsm->active_list, &s->active_node);
213
214
24.5k
    if (qsm->rr_cur == NULL)
215
18.0k
        qsm->rr_cur = s;
216
217
24.5k
    s->active = 1;
218
24.5k
}
219
220
static void stream_map_mark_inactive(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s)
221
1.12M
{
222
1.12M
    if (!s->active)
223
1.11M
        return;
224
225
11.7k
    if (qsm->rr_cur == s)
226
10.4k
        qsm->rr_cur = active_next(&qsm->active_list, s);
227
11.7k
    if (qsm->rr_cur == s)
228
9.02k
        qsm->rr_cur = NULL;
229
230
11.7k
    list_remove(&qsm->active_list, &s->active_node);
231
232
11.7k
    s->active = 0;
233
11.7k
}
234
235
void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping)
236
0
{
237
0
    qsm->rr_stepping = stepping;
238
0
    qsm->rr_counter = 0;
239
0
}
240
241
static int stream_has_data_to_send(QUIC_STREAM *s)
242
1.13M
{
243
1.13M
    OSSL_QUIC_FRAME_STREAM shdr;
244
1.13M
    OSSL_QTX_IOVEC iov[2];
245
1.13M
    size_t num_iov;
246
1.13M
    uint64_t fc_credit, fc_swm, fc_limit;
247
248
1.13M
    switch (s->send_state) {
249
102k
    case QUIC_SSTREAM_STATE_READY:
250
149k
    case QUIC_SSTREAM_STATE_SEND:
251
149k
    case QUIC_SSTREAM_STATE_DATA_SENT:
252
        /*
253
         * We can still have data to send in DATA_SENT due to retransmissions,
254
         * etc.
255
         */
256
149k
        break;
257
983k
    default:
258
983k
        return 0; /* Nothing to send. */
259
1.13M
    }
260
261
    /*
262
     * We cannot determine if we have data to send simply by checking if
263
     * ossl_quic_txfc_get_credit() is zero, because we may also have older
264
     * stream data we need to retransmit. The SSTREAM returns older data first,
265
     * so we do a simple comparison of the next chunk the SSTREAM wants to send
266
     * against the TXFC CWM.
267
     */
268
149k
    num_iov = OSSL_NELEM(iov);
269
149k
    if (!ossl_quic_sstream_get_stream_frame(s->sstream, 0, &shdr, iov,
270
149k
            &num_iov))
271
113k
        return 0;
272
273
36.2k
    fc_credit = ossl_quic_txfc_get_credit(&s->txfc, 0);
274
36.2k
    fc_swm = ossl_quic_txfc_get_swm(&s->txfc);
275
36.2k
    fc_limit = fc_swm + fc_credit;
276
277
36.2k
    return (shdr.is_fin && shdr.len == 0) || shdr.offset < fc_limit;
278
149k
}
279
280
static ossl_unused int qsm_send_part_permits_gc(const QUIC_STREAM *qs)
281
0
{
282
0
    switch (qs->send_state) {
283
0
    case QUIC_SSTREAM_STATE_NONE:
284
0
    case QUIC_SSTREAM_STATE_DATA_RECVD:
285
0
    case QUIC_SSTREAM_STATE_RESET_RECVD:
286
0
        return 1;
287
0
    default:
288
0
        return 0;
289
0
    }
290
0
}
291
292
static int qsm_ready_for_gc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs)
293
1.22M
{
294
1.22M
    int recv_stream_fully_drained = 0; /* TODO(QUIC FUTURE): Optimisation */
295
296
    /*
297
     * If sstream has no FIN, we auto-reset it at marked-for-deletion time, so
298
     * we don't need to worry about that here.
299
     */
300
1.22M
    assert(!qs->deleted
301
1.22M
        || !ossl_quic_stream_has_send(qs)
302
1.22M
        || ossl_quic_stream_send_is_reset(qs)
303
1.22M
        || ossl_quic_stream_send_get_final_size(qs, NULL));
304
305
1.22M
    return qs->deleted
306
12.6k
        && (!ossl_quic_stream_has_recv(qs)
307
12.6k
            || recv_stream_fully_drained
308
12.6k
            || qs->acked_stop_sending)
309
0
        && (!ossl_quic_stream_has_send(qs)
310
0
            || qs->send_state == QUIC_SSTREAM_STATE_DATA_RECVD
311
0
            || qs->send_state == QUIC_SSTREAM_STATE_RESET_RECVD);
312
1.22M
}
313
314
int ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP *qsm,
315
    uint64_t stream_ordinal,
316
    int is_uni)
317
74.7k
{
318
74.7k
    uint64_t stream_limit;
319
320
74.7k
    if (qsm->get_stream_limit_cb == NULL)
321
0
        return 1;
322
323
74.7k
    stream_limit = qsm->get_stream_limit_cb(is_uni, qsm->get_stream_limit_cb_arg);
324
74.7k
    return stream_ordinal < stream_limit;
325
74.7k
}
326
327
void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s)
328
1.22M
{
329
1.22M
    int should_be_active, allowed_by_stream_limit = 1;
330
331
1.22M
    if (ossl_quic_stream_is_server_init(s) == ossl_quic_channel_is_server(qsm->ch)) {
332
66.2k
        int is_uni = !ossl_quic_stream_is_bidi(s);
333
66.2k
        uint64_t stream_ordinal = s->id >> 2;
334
335
66.2k
        allowed_by_stream_limit
336
66.2k
            = ossl_quic_stream_map_is_local_allowed_by_stream_limit(qsm,
337
66.2k
                stream_ordinal,
338
66.2k
                is_uni);
339
66.2k
    }
340
341
1.22M
    if (s->send_state == QUIC_SSTREAM_STATE_DATA_SENT
342
0
        && ossl_quic_sstream_is_totally_acked(s->sstream))
343
0
        ossl_quic_stream_map_notify_totally_acked(qsm, s);
344
1.22M
    else if (s->shutdown_flush
345
0
        && s->send_state == QUIC_SSTREAM_STATE_SEND
346
0
        && ossl_quic_sstream_is_totally_acked(s->sstream))
347
0
        shutdown_flush_done(qsm, s);
348
349
1.22M
    if (!s->ready_for_gc) {
350
1.22M
        s->ready_for_gc = qsm_ready_for_gc(qsm, s);
351
1.22M
        if (s->ready_for_gc)
352
0
            list_insert_tail(&qsm->ready_for_gc_list, &s->ready_for_gc_node);
353
1.22M
    }
354
355
1.22M
    should_be_active
356
1.22M
        = allowed_by_stream_limit
357
1.22M
        && !s->ready_for_gc
358
1.22M
        && ((ossl_quic_stream_has_recv(s)
359
1.22M
                && !ossl_quic_stream_recv_is_reset(s)
360
1.19M
                && (s->recv_state == QUIC_RSTREAM_STATE_RECV
361
1.12M
                    && (s->want_max_stream_data
362
1.11M
                        || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0))))
363
1.21M
            || s->want_stop_sending
364
1.19M
            || s->want_reset_stream
365
1.15M
            || (!s->peer_stop_sending && stream_has_data_to_send(s)));
366
367
1.22M
    if (should_be_active)
368
99.6k
        stream_map_mark_active(qsm, s);
369
1.12M
    else
370
1.12M
        stream_map_mark_inactive(qsm, s);
371
1.22M
}
372
373
/*
374
 * Stream Send Part State Management
375
 * =================================
376
 */
377
378
int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP *qsm,
379
    QUIC_STREAM *qs)
380
18.0k
{
381
18.0k
    switch (qs->send_state) {
382
0
    case QUIC_SSTREAM_STATE_NONE:
383
        /* Stream without send part - caller error. */
384
0
        return 0;
385
386
18.0k
    case QUIC_SSTREAM_STATE_READY:
387
        /*
388
         * We always allocate a stream ID upfront, so we don't need to do it
389
         * here.
390
         */
391
18.0k
        qs->send_state = QUIC_SSTREAM_STATE_SEND;
392
18.0k
        return 1;
393
394
0
    default:
395
        /* Nothing to do. */
396
0
        return 1;
397
18.0k
    }
398
18.0k
}
399
400
int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP *qsm,
401
    QUIC_STREAM *qs)
402
0
{
403
0
    switch (qs->send_state) {
404
0
    default:
405
        /* Wrong state - caller error. */
406
0
    case QUIC_SSTREAM_STATE_NONE:
407
        /* Stream without send part - caller error. */
408
0
        return 0;
409
410
0
    case QUIC_SSTREAM_STATE_SEND:
411
0
        if (!ossl_quic_sstream_get_final_size(qs->sstream, &qs->send_final_size))
412
0
            return 0;
413
414
0
        qs->send_state = QUIC_SSTREAM_STATE_DATA_SENT;
415
0
        return 1;
416
0
    }
417
0
}
418
419
static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs)
420
6.58k
{
421
6.58k
    if (!qs->shutdown_flush)
422
6.58k
        return;
423
424
6.58k
    assert(qsm->num_shutdown_flush > 0);
425
0
    qs->shutdown_flush = 0;
426
0
    --qsm->num_shutdown_flush;
427
428
    /*
429
     * when num_shutdown_flush becomes zero we need to poke
430
     * SSL_poll() it's time to poke to SSL_shutdown() to proceed
431
     * with shutdown process as all streams are gone (flushed).
432
     */
433
0
    if (qsm->num_shutdown_flush == 0)
434
0
        ossl_quic_channel_notify_flush_done(qsm->ch);
435
0
}
436
437
int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP *qsm,
438
    QUIC_STREAM *qs)
439
0
{
440
0
    switch (qs->send_state) {
441
0
    default:
442
        /* Wrong state - caller error. */
443
0
    case QUIC_SSTREAM_STATE_NONE:
444
        /* Stream without send part - caller error. */
445
0
        return 0;
446
447
0
    case QUIC_SSTREAM_STATE_DATA_SENT:
448
0
        qs->send_state = QUIC_SSTREAM_STATE_DATA_RECVD;
449
        /*
450
         * Remember final size in case  SSL_get_stream_write_state()
451
         * gets called.
452
         */
453
0
        qs->have_final_size = ossl_quic_sstream_get_final_size(qs->sstream,
454
0
            NULL);
455
456
        /* We no longer need a QUIC_SSTREAM in this state. */
457
0
        ossl_quic_sstream_free(qs->sstream);
458
0
        qs->sstream = NULL;
459
460
0
        shutdown_flush_done(qsm, qs);
461
0
        return 1;
462
0
    }
463
0
}
464
465
int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm,
466
    QUIC_STREAM *qs,
467
    uint64_t aec)
468
104k
{
469
104k
    switch (qs->send_state) {
470
0
    default:
471
0
    case QUIC_SSTREAM_STATE_NONE:
472
        /*
473
         * RESET_STREAM pertains to sending part only, so we cannot reset a
474
         * receive-only stream.
475
         */
476
0
    case QUIC_SSTREAM_STATE_DATA_RECVD:
477
        /*
478
         * RFC 9000 s. 3.3: A sender MUST NOT [...] send RESET_STREAM from a
479
         * terminal state. If the stream has already finished normally and the
480
         * peer has acknowledged this, we cannot reset it.
481
         */
482
0
        return 0;
483
484
14.6k
    case QUIC_SSTREAM_STATE_READY:
485
14.6k
        if (!ossl_quic_stream_map_ensure_send_part_id(qsm, qs))
486
0
            return 0;
487
488
        /* FALLTHROUGH */
489
18.0k
    case QUIC_SSTREAM_STATE_SEND:
490
        /*
491
         * If we already have a final size (e.g. because we are coming from
492
         * DATA_SENT), we have to be consistent with that, so don't change it.
493
         * If we don't already have a final size, determine a final size value.
494
         * This is the value which we will end up using for a RESET_STREAM frame
495
         * for flow control purposes. We could send the stream size (total
496
         * number of bytes appended to QUIC_SSTREAM by the application), but it
497
         * is in our interest to exclude any bytes we have not actually
498
         * transmitted yet, to avoid unnecessarily consuming flow control
499
         * credit. We can get this from the TXFC.
500
         */
501
18.0k
        qs->send_final_size = ossl_quic_txfc_get_swm(&qs->txfc);
502
503
        /* FALLTHROUGH */
504
18.0k
    case QUIC_SSTREAM_STATE_DATA_SENT:
505
18.0k
        qs->reset_stream_aec = aec;
506
18.0k
        qs->want_reset_stream = 1;
507
18.0k
        qs->send_state = QUIC_SSTREAM_STATE_RESET_SENT;
508
509
18.0k
        ossl_quic_sstream_free(qs->sstream);
510
18.0k
        qs->sstream = NULL;
511
512
18.0k
        shutdown_flush_done(qsm, qs);
513
18.0k
        ossl_quic_stream_map_update_state(qsm, qs);
514
18.0k
        return 1;
515
516
86.2k
    case QUIC_SSTREAM_STATE_RESET_SENT:
517
86.2k
    case QUIC_SSTREAM_STATE_RESET_RECVD:
518
        /*
519
         * Idempotent - no-op. In any case, do not send RESET_STREAM again - as
520
         * mentioned, we must not send it from a terminal state.
521
         */
522
86.2k
        return 1;
523
104k
    }
524
104k
}
525
526
int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP *qsm,
527
    QUIC_STREAM *qs)
528
0
{
529
0
    switch (qs->send_state) {
530
0
    default:
531
        /* Wrong state - caller error. */
532
0
    case QUIC_SSTREAM_STATE_NONE:
533
        /* Stream without send part - caller error. */
534
0
        return 0;
535
536
0
    case QUIC_SSTREAM_STATE_RESET_SENT:
537
0
        qs->send_state = QUIC_SSTREAM_STATE_RESET_RECVD;
538
0
        return 1;
539
540
0
    case QUIC_SSTREAM_STATE_RESET_RECVD:
541
        /* Already in the correct state. */
542
0
        return 1;
543
0
    }
544
0
}
545
546
/*
547
 * Stream Receive Part State Management
548
 * ====================================
549
 */
550
551
int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP *qsm,
552
    QUIC_STREAM *qs,
553
    uint64_t final_size)
554
8.29k
{
555
8.29k
    switch (qs->recv_state) {
556
0
    default:
557
        /* Wrong state - caller error. */
558
0
    case QUIC_RSTREAM_STATE_NONE:
559
        /* Stream without receive part - caller error. */
560
0
        return 0;
561
562
8.29k
    case QUIC_RSTREAM_STATE_RECV:
563
8.29k
        qs->recv_state = QUIC_RSTREAM_STATE_SIZE_KNOWN;
564
8.29k
        return 1;
565
8.29k
    }
566
8.29k
}
567
568
int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP *qsm,
569
    QUIC_STREAM *qs)
570
3.22k
{
571
3.22k
    switch (qs->recv_state) {
572
0
    default:
573
        /* Wrong state - caller error. */
574
0
    case QUIC_RSTREAM_STATE_NONE:
575
        /* Stream without receive part - caller error. */
576
0
        return 0;
577
578
3.22k
    case QUIC_RSTREAM_STATE_SIZE_KNOWN:
579
3.22k
        qs->recv_state = QUIC_RSTREAM_STATE_DATA_RECVD;
580
3.22k
        qs->want_stop_sending = 0;
581
3.22k
        return 1;
582
3.22k
    }
583
3.22k
}
584
585
int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP *qsm,
586
    QUIC_STREAM *qs)
587
676
{
588
676
    switch (qs->recv_state) {
589
0
    default:
590
        /* Wrong state - caller error. */
591
0
    case QUIC_RSTREAM_STATE_NONE:
592
        /* Stream without receive part - caller error. */
593
0
        return 0;
594
595
676
    case QUIC_RSTREAM_STATE_DATA_RECVD:
596
676
        qs->recv_state = QUIC_RSTREAM_STATE_DATA_READ;
597
598
        /* QUIC_RSTREAM is no longer needed */
599
676
        ossl_quic_rstream_free(qs->rstream);
600
676
        qs->rstream = NULL;
601
676
        return 1;
602
676
    }
603
676
}
604
605
int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP *qsm,
606
    QUIC_STREAM *qs,
607
    uint64_t app_error_code,
608
    uint64_t final_size)
609
7.68k
{
610
7.68k
    uint64_t prev_final_size;
611
612
7.68k
    switch (qs->recv_state) {
613
0
    default:
614
0
    case QUIC_RSTREAM_STATE_NONE:
615
        /* Stream without receive part - caller error. */
616
0
        return 0;
617
618
1.93k
    case QUIC_RSTREAM_STATE_RECV:
619
1.94k
    case QUIC_RSTREAM_STATE_SIZE_KNOWN:
620
1.95k
    case QUIC_RSTREAM_STATE_DATA_RECVD:
621
1.95k
        if (ossl_quic_stream_recv_get_final_size(qs, &prev_final_size)
622
22
            && prev_final_size != final_size)
623
            /* Cannot change previous final size. */
624
0
            return 0;
625
626
1.95k
        qs->recv_state = QUIC_RSTREAM_STATE_RESET_RECVD;
627
1.95k
        qs->peer_reset_stream_aec = app_error_code;
628
629
        /* RFC 9000 s. 3.3: No point sending STOP_SENDING if already reset. */
630
1.95k
        qs->want_stop_sending = 0;
631
632
        /* QUIC_RSTREAM is no longer needed */
633
1.95k
        ossl_quic_rstream_free(qs->rstream);
634
1.95k
        qs->rstream = NULL;
635
636
1.95k
        ossl_quic_stream_map_update_state(qsm, qs);
637
1.95k
        return 1;
638
639
0
    case QUIC_RSTREAM_STATE_DATA_READ:
640
        /*
641
         * If we already retired the FIN to the application this is moot
642
         * - just ignore.
643
         */
644
5.72k
    case QUIC_RSTREAM_STATE_RESET_RECVD:
645
5.72k
    case QUIC_RSTREAM_STATE_RESET_READ:
646
        /* Could be a reordered/retransmitted frame - just ignore. */
647
5.72k
        return 1;
648
7.68k
    }
649
7.68k
}
650
651
int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP *qsm,
652
    QUIC_STREAM *qs)
653
194
{
654
194
    switch (qs->recv_state) {
655
0
    default:
656
        /* Wrong state - caller error. */
657
0
    case QUIC_RSTREAM_STATE_NONE:
658
        /* Stream without receive part - caller error. */
659
0
        return 0;
660
661
194
    case QUIC_RSTREAM_STATE_RESET_RECVD:
662
194
        qs->recv_state = QUIC_RSTREAM_STATE_RESET_READ;
663
194
        return 1;
664
194
    }
665
194
}
666
667
int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP *qsm,
668
    QUIC_STREAM *qs,
669
    uint64_t aec)
670
11.5k
{
671
11.5k
    if (qs->stop_sending)
672
0
        return 0;
673
674
11.5k
    switch (qs->recv_state) {
675
0
    default:
676
0
    case QUIC_RSTREAM_STATE_NONE:
677
        /* Send-only stream, so this makes no sense. */
678
0
    case QUIC_RSTREAM_STATE_DATA_RECVD:
679
0
    case QUIC_RSTREAM_STATE_DATA_READ:
680
        /*
681
         * Not really any point in STOP_SENDING if we already received all data.
682
         */
683
0
    case QUIC_RSTREAM_STATE_RESET_RECVD:
684
0
    case QUIC_RSTREAM_STATE_RESET_READ:
685
        /*
686
         * RFC 9000 s. 3.5: "STOP_SENDING SHOULD only be sent for a stream that
687
         * has not been reset by the peer."
688
         *
689
         * No point in STOP_SENDING if the peer already reset their send part.
690
         */
691
0
        return 0;
692
693
9.65k
    case QUIC_RSTREAM_STATE_RECV:
694
11.5k
    case QUIC_RSTREAM_STATE_SIZE_KNOWN:
695
        /*
696
         * RFC 9000 s. 3.5: "If the stream is in the Recv or Size Known state,
697
         * the transport SHOULD signal this by sending a STOP_SENDING frame to
698
         * prompt closure of the stream in the opposite direction."
699
         *
700
         * Note that it does make sense to send STOP_SENDING for a receive part
701
         * of a stream which has a known size (because we have received a FIN)
702
         * but which still has other (previous) stream data yet to be received.
703
         */
704
11.5k
        break;
705
11.5k
    }
706
707
11.5k
    qs->stop_sending = 1;
708
11.5k
    qs->stop_sending_aec = aec;
709
11.5k
    return ossl_quic_stream_map_schedule_stop_sending(qsm, qs);
710
11.5k
}
711
712
/* Called to mark STOP_SENDING for generation, or regeneration after loss. */
713
int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs)
714
11.5k
{
715
11.5k
    if (!qs->stop_sending)
716
0
        return 0;
717
718
    /*
719
     * Ignore the call as a no-op if already scheduled, or in a state
720
     * where it makes no sense to send STOP_SENDING.
721
     */
722
11.5k
    if (qs->want_stop_sending)
723
0
        return 1;
724
725
11.5k
    switch (qs->recv_state) {
726
0
    default:
727
0
        return 1; /* ignore */
728
9.65k
    case QUIC_RSTREAM_STATE_RECV:
729
11.5k
    case QUIC_RSTREAM_STATE_SIZE_KNOWN:
730
        /*
731
         * RFC 9000 s. 3.5: "An endpoint is expected to send another
732
         * STOP_SENDING frame if a packet containing a previous STOP_SENDING is
733
         * lost. However, once either all stream data or a RESET_STREAM frame
734
         * has been received for the stream -- that is, the stream is in any
735
         * state other than "Recv" or "Size Known" -- sending a STOP_SENDING
736
         * frame is unnecessary."
737
         */
738
11.5k
        break;
739
11.5k
    }
740
741
11.5k
    qs->want_stop_sending = 1;
742
11.5k
    ossl_quic_stream_map_update_state(qsm, qs);
743
11.5k
    return 1;
744
11.5k
}
745
746
QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm)
747
504
{
748
504
    return accept_head(&qsm->accept_list);
749
504
}
750
751
QUIC_STREAM *ossl_quic_stream_map_find_in_accept_queue(QUIC_STREAM_MAP *qsm,
752
    int is_uni)
753
0
{
754
0
    QUIC_STREAM *qs;
755
756
0
    if (ossl_quic_stream_map_get_accept_queue_len(qsm, is_uni) == 0)
757
0
        return NULL;
758
759
0
    qs = ossl_quic_stream_map_peek_accept_queue(qsm);
760
0
    while (qs != NULL) {
761
0
        if ((is_uni && !ossl_quic_stream_is_bidi(qs))
762
0
            || (!is_uni && ossl_quic_stream_is_bidi(qs)))
763
0
            break;
764
0
        qs = accept_next(&qsm->accept_list, qs);
765
0
    }
766
0
    return qs;
767
0
}
768
769
void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm,
770
    QUIC_STREAM *s)
771
148k
{
772
148k
    list_insert_tail(&qsm->accept_list, &s->accept_node);
773
148k
    if (ossl_quic_stream_is_bidi(s))
774
40.1k
        ++qsm->num_accept_bidi;
775
107k
    else
776
107k
        ++qsm->num_accept_uni;
777
148k
}
778
779
static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s)
780
7.53k
{
781
7.53k
    return ossl_quic_stream_is_bidi(s)
782
7.53k
        ? qsm->max_streams_bidi_rxfc
783
7.53k
        : qsm->max_streams_uni_rxfc;
784
7.53k
}
785
786
void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm,
787
    QUIC_STREAM *s,
788
    OSSL_TIME rtt)
789
7.53k
{
790
7.53k
    QUIC_RXFC *max_streams_rxfc;
791
792
7.53k
    list_remove(&qsm->accept_list, &s->accept_node);
793
7.53k
    if (ossl_quic_stream_is_bidi(s))
794
6.86k
        --qsm->num_accept_bidi;
795
671
    else
796
671
        --qsm->num_accept_uni;
797
798
7.53k
    if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL)
799
7.53k
        (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt);
800
7.53k
}
801
802
size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni)
803
22.7k
{
804
22.7k
    return is_uni ? qsm->num_accept_uni : qsm->num_accept_bidi;
805
22.7k
}
806
807
size_t ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP *qsm)
808
11.3k
{
809
11.3k
    return ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/0)
810
11.3k
        + ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/1);
811
11.3k
}
812
813
void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm)
814
78.8M
{
815
78.8M
    QUIC_STREAM *qs;
816
817
78.8M
    while ((qs = ready_for_gc_head(&qsm->ready_for_gc_list)) != NULL) {
818
0
        ossl_quic_stream_map_release(qsm, qs);
819
0
    }
820
78.8M
}
821
822
static int eligible_for_shutdown_flush(QUIC_STREAM *qs)
823
0
{
824
    /*
825
     * We only care about servicing the send part of a stream (if any) during
826
     * shutdown flush. We make sure we flush a stream if it is either
827
     * non-terminated or was terminated normally such as via
828
     * SSL_stream_conclude. A stream which was terminated via a reset is not
829
     * flushed, and we will have thrown away the send buffer in that case
830
     * anyway.
831
     */
832
0
    switch (qs->send_state) {
833
0
    case QUIC_SSTREAM_STATE_SEND:
834
0
    case QUIC_SSTREAM_STATE_DATA_SENT:
835
0
        return !ossl_quic_sstream_is_totally_acked(qs->sstream);
836
0
    default:
837
0
        return 0;
838
0
    }
839
0
}
840
841
static void begin_shutdown_flush_each(QUIC_STREAM *qs, void *arg)
842
0
{
843
0
    QUIC_STREAM_MAP *qsm = arg;
844
845
0
    if (!eligible_for_shutdown_flush(qs) || qs->shutdown_flush)
846
0
        return;
847
848
0
    qs->shutdown_flush = 1;
849
0
    ++qsm->num_shutdown_flush;
850
0
}
851
852
void ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP *qsm)
853
0
{
854
0
    qsm->num_shutdown_flush = 0;
855
856
0
    ossl_quic_stream_map_visit(qsm, begin_shutdown_flush_each, qsm);
857
0
}
858
859
int ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP *qsm)
860
0
{
861
0
    return qsm->num_shutdown_flush == 0;
862
0
}
863
864
/*
865
 * QUIC Stream Iterator
866
 * ====================
867
 */
868
void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm,
869
    int advance_rr)
870
8.81M
{
871
8.81M
    it->qsm = qsm;
872
8.81M
    it->stream = it->first_stream = qsm->rr_cur;
873
8.81M
    if (advance_rr && it->stream != NULL
874
14.5k
        && ++qsm->rr_counter >= qsm->rr_stepping) {
875
14.5k
        qsm->rr_counter = 0;
876
14.5k
        qsm->rr_cur = active_next(&qsm->active_list, qsm->rr_cur);
877
14.5k
    }
878
8.81M
}
879
880
void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it)
881
18.1k
{
882
18.1k
    if (it->stream == NULL)
883
0
        return;
884
885
18.1k
    it->stream = active_next(&it->qsm->active_list, it->stream);
886
18.1k
    if (it->stream == it->first_stream)
887
14.3k
        it->stream = NULL;
888
18.1k
}