2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
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
10 #ifndef OSSL_INTERNAL_QUIC_STREAM_MAP_H
11 # define OSSL_INTERNAL_QUIC_STREAM_MAP_H
14 # include "internal/e_os.h"
15 # include "internal/time.h"
16 # include "internal/common.h"
17 # include "internal/quic_types.h"
18 # include "internal/quic_stream.h"
19 # include "internal/quic_fc.h"
20 # include <openssl/lhash.h>
22 # ifndef OPENSSL_NO_QUIC
28 * Logical QUIC stream composing all relevant send and receive components.
30 typedef struct quic_stream_st QUIC_STREAM
;
32 typedef struct quic_stream_list_node_st QUIC_STREAM_LIST_NODE
;
34 struct quic_stream_list_node_st
{
35 QUIC_STREAM_LIST_NODE
*prev
, *next
;
39 * QUIC Send Stream States
40 * -----------------------
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
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.
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 /* / */
60 * QUIC Receive Stream States
61 * --------------------------
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.
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.
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 /* / */
80 struct quic_stream_st
{
81 QUIC_STREAM_LIST_NODE active_node
; /* for use by QUIC_STREAM_MAP */
82 QUIC_STREAM_LIST_NODE accept_node
; /* accept queue of remotely-created streams */
83 QUIC_STREAM_LIST_NODE ready_for_gc_node
; /* queue of streams now ready for GC */
85 /* Temporary link used by TXP. */
86 QUIC_STREAM
*txp_next
;
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,
96 * Application Error Code (AEC) used for STOP_SENDING frame.
97 * This is only valid if stop_sending is 1.
99 uint64_t stop_sending_aec
;
102 * Application Error Code (AEC) used for RESET_STREAM frame.
103 * This is only valid if reset_stream is 1.
105 uint64_t reset_stream_aec
;
108 * Application Error Code (AEC) for incoming STOP_SENDING frame.
109 * This is only valid if peer_stop_sending is 1.
111 uint64_t peer_stop_sending_aec
;
114 * Application Error Code (AEC) for incoming RESET_STREAM frame.
115 * This is only valid if peer_reset_stream is 1.
117 uint64_t peer_reset_stream_aec
;
119 /* Temporary value used by TXP. */
120 uint64_t txp_txfc_new_credit_consumed
;
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.
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.
133 uint64_t send_final_size
;
136 * Send stream part and receive stream part buffer management objects.
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.
151 QUIC_SSTREAM
*sstream
; /* NULL if RX-only */
152 QUIC_RSTREAM
*rstream
; /* NULL if TX only */
154 /* Stream-level flow control managers. */
155 QUIC_TXFC txfc
; /* NULL if RX-only */
156 QUIC_RXFC rxfc
; /* NULL if TX-only */
158 unsigned int type
: 8; /* QUIC_STREAM_INITIATOR_*, QUIC_STREAM_DIR_* */
160 unsigned int send_state
: 8; /* QUIC_SSTREAM_STATE_* */
161 unsigned int recv_state
: 8; /* QUIC_RSTREAM_STATE_* */
163 /* 1 iff this QUIC_STREAM is on the active queue (invariant). */
164 unsigned int active
: 1;
167 * This is a cpoy of the QUIC connection as_server value, indicating
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.
173 unsigned int as_server
: 1;
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
178 * sent and fully acknowledged.
180 unsigned int stop_sending
: 1;
183 * Has RESET_STREAM been requested (by us)? Works identically to
184 * STOP_SENDING for transmission purposes.
186 /* Has our peer sent a STOP_SENDING frame? */
187 unsigned int peer_stop_sending
: 1;
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;
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 */
201 /* Flags set when frames *we* sent were acknowledged. */
202 unsigned int acked_stop_sending
: 1;
205 * The stream's XSO has been deleted. Pending GC.
207 * Here is how stream deletion works:
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.
213 * - Once this is the case (i.e., no user-facing API object exposing the
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
218 * The following frames relate to the streams layer for a specific
224 * Ignore for a deleted stream.
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.)
232 * None, once we've decided to (someday) delete the stream.
236 * We cannot delete the stream until we have finished informing
237 * the peer that we are not going to be listening to it
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
248 * _Acknowledged_ receipt of a STOP_SENDING frame by the
249 * peer (unless the peer's send part has already FIN'd).
253 * We cannot delete the stream until we have finished informing
254 * the peer that we are not going to be transmitting on it
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
267 * _Acknowledged_ receipt of a RESET_STREAM frame or FIN by
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.
280 * In other words, our protocol obligation is simply:
283 * - the peer has acknowledged receipt of a STOP_SENDING frame sent
285 * - we have received a FIN and all preceding segments from the peer
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
300 * TODO(QUIC): Implement the latter case (currently we just
301 * always do STOP_SENDING).
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.
309 * Once these conditions are met, we can GC the QUIC_STREAM.
312 unsigned int deleted
: 1;
313 /* Set to 1 once the above conditions are actually met. */
314 unsigned int ready_for_gc
: 1;
317 #define QUIC_STREAM_INITIATOR_CLIENT 0
318 #define QUIC_STREAM_INITIATOR_SERVER 1
319 #define QUIC_STREAM_INITIATOR_MASK 1
321 #define QUIC_STREAM_DIR_BIDI 0
322 #define QUIC_STREAM_DIR_UNI 2
323 #define QUIC_STREAM_DIR_MASK 2
325 void ossl_quic_stream_check(const QUIC_STREAM
*s
);
328 * Returns 1 if the QUIC_STREAM was initiated by the endpoint with the server
331 static ossl_inline ossl_unused
int ossl_quic_stream_is_server_init(const QUIC_STREAM
*s
)
333 return (s
->type
& QUIC_STREAM_INITIATOR_MASK
) == QUIC_STREAM_INITIATOR_SERVER
;
337 * Returns 1 if the QUIC_STREAM is bidirectional and 0 if it is unidirectional.
339 static ossl_inline ossl_unused
int ossl_quic_stream_is_bidi(const QUIC_STREAM
*s
)
341 return (s
->type
& QUIC_STREAM_DIR_MASK
) == QUIC_STREAM_DIR_BIDI
;
344 /* Returns 1 if the QUIC_STREAM was locally initiated. */
345 static ossl_inline ossl_unused
int ossl_quic_stream_is_local_init(const QUIC_STREAM
*s
)
347 return ossl_quic_stream_is_server_init(s
) == s
->as_server
;
351 * Returns 1 if the QUIC_STREAM has a sending part, based on its stream type.
353 * Do NOT use (s->sstream != NULL) to test this; use this function. Note that
354 * even if this function returns 1, s->sstream might be NULL if the QUIC_SSTREAM
355 * has been deemed no longer needed, for example due to a RESET_STREAM.
357 static ossl_inline ossl_unused
int ossl_quic_stream_has_send(const QUIC_STREAM
*s
)
359 return s
->send_state
!= QUIC_SSTREAM_STATE_NONE
;
363 * Returns 1 if the QUIC_STREAM has a receiving part, based on its stream type.
365 * Do NOT use (s->rstream != NULL) to test this; use this function. Note that
366 * even if this function returns 1, s->rstream might be NULL if the QUIC_RSTREAM
367 * has been deemed no longer needed, for example if the receive stream is
368 * completely finished with.
370 static ossl_inline ossl_unused
int ossl_quic_stream_has_recv(const QUIC_STREAM
*s
)
372 return s
->recv_state
!= QUIC_RSTREAM_STATE_NONE
;
376 * Returns 1 if the QUIC_STREAM has a QUIC_SSTREAM send buffer associated with
377 * it. If this returns 1, s->sstream is guaranteed to be non-NULL. The converse
378 * is not necessarily true; erasure of a send stream buffer which is no longer
379 * required is an optimisation which the QSM may, but is not obliged, to
382 * This call should be used where it is desired to do something with the send
383 * stream buffer but there is no more specific send state restriction which is
386 * Note: This does NOT indicate whether it is suitable to allow an application
387 * to append to the buffer. DATA_SENT indicates all data (including FIN) has
388 * been *sent*; the absence of DATA_SENT does not mean a FIN has not been queued
389 * (meaning no more application data can be appended). This is enforced by
392 static ossl_inline ossl_unused
int ossl_quic_stream_has_send_buffer(const QUIC_STREAM
*s
)
394 switch (s
->send_state
) {
395 case QUIC_SSTREAM_STATE_READY
:
396 case QUIC_SSTREAM_STATE_SEND
:
397 case QUIC_SSTREAM_STATE_DATA_SENT
:
405 * Returns 1 if the QUIC_STREAM has a sending part which is in one of the reset
408 static ossl_inline ossl_unused
int ossl_quic_stream_send_is_reset(const QUIC_STREAM
*s
)
410 return s
->send_state
== QUIC_SSTREAM_STATE_RESET_SENT
411 || s
->send_state
== QUIC_SSTREAM_STATE_RESET_RECVD
;
415 * Returns 1 if the QUIC_STREAM has a QUIC_RSTREAM receive buffer associated
416 * with it. If this returns 1, s->rstream is guaranteed to be non-NULL. The
417 * converse is not necessarily true; erasure of a receive stream buffer which is
418 * no longer required is an optimisation which the QSM may, but is not obliged,
421 * This call should be used where it is desired to do something with the receive
422 * stream buffer but there is no more specific receive state restriction which is
425 static ossl_inline ossl_unused
int ossl_quic_stream_has_recv_buffer(const QUIC_STREAM
*s
)
427 switch (s
->recv_state
) {
428 case QUIC_RSTREAM_STATE_RECV
:
429 case QUIC_RSTREAM_STATE_SIZE_KNOWN
:
430 case QUIC_RSTREAM_STATE_DATA_RECVD
:
438 * Returns 1 if the QUIC_STREAM has a receiving part which is in one of the
441 static ossl_inline ossl_unused
int ossl_quic_stream_recv_is_reset(const QUIC_STREAM
*s
)
443 return s
->recv_state
== QUIC_RSTREAM_STATE_RESET_RECVD
444 || s
->recv_state
== QUIC_RSTREAM_STATE_RESET_READ
;
448 * Returns 1 if the stream has a send part and that part has a final size.
450 * If final_size is non-NULL, *final_size is the final size (on success) or an
451 * undefined value otherwise.
453 static ossl_inline ossl_unused
int ossl_quic_stream_send_get_final_size(const QUIC_STREAM
*s
,
454 uint64_t *final_size
)
456 switch (s
->send_state
) {
458 case QUIC_SSTREAM_STATE_NONE
:
460 case QUIC_SSTREAM_STATE_SEND
:
462 * SEND may or may not have had a FIN - even if we have a FIN we do not
463 * move to DATA_SENT until we have actually sent all the data. So
464 * ask the QUIC_SSTREAM.
466 return ossl_quic_sstream_get_final_size(s
->sstream
, final_size
);
467 case QUIC_SSTREAM_STATE_DATA_SENT
:
468 case QUIC_SSTREAM_STATE_DATA_RECVD
:
469 case QUIC_SSTREAM_STATE_RESET_SENT
:
470 case QUIC_SSTREAM_STATE_RESET_RECVD
:
471 if (final_size
!= NULL
)
472 *final_size
= s
->send_final_size
;
478 * Returns 1 if the stream has a receive part and that part has a final size.
480 * If final_size is non-NULL, *final_size is the final size (on success) or an
481 * undefined value otherwise.
483 static ossl_inline ossl_unused
int ossl_quic_stream_recv_get_final_size(const QUIC_STREAM
*s
,
484 uint64_t *final_size
)
486 switch (s
->recv_state
) {
488 case QUIC_RSTREAM_STATE_NONE
:
489 case QUIC_RSTREAM_STATE_RECV
:
492 case QUIC_RSTREAM_STATE_SIZE_KNOWN
:
493 case QUIC_RSTREAM_STATE_DATA_RECVD
:
494 case QUIC_RSTREAM_STATE_DATA_READ
:
495 case QUIC_RSTREAM_STATE_RESET_RECVD
:
496 case QUIC_RSTREAM_STATE_RESET_READ
:
497 if (!ossl_assert(ossl_quic_rxfc_get_final_size(&s
->rxfc
, final_size
)))
508 * The QUIC stream map:
510 * - maps stream IDs to QUIC_STREAM objects;
511 * - tracks which streams are 'active' (currently have data for transmission);
512 * - allows iteration over the active streams only.
515 typedef struct quic_stream_map_st
{
516 LHASH_OF(QUIC_STREAM
) *map
;
517 QUIC_STREAM_LIST_NODE active_list
;
518 QUIC_STREAM_LIST_NODE accept_list
;
519 QUIC_STREAM_LIST_NODE ready_for_gc_list
;
520 size_t rr_stepping
, rr_counter
, num_accept
;
522 uint64_t (*get_stream_limit_cb
)(int uni
, void *arg
);
523 void *get_stream_limit_cb_arg
;
524 QUIC_RXFC
*max_streams_bidi_rxfc
;
525 QUIC_RXFC
*max_streams_uni_rxfc
;
530 * get_stream_limit is a callback which is called to retrieve the current stream
531 * limit for streams created by us. This mechanism is not used for
532 * peer-initiated streams. If a stream's stream ID is x, a stream is allowed if
533 * (x >> 2) < returned limit value; i.e., the returned value is exclusive.
535 * If uni is 1, get the limit for locally-initiated unidirectional streams, else
536 * get the limit for locally-initiated bidirectional streams.
538 * If the callback is NULL, stream limiting is not applied.
539 * Stream limiting is used to determine if frames can currently be produced for
542 int ossl_quic_stream_map_init(QUIC_STREAM_MAP
*qsm
,
543 uint64_t (*get_stream_limit_cb
)(int uni
, void *arg
),
544 void *get_stream_limit_cb_arg
,
545 QUIC_RXFC
*max_streams_bidi_rxfc
,
546 QUIC_RXFC
*max_streams_uni_rxfc
,
550 * Any streams still in the map will be released as though
551 * ossl_quic_stream_map_release was called on them.
553 void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP
*qsm
);
556 * Allocate a new stream. type is a combination of one QUIC_STREAM_INITIATOR_*
557 * value and one QUIC_STREAM_DIR_* value. Note that clients can e.g. allocate
558 * server-initiated streams as they will need to allocate a QUIC_STREAM
559 * structure to track any stream created by the server, etc.
561 * stream_id must be a valid value. Returns NULL if a stream already exists
564 QUIC_STREAM
*ossl_quic_stream_map_alloc(QUIC_STREAM_MAP
*qsm
,
569 * Releases a stream object. Note that this must only be done once the teardown
570 * process is entirely complete and the object will never be referenced again.
572 void ossl_quic_stream_map_release(QUIC_STREAM_MAP
*qsm
, QUIC_STREAM
*stream
);
575 * Calls visit_cb() for each stream in the map. visit_cb_arg is an opaque
576 * argument which is passed through.
578 void ossl_quic_stream_map_visit(QUIC_STREAM_MAP
*qsm
,
579 void (*visit_cb
)(QUIC_STREAM
*stream
, void *arg
),
583 * Retrieves a stream by stream ID. Returns NULL if it does not exist.
585 QUIC_STREAM
*ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP
*qsm
,
589 * Marks the given stream as active or inactive based on its state. Idempotent.
591 * When a stream is marked active, it becomes available in the iteration list,
592 * and when a stream is marked inactive, it no longer appears in the iteration
595 * Calling this function invalidates any iterator currently pointing at the
596 * given stream object, but iterators not currently pointing at the given stream
597 * object are not invalidated.
599 void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP
*qsm
, QUIC_STREAM
*s
);
602 * Sets the RR stepping value, n. The RR rotation will be advanced every n
603 * packets. The default value is 1.
605 void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP
*qsm
, size_t stepping
);
613 * Ensures that the sending part has transitioned out of the READY state (i.e.,
614 * to SEND, or a subsequent state). This function is named as it is because,
615 * while on paper the distinction between READY and SEND is whether we have
616 * started transmitting application data, in practice the meaningful distinction
617 * between the two states is whether we have allocated a stream ID to the stream
618 * or not. QUIC permits us to defer stream ID allocation until first STREAM (or
619 * STREAM_DATA_BLOCKED) frame transmission for locally-initiated streams.
621 * Our implementation does not currently do this and we allocate stream IDs up
622 * front, however we may revisit this in the future. Calling this represents a
623 * demand for a stream ID by the caller and ensures one has been allocated to
624 * the stream, and causes us to transition to SEND if we are still in the READY
627 * Returns 0 if there is no send part (caller error) and 1 otherwise.
629 int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP
*qsm
,
633 * Transitions from SEND to the DATA_SENT state. Note that this is NOT the same
634 * as the point in time at which the final size of the stream becomes known
635 * (i.e., the time at which ossl_quic_sstream_fin()) is called as it occurs when
636 * we have SENT all data on a given stream send part, not merely buffered it.
637 * Note that this transition is NOT reversed in the event of some of that data
640 * Returns 1 if the state transition was successfully taken. Returns 0 if there
641 * is no send part (caller error) or if the state transition cannot be taken
642 * because the send part is not in the SEND state.
644 int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP
*qsm
,
648 * Transitions from the DATA_SENT to DATA_RECVD state; should be called
649 * when all transmitted stream data is ACKed by the peer.
651 * Returns 1 if the state transition was successfully taken. Returns 0 if there
652 * is no send part (caller error) or the state transition cannot be taken
653 * because the send part is not in the DATA_SENT state. Because
654 * ossl_quic_stream_map_notify_all_data_sent() should always be called prior to
655 * this function, the send state must already be in DATA_SENT in order for this
656 * function to succeed.
658 int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP
*qsm
,
662 * Resets the sending part of a stream. This is a transition from the READY,
663 * SEND or DATA_SENT send stream states to the RESET_SENT state.
665 * This function returns 1 if the transition is taken (i.e., if the send stream
666 * part was in one of the states above), or if it is already in the RESET_SENT
667 * state (idempotent operation), or if it has reached the RESET_RECVD state.
669 * It returns 0 if in the DATA_RECVD state, as a send stream cannot be reset
670 * in this state. It also returns 0 if there is no send part (caller error).
672 int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP
*qsm
,
677 * Transitions from the RESET_SENT to the RESET_RECVD state. This should be
678 * called when a sent RESET_STREAM frame has been acknowledged by the peer.
680 * This function returns 1 if the transition is taken (i.e., if the send stream
681 * part was in one of the states above) or if it is already in the RESET_RECVD
682 * state (idempotent operation).
684 * It returns 0 if not in the RESET_SENT or RESET_RECVD states, as this function
685 * should only be called after we have already sent a RESET_STREAM frame and
686 * entered the RESET_SENT state. It also returns 0 if there is no send part
689 int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP
*qsm
,
694 * Stream Receive Part
695 * ===================
699 * Transitions from the RECV receive stream state to the SIZE_KNOWN state. This
700 * should be called once a STREAM frame is received for the stream with the FIN
701 * bit set. final_size should be the final size of the stream in bytes.
703 * Returns 1 if the transition was taken.
705 int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP
*qsm
,
707 uint64_t final_size
);
710 * Transitions from the SIZE_KNOWN receive stream state to the DATA_RECVD state.
711 * This should be called once all data for a receive stream is received.
713 * Returns 1 if the transition was taken.
715 int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP
*qsm
,
719 * Transitions from the DATA_RECVD receive stream state to the DATA_READ state.
720 * This shuld be called once all data for a receive stream is read by the
723 * Returns 1 if the transition was taken.
725 int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP
*qsm
,
729 * Transitions from the RECV, SIZE_KNOWN or DATA_RECVD receive stream state to
730 * the RESET_RECVD state. This should be called on RESET_STREAM.
732 * Returns 1 if the transition was taken.
734 int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP
*qsm
,
736 uint64_t app_error_code
,
737 uint64_t final_size
);
740 * Transitions from the RESET_RECVD receive stream state to the RESET_READ
741 * receive stream state. This should be called when the application is notified
744 int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP
*qsm
,
748 * Marks the receiving part of a stream for STOP_SENDING. This is orthogonal to
749 * receive stream state as it does not affect it directly.
751 * Returns 1 if the receiving part of a stream was not already marked for
753 * Returns 0 otherwise, which need not be considered an error.
755 int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP
*qsm
,
760 * Marks the stream as wanting a STOP_SENDING frame transmitted. It is not valid
761 * to call this if ossl_quic_stream_map_stop_sending_recv_part() has not been
762 * called. For TXP use.
764 int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP
*qsm
,
769 * Accept Queue Management
770 * =======================
774 * Adds a stream to the accept queue.
776 void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP
*qsm
,
780 * Returns the next item to be popped from the accept queue, or NULL if it is
783 QUIC_STREAM
*ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP
*qsm
);
786 * Removes a stream from the accept queue. rtt is the estimated connection RTT.
787 * The stream is retired for the purposes of MAX_STREAMS RXFC.
789 * Precondition: s is in the accept queue.
791 void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP
*qsm
,
795 /* Returns the length of the accept queue. */
796 size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP
*qsm
);
799 * Delete streams ready for GC. Pointers to those QUIC_STREAM objects become
802 void ossl_quic_stream_map_gc(QUIC_STREAM_MAP
*qsm
);
805 * QUIC Stream Iterator
806 * ====================
808 * Allows the current set of active streams to be walked using a RR-based
809 * algorithm. Each time ossl_quic_stream_iter_init is called, the RR algorithm
810 * is stepped. The RR algorithm rotates the iteration order such that the next
811 * active stream is returned first after n calls to ossl_quic_stream_iter_init,
812 * where n is the stepping value configured via
813 * ossl_quic_stream_map_set_rr_stepping.
815 * Suppose there are three active streams and the configured stepping is n:
817 * Iteration 0n: [Stream 1] [Stream 2] [Stream 3]
818 * Iteration 1n: [Stream 2] [Stream 3] [Stream 1]
819 * Iteration 2n: [Stream 3] [Stream 1] [Stream 2]
822 typedef struct quic_stream_iter_st
{
823 QUIC_STREAM_MAP
*qsm
;
824 QUIC_STREAM
*first_stream
, *stream
;
828 * Initialise an iterator, advancing the RR algorithm as necessary (if
829 * advance_rr is 1). After calling this, it->stream will be the first stream in
830 * the iteration sequence, or NULL if there are no active streams.
832 void ossl_quic_stream_iter_init(QUIC_STREAM_ITER
*it
, QUIC_STREAM_MAP
*qsm
,
836 * Advances to next stream in iteration sequence. You do not need to call this
837 * immediately after calling ossl_quic_stream_iter_init(). If the end of the
838 * list is reached, it->stream will be NULL after calling this.
840 void ossl_quic_stream_iter_next(QUIC_STREAM_ITER
*it
);