xref: /freebsd/crypto/openssl/ssl/quic/quic_stream_map.c (revision 1523ccfd9c8c254f7928143d31c305384b05fd11)
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. */
list_insert_tail(QUIC_STREAM_LIST_NODE * l,QUIC_STREAM_LIST_NODE * n)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 
list_remove(QUIC_STREAM_LIST_NODE * l,QUIC_STREAM_LIST_NODE * n)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 
list_next(QUIC_STREAM_LIST_NODE * l,QUIC_STREAM_LIST_NODE * n,size_t off)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 
hash_stream(const QUIC_STREAM * s)74 static unsigned long hash_stream(const QUIC_STREAM *s)
75 {
76     return (unsigned long)s->id;
77 }
78 
cmp_stream(const QUIC_STREAM * a,const QUIC_STREAM * b)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 
ossl_quic_stream_map_init(QUIC_STREAM_MAP * qsm,uint64_t (* get_stream_limit_cb)(int uni,void * arg),void * get_stream_limit_cb_arg,QUIC_RXFC * max_streams_bidi_rxfc,QUIC_RXFC * max_streams_uni_rxfc,int is_server)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 
release_each(QUIC_STREAM * stream,void * arg)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 
ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP * qsm)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 
ossl_quic_stream_map_visit(QUIC_STREAM_MAP * qsm,void (* visit_cb)(QUIC_STREAM * stream,void * arg),void * visit_cb_arg)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 
ossl_quic_stream_map_alloc(QUIC_STREAM_MAP * qsm,uint64_t stream_id,int type)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 
ossl_quic_stream_map_release(QUIC_STREAM_MAP * qsm,QUIC_STREAM * stream)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 
ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP * qsm,uint64_t stream_id)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 
stream_map_mark_active(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s)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 
stream_map_mark_inactive(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s)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 
ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP * qsm,size_t stepping)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 
stream_has_data_to_send(QUIC_STREAM * s)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 
qsm_send_part_permits_gc(const QUIC_STREAM * qs)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 
qsm_ready_for_gc(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP * qsm,uint64_t stream_ordinal,int is_uni)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 
ossl_quic_stream_map_update_state(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s)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 
ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
shutdown_flush_done(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs,uint64_t aec)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 
ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs,uint64_t final_size)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 
ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs,uint64_t app_error_code,uint64_t final_size)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 
ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs,uint64_t aec)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. */
ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP * qsm,QUIC_STREAM * qs)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 
ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP * qsm)737 QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm)
738 {
739     return accept_head(&qsm->accept_list);
740 }
741 
ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s)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 
qsm_get_max_streams_rxfc(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s)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 
ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP * qsm,QUIC_STREAM * s,OSSL_TIME rtt)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 
ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP * qsm,int is_uni)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 
ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP * qsm)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 
ossl_quic_stream_map_gc(QUIC_STREAM_MAP * qsm)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 
eligible_for_shutdown_flush(QUIC_STREAM * qs)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 
begin_shutdown_flush_each(QUIC_STREAM * qs,void * arg)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 
ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP * qsm)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 
ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP * qsm)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  */
ossl_quic_stream_iter_init(QUIC_STREAM_ITER * it,QUIC_STREAM_MAP * qsm,int advance_rr)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 
ossl_quic_stream_iter_next(QUIC_STREAM_ITER * it)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