Coverage Report

Created: 2025-06-13 06:58

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