]> git.ipfire.org Git - thirdparty/openssl.git/blame - include/internal/quic_stream.h
QUIC TX Packetiser and Streams Mapper
[thirdparty/openssl.git] / include / internal / quic_stream.h
CommitLineData
83022590
HL
1/*
2* Copyright 2022 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_H
11# define OSSL_INTERNAL_QUIC_STREAM_H
12# pragma once
13
14#include "internal/e_os.h"
15#include "internal/time.h"
16#include "internal/quic_types.h"
17#include "internal/quic_wire.h"
18#include "internal/quic_record_tx.h"
bbf902c3
TM
19#include "internal/quic_record_rx.h"
20#include "internal/quic_record_rx_wrap.h"
e77396f6
TM
21#include "internal/quic_fc.h"
22#include "internal/quic_statm.h"
83022590
HL
23
24/*
25 * QUIC Send Stream
26 * ================
27 *
28 * The QUIC Send Stream Manager (QUIC_SSTREAM) is responsible for:
29 *
30 * - accepting octet strings of stream data;
31 *
32 * - generating corresponding STREAM frames;
33 *
34 * - receiving notifications of lost frames, in order to generate new STREAM
35 * frames for the lost data;
36 *
37 * - receiving notifications of acknowledged frames, in order to internally
38 * reuse memory used to store acknowledged stream data;
39 *
40 * - informing the caller of how much more stream data it can accept into
41 * its internal buffers, so as to ensure that the amount of unacknowledged
42 * data which can be written to a stream is not infinite and to allow the
43 * caller to manifest backpressure conditions to the user.
44 *
45 * The QUIC_SSTREAM is instantiated once for every stream with a send component
46 * (i.e., for a unidirectional send stream or for the send component of a
47 * bidirectional stream).
48 *
49 * Note: The terms 'TX' and 'RX' are used when referring to frames, packets and
50 * datagrams. The terms 'send' and 'receive' are used when referring to the
51 * stream abstraction. Applications send; we transmit.
52 */
53typedef struct quic_sstream_st QUIC_SSTREAM;
54
55/*
56 * Instantiates a new QUIC_SSTREAM. init_buf_size specifies the initial size of
57 * the stream data buffer in bytes, which must be positive.
58 */
59QUIC_SSTREAM *ossl_quic_sstream_new(size_t init_buf_size);
60
61/*
62 * Frees a QUIC_SSTREAM and associated stream data storage.
63 *
64 * Any iovecs returned by ossl_quic_sstream_get_stream_frame cease to be valid after
65 * calling this function.
66 */
67void ossl_quic_sstream_free(QUIC_SSTREAM *qss);
68
69/*
70 * (For TX packetizer use.) Retrieves information about application stream data
71 * which is ready for transmission.
72 *
73 * *hdr is filled with the logical offset, maximum possible length of stream
74 * data which can be transmitted, and a pointer to the stream data to be
75 * transmitted. is_fin is set to 1 if hdr->offset + hdr->len is the final size
76 * of the stream and 0 otherwise. hdr->stream_id is not set; the caller must set
77 * it.
78 *
79 * The caller is not obligated to send all of the data. If the caller does not
80 * send all of the data, the caller must reduce hdr->len before serializing the
81 * header structure and must ensure that hdr->is_fin is cleared.
82 *
83 * hdr->has_explicit_len is always set. It is the caller's responsibility to
84 * clear this if it wants to use the optimization of omitting the length field,
85 * as only the caller can know when this optimization can be performed.
86 *
87 * *num_iov must be set to the size of the iov array at call time. When this
88 * function returns successfully, it is updated to the number of iov entries
89 * which have been written.
90 *
91 * The stream data may be split across up to two IOVs due to internal ring
92 * buffer organisation. The sum of the lengths of the IOVs and the value written
93 * to hdr->len will always match. If the caller decides to send less than
94 * hdr->len of stream data, it must adjust the IOVs accordingly. This may be
95 * done by updating hdr->len and then calling the utility function
96 * ossl_quic_sstream_adjust_iov().
97 *
98 * After committing one or more bytes returned by ossl_quic_sstream_get_stream_frame to a
99 * packet, call ossl_quic_sstream_mark_transmitted with the inclusive range of logical
100 * byte numbers of the transmitted bytes (i.e., hdr->offset, hdr->offset +
101 * hdr->len - 1). If you do not call ossl_quic_sstream_mark_transmitted, the next call to
102 * ossl_quic_sstream_get_stream_frame will return the same data (or potentially the same
103 * and more, if more data has been appended by the application).
104 *
105 * It is the caller's responsibility to clamp the length of data which this
106 * function indicates is available according to other concerns, such as
107 * stream-level flow control, connection-level flow control, or the applicable
108 * maximum datagram payload length (MDPL) for a packet under construction.
109 *
110 * The skip argument can usually be given as zero. If it is non-zero, this
111 * function outputs a range which would be output if it were called again after
112 * calling ossl_quic_sstream_mark_transmitted() with the returned range, repeated 'skip'
113 * times, and so on. This may be useful for callers which wish to enumerate
114 * available stream frames and batch their calls to ossl_quic_sstream_mark_transmitted at
115 * a later time.
116 *
117 * On success, this function will never write *num_iov with a value other than
118 * 0, 1 or 2. A *num_iov value of 0 can only occurs when hdr->is_fin is set (for
119 * example, when a stream is closed after all existing data has been sent, and
120 * without sending any more data); otherwise the function returns 0 as there is
121 * nothing useful to report.
122 *
123 * Returns 1 on success and 0 if there is no stream data available for
124 * transmission, or on other error (such as if the caller provides fewer
125 * than two IOVs.)
126 */
127int ossl_quic_sstream_get_stream_frame(QUIC_SSTREAM *qss,
128 size_t skip,
129 OSSL_QUIC_FRAME_STREAM *hdr,
130 OSSL_QTX_IOVEC *iov,
131 size_t *num_iov);
132
a73078b7
HL
133/*
134 * Returns the current size of the stream; i.e., the number of bytes which have
135 * been appended to the stream so far.
136 */
137uint64_t ossl_quic_sstream_get_cur_size(QUIC_SSTREAM *qss);
138
83022590
HL
139/*
140 * (For TX packetizer use.) Marks a logical range of the send stream as having
141 * been transmitted.
142 *
143 * 0 denotes the first byte ever sent on the stream. The start and end values
144 * are both inclusive, therefore all calls to this function always mark at least
145 * one byte as being transmitted; if no bytes have been transmitted, do not call
146 * this function.
147 *
148 * If the STREAM frame sent had the FIN bit set, you must also call
149 * ossl_quic_sstream_mark_transmitted_fin() after calling this function.
150 *
151 * If you sent a zero-length STREAM frame with the FIN bit set, you need only
152 * call ossl_quic_sstream_mark_transmitted_fin() and must not call this function.
153 *
154 * Returns 1 on success and 0 on error (e.g. if end < start).
155 */
156int ossl_quic_sstream_mark_transmitted(QUIC_SSTREAM *qss,
157 uint64_t start,
158 uint64_t end);
159
160/*
161 * (For TX packetizer use.) Marks a STREAM frame with the FIN bit set as having
162 * been transmitted. final_size is the final size of the stream (i.e., the value
163 * offset + len of the transmitted STREAM frame).
164 *
165 * This function fails returning 0 if ossl_quic_sstream_fin() has not been called or if
166 * final_size is not correct. The final_size argument is not strictly needed by
167 * the QUIC_SSTREAM but is required as a sanity check.
168 */
169int ossl_quic_sstream_mark_transmitted_fin(QUIC_SSTREAM *qss,
170 uint64_t final_size);
171
172/*
173 * (RX/ACKM use.) Marks a logical range of the send stream as having been lost.
174 * The send stream will return the lost data for retransmission on a future call
175 * to ossl_quic_sstream_get_stream_frame. The start and end values denote logical byte
176 * numbers and are inclusive.
177 *
178 * If the lost frame had the FIN bit set, you must also call
179 * ossl_quic_sstream_mark_lost_fin() after calling this function.
180 *
181 * Returns 1 on success and 0 on error (e.g. if end < start).
182 */
183int ossl_quic_sstream_mark_lost(QUIC_SSTREAM *qss,
184 uint64_t start,
185 uint64_t end);
186
187/*
188 * (RX/ACKM use.) Informs the QUIC_SSTREAM that a STREAM frame with the FIN bit
189 * set was lost.
190 *
191 * Returns 1 on success and 0 on error.
192 */
193int ossl_quic_sstream_mark_lost_fin(QUIC_SSTREAM *qss);
194
195/*
196 * (RX/ACKM use.) Marks a logical range of the send stream as having been
197 * acknowledged, meaning that the storage for the data in that range of the
198 * stream can be now recycled and neither that logical range of the stream nor
199 * any subset of it can be retransmitted again. The start and end values are
200 * inclusive.
201 *
202 * If the acknowledged frame had the FIN bit set, you must also call
203 * ossl_quic_sstream_mark_acked_fin() after calling this function.
204 *
205 * Returns 1 on success and 0 on error (e.g. if end < start).
206 */
207int ossl_quic_sstream_mark_acked(QUIC_SSTREAM *qss,
208 uint64_t start,
209 uint64_t end);
210
211/*
212 * (RX/ACKM use.) Informs the QUIC_SSTREAM that a STREAM frame with the FIN bit
213 * set was acknowledged.
214 *
215 * Returns 1 on success and 0 on error.
216 */
217int ossl_quic_sstream_mark_acked_fin(QUIC_SSTREAM *qss);
218
219/*
220 * (Front end use.) Appends user data to the stream. The data is copied into the
221 * stream. The amount of data consumed from buf is written to *consumed on
222 * success (short writes are possible). The amount of data which can be written
223 * can be determined in advance by calling the ossl_quic_sstream_get_buffer_avail()
224 * function; data is copied into an internal ring buffer of finite size.
225 *
226 * If the buffer is full, this should be materialised as a backpressure
227 * condition by the front end. This is not considered a failure condition;
228 * *consumed is written as 0 and the function returns 1.
229 *
230 * Returns 1 on success or 0 on failure.
231 */
232int ossl_quic_sstream_append(QUIC_SSTREAM *qss,
233 const unsigned char *buf,
234 size_t buf_len,
235 size_t *consumed);
236
237/*
238 * Marks a stream as finished. ossl_quic_sstream_append() may not be called anymore
239 * after calling this.
240 */
241void ossl_quic_sstream_fin(QUIC_SSTREAM *qss);
242
243/*
244 * Resizes the internal ring buffer. All stream data is preserved safely.
245 *
246 * This can be used to expand or contract the ring buffer, but not to contract
247 * the ring buffer below the amount of stream data currently stored in it.
248 * Returns 1 on success and 0 on failure.
249 *
250 * IMPORTANT: Any buffers referenced by iovecs output by
251 * ossl_quic_sstream_get_stream_frame() cease to be valid after calling this function.
252 */
253int ossl_quic_sstream_set_buffer_size(QUIC_SSTREAM *qss, size_t num_bytes);
254
255/*
256 * Gets the internal ring buffer size in bytes.
257 */
258size_t ossl_quic_sstream_get_buffer_size(QUIC_SSTREAM *qss);
259
260/*
261 * Gets the number of bytes used in the internal ring buffer.
262 */
263size_t ossl_quic_sstream_get_buffer_used(QUIC_SSTREAM *qss);
264
265/*
266 * Gets the number of bytes free in the internal ring buffer.
267 */
268size_t ossl_quic_sstream_get_buffer_avail(QUIC_SSTREAM *qss);
269
270/*
271 * Utility function to ensure the length of an array of iovecs matches the
272 * length given as len. Trailing iovecs have their length values reduced or set
273 * to 0 as necessary.
274 */
275void ossl_quic_sstream_adjust_iov(size_t len,
276 OSSL_QTX_IOVEC *iov,
277 size_t num_iov);
278
bbf902c3
TM
279/*
280 * QUIC Receive Stream Manager
281 * ===========================
282 *
e77396f6
TM
283 * The QUIC Receive Stream Manager (QUIC_RSTREAM) is responsible for
284 * storing the received stream data frames until the application
285 * is able to read the data.
bbf902c3
TM
286 *
287 * The QUIC_RSTREAM is instantiated once for every stream that can receive data.
288 * (i.e., for a unidirectional receiving stream or for the receiving component
289 * of a bidirectional stream).
290 */
291typedef struct quic_rstream_st QUIC_RSTREAM;
292
293/*
e77396f6
TM
294 * Create a new instance of QUIC_RSTREAM with pointers to the flow
295 * controller and statistics module. They can be NULL for unit testing.
296 * If they are non-NULL, the `rxfc` is called when receive stream data
a17c713a 297 * is read by application. `statm` is queried for current rtt.
bbf902c3 298 */
e77396f6
TM
299QUIC_RSTREAM *ossl_quic_rstream_new(OSSL_QRX *qrx, QUIC_RXFC *rxfc,
300 OSSL_STATM *statm);
bbf902c3
TM
301
302/*
303 * Frees a QUIC_RSTREAM and any associated storage.
304 */
305void ossl_quic_rstream_free(QUIC_RSTREAM *qrs);
306
307/*
e77396f6
TM
308 * Adds received stream frame data to `qrs`. The `pkt_wrap` refcount is
309 * incremented if the `data` is queued directly without copying.
310 * It can be NULL for unit-testing purposes, i.e. if `data` is static or
311 * never released before calling ossl_quic_rstream_free().
312 * The `offset` is the absolute offset of the data in the stream.
313 * `data_len` can be 0 - can be useful for indicating `fin` for empty stream.
314 * Or to indicate `fin` without any further data added to the stream.
bbf902c3
TM
315 */
316
317int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT_WRAP *pkt_wrap,
318 uint64_t offset,
319 const unsigned char *data, uint64_t data_len,
320 int fin);
321
322/*
323 * Copies the data from the stream storage to buffer `buf` of size `size`.
324 * `readbytes` is set to the number of bytes actually copied.
325 * `fin` is set to 1 if all the data from the stream were read so the
326 * stream is finished. It is set to 0 otherwise.
327 */
328int ossl_quic_rstream_read(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
329 size_t *readbytes, int *fin);
330
331/*
332 * Peeks at the data in the stream storage. It copies them to buffer `buf`
333 * of size `size` and sets `readbytes` to the number of bytes actually copied.
334 * `fin` is set to 1 if the copied data reach end of the stream.
335 * It is set to 0 otherwise.
336 */
337int ossl_quic_rstream_peek(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
338 size_t *readbytes, int *fin);
339
340/*
341 * Returns the size of the data available for reading. `fin` is set to 1 if
342 * after reading all the available data the stream will be finished,
343 * set to 0 otherwise.
344 */
345int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin);
83022590
HL
346
347#endif