xref: /freebsd/crypto/openssl/include/internal/quic_port.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery  * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery  *
4*e7be843bSPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery  * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery  * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery  */
9*e7be843bSPierre Pronchery #ifndef OSSL_QUIC_PORT_H
10*e7be843bSPierre Pronchery # define OSSL_QUIC_PORT_H
11*e7be843bSPierre Pronchery 
12*e7be843bSPierre Pronchery # include <openssl/ssl.h>
13*e7be843bSPierre Pronchery # include "internal/quic_types.h"
14*e7be843bSPierre Pronchery # include "internal/quic_reactor.h"
15*e7be843bSPierre Pronchery # include "internal/quic_demux.h"
16*e7be843bSPierre Pronchery # include "internal/quic_predef.h"
17*e7be843bSPierre Pronchery # include "internal/thread_arch.h"
18*e7be843bSPierre Pronchery 
19*e7be843bSPierre Pronchery # ifndef OPENSSL_NO_QUIC
20*e7be843bSPierre Pronchery 
21*e7be843bSPierre Pronchery /*
22*e7be843bSPierre Pronchery  * QUIC Port
23*e7be843bSPierre Pronchery  * =========
24*e7be843bSPierre Pronchery  *
25*e7be843bSPierre Pronchery  * A QUIC Port (QUIC_PORT) represents a single UDP network socket and contains
26*e7be843bSPierre Pronchery  * zero or more subsidiary QUIC_CHANNEL instances, each of which represents a
27*e7be843bSPierre Pronchery  * single QUIC connection. All QUIC_CHANNEL instances must belong to a
28*e7be843bSPierre Pronchery  * QUIC_PORT.
29*e7be843bSPierre Pronchery  *
30*e7be843bSPierre Pronchery  * A QUIC port is responsible for managing a set of channels which all use the
31*e7be843bSPierre Pronchery  * same UDP socket, and (in future) for automatically creating new channels when
32*e7be843bSPierre Pronchery  * incoming connections are received.
33*e7be843bSPierre Pronchery  *
34*e7be843bSPierre Pronchery  * In order to retain compatibility with QUIC_TSERVER, it also supports a point
35*e7be843bSPierre Pronchery  * of legacy compatibility where a caller can create an incoming (server role)
36*e7be843bSPierre Pronchery  * channel and that channel will be automatically be bound to the next incoming
37*e7be843bSPierre Pronchery  * connection. In the future this will go away once QUIC_TSERVER is removed.
38*e7be843bSPierre Pronchery  *
39*e7be843bSPierre Pronchery  * All QUIC_PORT instances are created by a QUIC_ENGINE.
40*e7be843bSPierre Pronchery  */
41*e7be843bSPierre Pronchery typedef struct quic_port_args_st {
42*e7be843bSPierre Pronchery     /* The engine which the QUIC port is to be a child of. */
43*e7be843bSPierre Pronchery     QUIC_ENGINE     *engine;
44*e7be843bSPierre Pronchery 
45*e7be843bSPierre Pronchery     /*
46*e7be843bSPierre Pronchery      * This callback allows port_new_handshake_layer to pre-create a quic
47*e7be843bSPierre Pronchery      * connection object for the incoming channel
48*e7be843bSPierre Pronchery      * user_ssl_arg is expected to point to a quic listener object
49*e7be843bSPierre Pronchery      */
50*e7be843bSPierre Pronchery     SSL *(*get_conn_user_ssl)(QUIC_CHANNEL *ch, void *arg);
51*e7be843bSPierre Pronchery     void *user_ssl_arg;
52*e7be843bSPierre Pronchery 
53*e7be843bSPierre Pronchery     /*
54*e7be843bSPierre Pronchery      * This SSL_CTX will be used when constructing the handshake layer object
55*e7be843bSPierre Pronchery      * inside newly created channels.
56*e7be843bSPierre Pronchery      */
57*e7be843bSPierre Pronchery     SSL_CTX         *channel_ctx;
58*e7be843bSPierre Pronchery 
59*e7be843bSPierre Pronchery     /*
60*e7be843bSPierre Pronchery      * If 1, this port is to be used for multiple connections, so
61*e7be843bSPierre Pronchery      * non-zero-length CIDs should be used. If 0, this port will only be used
62*e7be843bSPierre Pronchery      * for a single connection, so a zero-length local CID can be used.
63*e7be843bSPierre Pronchery      */
64*e7be843bSPierre Pronchery     int             is_multi_conn;
65*e7be843bSPierre Pronchery 
66*e7be843bSPierre Pronchery     /*
67*e7be843bSPierre Pronchery      * if 1, this port should do server address validation
68*e7be843bSPierre Pronchery      */
69*e7be843bSPierre Pronchery     int             do_addr_validation;
70*e7be843bSPierre Pronchery } QUIC_PORT_ARGS;
71*e7be843bSPierre Pronchery 
72*e7be843bSPierre Pronchery /* Only QUIC_ENGINE should use this function. */
73*e7be843bSPierre Pronchery QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args);
74*e7be843bSPierre Pronchery 
75*e7be843bSPierre Pronchery void ossl_quic_port_free(QUIC_PORT *port);
76*e7be843bSPierre Pronchery 
77*e7be843bSPierre Pronchery /*
78*e7be843bSPierre Pronchery  * Operations
79*e7be843bSPierre Pronchery  * ==========
80*e7be843bSPierre Pronchery  */
81*e7be843bSPierre Pronchery 
82*e7be843bSPierre Pronchery /* Create an outgoing channel using this port. */
83*e7be843bSPierre Pronchery QUIC_CHANNEL *ossl_quic_port_create_outgoing(QUIC_PORT *port, SSL *tls);
84*e7be843bSPierre Pronchery 
85*e7be843bSPierre Pronchery /*
86*e7be843bSPierre Pronchery  * Create an incoming channel using this port.
87*e7be843bSPierre Pronchery  *
88*e7be843bSPierre Pronchery  * TODO(QUIC FUTURE): temporary TSERVER use only - will be removed.
89*e7be843bSPierre Pronchery  */
90*e7be843bSPierre Pronchery QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls);
91*e7be843bSPierre Pronchery 
92*e7be843bSPierre Pronchery /*
93*e7be843bSPierre Pronchery  * Pop an incoming channel from the incoming channel queue. Returns NULL if
94*e7be843bSPierre Pronchery  * there are no pending incoming channels.
95*e7be843bSPierre Pronchery  */
96*e7be843bSPierre Pronchery QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port);
97*e7be843bSPierre Pronchery 
98*e7be843bSPierre Pronchery /* Returns 1 if there is at least one connection incoming. */
99*e7be843bSPierre Pronchery int ossl_quic_port_have_incoming(QUIC_PORT *port);
100*e7be843bSPierre Pronchery 
101*e7be843bSPierre Pronchery /*
102*e7be843bSPierre Pronchery  * Delete any channels which are pending acceptance.
103*e7be843bSPierre Pronchery  */
104*e7be843bSPierre Pronchery void ossl_quic_port_drop_incoming(QUIC_PORT *port);
105*e7be843bSPierre Pronchery 
106*e7be843bSPierre Pronchery /*
107*e7be843bSPierre Pronchery  * Queries and Accessors
108*e7be843bSPierre Pronchery  * =====================
109*e7be843bSPierre Pronchery  */
110*e7be843bSPierre Pronchery 
111*e7be843bSPierre Pronchery /* Gets/sets the underlying network read and write BIO. */
112*e7be843bSPierre Pronchery BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port);
113*e7be843bSPierre Pronchery BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port);
114*e7be843bSPierre Pronchery int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio);
115*e7be843bSPierre Pronchery int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio);
116*e7be843bSPierre Pronchery SSL_CTX *ossl_quic_port_get_channel_ctx(QUIC_PORT *port);
117*e7be843bSPierre Pronchery 
118*e7be843bSPierre Pronchery /*
119*e7be843bSPierre Pronchery  * Re-poll the network BIOs already set to determine if their support for
120*e7be843bSPierre Pronchery  * polling has changed. If force is 0, only check again if the BIOs have been
121*e7be843bSPierre Pronchery  * changed.
122*e7be843bSPierre Pronchery  */
123*e7be843bSPierre Pronchery int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port, int force);
124*e7be843bSPierre Pronchery 
125*e7be843bSPierre Pronchery /* Gets the engine which this port is a child of. */
126*e7be843bSPierre Pronchery QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port);
127*e7be843bSPierre Pronchery 
128*e7be843bSPierre Pronchery /* Gets the reactor which can be used to tick/poll on the port. */
129*e7be843bSPierre Pronchery QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port);
130*e7be843bSPierre Pronchery 
131*e7be843bSPierre Pronchery /* Gets the demuxer belonging to the port. */
132*e7be843bSPierre Pronchery QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port);
133*e7be843bSPierre Pronchery 
134*e7be843bSPierre Pronchery /* Gets the mutex used by the port. */
135*e7be843bSPierre Pronchery CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port);
136*e7be843bSPierre Pronchery 
137*e7be843bSPierre Pronchery /* Gets the current time. */
138*e7be843bSPierre Pronchery OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port);
139*e7be843bSPierre Pronchery 
140*e7be843bSPierre Pronchery int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port);
141*e7be843bSPierre Pronchery int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port);
142*e7be843bSPierre Pronchery 
143*e7be843bSPierre Pronchery /* Returns 1 if the port is running/healthy, 0 if it has failed. */
144*e7be843bSPierre Pronchery int ossl_quic_port_is_running(const QUIC_PORT *port);
145*e7be843bSPierre Pronchery 
146*e7be843bSPierre Pronchery /*
147*e7be843bSPierre Pronchery  * Restores port-level error to the error stack. To be called only if
148*e7be843bSPierre Pronchery  * the port is no longer running.
149*e7be843bSPierre Pronchery  */
150*e7be843bSPierre Pronchery void ossl_quic_port_restore_err_state(const QUIC_PORT *port);
151*e7be843bSPierre Pronchery 
152*e7be843bSPierre Pronchery /* For use by QUIC_ENGINE. You should not need to call this directly. */
153*e7be843bSPierre Pronchery void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *r,
154*e7be843bSPierre Pronchery                             uint32_t flags);
155*e7be843bSPierre Pronchery 
156*e7be843bSPierre Pronchery /* Returns the number of queued incoming channels. */
157*e7be843bSPierre Pronchery size_t ossl_quic_port_get_num_incoming_channels(const QUIC_PORT *port);
158*e7be843bSPierre Pronchery 
159*e7be843bSPierre Pronchery /* Sets if incoming connections should currently be allowed. */
160*e7be843bSPierre Pronchery void ossl_quic_port_set_allow_incoming(QUIC_PORT *port, int allow_incoming);
161*e7be843bSPierre Pronchery 
162*e7be843bSPierre Pronchery /* Returns 1 if we are using addressed mode on the read side. */
163*e7be843bSPierre Pronchery int ossl_quic_port_is_addressed_r(const QUIC_PORT *port);
164*e7be843bSPierre Pronchery 
165*e7be843bSPierre Pronchery /* Returns 1 if we are using addressed mode on the write side. */
166*e7be843bSPierre Pronchery int ossl_quic_port_is_addressed_w(const QUIC_PORT *port);
167*e7be843bSPierre Pronchery 
168*e7be843bSPierre Pronchery /* Returns 1 if we are using addressed mode. */
169*e7be843bSPierre Pronchery int ossl_quic_port_is_addressed(const QUIC_PORT *port);
170*e7be843bSPierre Pronchery 
171*e7be843bSPierre Pronchery /*
172*e7be843bSPierre Pronchery  * Returns the current network BIO epoch. This increments whenever the network
173*e7be843bSPierre Pronchery  * BIO configuration changes.
174*e7be843bSPierre Pronchery  */
175*e7be843bSPierre Pronchery uint64_t ossl_quic_port_get_net_bio_epoch(const QUIC_PORT *port);
176*e7be843bSPierre Pronchery 
177*e7be843bSPierre Pronchery /*
178*e7be843bSPierre Pronchery  * Events
179*e7be843bSPierre Pronchery  * ======
180*e7be843bSPierre Pronchery  */
181*e7be843bSPierre Pronchery 
182*e7be843bSPierre Pronchery /*
183*e7be843bSPierre Pronchery  * Called if a permanent network error occurs. Terminates all channels
184*e7be843bSPierre Pronchery  * immediately. triggering_ch is an optional argument designating
185*e7be843bSPierre Pronchery  * a channel which encountered the network error.
186*e7be843bSPierre Pronchery  */
187*e7be843bSPierre Pronchery void ossl_quic_port_raise_net_error(QUIC_PORT *port,
188*e7be843bSPierre Pronchery                                     QUIC_CHANNEL *triggering_ch);
189*e7be843bSPierre Pronchery 
190*e7be843bSPierre Pronchery # endif
191*e7be843bSPierre Pronchery 
192*e7be843bSPierre Pronchery #endif
193