]> git.ipfire.org Git - thirdparty/openssl.git/blame - include/internal/quic_stream_map.h
Copyright year updates
[thirdparty/openssl.git] / include / internal / quic_stream_map.h
CommitLineData
a73078b7 1/*
b6461792 2* Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
a73078b7
HL
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#ifndef OSSL_INTERNAL_QUIC_STREAM_MAP_H
11# define OSSL_INTERNAL_QUIC_STREAM_MAP_H
12# pragma once
13
cbe7f586
HL
14# include "internal/e_os.h"
15# include "internal/time.h"
418e122c 16# include "internal/common.h"
cbe7f586 17# include "internal/quic_types.h"
ff3a26b2 18# include "internal/quic_predef.h"
cbe7f586
HL
19# include "internal/quic_stream.h"
20# include "internal/quic_fc.h"
21# include <openssl/lhash.h>
22
23# ifndef OPENSSL_NO_QUIC
a73078b7
HL
24
25/*
26 * QUIC Stream
27 * ===========
28 *
29 * Logical QUIC stream composing all relevant send and receive components.
30 */
a73078b7
HL
31
32typedef struct quic_stream_list_node_st QUIC_STREAM_LIST_NODE;
33
34struct quic_stream_list_node_st {
35 QUIC_STREAM_LIST_NODE *prev, *next;
36};
37
2f018d14
HL
38/*
39 * QUIC Send Stream States
40 * -----------------------
41 *
42 * These correspond to the states defined in RFC 9000 s. 3.1, with the
43 * exception of the NONE state which represents the absence of a send stream
44 * part.
45 *
46 * Invariants in each state are noted in comments below. In particular, once all
47 * data has been acknowledged received, or we have reset the stream, we don't
48 * need to keep the QUIC_SSTREAM and data buffers around. Of course, we also
49 * don't have a QUIC_SSTREAM on a receive-only stream.
50 */
51#define QUIC_SSTREAM_STATE_NONE 0 /* --- sstream == NULL */
52#define QUIC_SSTREAM_STATE_READY 1 /* \ */
53#define QUIC_SSTREAM_STATE_SEND 2 /* |-- sstream != NULL */
54#define QUIC_SSTREAM_STATE_DATA_SENT 3 /* / */
55#define QUIC_SSTREAM_STATE_DATA_RECVD 4 /* \ */
56#define QUIC_SSTREAM_STATE_RESET_SENT 5 /* |-- sstream == NULL */
57#define QUIC_SSTREAM_STATE_RESET_RECVD 6 /* / */
58
59/*
60 * QUIC Receive Stream States
61 * --------------------------
62 *
63 * These correspond to the states defined in RFC 9000 s. 3.2, with the exception
64 * of the NONE state which represents the absence of a receive stream part.
65 *
66 * Invariants in each state are noted in comments below. In particular, once all
67 * data has been read by the application, we don't need to keep the QUIC_RSTREAM
68 * and data buffers around. If the receive part is instead reset before it is
69 * finished, we also don't need to keep the QUIC_RSTREAM around. Finally, we
70 * don't need a QUIC_RSTREAM on a send-only stream.
71 */
72#define QUIC_RSTREAM_STATE_NONE 0 /* --- rstream == NULL */
73#define QUIC_RSTREAM_STATE_RECV 1 /* \ */
74#define QUIC_RSTREAM_STATE_SIZE_KNOWN 2 /* |-- rstream != NULL */
75#define QUIC_RSTREAM_STATE_DATA_RECVD 3 /* / */
76#define QUIC_RSTREAM_STATE_DATA_READ 4 /* \ */
77#define QUIC_RSTREAM_STATE_RESET_RECVD 5 /* |-- rstream == NULL */
78#define QUIC_RSTREAM_STATE_RESET_READ 6 /* / */
79
a73078b7
HL
80struct quic_stream_st {
81 QUIC_STREAM_LIST_NODE active_node; /* for use by QUIC_STREAM_MAP */
f20fdd16 82 QUIC_STREAM_LIST_NODE accept_node; /* accept queue of remotely-created streams */
0847e63e 83 QUIC_STREAM_LIST_NODE ready_for_gc_node; /* queue of streams now ready for GC */
a73078b7
HL
84
85 /* Temporary link used by TXP. */
86 QUIC_STREAM *txp_next;
87
88 /*
89 * QUIC Stream ID. Do not assume that this encodes a type as this is a
90 * version-specific property and may change between QUIC versions; instead,
91 * use the type field.
92 */
93 uint64_t id;
94
95 /*
96 * Application Error Code (AEC) used for STOP_SENDING frame.
97 * This is only valid if stop_sending is 1.
98 */
99 uint64_t stop_sending_aec;
100
101 /*
102 * Application Error Code (AEC) used for RESET_STREAM frame.
103 * This is only valid if reset_stream is 1.
104 */
105 uint64_t reset_stream_aec;
106
b6fc2294
HL
107 /*
108 * Application Error Code (AEC) for incoming STOP_SENDING frame.
109 * This is only valid if peer_stop_sending is 1.
110 */
111 uint64_t peer_stop_sending_aec;
112
113 /*
114 * Application Error Code (AEC) for incoming RESET_STREAM frame.
5fc256cd 115 * This is only valid if peer_reset_stream is 1.
b6fc2294
HL
116 */
117 uint64_t peer_reset_stream_aec;
118
a73078b7
HL
119 /* Temporary value used by TXP. */
120 uint64_t txp_txfc_new_credit_consumed;
121
418e122c
HL
122 /*
123 * The final size of the send stream. Although this information can be
124 * discerned from a QUIC_SSTREAM, it is stored separately as we need to keep
125 * track of this even if we have thrown away the QUIC_SSTREAM. Use
126 * ossl_quic_stream_send_get_final_size to determine if this contain a
127 * valid value or if there is no final size yet for a sending part.
128 *
129 * For the receive part, the final size is tracked by the stream-level RXFC;
130 * use ossl_quic_stream_recv_get_final_size or
131 * ossl_quic_rxfc_get_final_size.
132 */
133 uint64_t send_final_size;
134
2f018d14
HL
135 /*
136 * Send stream part and receive stream part buffer management objects.
137 *
138 * DO NOT test these pointers (sstream, rstream) for NULL. Determine the
139 * state of the send or receive stream part first using the appropriate
140 * function; then the invariant of that state guarantees that sstream or
141 * rstream either is or is not NULL respectively, therefore there is no
142 * valid use case for testing these pointers for NULL. In particular, a
143 * stream with a send part can still have sstream as NULL, and a stream with
144 * a receive part can still have rstream as NULL. QUIC_SSTREAM and
145 * QUIC_RSTREAM are stream buffer resource management objects which exist
146 * only when they need to for buffer management purposes. The existence or
147 * non-existence of a QUIC_SSTREAM or QUIC_RSTREAM object does not
148 * correspond with whether a stream's respective send or receive part
149 * logically exists or not.
150 */
a73078b7 151 QUIC_SSTREAM *sstream; /* NULL if RX-only */
56a1a0ad 152 QUIC_RSTREAM *rstream; /* NULL if TX only */
2f018d14
HL
153
154 /* Stream-level flow control managers. */
a73078b7
HL
155 QUIC_TXFC txfc; /* NULL if RX-only */
156 QUIC_RXFC rxfc; /* NULL if TX-only */
2f018d14
HL
157
158 unsigned int type : 8; /* QUIC_STREAM_INITIATOR_*, QUIC_STREAM_DIR_* */
159
160 unsigned int send_state : 8; /* QUIC_SSTREAM_STATE_* */
161 unsigned int recv_state : 8; /* QUIC_RSTREAM_STATE_* */
162
163 /* 1 iff this QUIC_STREAM is on the active queue (invariant). */
a73078b7
HL
164 unsigned int active : 1;
165
2f018d14 166 /*
1d547f8f 167 * This is a copy of the QUIC connection as_server value, indicating
2f018d14
HL
168 * whether we are locally operating as a server or not. Having this
169 * significantly simplifies stream type determination relative to our
170 * perspective. It never changes after a QUIC_STREAM is created and is the
171 * same for all QUIC_STREAMS under a QUIC_STREAM_MAP.
172 */
173 unsigned int as_server : 1;
174
a73078b7 175 /*
cbe7f586
HL
176 * Has STOP_SENDING been requested (by us)? Note that this is not the same
177 * as want_stop_sending below, as a STOP_SENDING frame may already have been
a73078b7
HL
178 * sent and fully acknowledged.
179 */
180 unsigned int stop_sending : 1;
181
182 /*
cbe7f586
HL
183 * Has RESET_STREAM been requested (by us)? Works identically to
184 * STOP_SENDING for transmission purposes.
a73078b7 185 */
cbe7f586
HL
186 /* Has our peer sent a STOP_SENDING frame? */
187 unsigned int peer_stop_sending : 1;
cbe7f586 188
a73078b7
HL
189 /* Temporary flags used by TXP. */
190 unsigned int txp_sent_fc : 1;
191 unsigned int txp_sent_stop_sending : 1;
192 unsigned int txp_sent_reset_stream : 1;
193 unsigned int txp_drained : 1;
194 unsigned int txp_blocked : 1;
195
196 /* Frame regeneration flags. */
197 unsigned int want_max_stream_data : 1; /* used for regen only */
198 unsigned int want_stop_sending : 1; /* used for gen or regen */
199 unsigned int want_reset_stream : 1; /* used for gen or regen */
cbe7f586 200
9cacba43
HL
201 /* Flags set when frames *we* sent were acknowledged. */
202 unsigned int acked_stop_sending : 1;
9cacba43 203
0847e63e
HL
204 /*
205 * The stream's XSO has been deleted. Pending GC.
206 *
207 * Here is how stream deletion works:
208 *
209 * - A QUIC_STREAM cannot be deleted until it is neither in the accept
210 * queue nor has an associated XSO. This condition occurs when and only
211 * when deleted is true.
212 *
22b1a96f 213 * - Once this is the case (i.e., no user-facing API object exposing the
0847e63e
HL
214 * stream), we can delete the stream once we determine that all of our
215 * protocol obligations requiring us to keep the QUIC_STREAM around have
216 * been met.
217 *
218 * The following frames relate to the streams layer for a specific
219 * stream:
220 *
221 * STREAM
222 *
223 * RX Obligations:
224 * Ignore for a deleted stream.
225 *
226 * (This is different from our obligation for a
227 * locally-initiated stream ID we have not created yet,
228 * which we must treat as a protocol error. This can be
229 * distinguished via a simple monotonic counter.)
230 *
231 * TX Obligations:
232 * None, once we've decided to (someday) delete the stream.
233 *
234 * STOP_SENDING
235 *
236 * We cannot delete the stream until we have finished informing
237 * the peer that we are not going to be listening to it
238 * anymore.
239 *
240 * RX Obligations:
241 * When we delete a stream we must have already had a FIN
242 * or RESET_STREAM we transmitted acknowledged by the peer.
243 * Thus we can ignore STOP_SENDING frames for deleted
244 * streams (if they occur, they are probably just
245 * retransmissions).
246 *
247 * TX Obligations:
248 * _Acknowledged_ receipt of a STOP_SENDING frame by the
249 * peer (unless the peer's send part has already FIN'd).
250 *
251 * RESET_STREAM
252 *
253 * We cannot delete the stream until we have finished informing
254 * the peer that we are not going to be transmitting on it
255 * anymore.
256 *
257 * RX Obligations:
258 * This indicates the peer is not going to send any more
259 * data on the stream. We don't need to care about this
260 * since once a stream is marked for deletion we don't care
261 * about any data it does send. We can ignore this for
262 * deleted streams. The important criterion is that the
263 * peer has been successfully delivered our STOP_SENDING
264 * frame.
265 *
266 * TX Obligations:
267 * _Acknowledged_ receipt of a RESET_STREAM frame or FIN by
268 * the peer.
269 *
270 * MAX_STREAM_DATA
271 *
272 * RX Obligations:
273 * Ignore. Since we are not going to be sending any more
274 * data on a stream once it has been marked for deletion,
275 * we don't need to care about flow control information.
276 *
277 * TX Obligations:
278 * None.
279 *
280 * In other words, our protocol obligation is simply:
281 *
282 * - either:
283 * - the peer has acknowledged receipt of a STOP_SENDING frame sent
284 * by us; -or-
285 * - we have received a FIN and all preceding segments from the peer
286 *
287 * [NOTE: The actual criterion required here is simply 'we have
288 * received a FIN from the peer'. However, due to reordering and
289 * retransmissions we might subsequently receive non-FIN segments
290 * out of order. The FIN means we know the peer will stop
291 * transmitting on the stream at *some* point, but by sending
292 * STOP_SENDING we can avoid these needless retransmissions we
293 * will just ignore anyway. In actuality we could just handle all
294 * cases by sending a STOP_SENDING. The strategy we choose is to
295 * only avoid sending a STOP_SENDING and rely on a received FIN
296 * when we have received all preceding data, as this makes it
297 * reasonably certain no benefit would be gained by sending
298 * STOP_SENDING.]
299 *
44cb36d0
TM
300 * TODO(QUIC FUTURE): Implement the latter case (currently we
301 just always do STOP_SENDING).
0847e63e
HL
302 *
303 * and;
304 *
305 * - we have drained our send stream (for a finished send stream)
306 * and got acknowledgement all parts of it including the FIN, or
307 * sent a RESET_STREAM frame and got acknowledgement of that frame.
308 *
309 * Once these conditions are met, we can GC the QUIC_STREAM.
310 *
311 */
2dbc39de 312 unsigned int deleted : 1;
0847e63e
HL
313 /* Set to 1 once the above conditions are actually met. */
314 unsigned int ready_for_gc : 1;
b864110a
HL
315 /* Set to 1 if this is currently counted in the shutdown flush stream count. */
316 unsigned int shutdown_flush : 1;
a73078b7
HL
317};
318
2f018d14
HL
319#define QUIC_STREAM_INITIATOR_CLIENT 0
320#define QUIC_STREAM_INITIATOR_SERVER 1
321#define QUIC_STREAM_INITIATOR_MASK 1
322
323#define QUIC_STREAM_DIR_BIDI 0
324#define QUIC_STREAM_DIR_UNI 2
325#define QUIC_STREAM_DIR_MASK 2
326
327void ossl_quic_stream_check(const QUIC_STREAM *s);
328
329/*
330 * Returns 1 if the QUIC_STREAM was initiated by the endpoint with the server
331 * role.
332 */
333static ossl_inline ossl_unused int ossl_quic_stream_is_server_init(const QUIC_STREAM *s)
334{
335 return (s->type & QUIC_STREAM_INITIATOR_MASK) == QUIC_STREAM_INITIATOR_SERVER;
336}
337
338/*
339 * Returns 1 if the QUIC_STREAM is bidirectional and 0 if it is unidirectional.
340 */
341static ossl_inline ossl_unused int ossl_quic_stream_is_bidi(const QUIC_STREAM *s)
342{
343 return (s->type & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_BIDI;
344}
345
346/* Returns 1 if the QUIC_STREAM was locally initiated. */
347static ossl_inline ossl_unused int ossl_quic_stream_is_local_init(const QUIC_STREAM *s)
348{
349 return ossl_quic_stream_is_server_init(s) == s->as_server;
350}
351
352/*
353 * Returns 1 if the QUIC_STREAM has a sending part, based on its stream type.
354 *
355 * Do NOT use (s->sstream != NULL) to test this; use this function. Note that
356 * even if this function returns 1, s->sstream might be NULL if the QUIC_SSTREAM
357 * has been deemed no longer needed, for example due to a RESET_STREAM.
358 */
359static ossl_inline ossl_unused int ossl_quic_stream_has_send(const QUIC_STREAM *s)
360{
361 return s->send_state != QUIC_SSTREAM_STATE_NONE;
362}
363
364/*
365 * Returns 1 if the QUIC_STREAM has a receiving part, based on its stream type.
366 *
367 * Do NOT use (s->rstream != NULL) to test this; use this function. Note that
368 * even if this function returns 1, s->rstream might be NULL if the QUIC_RSTREAM
369 * has been deemed no longer needed, for example if the receive stream is
370 * completely finished with.
371 */
372static ossl_inline ossl_unused int ossl_quic_stream_has_recv(const QUIC_STREAM *s)
373{
374 return s->recv_state != QUIC_RSTREAM_STATE_NONE;
375}
376
377/*
378 * Returns 1 if the QUIC_STREAM has a QUIC_SSTREAM send buffer associated with
379 * it. If this returns 1, s->sstream is guaranteed to be non-NULL. The converse
380 * is not necessarily true; erasure of a send stream buffer which is no longer
381 * required is an optimisation which the QSM may, but is not obliged, to
382 * perform.
383 *
384 * This call should be used where it is desired to do something with the send
385 * stream buffer but there is no more specific send state restriction which is
386 * applicable.
387 *
388 * Note: This does NOT indicate whether it is suitable to allow an application
389 * to append to the buffer. DATA_SENT indicates all data (including FIN) has
390 * been *sent*; the absence of DATA_SENT does not mean a FIN has not been queued
391 * (meaning no more application data can be appended). This is enforced by
392 * QUIC_SSTREAM.
393 */
394static ossl_inline ossl_unused int ossl_quic_stream_has_send_buffer(const QUIC_STREAM *s)
395{
396 switch (s->send_state) {
397 case QUIC_SSTREAM_STATE_READY:
398 case QUIC_SSTREAM_STATE_SEND:
399 case QUIC_SSTREAM_STATE_DATA_SENT:
400 return 1;
401 default:
402 return 0;
403 }
404}
405
406/*
407 * Returns 1 if the QUIC_STREAM has a sending part which is in one of the reset
408 * states.
409 */
410static ossl_inline ossl_unused int ossl_quic_stream_send_is_reset(const QUIC_STREAM *s)
411{
412 return s->send_state == QUIC_SSTREAM_STATE_RESET_SENT
413 || s->send_state == QUIC_SSTREAM_STATE_RESET_RECVD;
414}
415
416/*
417 * Returns 1 if the QUIC_STREAM has a QUIC_RSTREAM receive buffer associated
418 * with it. If this returns 1, s->rstream is guaranteed to be non-NULL. The
419 * converse is not necessarily true; erasure of a receive stream buffer which is
420 * no longer required is an optimisation which the QSM may, but is not obliged,
421 * to perform.
422 *
423 * This call should be used where it is desired to do something with the receive
424 * stream buffer but there is no more specific receive state restriction which is
425 * applicable.
426 */
427static ossl_inline ossl_unused int ossl_quic_stream_has_recv_buffer(const QUIC_STREAM *s)
428{
429 switch (s->recv_state) {
430 case QUIC_RSTREAM_STATE_RECV:
431 case QUIC_RSTREAM_STATE_SIZE_KNOWN:
432 case QUIC_RSTREAM_STATE_DATA_RECVD:
433 return 1;
434 default:
435 return 0;
436 }
437}
438
439/*
440 * Returns 1 if the QUIC_STREAM has a receiving part which is in one of the
441 * reset states.
442 */
443static ossl_inline ossl_unused int ossl_quic_stream_recv_is_reset(const QUIC_STREAM *s)
444{
445 return s->recv_state == QUIC_RSTREAM_STATE_RESET_RECVD
446 || s->recv_state == QUIC_RSTREAM_STATE_RESET_READ;
447}
448
418e122c
HL
449/*
450 * Returns 1 if the stream has a send part and that part has a final size.
451 *
452 * If final_size is non-NULL, *final_size is the final size (on success) or an
453 * undefined value otherwise.
454 */
455static ossl_inline ossl_unused int ossl_quic_stream_send_get_final_size(const QUIC_STREAM *s,
456 uint64_t *final_size)
457{
458 switch (s->send_state) {
459 default:
460 case QUIC_SSTREAM_STATE_NONE:
461 return 0;
462 case QUIC_SSTREAM_STATE_SEND:
463 /*
464 * SEND may or may not have had a FIN - even if we have a FIN we do not
465 * move to DATA_SENT until we have actually sent all the data. So
466 * ask the QUIC_SSTREAM.
467 */
468 return ossl_quic_sstream_get_final_size(s->sstream, final_size);
469 case QUIC_SSTREAM_STATE_DATA_SENT:
470 case QUIC_SSTREAM_STATE_DATA_RECVD:
471 case QUIC_SSTREAM_STATE_RESET_SENT:
472 case QUIC_SSTREAM_STATE_RESET_RECVD:
473 if (final_size != NULL)
474 *final_size = s->send_final_size;
475 return 1;
476 }
477}
478
479/*
480 * Returns 1 if the stream has a receive part and that part has a final size.
481 *
482 * If final_size is non-NULL, *final_size is the final size (on success) or an
483 * undefined value otherwise.
484 */
485static ossl_inline ossl_unused int ossl_quic_stream_recv_get_final_size(const QUIC_STREAM *s,
486 uint64_t *final_size)
487{
488 switch (s->recv_state) {
489 default:
490 case QUIC_RSTREAM_STATE_NONE:
491 case QUIC_RSTREAM_STATE_RECV:
492 return 0;
493
494 case QUIC_RSTREAM_STATE_SIZE_KNOWN:
495 case QUIC_RSTREAM_STATE_DATA_RECVD:
496 case QUIC_RSTREAM_STATE_DATA_READ:
497 case QUIC_RSTREAM_STATE_RESET_RECVD:
498 case QUIC_RSTREAM_STATE_RESET_READ:
499 if (!ossl_assert(ossl_quic_rxfc_get_final_size(&s->rxfc, final_size)))
500 return 0;
501
502 return 1;
503 }
504}
505
2f018d14 506/*
a73078b7
HL
507 * QUIC Stream Map
508 * ===============
509 *
510 * The QUIC stream map:
511 *
512 * - maps stream IDs to QUIC_STREAM objects;
513 * - tracks which streams are 'active' (currently have data for transmission);
514 * - allows iteration over the active streams only.
515 *
516 */
ff3a26b2 517struct quic_stream_map_st {
a73078b7
HL
518 LHASH_OF(QUIC_STREAM) *map;
519 QUIC_STREAM_LIST_NODE active_list;
f20fdd16 520 QUIC_STREAM_LIST_NODE accept_list;
0847e63e 521 QUIC_STREAM_LIST_NODE ready_for_gc_list;
b864110a 522 size_t rr_stepping, rr_counter;
a5d16ac3 523 size_t num_accept_bidi, num_accept_uni, num_shutdown_flush;
a73078b7 524 QUIC_STREAM *rr_cur;
cbe7f586
HL
525 uint64_t (*get_stream_limit_cb)(int uni, void *arg);
526 void *get_stream_limit_cb_arg;
90cecc40
HL
527 QUIC_RXFC *max_streams_bidi_rxfc;
528 QUIC_RXFC *max_streams_uni_rxfc;
5915a900 529 int is_server;
ff3a26b2 530};
a73078b7 531
cbe7f586
HL
532/*
533 * get_stream_limit is a callback which is called to retrieve the current stream
534 * limit for streams created by us. This mechanism is not used for
535 * peer-initiated streams. If a stream's stream ID is x, a stream is allowed if
536 * (x >> 2) < returned limit value; i.e., the returned value is exclusive.
537 *
538 * If uni is 1, get the limit for locally-initiated unidirectional streams, else
539 * get the limit for locally-initiated bidirectional streams.
540 *
541 * If the callback is NULL, stream limiting is not applied.
542 * Stream limiting is used to determine if frames can currently be produced for
543 * a stream.
544 */
545int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm,
546 uint64_t (*get_stream_limit_cb)(int uni, void *arg),
90cecc40
HL
547 void *get_stream_limit_cb_arg,
548 QUIC_RXFC *max_streams_bidi_rxfc,
5915a900
HL
549 QUIC_RXFC *max_streams_uni_rxfc,
550 int is_server);
a73078b7
HL
551
552/*
553 * Any streams still in the map will be released as though
554 * ossl_quic_stream_map_release was called on them.
555 */
556void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm);
557
a73078b7
HL
558/*
559 * Allocate a new stream. type is a combination of one QUIC_STREAM_INITIATOR_*
560 * value and one QUIC_STREAM_DIR_* value. Note that clients can e.g. allocate
561 * server-initiated streams as they will need to allocate a QUIC_STREAM
562 * structure to track any stream created by the server, etc.
563 *
564 * stream_id must be a valid value. Returns NULL if a stream already exists
565 * with the given ID.
566 */
567QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm,
568 uint64_t stream_id,
569 int type);
570
571/*
572 * Releases a stream object. Note that this must only be done once the teardown
573 * process is entirely complete and the object will never be referenced again.
574 */
575void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream);
576
577/*
578 * Calls visit_cb() for each stream in the map. visit_cb_arg is an opaque
579 * argument which is passed through.
580 */
581void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm,
582 void (*visit_cb)(QUIC_STREAM *stream, void *arg),
583 void *visit_cb_arg);
584
585/*
586 * Retrieves a stream by stream ID. Returns NULL if it does not exist.
587 */
588QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm,
589 uint64_t stream_id);
590
591/*
592 * Marks the given stream as active or inactive based on its state. Idempotent.
593 *
594 * When a stream is marked active, it becomes available in the iteration list,
595 * and when a stream is marked inactive, it no longer appears in the iteration
596 * list.
597 *
598 * Calling this function invalidates any iterator currently pointing at the
599 * given stream object, but iterators not currently pointing at the given stream
600 * object are not invalidated.
601 */
602void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s);
603
604/*
605 * Sets the RR stepping value, n. The RR rotation will be advanced every n
606 * packets. The default value is 1.
607 */
608void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping);
609
9d6bd3d3
HL
610/*
611 * Returns 1 if the stream ordinal given is allowed by the current stream count
612 * flow control limit, assuming a locally initiated stream of a type described
613 * by is_uni.
614 *
615 * Note that stream_ordinal is a stream ordinal, not a stream ID.
616 */
617int ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP *qsm,
618 uint64_t stream_ordinal,
619 int is_uni);
620
2f018d14
HL
621/*
622 * Stream Send Part
623 * ================
624 */
625
b89c81e4 626/*
2f018d14
HL
627 * Ensures that the sending part has transitioned out of the READY state (i.e.,
628 * to SEND, or a subsequent state). This function is named as it is because,
629 * while on paper the distinction between READY and SEND is whether we have
630 * started transmitting application data, in practice the meaningful distinction
631 * between the two states is whether we have allocated a stream ID to the stream
632 * or not. QUIC permits us to defer stream ID allocation until first STREAM (or
633 * STREAM_DATA_BLOCKED) frame transmission for locally-initiated streams.
e8b9f632 634 *
2f018d14 635 * Our implementation does not currently do this and we allocate stream IDs up
96b7df60
HL
636 * front, however we may revisit this in the future. Calling this represents a
637 * demand for a stream ID by the caller and ensures one has been allocated to
638 * the stream, and causes us to transition to SEND if we are still in the READY
639 * state.
2f018d14
HL
640 *
641 * Returns 0 if there is no send part (caller error) and 1 otherwise.
642 */
643int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP *qsm,
644 QUIC_STREAM *qs);
645
646/*
b3695154
HL
647 * Transitions from SEND to the DATA_SENT state. Note that this is NOT the same
648 * as the point in time at which the final size of the stream becomes known
649 * (i.e., the time at which ossl_quic_sstream_fin()) is called as it occurs when
650 * we have SENT all data on a given stream send part, not merely buffered it.
651 * Note that this transition is NOT reversed in the event of some of that data
652 * being lost.
2f018d14
HL
653 *
654 * Returns 1 if the state transition was successfully taken. Returns 0 if there
655 * is no send part (caller error) or if the state transition cannot be taken
656 * because the send part is not in the SEND state.
657 */
658int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP *qsm,
659 QUIC_STREAM *qs);
660
661/*
662 * Transitions from the DATA_SENT to DATA_RECVD state; should be called
663 * when all transmitted stream data is ACKed by the peer.
664 *
b3695154
HL
665 * Returns 1 if the state transition was successfully taken. Returns 0 if there
666 * is no send part (caller error) or the state transition cannot be taken
667 * because the send part is not in the DATA_SENT state. Because
668 * ossl_quic_stream_map_notify_all_data_sent() should always be called prior to
669 * this function, the send state must already be in DATA_SENT in order for this
2f018d14
HL
670 * function to succeed.
671 */
672int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP *qsm,
673 QUIC_STREAM *qs);
674
675/*
676 * Resets the sending part of a stream. This is a transition from the READY,
677 * SEND or DATA_SENT send stream states to the RESET_SENT state.
678 *
679 * This function returns 1 if the transition is taken (i.e., if the send stream
680 * part was in one of the states above), or if it is already in the RESET_SENT
681 * state (idempotent operation), or if it has reached the RESET_RECVD state.
682 *
683 * It returns 0 if in the DATA_RECVD state, as a send stream cannot be reset
684 * in this state. It also returns 0 if there is no send part (caller error).
e8b9f632
HL
685 */
686int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm,
687 QUIC_STREAM *qs,
688 uint64_t aec);
689
690/*
2f018d14
HL
691 * Transitions from the RESET_SENT to the RESET_RECVD state. This should be
692 * called when a sent RESET_STREAM frame has been acknowledged by the peer.
693 *
694 * This function returns 1 if the transition is taken (i.e., if the send stream
695 * part was in one of the states above) or if it is already in the RESET_RECVD
696 * state (idempotent operation).
697 *
b3695154
HL
698 * It returns 0 if not in the RESET_SENT or RESET_RECVD states, as this function
699 * should only be called after we have already sent a RESET_STREAM frame and
700 * entered the RESET_SENT state. It also returns 0 if there is no send part
701 * (caller error).
2f018d14
HL
702 */
703int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP *qsm,
704 QUIC_STREAM *qs);
705
706
707/*
708 * Stream Receive Part
709 * ===================
710 */
711
712/*
b3695154
HL
713 * Transitions from the RECV receive stream state to the SIZE_KNOWN state. This
714 * should be called once a STREAM frame is received for the stream with the FIN
715 * bit set. final_size should be the final size of the stream in bytes.
e8b9f632 716 *
2f018d14
HL
717 * Returns 1 if the transition was taken.
718 */
719int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP *qsm,
418e122c
HL
720 QUIC_STREAM *qs,
721 uint64_t final_size);
2f018d14 722
b3695154
HL
723/*
724 * Transitions from the SIZE_KNOWN receive stream state to the DATA_RECVD state.
725 * This should be called once all data for a receive stream is received.
726 *
727 * Returns 1 if the transition was taken.
728 */
2f018d14
HL
729int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP *qsm,
730 QUIC_STREAM *qs);
731
b3695154
HL
732/*
733 * Transitions from the DATA_RECVD receive stream state to the DATA_READ state.
1d547f8f 734 * This should be called once all data for a receive stream is read by the
b3695154
HL
735 * application.
736 *
737 * Returns 1 if the transition was taken.
738 */
2f018d14
HL
739int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP *qsm,
740 QUIC_STREAM *qs);
741
b3695154
HL
742/*
743 * Transitions from the RECV, SIZE_KNOWN or DATA_RECVD receive stream state to
744 * the RESET_RECVD state. This should be called on RESET_STREAM.
745 *
746 * Returns 1 if the transition was taken.
747 */
2f018d14
HL
748int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP *qsm,
749 QUIC_STREAM *qs,
2cc0e2dd
HL
750 uint64_t app_error_code,
751 uint64_t final_size);
2f018d14 752
b3695154
HL
753/*
754 * Transitions from the RESET_RECVD receive stream state to the RESET_READ
755 * receive stream state. This should be called when the application is notified
756 * of a stream reset.
757 */
2f018d14
HL
758int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP *qsm,
759 QUIC_STREAM *qs);
760
761/*
762 * Marks the receiving part of a stream for STOP_SENDING. This is orthogonal to
763 * receive stream state as it does not affect it directly.
764 *
765 * Returns 1 if the receiving part of a stream was not already marked for
e8b9f632
HL
766 * STOP_SENDING.
767 * Returns 0 otherwise, which need not be considered an error.
b89c81e4 768 */
e8b9f632
HL
769int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP *qsm,
770 QUIC_STREAM *qs,
771 uint64_t aec);
b89c81e4 772
418e122c
HL
773/*
774 * Marks the stream as wanting a STOP_SENDING frame transmitted. It is not valid
96b7df60 775 * to call this if ossl_quic_stream_map_stop_sending_recv_part() has not been
418e122c
HL
776 * called. For TXP use.
777 */
778int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP *qsm,
779 QUIC_STREAM *qs);
780
781
2f018d14
HL
782/*
783 * Accept Queue Management
784 * =======================
785 */
786
f20fdd16
HL
787/*
788 * Adds a stream to the accept queue.
789 */
790void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm,
791 QUIC_STREAM *s);
792
793/*
794 * Returns the next item to be popped from the accept queue, or NULL if it is
795 * empty.
796 */
797QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm);
798
799/*
90cecc40
HL
800 * Removes a stream from the accept queue. rtt is the estimated connection RTT.
801 * The stream is retired for the purposes of MAX_STREAMS RXFC.
f20fdd16
HL
802 *
803 * Precondition: s is in the accept queue.
804 */
805void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm,
90cecc40
HL
806 QUIC_STREAM *s,
807 OSSL_TIME rtt);
f20fdd16 808
a5d16ac3
HL
809/* Returns the length of the accept queue for the given stream type. */
810size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni);
811
812/* Returns the total length of the accept queues for all stream types. */
813size_t ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP *qsm);
f20fdd16 814
b864110a
HL
815/*
816 * Shutdown Flush and GC
817 * =====================
818 */
819
0847e63e
HL
820/*
821 * Delete streams ready for GC. Pointers to those QUIC_STREAM objects become
822 * invalid.
823 */
824void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm);
825
b864110a
HL
826/*
827 * Begins shutdown stream flush triage. Analyses all streams, including deleted
828 * but not yet GC'd streams, to determine if we should wait for that stream to
829 * be fully flushed before shutdown. After calling this, call
830 * ossl_quic_stream_map_is_shutdown_flush_finished() to determine if all
831 * shutdown flush eligible streams have been flushed.
832 */
833void ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP *qsm);
834
835/*
836 * Returns 1 if all shutdown flush eligible streams have finished flushing,
837 * or if ossl_quic_stream_map_begin_shutdown_flush() has not been called.
838 */
839int ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP *qsm);
840
a73078b7
HL
841/*
842 * QUIC Stream Iterator
843 * ====================
844 *
845 * Allows the current set of active streams to be walked using a RR-based
846 * algorithm. Each time ossl_quic_stream_iter_init is called, the RR algorithm
847 * is stepped. The RR algorithm rotates the iteration order such that the next
848 * active stream is returned first after n calls to ossl_quic_stream_iter_init,
849 * where n is the stepping value configured via
850 * ossl_quic_stream_map_set_rr_stepping.
851 *
852 * Suppose there are three active streams and the configured stepping is n:
853 *
854 * Iteration 0n: [Stream 1] [Stream 2] [Stream 3]
855 * Iteration 1n: [Stream 2] [Stream 3] [Stream 1]
856 * Iteration 2n: [Stream 3] [Stream 1] [Stream 2]
857 *
858 */
859typedef struct quic_stream_iter_st {
860 QUIC_STREAM_MAP *qsm;
861 QUIC_STREAM *first_stream, *stream;
862} QUIC_STREAM_ITER;
863
864/*
865 * Initialise an iterator, advancing the RR algorithm as necessary (if
866 * advance_rr is 1). After calling this, it->stream will be the first stream in
867 * the iteration sequence, or NULL if there are no active streams.
868 */
869void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm,
870 int advance_rr);
871
872/*
873 * Advances to next stream in iteration sequence. You do not need to call this
874 * immediately after calling ossl_quic_stream_iter_init(). If the end of the
875 * list is reached, it->stream will be NULL after calling this.
876 */
877void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it);
878
cbe7f586
HL
879# endif
880
a73078b7 881#endif