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