QUIC APL, TSERVER: Start using a QUIC_ENGINE object
[openssl.git] / include / internal / quic_demux.h
1 /*
2  * Copyright 2022-2023 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_QUIC_DEMUX_H
11 # define OSSL_QUIC_DEMUX_H
12
13 # include <openssl/ssl.h>
14 # include "internal/quic_types.h"
15 # include "internal/quic_predef.h"
16 # include "internal/bio_addr.h"
17 # include "internal/time.h"
18 # include "internal/list.h"
19
20 # ifndef OPENSSL_NO_QUIC
21
22 /*
23  * QUIC Demuxer
24  * ============
25  *
26  * The QUIC connection demuxer is the entity responsible for receiving datagrams
27  * from the network via a datagram BIO. It parses the headers of the first
28  * packet in the datagram to determine that packet's DCID and hands off
29  * processing of the entire datagram to a single callback function which can
30  * decide how to handle and route the datagram, for example by looking up
31  * a QRX instance and injecting the URXE into that QRX.
32  *
33  * A QRX will typically be instantiated per QUIC connection and contains the
34  * cryptographic resources needed to decrypt QUIC packets for that connection.
35  * However, it is up to the callback function to handle routing, for example by
36  * consulting a LCIDM instance. Thus the demuxer has no specific knowledge of
37  * any QRX and is not coupled to it. All CID knowledge is also externalised into
38  * a LCIDM or other CID state tracking object, without the DEMUX being coupled
39  * to any particular DCID resolution mechanism.
40  *
41  * URX Queue
42  * ---------
43  *
44  * Since the demuxer must handle the initial reception of datagrams from the OS,
45  * RX queue management for new, unprocessed datagrams is also handled by the
46  * demuxer.
47  *
48  * The demuxer maintains a queue of Unprocessed RX Entries (URXEs), which store
49  * unprocessed (i.e., encrypted, unvalidated) data received from the network.
50  * The URXE queue is designed to allow multiple datagrams to be received in a
51  * single call to BIO_recvmmsg, where supported.
52  *
53  * One URXE is used per received datagram. Each datagram may contain multiple
54  * packets, however, this is not the demuxer's concern. QUIC prohibits different
55  * packets in the same datagram from containing different DCIDs; the demuxer
56  * only considers the DCID of the first packet in a datagram when deciding how
57  * to route a received datagram, and it is the responsibility of the QRX to
58  * enforce this rule. Packets other than the first packet in a datagram are not
59  * examined by the demuxer, and the demuxer does not perform validation of
60  * packet headers other than to the minimum extent necessary to extract the
61  * DCID; further parsing and validation of packet headers is the responsibility
62  * of the QRX.
63  *
64  * Rather than defining an opaque interface, the URXE structure internals
65  * are exposed. Since the demuxer is only exposed to other parts of the QUIC
66  * implementation internals, this poses no problem, and has a number of
67  * advantages:
68  *
69  *   - Fields in the URXE can be allocated to support requirements in other
70  *     components, like the QRX, which would otherwise have to allocate extra
71  *     memory corresponding to each URXE.
72  *
73  *   - Other components, like the QRX, can keep the URXE in queues of its own
74  *     when it is not being managed by the demuxer.
75  *
76  * URX Queue Structure
77  * -------------------
78  *
79  * The URXE queue is maintained as a simple doubly-linked list. URXE entries are
80  * moved between different lists in their lifecycle (for example, from a free
81  * list to a pending list and vice versa). The buffer into which datagrams are
82  * received immediately follows this URXE header structure and is part of the
83  * same allocation.
84  */
85
86 /* Maximum number of packets we allow to exist in one datagram. */
87 #define QUIC_MAX_PKT_PER_URXE       (sizeof(uint64_t) * 8)
88
89 struct quic_urxe_st {
90     OSSL_LIST_MEMBER(urxe, QUIC_URXE);
91
92     /*
93      * The URXE data starts after this structure so we don't need a pointer.
94      * data_len stores the current length (i.e., the length of the received
95      * datagram) and alloc_len stores the allocation length. The URXE will be
96      * reallocated if we need a larger allocation than is available, though this
97      * should not be common as we will have a good idea of worst-case MTUs up
98      * front.
99      */
100     size_t          data_len, alloc_len;
101
102     /*
103      * Bitfields per packet. processed indicates the packet has been processed
104      * and must not be processed again, hpr_removed indicates header protection
105      * has already been removed. Used by QRX only; not used by the demuxer.
106      */
107     uint64_t        processed, hpr_removed;
108
109     /*
110      * Address of peer we received the datagram from, and the local interface
111      * address we received it on. If local address support is not enabled, local
112      * is zeroed.
113      */
114     BIO_ADDR        peer, local;
115
116     /*
117      * Time at which datagram was received (or ossl_time_zero()) if a now
118      * function was not provided).
119      */
120     OSSL_TIME       time;
121
122     /*
123      * Used by the QRX to mark whether a datagram has been deferred. Used by the
124      * QRX only; not used by the demuxer.
125      */
126     char            deferred;
127
128     /*
129      * Used by the DEMUX to track if a URXE has been handed out. Used primarily
130      * for debugging purposes.
131      */
132     char            demux_state;
133 };
134
135 /* Accessors for URXE buffer. */
136 static ossl_unused ossl_inline unsigned char *
137 ossl_quic_urxe_data(const QUIC_URXE *e)
138 {
139     return (unsigned char *)&e[1];
140 }
141
142 static ossl_unused ossl_inline unsigned char *
143 ossl_quic_urxe_data_end(const QUIC_URXE *e)
144 {
145     return ossl_quic_urxe_data(e) + e->data_len;
146 }
147
148 /* List structure tracking a queue of URXEs. */
149 DEFINE_LIST_OF(urxe, QUIC_URXE);
150 typedef OSSL_LIST(urxe) QUIC_URXE_LIST;
151
152 /*
153  * List management helpers. These are used by the demuxer but can also be used
154  * by users of the demuxer to manage URXEs.
155  */
156 void ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e);
157 void ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e);
158 void ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e);
159
160 /*
161  * Called when a datagram is received for a given connection ID.
162  *
163  * e is a URXE containing the datagram payload. It is permissible for the callee
164  * to mutate this buffer; once the demuxer calls this callback, it will never
165  * read the buffer again.
166  *
167  * If a DCID was identified for the datagram, dcid is non-NULL; otherwise
168  * it is NULL.
169  *
170  * The callee must arrange for ossl_quic_demux_release_urxe or
171  * ossl_quic_demux_reinject_urxe to be called on the URXE at some point in the
172  * future (this need not be before the callback returns).
173  *
174  * At the time the callback is made, the URXE will not be in any queue,
175  * therefore the callee can use the prev and next fields as it wishes.
176  */
177 typedef void (ossl_quic_demux_cb_fn)(QUIC_URXE *e, void *arg,
178                                      const QUIC_CONN_ID *dcid);
179
180 /*
181  * Creates a new demuxer. The given BIO is used to receive datagrams from the
182  * network using BIO_recvmmsg. short_conn_id_len is the length of destination
183  * connection IDs used in RX'd packets; it must have the same value for all
184  * connections used on a socket. default_urxe_alloc_len is the buffer size to
185  * receive datagrams into; it should be a value large enough to contain any
186  * received datagram according to local MTUs, etc.
187  *
188  * now is an optional function used to determine the time a datagram was
189  * received. now_arg is an opaque argument passed to the function. If now is
190  * NULL, ossl_time_zero() is used as the datagram reception time.
191  */
192 QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio,
193                                 size_t short_conn_id_len,
194                                 OSSL_TIME (*now)(void *arg),
195                                 void *now_arg);
196
197 /*
198  * Destroy a demuxer. All URXEs must have been released back to the demuxer
199  * before calling this. No-op if demux is NULL.
200  */
201 void ossl_quic_demux_free(QUIC_DEMUX *demux);
202
203 /*
204  * Changes the BIO which the demuxer reads from. This also sets the MTU if the
205  * BIO supports querying the MTU.
206  */
207 void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio);
208
209 /*
210  * Changes the MTU in bytes we use to receive datagrams.
211  */
212 int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu);
213
214 /*
215  * Set the default packet handler. This is used for incoming packets which don't
216  * match a registered DCID. This is only needed for servers. If a default packet
217  * handler is not set, a packet which doesn't match a registered DCID is
218  * silently dropped. A default packet handler may be unset by passing NULL.
219  *
220  * The handler is responsible for ensuring that ossl_quic_demux_reinject_urxe or
221  * ossl_quic_demux_release_urxe is called on the passed packet at some point in
222  * the future, which may or may not be before the handler returns.
223  */
224 void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux,
225                                          ossl_quic_demux_cb_fn *cb,
226                                          void *cb_arg);
227
228 /*
229  * Releases a URXE back to the demuxer. No reference must be made to the URXE or
230  * its buffer after calling this function. The URXE must not be in any queue;
231  * that is, its prev and next pointers must be NULL.
232  */
233 void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux,
234                                   QUIC_URXE *e);
235
236 /*
237  * Reinjects a URXE which was issued to a registered DCID callback or the
238  * default packet handler callback back into the pending queue. This is useful
239  * when a packet has been handled by the default packet handler callback such
240  * that a DCID has now been registered and can be dispatched normally by DCID.
241  * Once this has been called, the caller must not touch the URXE anymore and
242  * must not also call ossl_quic_demux_release_urxe().
243  *
244  * The URXE is reinjected at the head of the queue, so it will be reprocessed
245  * immediately.
246  */
247 void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux,
248                                    QUIC_URXE *e);
249
250 /*
251  * Process any unprocessed RX'd datagrams, by calling registered callbacks by
252  * connection ID, reading more datagrams from the BIO if necessary.
253  *
254  * Returns one of the following values:
255  *
256  *     QUIC_DEMUX_PUMP_RES_OK
257  *         At least one incoming datagram was processed.
258  *
259  *     QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL
260  *         No more incoming datagrams are currently available.
261  *         Call again later.
262  *
263  *     QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL
264  *         Either the network read BIO has failed in a non-transient fashion, or
265  *         the QUIC implementation has encountered an internal state, assertion
266  *         or allocation error. The caller should tear down the connection
267  *         similarly to in the case of a protocol violation.
268  *
269  */
270 #define QUIC_DEMUX_PUMP_RES_OK              1
271 #define QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL  (-1)
272 #define QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL  (-2)
273
274 int ossl_quic_demux_pump(QUIC_DEMUX *demux);
275
276 /*
277  * Artificially inject a packet into the demuxer for testing purposes. The
278  * buffer must not exceed the URXE size being used by the demuxer.
279  *
280  * If peer or local are NULL, their respective fields are zeroed in the injected
281  * URXE.
282  *
283  * Returns 1 on success or 0 on failure.
284  */
285 int ossl_quic_demux_inject(QUIC_DEMUX *demux,
286                            const unsigned char *buf,
287                            size_t buf_len,
288                            const BIO_ADDR *peer,
289                            const BIO_ADDR *local);
290
291 /*
292  * Returns 1 if there are any pending URXEs.
293  */
294 int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux);
295
296 # endif
297
298 #endif