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