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