Coverage Report

Created: 2026-07-12 07:21

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