Coverage Report

Created: 2026-10-28 06:28

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