/src/openssl/ssl/quic/quic_channel.c
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  |  | #include <openssl/rand.h>  | 
11  |  | #include <openssl/err.h>  | 
12  |  | #include "internal/ssl_unwrap.h"  | 
13  |  | #include "internal/quic_channel.h"  | 
14  |  | #include "internal/quic_error.h"  | 
15  |  | #include "internal/quic_rx_depack.h"  | 
16  |  | #include "internal/quic_lcidm.h"  | 
17  |  | #include "internal/quic_srtm.h"  | 
18  |  | #include "internal/qlog_event_helpers.h"  | 
19  |  | #include "internal/quic_txp.h"  | 
20  |  | #include "internal/quic_tls.h"  | 
21  |  | #include "internal/quic_ssl.h"  | 
22  |  | #include "../ssl_local.h"  | 
23  |  | #include "quic_channel_local.h"  | 
24  |  | #include "quic_port_local.h"  | 
25  |  | #include "quic_engine_local.h"  | 
26  |  |  | 
27  | 0  | #define INIT_CRYPTO_RECV_BUF_LEN    16384  | 
28  | 0  | #define INIT_CRYPTO_SEND_BUF_LEN    16384  | 
29  | 0  | #define INIT_APP_BUF_LEN             8192  | 
30  |  |  | 
31  |  | /*  | 
32  |  |  * Interval before we force a PING to ensure NATs don't timeout. This is based  | 
33  |  |  * on the lowest commonly seen value of 30 seconds as cited in RFC 9000 s.  | 
34  |  |  * 10.1.2.  | 
35  |  |  */  | 
36  | 0  | #define MAX_NAT_INTERVAL (ossl_ms2time(25000))  | 
37  |  |  | 
38  |  | /*  | 
39  |  |  * Our maximum ACK delay on the TX side. This is up to us to choose. Note that  | 
40  |  |  * this could differ from QUIC_DEFAULT_MAX_DELAY in future as that is a protocol  | 
41  |  |  * value which determines the value of the maximum ACK delay if the  | 
42  |  |  * max_ack_delay transport parameter is not set.  | 
43  |  |  */  | 
44  | 0  | #define DEFAULT_MAX_ACK_DELAY   QUIC_DEFAULT_MAX_ACK_DELAY  | 
45  |  |  | 
46  | 0  | DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL); Unexecuted instantiation: quic_channel.c:ossl_list_ch_insert_tail Unexecuted instantiation: quic_channel.c:ossl_list_ch_remove  | 
47  |  |  | 
48  |  | static void ch_save_err_state(QUIC_CHANNEL *ch);  | 
49  |  | static int ch_rx(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads);  | 
50  |  | static int ch_tx(QUIC_CHANNEL *ch, int *notify_other_threads);  | 
51  |  | static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads);  | 
52  |  | static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only);  | 
53  |  | static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch);  | 
54  |  | static int ch_retry(QUIC_CHANNEL *ch,  | 
55  |  |                     const unsigned char *retry_token,  | 
56  |  |                     size_t retry_token_len,  | 
57  |  |                     const QUIC_CONN_ID *retry_scid,  | 
58  |  |                     int drop_later_pn);  | 
59  |  | static int ch_restart(QUIC_CHANNEL *ch);  | 
60  |  |  | 
61  |  | static void ch_cleanup(QUIC_CHANNEL *ch);  | 
62  |  | static int ch_generate_transport_params(QUIC_CHANNEL *ch);  | 
63  |  | static int ch_on_transport_params(const unsigned char *params,  | 
64  |  |                                   size_t params_len,  | 
65  |  |                                   void *arg);  | 
66  |  | static int ch_on_handshake_alert(void *arg, unsigned char alert_code);  | 
67  |  | static int ch_on_handshake_complete(void *arg);  | 
68  |  | static int ch_on_handshake_yield_secret(uint32_t prot_level, int direction,  | 
69  |  |                                         uint32_t suite_id, EVP_MD *md,  | 
70  |  |                                         const unsigned char *secret,  | 
71  |  |                                         size_t secret_len,  | 
72  |  |                                         void *arg);  | 
73  |  | static int ch_on_crypto_recv_record(const unsigned char **buf,  | 
74  |  |                                     size_t *bytes_read, void *arg);  | 
75  |  | static int ch_on_crypto_release_record(size_t bytes_read, void *arg);  | 
76  |  | static int crypto_ensure_empty(QUIC_RSTREAM *rstream);  | 
77  |  | static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len,  | 
78  |  |                              size_t *consumed, void *arg);  | 
79  |  | static OSSL_TIME get_time(void *arg);  | 
80  |  | static uint64_t get_stream_limit(int uni, void *arg);  | 
81  |  | static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg);  | 
82  |  | static void rxku_detected(QUIC_PN pn, void *arg);  | 
83  |  | static int ch_retry(QUIC_CHANNEL *ch,  | 
84  |  |                     const unsigned char *retry_token,  | 
85  |  |                     size_t retry_token_len,  | 
86  |  |                     const QUIC_CONN_ID *retry_scid,  | 
87  |  |                     int drop_later_pn);  | 
88  |  | static void ch_update_idle(QUIC_CHANNEL *ch);  | 
89  |  | static int ch_discard_el(QUIC_CHANNEL *ch,  | 
90  |  |                          uint32_t enc_level);  | 
91  |  | static void ch_on_idle_timeout(QUIC_CHANNEL *ch);  | 
92  |  | static void ch_update_idle(QUIC_CHANNEL *ch);  | 
93  |  | static void ch_update_ping_deadline(QUIC_CHANNEL *ch);  | 
94  |  | static void ch_on_terminating_timeout(QUIC_CHANNEL *ch);  | 
95  |  | static void ch_start_terminating(QUIC_CHANNEL *ch,  | 
96  |  |                                  const QUIC_TERMINATE_CAUSE *tcause,  | 
97  |  |                                  int force_immediate);  | 
98  |  | static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space,  | 
99  |  |                              void *arg);  | 
100  |  | static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt);  | 
101  |  | static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch);  | 
102  |  | static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state);  | 
103  |  |  | 
104  |  | DEFINE_LHASH_OF_EX(QUIC_SRT_ELEM);  | 
105  |  |  | 
106  |  | QUIC_NEEDS_LOCK  | 
107  |  | static QLOG *ch_get_qlog(QUIC_CHANNEL *ch)  | 
108  | 0  | { | 
109  | 0  | #ifndef OPENSSL_NO_QLOG  | 
110  | 0  |     QLOG_TRACE_INFO qti = {0}; | 
111  |  | 
  | 
112  | 0  |     if (ch->qlog != NULL)  | 
113  | 0  |         return ch->qlog;  | 
114  |  |  | 
115  | 0  |     if (!ch->use_qlog)  | 
116  | 0  |         return NULL;  | 
117  |  |  | 
118  | 0  |     if (ch->is_server && ch->init_dcid.id_len == 0)  | 
119  | 0  |         return NULL;  | 
120  |  |  | 
121  | 0  |     qti.odcid       = ch->init_dcid;  | 
122  | 0  |     qti.title       = ch->qlog_title;  | 
123  | 0  |     qti.description = NULL;  | 
124  | 0  |     qti.group_id    = NULL;  | 
125  | 0  |     qti.is_server   = ch->is_server;  | 
126  | 0  |     qti.now_cb      = get_time;  | 
127  | 0  |     qti.now_cb_arg  = ch;  | 
128  | 0  |     if ((ch->qlog = ossl_qlog_new_from_env(&qti)) == NULL) { | 
129  | 0  |         ch->use_qlog = 0; /* don't try again */  | 
130  | 0  |         return NULL;  | 
131  | 0  |     }  | 
132  |  |  | 
133  | 0  |     return ch->qlog;  | 
134  |  | #else  | 
135  |  |     return NULL;  | 
136  |  | #endif  | 
137  | 0  | }  | 
138  |  |  | 
139  |  | QUIC_NEEDS_LOCK  | 
140  |  | static QLOG *ch_get_qlog_cb(void *arg)  | 
141  | 0  | { | 
142  | 0  |     QUIC_CHANNEL *ch = arg;  | 
143  |  | 
  | 
144  | 0  |     return ch_get_qlog(ch);  | 
145  | 0  | }  | 
146  |  |  | 
147  |  | /*  | 
148  |  |  * QUIC Channel Initialization and Teardown  | 
149  |  |  * ========================================  | 
150  |  |  */  | 
151  | 0  | #define DEFAULT_INIT_CONN_RXFC_WND      (768 * 1024)  | 
152  | 0  | #define DEFAULT_CONN_RXFC_MAX_WND_MUL   20  | 
153  |  |  | 
154  | 0  | #define DEFAULT_INIT_STREAM_RXFC_WND    (512 * 1024)  | 
155  | 0  | #define DEFAULT_STREAM_RXFC_MAX_WND_MUL 12  | 
156  |  |  | 
157  | 0  | #define DEFAULT_INIT_CONN_MAX_STREAMS           100  | 
158  |  |  | 
159  |  | static int ch_init(QUIC_CHANNEL *ch)  | 
160  | 0  | { | 
161  | 0  |     OSSL_QUIC_TX_PACKETISER_ARGS txp_args = {0}; | 
162  | 0  |     OSSL_QTX_ARGS qtx_args = {0}; | 
163  | 0  |     OSSL_QRX_ARGS qrx_args = {0}; | 
164  | 0  |     QUIC_TLS_ARGS tls_args = {0}; | 
165  | 0  |     uint32_t pn_space;  | 
166  | 0  |     size_t rx_short_dcid_len;  | 
167  | 0  |     size_t tx_init_dcid_len;  | 
168  |  | 
  | 
169  | 0  |     if (ch->port == NULL || ch->lcidm == NULL || ch->srtm == NULL)  | 
170  | 0  |         goto err;  | 
171  |  |  | 
172  | 0  |     rx_short_dcid_len = ossl_quic_port_get_rx_short_dcid_len(ch->port);  | 
173  | 0  |     tx_init_dcid_len = ossl_quic_port_get_tx_init_dcid_len(ch->port);  | 
174  |  |  | 
175  |  |     /* For clients, generate our initial DCID. */  | 
176  | 0  |     if (!ch->is_server  | 
177  | 0  |         && !ossl_quic_gen_rand_conn_id(ch->port->engine->libctx, tx_init_dcid_len,  | 
178  | 0  |                                        &ch->init_dcid))  | 
179  | 0  |         goto err;  | 
180  |  |  | 
181  |  |     /* We plug in a network write BIO to the QTX later when we get one. */  | 
182  | 0  |     qtx_args.libctx             = ch->port->engine->libctx;  | 
183  | 0  |     qtx_args.get_qlog_cb        = ch_get_qlog_cb;  | 
184  | 0  |     qtx_args.get_qlog_cb_arg    = ch;  | 
185  | 0  |     qtx_args.mdpl               = QUIC_MIN_INITIAL_DGRAM_LEN;  | 
186  | 0  |     ch->rx_max_udp_payload_size = qtx_args.mdpl;  | 
187  |  | 
  | 
188  | 0  |     ch->ping_deadline = ossl_time_infinite();  | 
189  |  | 
  | 
190  | 0  |     ch->qtx = ossl_qtx_new(&qtx_args);  | 
191  | 0  |     if (ch->qtx == NULL)  | 
192  | 0  |         goto err;  | 
193  |  |  | 
194  | 0  |     ch->txpim = ossl_quic_txpim_new();  | 
195  | 0  |     if (ch->txpim == NULL)  | 
196  | 0  |         goto err;  | 
197  |  |  | 
198  | 0  |     ch->cfq = ossl_quic_cfq_new();  | 
199  | 0  |     if (ch->cfq == NULL)  | 
200  | 0  |         goto err;  | 
201  |  |  | 
202  | 0  |     if (!ossl_quic_txfc_init(&ch->conn_txfc, NULL))  | 
203  | 0  |         goto err;  | 
204  |  |  | 
205  |  |     /*  | 
206  |  |      * Note: The TP we transmit governs what the peer can transmit and thus  | 
207  |  |      * applies to the RXFC.  | 
208  |  |      */  | 
209  | 0  |     ch->tx_init_max_stream_data_bidi_local  = DEFAULT_INIT_STREAM_RXFC_WND;  | 
210  | 0  |     ch->tx_init_max_stream_data_bidi_remote = DEFAULT_INIT_STREAM_RXFC_WND;  | 
211  | 0  |     ch->tx_init_max_stream_data_uni         = DEFAULT_INIT_STREAM_RXFC_WND;  | 
212  |  | 
  | 
213  | 0  |     if (!ossl_quic_rxfc_init(&ch->conn_rxfc, NULL,  | 
214  | 0  |                              DEFAULT_INIT_CONN_RXFC_WND,  | 
215  | 0  |                              DEFAULT_CONN_RXFC_MAX_WND_MUL *  | 
216  | 0  |                              DEFAULT_INIT_CONN_RXFC_WND,  | 
217  | 0  |                              get_time, ch))  | 
218  | 0  |         goto err;  | 
219  |  |  | 
220  | 0  |     for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space)  | 
221  | 0  |         if (!ossl_quic_rxfc_init_standalone(&ch->crypto_rxfc[pn_space],  | 
222  | 0  |                                             INIT_CRYPTO_RECV_BUF_LEN,  | 
223  | 0  |                                             get_time, ch))  | 
224  | 0  |             goto err;  | 
225  |  |  | 
226  | 0  |     if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_bidi_rxfc,  | 
227  | 0  |                                         DEFAULT_INIT_CONN_MAX_STREAMS,  | 
228  | 0  |                                         get_time, ch))  | 
229  | 0  |         goto err;  | 
230  |  |  | 
231  | 0  |     if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_uni_rxfc,  | 
232  | 0  |                                         DEFAULT_INIT_CONN_MAX_STREAMS,  | 
233  | 0  |                                         get_time, ch))  | 
234  | 0  |         goto err;  | 
235  |  |  | 
236  | 0  |     if (!ossl_statm_init(&ch->statm))  | 
237  | 0  |         goto err;  | 
238  |  |  | 
239  | 0  |     ch->have_statm = 1;  | 
240  | 0  |     ch->cc_method = &ossl_cc_newreno_method;  | 
241  | 0  |     if ((ch->cc_data = ch->cc_method->new(get_time, ch)) == NULL)  | 
242  | 0  |         goto err;  | 
243  |  |  | 
244  | 0  |     if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm,  | 
245  | 0  |                                   ch->cc_method, ch->cc_data,  | 
246  | 0  |                                   ch->is_server)) == NULL)  | 
247  | 0  |         goto err;  | 
248  |  |  | 
249  | 0  |     if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch,  | 
250  | 0  |                                    &ch->max_streams_bidi_rxfc,  | 
251  | 0  |                                    &ch->max_streams_uni_rxfc,  | 
252  | 0  |                                    ch))  | 
253  | 0  |         goto err;  | 
254  |  |  | 
255  | 0  |     ch->have_qsm = 1;  | 
256  |  | 
  | 
257  | 0  |     if (!ch->is_server  | 
258  | 0  |         && !ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &ch->init_scid))  | 
259  | 0  |         goto err;  | 
260  |  |  | 
261  | 0  |     txp_args.cur_scid               = ch->init_scid;  | 
262  | 0  |     txp_args.cur_dcid               = ch->init_dcid;  | 
263  | 0  |     txp_args.ack_delay_exponent     = 3;  | 
264  | 0  |     txp_args.qtx                    = ch->qtx;  | 
265  | 0  |     txp_args.txpim                  = ch->txpim;  | 
266  | 0  |     txp_args.cfq                    = ch->cfq;  | 
267  | 0  |     txp_args.ackm                   = ch->ackm;  | 
268  | 0  |     txp_args.qsm                    = &ch->qsm;  | 
269  | 0  |     txp_args.conn_txfc              = &ch->conn_txfc;  | 
270  | 0  |     txp_args.conn_rxfc              = &ch->conn_rxfc;  | 
271  | 0  |     txp_args.max_streams_bidi_rxfc  = &ch->max_streams_bidi_rxfc;  | 
272  | 0  |     txp_args.max_streams_uni_rxfc   = &ch->max_streams_uni_rxfc;  | 
273  | 0  |     txp_args.cc_method              = ch->cc_method;  | 
274  | 0  |     txp_args.cc_data                = ch->cc_data;  | 
275  | 0  |     txp_args.now                    = get_time;  | 
276  | 0  |     txp_args.now_arg                = ch;  | 
277  | 0  |     txp_args.get_qlog_cb            = ch_get_qlog_cb;  | 
278  | 0  |     txp_args.get_qlog_cb_arg        = ch;  | 
279  | 0  |     txp_args.protocol_version       = QUIC_VERSION_1;  | 
280  |  | 
  | 
281  | 0  |     for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { | 
282  | 0  |         ch->crypto_send[pn_space] = ossl_quic_sstream_new(INIT_CRYPTO_SEND_BUF_LEN);  | 
283  | 0  |         if (ch->crypto_send[pn_space] == NULL)  | 
284  | 0  |             goto err;  | 
285  |  |  | 
286  | 0  |         txp_args.crypto[pn_space] = ch->crypto_send[pn_space];  | 
287  | 0  |     }  | 
288  |  |  | 
289  | 0  |     ch->txp = ossl_quic_tx_packetiser_new(&txp_args);  | 
290  | 0  |     if (ch->txp == NULL)  | 
291  | 0  |         goto err;  | 
292  |  |  | 
293  |  |     /* clients have no amplification limit, so are considered always valid */  | 
294  | 0  |     if (!ch->is_server)  | 
295  | 0  |         ossl_quic_tx_packetiser_set_validated(ch->txp);  | 
296  |  | 
  | 
297  | 0  |     ossl_quic_tx_packetiser_set_ack_tx_cb(ch->txp, ch_on_txp_ack_tx, ch);  | 
298  |  |  | 
299  |  |     /*  | 
300  |  |      * qrx does not exist yet, then we must be dealing with client channel  | 
301  |  |      * (QUIC connection initiator).  | 
302  |  |      * If qrx exists already, then we are dealing with server channel which  | 
303  |  |      * qrx gets created by port_default_packet_handler() before  | 
304  |  |      * port_default_packet_handler() accepts connection and creates channel  | 
305  |  |      * for it.  | 
306  |  |      * The exception here is tserver which always creates channel,  | 
307  |  |      * before the first packet is ever seen.  | 
308  |  |      */  | 
309  | 0  |     if (ch->qrx == NULL && ch->is_tserver_ch == 0) { | 
310  |  |         /* we are regular client, create channel */  | 
311  | 0  |         qrx_args.libctx             = ch->port->engine->libctx;  | 
312  | 0  |         qrx_args.demux              = ch->port->demux;  | 
313  | 0  |         qrx_args.short_conn_id_len  = rx_short_dcid_len;  | 
314  | 0  |         qrx_args.max_deferred       = 32;  | 
315  |  | 
  | 
316  | 0  |         if ((ch->qrx = ossl_qrx_new(&qrx_args)) == NULL)  | 
317  | 0  |             goto err;  | 
318  | 0  |     }  | 
319  |  |  | 
320  | 0  |     if (ch->qrx != NULL) { | 
321  |  |         /*  | 
322  |  |          * callbacks for channels associated with tserver's port  | 
323  |  |          * are set up later when we call ossl_quic_channel_bind_qrx()  | 
324  |  |          * in port_default_packet_handler()  | 
325  |  |          */  | 
326  | 0  |         if (!ossl_qrx_set_late_validation_cb(ch->qrx,  | 
327  | 0  |                                              rx_late_validate,  | 
328  | 0  |                                              ch))  | 
329  | 0  |             goto err;  | 
330  |  |  | 
331  | 0  |         if (!ossl_qrx_set_key_update_cb(ch->qrx,  | 
332  | 0  |                                         rxku_detected,  | 
333  | 0  |                                         ch))  | 
334  | 0  |             goto err;  | 
335  | 0  |     }  | 
336  |  |  | 
337  |  |  | 
338  | 0  |     for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { | 
339  | 0  |         ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, 0);  | 
340  | 0  |         if (ch->crypto_recv[pn_space] == NULL)  | 
341  | 0  |             goto err;  | 
342  | 0  |     }  | 
343  |  |  | 
344  |  |     /* Plug in the TLS handshake layer. */  | 
345  | 0  |     tls_args.s                          = ch->tls;  | 
346  | 0  |     tls_args.crypto_send_cb             = ch_on_crypto_send;  | 
347  | 0  |     tls_args.crypto_send_cb_arg         = ch;  | 
348  | 0  |     tls_args.crypto_recv_rcd_cb         = ch_on_crypto_recv_record;  | 
349  | 0  |     tls_args.crypto_recv_rcd_cb_arg     = ch;  | 
350  | 0  |     tls_args.crypto_release_rcd_cb      = ch_on_crypto_release_record;  | 
351  | 0  |     tls_args.crypto_release_rcd_cb_arg  = ch;  | 
352  | 0  |     tls_args.yield_secret_cb            = ch_on_handshake_yield_secret;  | 
353  | 0  |     tls_args.yield_secret_cb_arg        = ch;  | 
354  | 0  |     tls_args.got_transport_params_cb    = ch_on_transport_params;  | 
355  | 0  |     tls_args.got_transport_params_cb_arg= ch;  | 
356  | 0  |     tls_args.handshake_complete_cb      = ch_on_handshake_complete;  | 
357  | 0  |     tls_args.handshake_complete_cb_arg  = ch;  | 
358  | 0  |     tls_args.alert_cb                   = ch_on_handshake_alert;  | 
359  | 0  |     tls_args.alert_cb_arg               = ch;  | 
360  | 0  |     tls_args.is_server                  = ch->is_server;  | 
361  | 0  |     tls_args.ossl_quic                  = 1;  | 
362  |  | 
  | 
363  | 0  |     if ((ch->qtls = ossl_quic_tls_new(&tls_args)) == NULL)  | 
364  | 0  |         goto err;  | 
365  |  |  | 
366  | 0  |     ch->tx_max_ack_delay        = DEFAULT_MAX_ACK_DELAY;  | 
367  | 0  |     ch->rx_max_ack_delay        = QUIC_DEFAULT_MAX_ACK_DELAY;  | 
368  | 0  |     ch->rx_ack_delay_exp        = QUIC_DEFAULT_ACK_DELAY_EXP;  | 
369  | 0  |     ch->rx_active_conn_id_limit = QUIC_MIN_ACTIVE_CONN_ID_LIMIT;  | 
370  | 0  |     ch->tx_enc_level            = QUIC_ENC_LEVEL_INITIAL;  | 
371  | 0  |     ch->rx_enc_level            = QUIC_ENC_LEVEL_INITIAL;  | 
372  | 0  |     ch->txku_threshold_override = UINT64_MAX;  | 
373  |  | 
  | 
374  | 0  |     ch->max_idle_timeout_local_req  = QUIC_DEFAULT_IDLE_TIMEOUT;  | 
375  | 0  |     ch->max_idle_timeout_remote_req = 0;  | 
376  | 0  |     ch->max_idle_timeout            = ch->max_idle_timeout_local_req;  | 
377  |  | 
  | 
378  | 0  |     ossl_ackm_set_tx_max_ack_delay(ch->ackm, ossl_ms2time(ch->tx_max_ack_delay));  | 
379  | 0  |     ossl_ackm_set_rx_max_ack_delay(ch->ackm, ossl_ms2time(ch->rx_max_ack_delay));  | 
380  |  | 
  | 
381  | 0  |     ch_update_idle(ch);  | 
382  | 0  |     ossl_list_ch_insert_tail(&ch->port->channel_list, ch);  | 
383  | 0  |     ch->on_port_list = 1;  | 
384  | 0  |     return 1;  | 
385  |  |  | 
386  | 0  | err:  | 
387  | 0  |     ch_cleanup(ch);  | 
388  | 0  |     return 0;  | 
389  | 0  | }  | 
390  |  |  | 
391  |  | static void ch_cleanup(QUIC_CHANNEL *ch)  | 
392  | 0  | { | 
393  | 0  |     uint32_t pn_space;  | 
394  |  | 
  | 
395  | 0  |     if (ch->ackm != NULL)  | 
396  | 0  |         for (pn_space = QUIC_PN_SPACE_INITIAL;  | 
397  | 0  |              pn_space < QUIC_PN_SPACE_NUM;  | 
398  | 0  |              ++pn_space)  | 
399  | 0  |             ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space);  | 
400  |  | 
  | 
401  | 0  |     if (ch->lcidm != NULL)  | 
402  | 0  |         ossl_quic_lcidm_cull(ch->lcidm, ch);  | 
403  |  | 
  | 
404  | 0  |     if (ch->srtm != NULL)  | 
405  | 0  |         ossl_quic_srtm_cull(ch->srtm, ch);  | 
406  |  | 
  | 
407  | 0  |     ossl_quic_tx_packetiser_free(ch->txp);  | 
408  | 0  |     ossl_quic_txpim_free(ch->txpim);  | 
409  | 0  |     ossl_quic_cfq_free(ch->cfq);  | 
410  | 0  |     ossl_qtx_free(ch->qtx);  | 
411  | 0  |     if (ch->cc_data != NULL)  | 
412  | 0  |         ch->cc_method->free(ch->cc_data);  | 
413  | 0  |     if (ch->have_statm)  | 
414  | 0  |         ossl_statm_destroy(&ch->statm);  | 
415  | 0  |     ossl_ackm_free(ch->ackm);  | 
416  |  | 
  | 
417  | 0  |     if (ch->have_qsm)  | 
418  | 0  |         ossl_quic_stream_map_cleanup(&ch->qsm);  | 
419  |  | 
  | 
420  | 0  |     for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) { | 
421  | 0  |         ossl_quic_sstream_free(ch->crypto_send[pn_space]);  | 
422  | 0  |         ossl_quic_rstream_free(ch->crypto_recv[pn_space]);  | 
423  | 0  |     }  | 
424  |  | 
  | 
425  | 0  |     ossl_qrx_pkt_release(ch->qrx_pkt);  | 
426  | 0  |     ch->qrx_pkt = NULL;  | 
427  |  | 
  | 
428  | 0  |     ossl_quic_tls_free(ch->qtls);  | 
429  | 0  |     ossl_qrx_free(ch->qrx);  | 
430  | 0  |     OPENSSL_free(ch->local_transport_params);  | 
431  | 0  |     OPENSSL_free((char *)ch->terminate_cause.reason);  | 
432  | 0  |     OSSL_ERR_STATE_free(ch->err_state);  | 
433  | 0  |     OPENSSL_free(ch->ack_range_scratch);  | 
434  | 0  |     OPENSSL_free(ch->pending_new_token);  | 
435  |  | 
  | 
436  | 0  |     if (ch->on_port_list) { | 
437  | 0  |         ossl_list_ch_remove(&ch->port->channel_list, ch);  | 
438  | 0  |         ch->on_port_list = 0;  | 
439  | 0  |     }  | 
440  |  | 
  | 
441  | 0  | #ifndef OPENSSL_NO_QLOG  | 
442  | 0  |     if (ch->qlog != NULL)  | 
443  | 0  |         ossl_qlog_flush(ch->qlog); /* best effort */  | 
444  |  | 
  | 
445  | 0  |     OPENSSL_free(ch->qlog_title);  | 
446  | 0  |     ossl_qlog_free(ch->qlog);  | 
447  | 0  | #endif  | 
448  | 0  | }  | 
449  |  |  | 
450  |  | int ossl_quic_channel_init(QUIC_CHANNEL *ch)  | 
451  | 0  | { | 
452  | 0  |     return ch_init(ch);  | 
453  | 0  | }  | 
454  |  |  | 
455  |  | void ossl_quic_channel_bind_qrx(QUIC_CHANNEL *tserver_ch, OSSL_QRX *qrx)  | 
456  | 0  | { | 
457  | 0  |     if (tserver_ch->qrx == NULL && tserver_ch->is_tserver_ch == 1) { | 
458  | 0  |         tserver_ch->qrx = qrx;  | 
459  | 0  |         ossl_qrx_set_late_validation_cb(tserver_ch->qrx, rx_late_validate,  | 
460  | 0  |                                         tserver_ch);  | 
461  | 0  |         ossl_qrx_set_key_update_cb(tserver_ch->qrx, rxku_detected,  | 
462  | 0  |                                    tserver_ch);  | 
463  | 0  |     }  | 
464  | 0  | }  | 
465  |  |  | 
466  |  | QUIC_CHANNEL *ossl_quic_channel_alloc(const QUIC_CHANNEL_ARGS *args)  | 
467  | 0  | { | 
468  | 0  |     QUIC_CHANNEL *ch = NULL;  | 
469  |  | 
  | 
470  | 0  |     if ((ch = OPENSSL_zalloc(sizeof(*ch))) == NULL)  | 
471  | 0  |         return NULL;  | 
472  |  |  | 
473  | 0  |     ch->port           = args->port;  | 
474  | 0  |     ch->is_server      = args->is_server;  | 
475  | 0  |     ch->tls            = args->tls;  | 
476  | 0  |     ch->lcidm          = args->lcidm;  | 
477  | 0  |     ch->srtm           = args->srtm;  | 
478  | 0  |     ch->qrx            = args->qrx;  | 
479  | 0  |     ch->is_tserver_ch  = args->is_tserver_ch;  | 
480  | 0  | #ifndef OPENSSL_NO_QLOG  | 
481  | 0  |     ch->use_qlog    = args->use_qlog;  | 
482  |  | 
  | 
483  | 0  |     if (ch->use_qlog && args->qlog_title != NULL) { | 
484  | 0  |         if ((ch->qlog_title = OPENSSL_strdup(args->qlog_title)) == NULL) { | 
485  | 0  |             OPENSSL_free(ch);  | 
486  | 0  |             return NULL;  | 
487  | 0  |         }  | 
488  | 0  |     }  | 
489  | 0  | #endif  | 
490  |  |  | 
491  | 0  |     return ch;  | 
492  | 0  | }  | 
493  |  |  | 
494  |  | void ossl_quic_channel_free(QUIC_CHANNEL *ch)  | 
495  | 0  | { | 
496  | 0  |     if (ch == NULL)  | 
497  | 0  |         return;  | 
498  |  |  | 
499  | 0  |     ch_cleanup(ch);  | 
500  | 0  |     OPENSSL_free(ch);  | 
501  | 0  | }  | 
502  |  |  | 
503  |  | /* Set mutator callbacks for test framework support */  | 
504  |  | int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,  | 
505  |  |                                   ossl_mutate_packet_cb mutatecb,  | 
506  |  |                                   ossl_finish_mutate_cb finishmutatecb,  | 
507  |  |                                   void *mutatearg)  | 
508  | 0  | { | 
509  | 0  |     if (ch->qtx == NULL)  | 
510  | 0  |         return 0;  | 
511  |  |  | 
512  | 0  |     ossl_qtx_set_mutator(ch->qtx, mutatecb, finishmutatecb, mutatearg);  | 
513  | 0  |     return 1;  | 
514  | 0  | }  | 
515  |  |  | 
516  |  | int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr)  | 
517  | 0  | { | 
518  | 0  |     if (!ch->addressed_mode)  | 
519  | 0  |         return 0;  | 
520  |  |  | 
521  | 0  |     return BIO_ADDR_copy(peer_addr, &ch->cur_peer_addr);  | 
522  | 0  | }  | 
523  |  |  | 
524  |  | int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr)  | 
525  | 0  | { | 
526  | 0  |     if (ch->state != QUIC_CHANNEL_STATE_IDLE)  | 
527  | 0  |         return 0;  | 
528  |  |  | 
529  | 0  |     if (peer_addr == NULL || BIO_ADDR_family(peer_addr) == AF_UNSPEC) { | 
530  | 0  |         BIO_ADDR_clear(&ch->cur_peer_addr);  | 
531  | 0  |         ch->addressed_mode = 0;  | 
532  | 0  |         return 1;  | 
533  | 0  |     }  | 
534  |  |  | 
535  | 0  |     if (!BIO_ADDR_copy(&ch->cur_peer_addr, peer_addr)) { | 
536  | 0  |         ch->addressed_mode = 0;  | 
537  | 0  |         return 0;  | 
538  | 0  |     }  | 
539  | 0  |     ch->addressed_mode = 1;  | 
540  |  | 
  | 
541  | 0  |     return 1;  | 
542  | 0  | }  | 
543  |  |  | 
544  |  | QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch)  | 
545  | 0  | { | 
546  | 0  |     return ossl_quic_port_get0_reactor(ch->port);  | 
547  | 0  | }  | 
548  |  |  | 
549  |  | QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch)  | 
550  | 0  | { | 
551  | 0  |     return &ch->qsm;  | 
552  | 0  | }  | 
553  |  |  | 
554  |  | OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch)  | 
555  | 0  | { | 
556  | 0  |     return &ch->statm;  | 
557  | 0  | }  | 
558  |  |  | 
559  |  | SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch)  | 
560  | 0  | { | 
561  | 0  |     return ch->tls;  | 
562  | 0  | }  | 
563  |  |  | 
564  |  | static void free_buf_mem(unsigned char *buf, size_t buf_len, void *arg)  | 
565  | 0  | { | 
566  | 0  |     BUF_MEM_free((BUF_MEM *)arg);  | 
567  | 0  | }  | 
568  |  |  | 
569  |  | int ossl_quic_channel_schedule_new_token(QUIC_CHANNEL *ch,  | 
570  |  |                                          const unsigned char *token,  | 
571  |  |                                          size_t token_len)  | 
572  | 0  | { | 
573  | 0  |     int rc = 0;  | 
574  | 0  |     QUIC_CFQ_ITEM *cfq_item;  | 
575  | 0  |     WPACKET wpkt;  | 
576  | 0  |     BUF_MEM *buf_mem = NULL;  | 
577  | 0  |     size_t l = 0;  | 
578  |  | 
  | 
579  | 0  |     buf_mem = BUF_MEM_new();  | 
580  | 0  |     if (buf_mem == NULL)  | 
581  | 0  |         goto err;  | 
582  |  |  | 
583  | 0  |     if (!WPACKET_init(&wpkt, buf_mem))  | 
584  | 0  |         goto err;  | 
585  |  |  | 
586  | 0  |     if (!ossl_quic_wire_encode_frame_new_token(&wpkt, token,  | 
587  | 0  |                                                token_len)) { | 
588  | 0  |         WPACKET_cleanup(&wpkt);  | 
589  | 0  |         goto err;  | 
590  | 0  |     }  | 
591  |  |  | 
592  | 0  |     WPACKET_finish(&wpkt);  | 
593  |  | 
  | 
594  | 0  |     if (!WPACKET_get_total_written(&wpkt, &l))  | 
595  | 0  |         goto err;  | 
596  |  |  | 
597  | 0  |     cfq_item = ossl_quic_cfq_add_frame(ch->cfq, 1,  | 
598  | 0  |                                        QUIC_PN_SPACE_APP,  | 
599  | 0  |                                        OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, 0,  | 
600  | 0  |                                        (unsigned char *)buf_mem->data, l,  | 
601  | 0  |                                        free_buf_mem,  | 
602  | 0  |                                        buf_mem);  | 
603  | 0  |     if (cfq_item == NULL)  | 
604  | 0  |         goto err;  | 
605  |  |  | 
606  | 0  |     rc = 1;  | 
607  | 0  | err:  | 
608  | 0  |     if (!rc)  | 
609  | 0  |         BUF_MEM_free(buf_mem);  | 
610  | 0  |     return rc;  | 
611  | 0  | }  | 
612  |  |  | 
613  |  | size_t ossl_quic_channel_get_short_header_conn_id_len(QUIC_CHANNEL *ch)  | 
614  | 0  | { | 
615  | 0  |     return ossl_quic_port_get_rx_short_dcid_len(ch->port);  | 
616  | 0  | }  | 
617  |  |  | 
618  |  | QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch,  | 
619  |  |                                                 uint64_t stream_id)  | 
620  | 0  | { | 
621  | 0  |     return ossl_quic_stream_map_get_by_id(&ch->qsm, stream_id);  | 
622  | 0  | }  | 
623  |  |  | 
624  |  | int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch)  | 
625  | 0  | { | 
626  | 0  |     return ch != NULL && ch->state == QUIC_CHANNEL_STATE_ACTIVE;  | 
627  | 0  | }  | 
628  |  |  | 
629  |  | int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch)  | 
630  | 0  | { | 
631  | 0  |     return ch->state == QUIC_CHANNEL_STATE_TERMINATING_CLOSING;  | 
632  | 0  | }  | 
633  |  |  | 
634  |  | static int ossl_quic_channel_is_draining(const QUIC_CHANNEL *ch)  | 
635  | 0  | { | 
636  | 0  |     return ch->state == QUIC_CHANNEL_STATE_TERMINATING_DRAINING;  | 
637  | 0  | }  | 
638  |  |  | 
639  |  | static int ossl_quic_channel_is_terminating(const QUIC_CHANNEL *ch)  | 
640  | 0  | { | 
641  | 0  |     return ossl_quic_channel_is_closing(ch)  | 
642  | 0  |         || ossl_quic_channel_is_draining(ch);  | 
643  | 0  | }  | 
644  |  |  | 
645  |  | int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch)  | 
646  | 0  | { | 
647  | 0  |     return ch->state == QUIC_CHANNEL_STATE_TERMINATED;  | 
648  | 0  | }  | 
649  |  |  | 
650  |  | int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch)  | 
651  | 0  | { | 
652  | 0  |     return ossl_quic_channel_is_terminating(ch)  | 
653  | 0  |         || ossl_quic_channel_is_terminated(ch);  | 
654  | 0  | }  | 
655  |  |  | 
656  |  | int ossl_quic_channel_is_server(const QUIC_CHANNEL *ch)  | 
657  | 0  | { | 
658  | 0  |     return ch->is_server;  | 
659  | 0  | }  | 
660  |  |  | 
661  |  | void ossl_quic_channel_notify_flush_done(QUIC_CHANNEL *ch)  | 
662  | 0  | { | 
663  | 0  |     ch_record_state_transition(ch, ch->terminate_cause.remote  | 
664  | 0  |                                    ? QUIC_CHANNEL_STATE_TERMINATING_DRAINING  | 
665  | 0  |                                    : QUIC_CHANNEL_STATE_TERMINATING_CLOSING);  | 
666  |  |     /*  | 
667  |  |      * RFC 9000 s. 10.2 Immediate Close  | 
668  |  |      *  These states SHOULD persist for at least three times  | 
669  |  |      *  the current PTO interval as defined in [QUIC-RECOVERY].  | 
670  |  |      */  | 
671  | 0  |     ch->terminate_deadline  | 
672  | 0  |         = ossl_time_add(get_time(ch),  | 
673  | 0  |                         ossl_time_multiply(ossl_ackm_get_pto_duration(ch->ackm), 3));  | 
674  | 0  |     if (!ch->terminate_cause.remote) { | 
675  | 0  |         OSSL_QUIC_FRAME_CONN_CLOSE f = {0}; | 
676  |  |  | 
677  |  |         /* best effort */  | 
678  | 0  |         f.error_code = ch->terminate_cause.error_code;  | 
679  | 0  |         f.frame_type = ch->terminate_cause.frame_type;  | 
680  | 0  |         f.is_app     = ch->terminate_cause.app;  | 
681  | 0  |         f.reason     = (char *)ch->terminate_cause.reason;  | 
682  | 0  |         f.reason_len = ch->terminate_cause.reason_len;  | 
683  | 0  |         ossl_quic_tx_packetiser_schedule_conn_close(ch->txp, &f);  | 
684  |  |         /*  | 
685  |  |          * RFC 9000 s. 10.2.2 Draining Connection State:  | 
686  |  |          *  An endpoint that receives a CONNECTION_CLOSE frame MAY  | 
687  |  |          *  send a single packet containing a CONNECTION_CLOSE  | 
688  |  |          *  frame before entering the draining state, using a  | 
689  |  |          *  NO_ERROR code if appropriate  | 
690  |  |          */  | 
691  | 0  |         ch->conn_close_queued = 1;  | 
692  | 0  |     }  | 
693  | 0  | }  | 
694  |  |  | 
695  |  | const QUIC_TERMINATE_CAUSE *  | 
696  |  | ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch)  | 
697  | 0  | { | 
698  | 0  |     return ossl_quic_channel_is_term_any(ch) ? &ch->terminate_cause : NULL;  | 
699  | 0  | }  | 
700  |  |  | 
701  |  | int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch)  | 
702  | 0  | { | 
703  | 0  |     return ch->handshake_complete;  | 
704  | 0  | }  | 
705  |  |  | 
706  |  | int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch)  | 
707  | 0  | { | 
708  | 0  |     return ch->handshake_confirmed;  | 
709  | 0  | }  | 
710  |  |  | 
711  |  | QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch)  | 
712  | 0  | { | 
713  | 0  |     return ch->port->demux;  | 
714  | 0  | }  | 
715  |  |  | 
716  |  | QUIC_PORT *ossl_quic_channel_get0_port(QUIC_CHANNEL *ch)  | 
717  | 0  | { | 
718  | 0  |     return ch->port;  | 
719  | 0  | }  | 
720  |  |  | 
721  |  | QUIC_ENGINE *ossl_quic_channel_get0_engine(QUIC_CHANNEL *ch)  | 
722  | 0  | { | 
723  | 0  |     return ossl_quic_port_get0_engine(ch->port);  | 
724  | 0  | }  | 
725  |  |  | 
726  |  | CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch)  | 
727  | 0  | { | 
728  | 0  |     return ossl_quic_port_get0_mutex(ch->port);  | 
729  | 0  | }  | 
730  |  |  | 
731  |  | int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch)  | 
732  | 0  | { | 
733  | 0  |     return ossl_quic_demux_has_pending(ch->port->demux)  | 
734  | 0  |         || ossl_qrx_processed_read_pending(ch->qrx);  | 
735  | 0  | }  | 
736  |  |  | 
737  |  | /*  | 
738  |  |  * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components  | 
739  |  |  * ================================================================  | 
740  |  |  */  | 
741  |  |  | 
742  |  | /* Used by various components. */  | 
743  |  | static OSSL_TIME get_time(void *arg)  | 
744  | 0  | { | 
745  | 0  |     QUIC_CHANNEL *ch = arg;  | 
746  |  | 
  | 
747  | 0  |     return ossl_quic_port_get_time(ch->port);  | 
748  | 0  | }  | 
749  |  |  | 
750  |  | /* Used by QSM. */  | 
751  |  | static uint64_t get_stream_limit(int uni, void *arg)  | 
752  | 0  | { | 
753  | 0  |     QUIC_CHANNEL *ch = arg;  | 
754  |  | 
  | 
755  | 0  |     return uni ? ch->max_local_streams_uni : ch->max_local_streams_bidi;  | 
756  | 0  | }  | 
757  |  |  | 
758  |  | /*  | 
759  |  |  * Called by QRX to determine if a packet is potentially invalid before trying  | 
760  |  |  * to decrypt it.  | 
761  |  |  */  | 
762  |  | static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg)  | 
763  | 0  | { | 
764  | 0  |     QUIC_CHANNEL *ch = arg;  | 
765  |  |  | 
766  |  |     /* Potential duplicates should not be processed. */  | 
767  | 0  |     if (!ossl_ackm_is_rx_pn_processable(ch->ackm, pn, pn_space))  | 
768  | 0  |         return 0;  | 
769  |  |  | 
770  | 0  |     return 1;  | 
771  | 0  | }  | 
772  |  |  | 
773  |  | /*  | 
774  |  |  * Triggers a TXKU (whether spontaneous or solicited). Does not check whether  | 
775  |  |  * spontaneous TXKU is currently allowed.  | 
776  |  |  */  | 
777  |  | QUIC_NEEDS_LOCK  | 
778  |  | static void ch_trigger_txku(QUIC_CHANNEL *ch)  | 
779  | 0  | { | 
780  | 0  |     uint64_t next_pn  | 
781  | 0  |         = ossl_quic_tx_packetiser_get_next_pn(ch->txp, QUIC_PN_SPACE_APP);  | 
782  |  | 
  | 
783  | 0  |     if (!ossl_quic_pn_valid(next_pn)  | 
784  | 0  |         || !ossl_qtx_trigger_key_update(ch->qtx)) { | 
785  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,  | 
786  | 0  |                                                "key update");  | 
787  | 0  |         return;  | 
788  | 0  |     }  | 
789  |  |  | 
790  | 0  |     ch->txku_in_progress    = 1;  | 
791  | 0  |     ch->txku_pn             = next_pn;  | 
792  | 0  |     ch->rxku_expected       = ch->ku_locally_initiated;  | 
793  | 0  | }  | 
794  |  |  | 
795  |  | QUIC_NEEDS_LOCK  | 
796  |  | static int txku_in_progress(QUIC_CHANNEL *ch)  | 
797  | 0  | { | 
798  | 0  |     if (ch->txku_in_progress  | 
799  | 0  |         && ossl_ackm_get_largest_acked(ch->ackm, QUIC_PN_SPACE_APP) >= ch->txku_pn) { | 
800  | 0  |         OSSL_TIME pto = ossl_ackm_get_pto_duration(ch->ackm);  | 
801  |  |  | 
802  |  |         /*  | 
803  |  |          * RFC 9001 s. 6.5: Endpoints SHOULD wait three times the PTO before  | 
804  |  |          * initiating a key update after receiving an acknowledgment that  | 
805  |  |          * confirms that the previous key update was received.  | 
806  |  |          *  | 
807  |  |          * Note that by the above wording, this period starts from when we get  | 
808  |  |          * the ack for a TXKU-triggering packet, not when the TXKU is initiated.  | 
809  |  |          * So we defer TXKU cooldown deadline calculation to this point.  | 
810  |  |          */  | 
811  | 0  |         ch->txku_in_progress        = 0;  | 
812  | 0  |         ch->txku_cooldown_deadline  = ossl_time_add(get_time(ch),  | 
813  | 0  |                                                     ossl_time_multiply(pto, 3));  | 
814  | 0  |     }  | 
815  |  | 
  | 
816  | 0  |     return ch->txku_in_progress;  | 
817  | 0  | }  | 
818  |  |  | 
819  |  | QUIC_NEEDS_LOCK  | 
820  |  | static int txku_allowed(QUIC_CHANNEL *ch)  | 
821  | 0  | { | 
822  | 0  |     return ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT /* Sanity check. */  | 
823  |  |         /* Strict RFC 9001 criterion for TXKU. */  | 
824  | 0  |         && ch->handshake_confirmed  | 
825  | 0  |         && !txku_in_progress(ch);  | 
826  | 0  | }  | 
827  |  |  | 
828  |  | QUIC_NEEDS_LOCK  | 
829  |  | static int txku_recommendable(QUIC_CHANNEL *ch)  | 
830  | 0  | { | 
831  | 0  |     if (!txku_allowed(ch))  | 
832  | 0  |         return 0;  | 
833  |  |  | 
834  | 0  |     return  | 
835  |  |         /* Recommended RFC 9001 criterion for TXKU. */  | 
836  | 0  |         ossl_time_compare(get_time(ch), ch->txku_cooldown_deadline) >= 0  | 
837  |  |         /* Some additional sensible criteria. */  | 
838  | 0  |         && !ch->rxku_in_progress  | 
839  | 0  |         && !ch->rxku_pending_confirm;  | 
840  | 0  | }  | 
841  |  |  | 
842  |  | QUIC_NEEDS_LOCK  | 
843  |  | static int txku_desirable(QUIC_CHANNEL *ch)  | 
844  | 0  | { | 
845  | 0  |     uint64_t cur_pkt_count, max_pkt_count, thresh_pkt_count;  | 
846  | 0  |     const uint32_t enc_level = QUIC_ENC_LEVEL_1RTT;  | 
847  |  |  | 
848  |  |     /* Check AEAD limit to determine if we should perform a spontaneous TXKU. */  | 
849  | 0  |     cur_pkt_count = ossl_qtx_get_cur_epoch_pkt_count(ch->qtx, enc_level);  | 
850  | 0  |     max_pkt_count = ossl_qtx_get_max_epoch_pkt_count(ch->qtx, enc_level);  | 
851  |  | 
  | 
852  | 0  |     thresh_pkt_count = max_pkt_count / 2;  | 
853  | 0  |     if (ch->txku_threshold_override != UINT64_MAX)  | 
854  | 0  |         thresh_pkt_count = ch->txku_threshold_override;  | 
855  |  | 
  | 
856  | 0  |     return cur_pkt_count >= thresh_pkt_count;  | 
857  | 0  | }  | 
858  |  |  | 
859  |  | QUIC_NEEDS_LOCK  | 
860  |  | static void ch_maybe_trigger_spontaneous_txku(QUIC_CHANNEL *ch)  | 
861  | 0  | { | 
862  | 0  |     if (!txku_recommendable(ch) || !txku_desirable(ch))  | 
863  | 0  |         return;  | 
864  |  |  | 
865  | 0  |     ch->ku_locally_initiated = 1;  | 
866  | 0  |     ch_trigger_txku(ch);  | 
867  | 0  | }  | 
868  |  |  | 
869  |  | QUIC_NEEDS_LOCK  | 
870  |  | static int rxku_allowed(QUIC_CHANNEL *ch)  | 
871  | 0  | { | 
872  |  |     /*  | 
873  |  |      * RFC 9001 s. 6.1: An endpoint MUST NOT initiate a key update prior to  | 
874  |  |      * having confirmed the handshake (Section 4.1.2).  | 
875  |  |      *  | 
876  |  |      * RFC 9001 s. 6.1: An endpoint MUST NOT initiate a subsequent key update  | 
877  |  |      * unless it has received an acknowledgment for a packet that was sent  | 
878  |  |      * protected with keys from the current key phase.  | 
879  |  |      *  | 
880  |  |      * RFC 9001 s. 6.2: If an endpoint detects a second update before it has  | 
881  |  |      * sent any packets with updated keys containing an acknowledgment for the  | 
882  |  |      * packet that initiated the key update, it indicates that its peer has  | 
883  |  |      * updated keys twice without awaiting confirmation. An endpoint MAY treat  | 
884  |  |      * such consecutive key updates as a connection error of type  | 
885  |  |      * KEY_UPDATE_ERROR.  | 
886  |  |      */  | 
887  | 0  |     return ch->handshake_confirmed && !ch->rxku_pending_confirm;  | 
888  | 0  | }  | 
889  |  |  | 
890  |  | /*  | 
891  |  |  * Called when the QRX detects a new RX key update event.  | 
892  |  |  */  | 
893  |  | enum rxku_decision { | 
894  |  |     DECISION_RXKU_ONLY,  | 
895  |  |     DECISION_PROTOCOL_VIOLATION,  | 
896  |  |     DECISION_SOLICITED_TXKU  | 
897  |  | };  | 
898  |  |  | 
899  |  | /* Called when the QRX detects a key update has occurred. */  | 
900  |  | QUIC_NEEDS_LOCK  | 
901  |  | static void rxku_detected(QUIC_PN pn, void *arg)  | 
902  | 0  | { | 
903  | 0  |     QUIC_CHANNEL *ch = arg;  | 
904  | 0  |     enum rxku_decision decision;  | 
905  | 0  |     OSSL_TIME pto;  | 
906  |  |  | 
907  |  |     /*  | 
908  |  |      * Note: rxku_in_progress is always 0 here as an RXKU cannot be detected  | 
909  |  |      * when we are still in UPDATING or COOLDOWN (see quic_record_rx.h).  | 
910  |  |      */  | 
911  | 0  |     assert(!ch->rxku_in_progress);  | 
912  |  | 
  | 
913  | 0  |     if (!rxku_allowed(ch))  | 
914  |  |         /* Is RXKU even allowed at this time? */  | 
915  | 0  |         decision = DECISION_PROTOCOL_VIOLATION;  | 
916  |  |  | 
917  | 0  |     else if (ch->ku_locally_initiated)  | 
918  |  |         /*  | 
919  |  |          * If this key update was locally initiated (meaning that this detected  | 
920  |  |          * RXKU event is a result of our own spontaneous TXKU), we do not  | 
921  |  |          * trigger another TXKU; after all, to do so would result in an infinite  | 
922  |  |          * ping-pong of key updates. We still process it as an RXKU.  | 
923  |  |          */  | 
924  | 0  |         decision = DECISION_RXKU_ONLY;  | 
925  |  |  | 
926  | 0  |     else  | 
927  |  |         /*  | 
928  |  |          * Otherwise, a peer triggering a KU means we have to trigger a KU also.  | 
929  |  |          */  | 
930  | 0  |         decision = DECISION_SOLICITED_TXKU;  | 
931  |  | 
  | 
932  | 0  |     if (decision == DECISION_PROTOCOL_VIOLATION) { | 
933  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR,  | 
934  | 0  |                                                0, "RX key update again too soon");  | 
935  | 0  |         return;  | 
936  | 0  |     }  | 
937  |  |  | 
938  | 0  |     pto = ossl_ackm_get_pto_duration(ch->ackm);  | 
939  |  | 
  | 
940  | 0  |     ch->ku_locally_initiated        = 0;  | 
941  | 0  |     ch->rxku_in_progress            = 1;  | 
942  | 0  |     ch->rxku_pending_confirm        = 1;  | 
943  | 0  |     ch->rxku_trigger_pn             = pn;  | 
944  | 0  |     ch->rxku_update_end_deadline    = ossl_time_add(get_time(ch), pto);  | 
945  | 0  |     ch->rxku_expected               = 0;  | 
946  |  | 
  | 
947  | 0  |     if (decision == DECISION_SOLICITED_TXKU)  | 
948  |  |         /* NOT gated by usual txku_allowed() */  | 
949  | 0  |         ch_trigger_txku(ch);  | 
950  |  |  | 
951  |  |     /*  | 
952  |  |      * Ordinarily, we only generate ACK when some ACK-eliciting frame has been  | 
953  |  |      * received. In some cases, this may not occur for a long time, for example  | 
954  |  |      * if transmission of application data is going in only one direction and  | 
955  |  |      * nothing else is happening with the connection. However, since the peer  | 
956  |  |      * cannot initiate a subsequent (spontaneous) TXKU until its prior  | 
957  |  |      * (spontaneous or solicited) TXKU has completed - meaning that prior  | 
958  |  |      * TXKU's trigger packet (or subsequent packet) has been acknowledged, this  | 
959  |  |      * can lead to very long times before a TXKU is considered 'completed'.  | 
960  |  |      * Optimise this by forcing ACK generation after triggering TXKU.  | 
961  |  |      * (Basically, we consider a RXKU event something that is 'ACK-eliciting',  | 
962  |  |      * which it more or less should be; it is necessarily separate from ordinary  | 
963  |  |      * processing of ACK-eliciting frames as key update is not indicated via a  | 
964  |  |      * frame.)  | 
965  |  |      */  | 
966  | 0  |     ossl_quic_tx_packetiser_schedule_ack(ch->txp, QUIC_PN_SPACE_APP);  | 
967  | 0  | }  | 
968  |  |  | 
969  |  | /* Called per tick to handle RXKU timer events. */  | 
970  |  | QUIC_NEEDS_LOCK  | 
971  |  | static void ch_rxku_tick(QUIC_CHANNEL *ch)  | 
972  | 0  | { | 
973  | 0  |     if (!ch->rxku_in_progress  | 
974  | 0  |         || ossl_time_compare(get_time(ch), ch->rxku_update_end_deadline) < 0)  | 
975  | 0  |         return;  | 
976  |  |  | 
977  | 0  |     ch->rxku_update_end_deadline    = ossl_time_infinite();  | 
978  | 0  |     ch->rxku_in_progress            = 0;  | 
979  |  | 
  | 
980  | 0  |     if (!ossl_qrx_key_update_timeout(ch->qrx, /*normal=*/1))  | 
981  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,  | 
982  | 0  |                                                "RXKU cooldown internal error");  | 
983  | 0  | }  | 
984  |  |  | 
985  |  | QUIC_NEEDS_LOCK  | 
986  |  | static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space,  | 
987  |  |                              void *arg)  | 
988  | 0  | { | 
989  | 0  |     QUIC_CHANNEL *ch = arg;  | 
990  |  | 
  | 
991  | 0  |     if (pn_space != QUIC_PN_SPACE_APP || !ch->rxku_pending_confirm  | 
992  | 0  |         || !ossl_quic_frame_ack_contains_pn(ack, ch->rxku_trigger_pn))  | 
993  | 0  |         return;  | 
994  |  |  | 
995  |  |     /*  | 
996  |  |      * Defer clearing rxku_pending_confirm until TXP generate call returns  | 
997  |  |      * successfully.  | 
998  |  |      */  | 
999  | 0  |     ch->rxku_pending_confirm_done = 1;  | 
1000  | 0  | }  | 
1001  |  |  | 
1002  |  | /*  | 
1003  |  |  * QUIC Channel: Handshake Layer Event Handling  | 
1004  |  |  * ============================================  | 
1005  |  |  */  | 
1006  |  | static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len,  | 
1007  |  |                              size_t *consumed, void *arg)  | 
1008  | 0  | { | 
1009  | 0  |     int ret;  | 
1010  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1011  | 0  |     uint32_t enc_level = ch->tx_enc_level;  | 
1012  | 0  |     uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);  | 
1013  | 0  |     QUIC_SSTREAM *sstream = ch->crypto_send[pn_space];  | 
1014  |  | 
  | 
1015  | 0  |     if (!ossl_assert(sstream != NULL))  | 
1016  | 0  |         return 0;  | 
1017  |  |  | 
1018  | 0  |     ret = ossl_quic_sstream_append(sstream, buf, buf_len, consumed);  | 
1019  | 0  |     return ret;  | 
1020  | 0  | }  | 
1021  |  |  | 
1022  |  | static int crypto_ensure_empty(QUIC_RSTREAM *rstream)  | 
1023  | 0  | { | 
1024  | 0  |     size_t avail = 0;  | 
1025  | 0  |     int is_fin = 0;  | 
1026  |  | 
  | 
1027  | 0  |     if (rstream == NULL)  | 
1028  | 0  |         return 1;  | 
1029  |  |  | 
1030  | 0  |     if (!ossl_quic_rstream_available(rstream, &avail, &is_fin))  | 
1031  | 0  |         return 0;  | 
1032  |  |  | 
1033  | 0  |     return avail == 0;  | 
1034  | 0  | }  | 
1035  |  |  | 
1036  |  | static int ch_on_crypto_recv_record(const unsigned char **buf,  | 
1037  |  |                                     size_t *bytes_read, void *arg)  | 
1038  | 0  | { | 
1039  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1040  | 0  |     QUIC_RSTREAM *rstream;  | 
1041  | 0  |     int is_fin = 0; /* crypto stream is never finished, so we don't use this */  | 
1042  | 0  |     uint32_t i;  | 
1043  |  |  | 
1044  |  |     /*  | 
1045  |  |      * After we move to a later EL we must not allow our peer to send any new  | 
1046  |  |      * bytes in the crypto stream on a previous EL. Retransmissions of old bytes  | 
1047  |  |      * are allowed.  | 
1048  |  |      *  | 
1049  |  |      * In practice we will only move to a new EL when we have consumed all bytes  | 
1050  |  |      * which should be sent on the crypto stream at a previous EL. For example,  | 
1051  |  |      * the Handshake EL should not be provisioned until we have completely  | 
1052  |  |      * consumed a TLS 1.3 ServerHello. Thus when we provision an EL the output  | 
1053  |  |      * of ossl_quic_rstream_available() should be 0 for all lower ELs. Thus if a  | 
1054  |  |      * given EL is available we simply ensure we have not received any further  | 
1055  |  |      * bytes at a lower EL.  | 
1056  |  |      */  | 
1057  | 0  |     for (i = QUIC_ENC_LEVEL_INITIAL; i < ch->rx_enc_level; ++i)  | 
1058  | 0  |         if (i != QUIC_ENC_LEVEL_0RTT &&  | 
1059  | 0  |             !crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { | 
1060  |  |             /* Protocol violation (RFC 9001 s. 4.1.3) */  | 
1061  | 0  |             ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
1062  | 0  |                                                    OSSL_QUIC_FRAME_TYPE_CRYPTO,  | 
1063  | 0  |                                                    "crypto stream data in wrong EL");  | 
1064  | 0  |             return 0;  | 
1065  | 0  |         }  | 
1066  |  |  | 
1067  | 0  |     rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->rx_enc_level)];  | 
1068  | 0  |     if (rstream == NULL)  | 
1069  | 0  |         return 0;  | 
1070  |  |  | 
1071  | 0  |     return ossl_quic_rstream_get_record(rstream, buf, bytes_read,  | 
1072  | 0  |                                         &is_fin);  | 
1073  | 0  | }  | 
1074  |  |  | 
1075  |  | static int ch_on_crypto_release_record(size_t bytes_read, void *arg)  | 
1076  | 0  | { | 
1077  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1078  | 0  |     QUIC_RSTREAM *rstream;  | 
1079  | 0  |     OSSL_RTT_INFO rtt_info;  | 
1080  | 0  |     uint32_t rx_pn_space = ossl_quic_enc_level_to_pn_space(ch->rx_enc_level);  | 
1081  |  | 
  | 
1082  | 0  |     rstream = ch->crypto_recv[rx_pn_space];  | 
1083  | 0  |     if (rstream == NULL)  | 
1084  | 0  |         return 0;  | 
1085  |  |  | 
1086  | 0  |     ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info);  | 
1087  | 0  |     if (!ossl_quic_rxfc_on_retire(&ch->crypto_rxfc[rx_pn_space], bytes_read,  | 
1088  | 0  |                                   rtt_info.smoothed_rtt))  | 
1089  | 0  |         return 0;  | 
1090  |  |  | 
1091  | 0  |     return ossl_quic_rstream_release_record(rstream, bytes_read);  | 
1092  | 0  | }  | 
1093  |  |  | 
1094  |  | static int ch_on_handshake_yield_secret(uint32_t prot_level, int direction,  | 
1095  |  |                                         uint32_t suite_id, EVP_MD *md,  | 
1096  |  |                                         const unsigned char *secret,  | 
1097  |  |                                         size_t secret_len,  | 
1098  |  |                                         void *arg)  | 
1099  | 0  | { | 
1100  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1101  | 0  |     uint32_t i;  | 
1102  | 0  |     uint32_t enc_level;  | 
1103  |  |  | 
1104  |  |     /* Convert TLS protection level to QUIC encryption level */  | 
1105  | 0  |     switch (prot_level) { | 
1106  | 0  |     case OSSL_RECORD_PROTECTION_LEVEL_EARLY:  | 
1107  | 0  |         enc_level = QUIC_ENC_LEVEL_0RTT;  | 
1108  | 0  |         break;  | 
1109  |  |  | 
1110  | 0  |     case OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE:  | 
1111  | 0  |         enc_level = QUIC_ENC_LEVEL_HANDSHAKE;  | 
1112  | 0  |         break;  | 
1113  |  |  | 
1114  | 0  |     case OSSL_RECORD_PROTECTION_LEVEL_APPLICATION:  | 
1115  | 0  |         enc_level = QUIC_ENC_LEVEL_1RTT;  | 
1116  | 0  |         break;  | 
1117  |  |  | 
1118  | 0  |     default:  | 
1119  | 0  |         return 0;  | 
1120  | 0  |     }  | 
1121  |  |  | 
1122  | 0  |     if (enc_level < QUIC_ENC_LEVEL_HANDSHAKE || enc_level >= QUIC_ENC_LEVEL_NUM)  | 
1123  |  |         /* Invalid EL. */  | 
1124  | 0  |         return 0;  | 
1125  |  |  | 
1126  |  |  | 
1127  | 0  |     if (direction) { | 
1128  |  |         /* TX */  | 
1129  | 0  |         if (enc_level <= ch->tx_enc_level)  | 
1130  |  |             /*  | 
1131  |  |              * Does not make sense for us to try and provision an EL we have already  | 
1132  |  |              * attained.  | 
1133  |  |              */  | 
1134  | 0  |             return 0;  | 
1135  |  |  | 
1136  | 0  |         if (!ossl_qtx_provide_secret(ch->qtx, enc_level,  | 
1137  | 0  |                                      suite_id, md,  | 
1138  | 0  |                                      secret, secret_len))  | 
1139  | 0  |             return 0;  | 
1140  |  |  | 
1141  | 0  |         ch->tx_enc_level = enc_level;  | 
1142  | 0  |     } else { | 
1143  |  |         /* RX */  | 
1144  | 0  |         if (enc_level <= ch->rx_enc_level)  | 
1145  |  |             /*  | 
1146  |  |              * Does not make sense for us to try and provision an EL we have already  | 
1147  |  |              * attained.  | 
1148  |  |              */  | 
1149  | 0  |             return 0;  | 
1150  |  |  | 
1151  |  |         /*  | 
1152  |  |          * Ensure all crypto streams for previous ELs are now empty of available  | 
1153  |  |          * data.  | 
1154  |  |          */  | 
1155  | 0  |         for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i)  | 
1156  | 0  |             if (!crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) { | 
1157  |  |                 /* Protocol violation (RFC 9001 s. 4.1.3) */  | 
1158  | 0  |                 ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
1159  | 0  |                                                     OSSL_QUIC_FRAME_TYPE_CRYPTO,  | 
1160  | 0  |                                                     "crypto stream data in wrong EL");  | 
1161  | 0  |                 return 0;  | 
1162  | 0  |             }  | 
1163  |  |  | 
1164  | 0  |         if (!ossl_qrx_provide_secret(ch->qrx, enc_level,  | 
1165  | 0  |                                      suite_id, md,  | 
1166  | 0  |                                      secret, secret_len))  | 
1167  | 0  |             return 0;  | 
1168  |  |  | 
1169  | 0  |         ch->have_new_rx_secret = 1;  | 
1170  | 0  |         ch->rx_enc_level = enc_level;  | 
1171  | 0  |     }  | 
1172  |  |  | 
1173  | 0  |     return 1;  | 
1174  | 0  | }  | 
1175  |  |  | 
1176  |  | static int ch_on_handshake_complete(void *arg)  | 
1177  | 0  | { | 
1178  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1179  |  | 
  | 
1180  | 0  |     if (!ossl_assert(!ch->handshake_complete))  | 
1181  | 0  |         return 0; /* this should not happen twice */  | 
1182  |  |  | 
1183  | 0  |     if (!ossl_assert(ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT))  | 
1184  | 0  |         return 0;  | 
1185  |  |  | 
1186  |  |     /*  | 
1187  |  |      * When handshake is complete, we no longer need to abide by the  | 
1188  |  |      * 3x amplification limit, though we should be validated as soon  | 
1189  |  |      * as we see a handshake key encrypted packet (see ossl_quic_handle_packet)  | 
1190  |  |      */  | 
1191  | 0  |     ossl_quic_tx_packetiser_set_validated(ch->txp);  | 
1192  |  | 
  | 
1193  | 0  |     if (!ch->got_remote_transport_params) { | 
1194  |  |         /*  | 
1195  |  |          * Was not a valid QUIC handshake if we did not get valid transport  | 
1196  |  |          * params.  | 
1197  |  |          */  | 
1198  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CRYPTO_MISSING_EXT,  | 
1199  | 0  |                                                OSSL_QUIC_FRAME_TYPE_CRYPTO,  | 
1200  | 0  |                                                "no transport parameters received");  | 
1201  | 0  |         return 0;  | 
1202  | 0  |     }  | 
1203  |  |  | 
1204  |  |     /* Don't need transport parameters anymore. */  | 
1205  | 0  |     OPENSSL_free(ch->local_transport_params);  | 
1206  | 0  |     ch->local_transport_params = NULL;  | 
1207  |  |  | 
1208  |  |     /* Tell the QRX it can now process 1-RTT packets. */  | 
1209  | 0  |     ossl_qrx_allow_1rtt_processing(ch->qrx);  | 
1210  |  |  | 
1211  |  |     /* Tell TXP the handshake is complete. */  | 
1212  | 0  |     ossl_quic_tx_packetiser_notify_handshake_complete(ch->txp);  | 
1213  |  | 
  | 
1214  | 0  |     ch->handshake_complete = 1;  | 
1215  |  | 
  | 
1216  | 0  |     if (ch->pending_new_token != NULL) { | 
1217  |  |         /*  | 
1218  |  |          * Note this is a best effort operation here  | 
1219  |  |          * If scheduling a new token fails, the worst outcome is that  | 
1220  |  |          * a client, not having received it, will just have to go through  | 
1221  |  |          * an extra roundtrip on a subsequent connection via the retry frame  | 
1222  |  |          * path, at which point we get another opportunity to schedule another  | 
1223  |  |          * new token.  As a result, we don't need to handle any errors here  | 
1224  |  |          */  | 
1225  | 0  |         ossl_quic_channel_schedule_new_token(ch,  | 
1226  | 0  |                                              ch->pending_new_token,  | 
1227  | 0  |                                              ch->pending_new_token_len);  | 
1228  | 0  |         OPENSSL_free(ch->pending_new_token);  | 
1229  | 0  |         ch->pending_new_token = NULL;  | 
1230  | 0  |         ch->pending_new_token_len = 0;  | 
1231  | 0  |     }  | 
1232  |  | 
  | 
1233  | 0  |     if (ch->is_server) { | 
1234  |  |         /*  | 
1235  |  |          * On the server, the handshake is confirmed as soon as it is complete.  | 
1236  |  |          */  | 
1237  | 0  |         ossl_quic_channel_on_handshake_confirmed(ch);  | 
1238  |  | 
  | 
1239  | 0  |         ossl_quic_tx_packetiser_schedule_handshake_done(ch->txp);  | 
1240  | 0  |     }  | 
1241  |  | 
  | 
1242  | 0  |     ch_record_state_transition(ch, ch->state);  | 
1243  | 0  |     return 1;  | 
1244  | 0  | }  | 
1245  |  |  | 
1246  |  | static int ch_on_handshake_alert(void *arg, unsigned char alert_code)  | 
1247  | 0  | { | 
1248  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1249  |  |  | 
1250  |  |     /*  | 
1251  |  |      * RFC 9001 s. 4.4: More specifically, servers MUST NOT send post-handshake  | 
1252  |  |      * TLS CertificateRequest messages, and clients MUST treat receipt of such  | 
1253  |  |      * messages as a connection error of type PROTOCOL_VIOLATION.  | 
1254  |  |      */  | 
1255  | 0  |     if (alert_code == SSL_AD_UNEXPECTED_MESSAGE  | 
1256  | 0  |             && ch->handshake_complete  | 
1257  | 0  |             && ossl_quic_tls_is_cert_request(ch->qtls))  | 
1258  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
1259  | 0  |                                                OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
1260  | 0  |                                                0,  | 
1261  | 0  |                                                "Post-handshake TLS "  | 
1262  | 0  |                                                "CertificateRequest received");  | 
1263  |  |     /*  | 
1264  |  |      * RFC 9001 s. 4.6.1: Servers MUST NOT send the early_data extension with a  | 
1265  |  |      * max_early_data_size field set to any value other than 0xffffffff. A  | 
1266  |  |      * client MUST treat receipt of a NewSessionTicket that contains an  | 
1267  |  |      * early_data extension with any other value as a connection error of type  | 
1268  |  |      * PROTOCOL_VIOLATION.  | 
1269  |  |      */  | 
1270  | 0  |     else if (alert_code == SSL_AD_ILLEGAL_PARAMETER  | 
1271  | 0  |              && ch->handshake_complete  | 
1272  | 0  |              && ossl_quic_tls_has_bad_max_early_data(ch->qtls))  | 
1273  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
1274  | 0  |                                                OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
1275  | 0  |                                                0,  | 
1276  | 0  |                                                "Bad max_early_data received");  | 
1277  | 0  |     else  | 
1278  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
1279  | 0  |                                                OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN  | 
1280  | 0  |                                                + alert_code,  | 
1281  | 0  |                                                0, "handshake alert");  | 
1282  |  | 
  | 
1283  | 0  |     return 1;  | 
1284  | 0  | }  | 
1285  |  |  | 
1286  |  | /*  | 
1287  |  |  * QUIC Channel: Transport Parameter Handling  | 
1288  |  |  * ==========================================  | 
1289  |  |  */  | 
1290  |  |  | 
1291  |  | /*  | 
1292  |  |  * Called by handshake layer when we receive QUIC Transport Parameters from the  | 
1293  |  |  * peer. Note that these are not authenticated until the handshake is marked  | 
1294  |  |  * as complete.  | 
1295  |  |  */  | 
1296  |  | #define TP_REASON_SERVER_ONLY(x) \  | 
1297  | 0  |     x " may not be sent by a client"  | 
1298  |  | #define TP_REASON_DUP(x) \  | 
1299  | 0  |     x " appears multiple times"  | 
1300  |  | #define TP_REASON_MALFORMED(x) \  | 
1301  | 0  |     x " is malformed"  | 
1302  |  | #define TP_REASON_EXPECTED_VALUE(x) \  | 
1303  | 0  |     x " does not match expected value"  | 
1304  |  | #define TP_REASON_NOT_RETRY(x) \  | 
1305  | 0  |     x " sent when not performing a retry"  | 
1306  |  | #define TP_REASON_REQUIRED(x) \  | 
1307  | 0  |     x " was not sent but is required"  | 
1308  |  | #define TP_REASON_INTERNAL_ERROR(x) \  | 
1309  | 0  |     x " encountered internal error"  | 
1310  |  |  | 
1311  |  | static void txfc_bump_cwm_bidi(QUIC_STREAM *s, void *arg)  | 
1312  | 0  | { | 
1313  | 0  |     if (!ossl_quic_stream_is_bidi(s)  | 
1314  | 0  |         || ossl_quic_stream_is_server_init(s))  | 
1315  | 0  |         return;  | 
1316  |  |  | 
1317  | 0  |     ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg);  | 
1318  | 0  | }  | 
1319  |  |  | 
1320  |  | static void txfc_bump_cwm_uni(QUIC_STREAM *s, void *arg)  | 
1321  | 0  | { | 
1322  | 0  |     if (ossl_quic_stream_is_bidi(s)  | 
1323  | 0  |         || ossl_quic_stream_is_server_init(s))  | 
1324  | 0  |         return;  | 
1325  |  |  | 
1326  | 0  |     ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg);  | 
1327  | 0  | }  | 
1328  |  |  | 
1329  |  | static void do_update(QUIC_STREAM *s, void *arg)  | 
1330  | 0  | { | 
1331  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1332  |  | 
  | 
1333  | 0  |     ossl_quic_stream_map_update_state(&ch->qsm, s);  | 
1334  | 0  | }  | 
1335  |  |  | 
1336  |  | static uint64_t min_u64_ignore_0(uint64_t a, uint64_t b)  | 
1337  | 0  | { | 
1338  | 0  |     if (a == 0)  | 
1339  | 0  |         return b;  | 
1340  | 0  |     if (b == 0)  | 
1341  | 0  |         return a;  | 
1342  |  |  | 
1343  | 0  |     return a < b ? a : b;  | 
1344  | 0  | }  | 
1345  |  |  | 
1346  |  | static int ch_on_transport_params(const unsigned char *params,  | 
1347  |  |                                   size_t params_len,  | 
1348  |  |                                   void *arg)  | 
1349  | 0  | { | 
1350  | 0  |     QUIC_CHANNEL *ch = arg;  | 
1351  | 0  |     PACKET pkt;  | 
1352  | 0  |     uint64_t id, v;  | 
1353  | 0  |     size_t len;  | 
1354  | 0  |     const unsigned char *body;  | 
1355  | 0  |     int got_orig_dcid = 0;  | 
1356  | 0  |     int got_initial_scid = 0;  | 
1357  | 0  |     int got_retry_scid = 0;  | 
1358  | 0  |     int got_initial_max_data = 0;  | 
1359  | 0  |     int got_initial_max_stream_data_bidi_local = 0;  | 
1360  | 0  |     int got_initial_max_stream_data_bidi_remote = 0;  | 
1361  | 0  |     int got_initial_max_stream_data_uni = 0;  | 
1362  | 0  |     int got_initial_max_streams_bidi = 0;  | 
1363  | 0  |     int got_initial_max_streams_uni = 0;  | 
1364  | 0  |     int got_stateless_reset_token = 0;  | 
1365  | 0  |     int got_preferred_addr = 0;  | 
1366  | 0  |     int got_ack_delay_exp = 0;  | 
1367  | 0  |     int got_max_ack_delay = 0;  | 
1368  | 0  |     int got_max_udp_payload_size = 0;  | 
1369  | 0  |     int got_max_idle_timeout = 0;  | 
1370  | 0  |     int got_active_conn_id_limit = 0;  | 
1371  | 0  |     int got_disable_active_migration = 0;  | 
1372  | 0  |     QUIC_CONN_ID cid;  | 
1373  | 0  |     const char *reason = "bad transport parameter";  | 
1374  | 0  |     ossl_unused uint64_t rx_max_idle_timeout = 0;  | 
1375  | 0  |     ossl_unused const void *stateless_reset_token_p = NULL;  | 
1376  | 0  |     QUIC_PREFERRED_ADDR pfa;  | 
1377  | 0  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ch->tls);  | 
1378  |  | 
  | 
1379  | 0  |     if (sc == NULL) { | 
1380  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,  | 
1381  | 0  |                                                "could not get ssl connection");  | 
1382  | 0  |         return 0;  | 
1383  | 0  |     }  | 
1384  |  |     /*  | 
1385  |  |      * When HRR happens the client sends the transport params in the new client  | 
1386  |  |      * hello again. Reset the transport params here and load them again.  | 
1387  |  |      */  | 
1388  | 0  |     if (ch->is_server && sc->hello_retry_request != SSL_HRR_NONE  | 
1389  | 0  |         && ch->got_remote_transport_params) { | 
1390  | 0  |         ch->max_local_streams_bidi = 0;  | 
1391  | 0  |         ch->max_local_streams_uni = 0;  | 
1392  | 0  |         ch->got_local_transport_params = 0;  | 
1393  | 0  |         OPENSSL_free(ch->local_transport_params);  | 
1394  | 0  |         ch->local_transport_params = NULL;  | 
1395  | 0  |     } else if (ch->got_remote_transport_params) { | 
1396  | 0  |         reason = "multiple transport parameter extensions";  | 
1397  | 0  |         goto malformed;  | 
1398  | 0  |     }  | 
1399  |  |  | 
1400  | 0  |     if (!PACKET_buf_init(&pkt, params, params_len)) { | 
1401  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,  | 
1402  | 0  |                                                "internal error (packet buf init)");  | 
1403  | 0  |         return 0;  | 
1404  | 0  |     }  | 
1405  |  |  | 
1406  | 0  |     while (PACKET_remaining(&pkt) > 0) { | 
1407  | 0  |         if (!ossl_quic_wire_peek_transport_param(&pkt, &id))  | 
1408  | 0  |             goto malformed;  | 
1409  |  |  | 
1410  | 0  |         switch (id) { | 
1411  | 0  |         case QUIC_TPARAM_ORIG_DCID:  | 
1412  | 0  |             if (got_orig_dcid) { | 
1413  | 0  |                 reason = TP_REASON_DUP("ORIG_DCID"); | 
1414  | 0  |                 goto malformed;  | 
1415  | 0  |             }  | 
1416  |  |  | 
1417  | 0  |             if (ch->is_server) { | 
1418  | 0  |                 reason = TP_REASON_SERVER_ONLY("ORIG_DCID"); | 
1419  | 0  |                 goto malformed;  | 
1420  | 0  |             }  | 
1421  |  |  | 
1422  | 0  |             if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { | 
1423  | 0  |                 reason = TP_REASON_MALFORMED("ORIG_DCID"); | 
1424  | 0  |                 goto malformed;  | 
1425  | 0  |             }  | 
1426  |  |  | 
1427  |  | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION  | 
1428  |  |             /* Must match our initial DCID. */  | 
1429  |  |             if (!ossl_quic_conn_id_eq(&ch->init_dcid, &cid)) { | 
1430  |  |                 reason = TP_REASON_EXPECTED_VALUE("ORIG_DCID"); | 
1431  |  |                 goto malformed;  | 
1432  |  |             }  | 
1433  |  | #endif  | 
1434  |  |  | 
1435  | 0  |             got_orig_dcid = 1;  | 
1436  | 0  |             break;  | 
1437  |  |  | 
1438  | 0  |         case QUIC_TPARAM_RETRY_SCID:  | 
1439  | 0  |             if (ch->is_server) { | 
1440  | 0  |                 reason = TP_REASON_SERVER_ONLY("RETRY_SCID"); | 
1441  | 0  |                 goto malformed;  | 
1442  | 0  |             }  | 
1443  |  |  | 
1444  | 0  |             if (got_retry_scid) { | 
1445  | 0  |                 reason = TP_REASON_DUP("RETRY_SCID"); | 
1446  | 0  |                 goto malformed;  | 
1447  | 0  |             }  | 
1448  |  |  | 
1449  | 0  |             if (!ch->doing_retry) { | 
1450  | 0  |                 reason = TP_REASON_NOT_RETRY("RETRY_SCID"); | 
1451  | 0  |                 goto malformed;  | 
1452  | 0  |             }  | 
1453  |  |  | 
1454  | 0  |             if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { | 
1455  | 0  |                 reason = TP_REASON_MALFORMED("RETRY_SCID"); | 
1456  | 0  |                 goto malformed;  | 
1457  | 0  |             }  | 
1458  |  |  | 
1459  |  |             /* Must match Retry packet SCID. */  | 
1460  | 0  |             if (!ossl_quic_conn_id_eq(&ch->retry_scid, &cid)) { | 
1461  | 0  |                 reason = TP_REASON_EXPECTED_VALUE("RETRY_SCID"); | 
1462  | 0  |                 goto malformed;  | 
1463  | 0  |             }  | 
1464  |  |  | 
1465  | 0  |             got_retry_scid = 1;  | 
1466  | 0  |             break;  | 
1467  |  |  | 
1468  | 0  |         case QUIC_TPARAM_INITIAL_SCID:  | 
1469  | 0  |             if (got_initial_scid) { | 
1470  |  |                 /* must not appear more than once */  | 
1471  | 0  |                 reason = TP_REASON_DUP("INITIAL_SCID"); | 
1472  | 0  |                 goto malformed;  | 
1473  | 0  |             }  | 
1474  |  |  | 
1475  | 0  |             if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) { | 
1476  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_SCID"); | 
1477  | 0  |                 goto malformed;  | 
1478  | 0  |             }  | 
1479  |  |  | 
1480  | 0  |             if (!ossl_quic_conn_id_eq(&ch->init_scid, &cid)) { | 
1481  | 0  |                 reason = TP_REASON_EXPECTED_VALUE("INITIAL_SCID"); | 
1482  | 0  |                 goto malformed;  | 
1483  | 0  |             }  | 
1484  |  |  | 
1485  | 0  |             got_initial_scid = 1;  | 
1486  | 0  |             break;  | 
1487  |  |  | 
1488  | 0  |         case QUIC_TPARAM_INITIAL_MAX_DATA:  | 
1489  | 0  |             if (got_initial_max_data) { | 
1490  |  |                 /* must not appear more than once */  | 
1491  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_DATA"); | 
1492  | 0  |                 goto malformed;  | 
1493  | 0  |             }  | 
1494  |  |  | 
1495  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { | 
1496  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_DATA"); | 
1497  | 0  |                 goto malformed;  | 
1498  | 0  |             }  | 
1499  |  |  | 
1500  | 0  |             ossl_quic_txfc_bump_cwm(&ch->conn_txfc, v);  | 
1501  | 0  |             got_initial_max_data = 1;  | 
1502  | 0  |             break;  | 
1503  |  |  | 
1504  | 0  |         case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:  | 
1505  | 0  |             if (got_initial_max_stream_data_bidi_local) { | 
1506  |  |                 /* must not appear more than once */  | 
1507  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"); | 
1508  | 0  |                 goto malformed;  | 
1509  | 0  |             }  | 
1510  |  |  | 
1511  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { | 
1512  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL"); | 
1513  | 0  |                 goto malformed;  | 
1514  | 0  |             }  | 
1515  |  |  | 
1516  |  |             /*  | 
1517  |  |              * This is correct; the BIDI_LOCAL TP governs streams created by  | 
1518  |  |              * the endpoint which sends the TP, i.e., our peer.  | 
1519  |  |              */  | 
1520  | 0  |             ch->rx_init_max_stream_data_bidi_remote = v;  | 
1521  | 0  |             got_initial_max_stream_data_bidi_local = 1;  | 
1522  | 0  |             break;  | 
1523  |  |  | 
1524  | 0  |         case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:  | 
1525  | 0  |             if (got_initial_max_stream_data_bidi_remote) { | 
1526  |  |                 /* must not appear more than once */  | 
1527  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"); | 
1528  | 0  |                 goto malformed;  | 
1529  | 0  |             }  | 
1530  |  |  | 
1531  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { | 
1532  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE"); | 
1533  | 0  |                 goto malformed;  | 
1534  | 0  |             }  | 
1535  |  |  | 
1536  |  |             /*  | 
1537  |  |              * This is correct; the BIDI_REMOTE TP governs streams created  | 
1538  |  |              * by the endpoint which receives the TP, i.e., us.  | 
1539  |  |              */  | 
1540  | 0  |             ch->rx_init_max_stream_data_bidi_local = v;  | 
1541  |  |  | 
1542  |  |             /* Apply to all existing streams. */  | 
1543  | 0  |             ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_bidi, &v);  | 
1544  | 0  |             got_initial_max_stream_data_bidi_remote = 1;  | 
1545  | 0  |             break;  | 
1546  |  |  | 
1547  | 0  |         case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI:  | 
1548  | 0  |             if (got_initial_max_stream_data_uni) { | 
1549  |  |                 /* must not appear more than once */  | 
1550  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_UNI"); | 
1551  | 0  |                 goto malformed;  | 
1552  | 0  |             }  | 
1553  |  |  | 
1554  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { | 
1555  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_UNI"); | 
1556  | 0  |                 goto malformed;  | 
1557  | 0  |             }  | 
1558  |  |  | 
1559  | 0  |             ch->rx_init_max_stream_data_uni = v;  | 
1560  |  |  | 
1561  |  |             /* Apply to all existing streams. */  | 
1562  | 0  |             ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_uni, &v);  | 
1563  | 0  |             got_initial_max_stream_data_uni = 1;  | 
1564  | 0  |             break;  | 
1565  |  |  | 
1566  | 0  |         case QUIC_TPARAM_ACK_DELAY_EXP:  | 
1567  | 0  |             if (got_ack_delay_exp) { | 
1568  |  |                 /* must not appear more than once */  | 
1569  | 0  |                 reason = TP_REASON_DUP("ACK_DELAY_EXP"); | 
1570  | 0  |                 goto malformed;  | 
1571  | 0  |             }  | 
1572  |  |  | 
1573  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1574  | 0  |                 || v > QUIC_MAX_ACK_DELAY_EXP) { | 
1575  | 0  |                 reason = TP_REASON_MALFORMED("ACK_DELAY_EXP"); | 
1576  | 0  |                 goto malformed;  | 
1577  | 0  |             }  | 
1578  |  |  | 
1579  | 0  |             ch->rx_ack_delay_exp = (unsigned char)v;  | 
1580  | 0  |             got_ack_delay_exp = 1;  | 
1581  | 0  |             break;  | 
1582  |  |  | 
1583  | 0  |         case QUIC_TPARAM_MAX_ACK_DELAY:  | 
1584  | 0  |             if (got_max_ack_delay) { | 
1585  |  |                 /* must not appear more than once */  | 
1586  | 0  |                 reason = TP_REASON_DUP("MAX_ACK_DELAY"); | 
1587  | 0  |                 goto malformed;  | 
1588  | 0  |             }  | 
1589  |  |  | 
1590  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1591  | 0  |                 || v >= (((uint64_t)1) << 14)) { | 
1592  | 0  |                 reason = TP_REASON_MALFORMED("MAX_ACK_DELAY"); | 
1593  | 0  |                 goto malformed;  | 
1594  | 0  |             }  | 
1595  |  |  | 
1596  | 0  |             ch->rx_max_ack_delay = v;  | 
1597  | 0  |             ossl_ackm_set_rx_max_ack_delay(ch->ackm,  | 
1598  | 0  |                                            ossl_ms2time(ch->rx_max_ack_delay));  | 
1599  |  | 
  | 
1600  | 0  |             got_max_ack_delay = 1;  | 
1601  | 0  |             break;  | 
1602  |  |  | 
1603  | 0  |         case QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI:  | 
1604  | 0  |             if (got_initial_max_streams_bidi) { | 
1605  |  |                 /* must not appear more than once */  | 
1606  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_BIDI"); | 
1607  | 0  |                 goto malformed;  | 
1608  | 0  |             }  | 
1609  |  |  | 
1610  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1611  | 0  |                 || v > (((uint64_t)1) << 60)) { | 
1612  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_BIDI"); | 
1613  | 0  |                 goto malformed;  | 
1614  | 0  |             }  | 
1615  |  |  | 
1616  | 0  |             assert(ch->max_local_streams_bidi == 0);  | 
1617  | 0  |             ch->max_local_streams_bidi = v;  | 
1618  | 0  |             got_initial_max_streams_bidi = 1;  | 
1619  | 0  |             break;  | 
1620  |  |  | 
1621  | 0  |         case QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI:  | 
1622  | 0  |             if (got_initial_max_streams_uni) { | 
1623  |  |                 /* must not appear more than once */  | 
1624  | 0  |                 reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_UNI"); | 
1625  | 0  |                 goto malformed;  | 
1626  | 0  |             }  | 
1627  |  |  | 
1628  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1629  | 0  |                 || v > (((uint64_t)1) << 60)) { | 
1630  | 0  |                 reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_UNI"); | 
1631  | 0  |                 goto malformed;  | 
1632  | 0  |             }  | 
1633  |  |  | 
1634  | 0  |             assert(ch->max_local_streams_uni == 0);  | 
1635  | 0  |             ch->max_local_streams_uni = v;  | 
1636  | 0  |             got_initial_max_streams_uni = 1;  | 
1637  | 0  |             break;  | 
1638  |  |  | 
1639  | 0  |         case QUIC_TPARAM_MAX_IDLE_TIMEOUT:  | 
1640  | 0  |             if (got_max_idle_timeout) { | 
1641  |  |                 /* must not appear more than once */  | 
1642  | 0  |                 reason = TP_REASON_DUP("MAX_IDLE_TIMEOUT"); | 
1643  | 0  |                 goto malformed;  | 
1644  | 0  |             }  | 
1645  |  |  | 
1646  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) { | 
1647  | 0  |                 reason = TP_REASON_MALFORMED("MAX_IDLE_TIMEOUT"); | 
1648  | 0  |                 goto malformed;  | 
1649  | 0  |             }  | 
1650  |  |  | 
1651  | 0  |             ch->max_idle_timeout_remote_req = v;  | 
1652  |  | 
  | 
1653  | 0  |             ch->max_idle_timeout = min_u64_ignore_0(ch->max_idle_timeout_local_req,  | 
1654  | 0  |                                                     ch->max_idle_timeout_remote_req);  | 
1655  |  |  | 
1656  |  | 
  | 
1657  | 0  |             ch_update_idle(ch);  | 
1658  | 0  |             got_max_idle_timeout = 1;  | 
1659  | 0  |             rx_max_idle_timeout = v;  | 
1660  | 0  |             break;  | 
1661  |  |  | 
1662  | 0  |         case QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE:  | 
1663  | 0  |             if (got_max_udp_payload_size) { | 
1664  |  |                 /* must not appear more than once */  | 
1665  | 0  |                 reason = TP_REASON_DUP("MAX_UDP_PAYLOAD_SIZE"); | 
1666  | 0  |                 goto malformed;  | 
1667  | 0  |             }  | 
1668  |  |  | 
1669  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1670  | 0  |                 || v < QUIC_MIN_INITIAL_DGRAM_LEN) { | 
1671  | 0  |                 reason = TP_REASON_MALFORMED("MAX_UDP_PAYLOAD_SIZE"); | 
1672  | 0  |                 goto malformed;  | 
1673  | 0  |             }  | 
1674  |  |  | 
1675  | 0  |             ch->rx_max_udp_payload_size = v;  | 
1676  | 0  |             got_max_udp_payload_size    = 1;  | 
1677  | 0  |             break;  | 
1678  |  |  | 
1679  | 0  |         case QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT:  | 
1680  | 0  |             if (got_active_conn_id_limit) { | 
1681  |  |                 /* must not appear more than once */  | 
1682  | 0  |                 reason = TP_REASON_DUP("ACTIVE_CONN_ID_LIMIT"); | 
1683  | 0  |                 goto malformed;  | 
1684  | 0  |             }  | 
1685  |  |  | 
1686  | 0  |             if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)  | 
1687  | 0  |                 || v < QUIC_MIN_ACTIVE_CONN_ID_LIMIT) { | 
1688  | 0  |                 reason = TP_REASON_MALFORMED("ACTIVE_CONN_ID_LIMIT"); | 
1689  | 0  |                 goto malformed;  | 
1690  | 0  |             }  | 
1691  |  |  | 
1692  | 0  |             ch->rx_active_conn_id_limit = v;  | 
1693  | 0  |             got_active_conn_id_limit = 1;  | 
1694  | 0  |             break;  | 
1695  |  |  | 
1696  | 0  |         case QUIC_TPARAM_STATELESS_RESET_TOKEN:  | 
1697  | 0  |             if (got_stateless_reset_token) { | 
1698  | 0  |                 reason = TP_REASON_DUP("STATELESS_RESET_TOKEN"); | 
1699  | 0  |                 goto malformed;  | 
1700  | 0  |             }  | 
1701  |  |  | 
1702  |  |             /*  | 
1703  |  |              * RFC 9000 s. 18.2: This transport parameter MUST NOT be sent  | 
1704  |  |              * by a client but MAY be sent by a server.  | 
1705  |  |              */  | 
1706  | 0  |             if (ch->is_server) { | 
1707  | 0  |                 reason = TP_REASON_SERVER_ONLY("STATELESS_RESET_TOKEN"); | 
1708  | 0  |                 goto malformed;  | 
1709  | 0  |             }  | 
1710  |  |  | 
1711  | 0  |             body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len);  | 
1712  | 0  |             if (body == NULL || len != QUIC_STATELESS_RESET_TOKEN_LEN) { | 
1713  | 0  |                 reason = TP_REASON_MALFORMED("STATELESS_RESET_TOKEN"); | 
1714  | 0  |                 goto malformed;  | 
1715  | 0  |             }  | 
1716  | 0  |             if (!ossl_quic_srtm_add(ch->srtm, ch, ch->cur_remote_seq_num,  | 
1717  | 0  |                                     (const QUIC_STATELESS_RESET_TOKEN *)body)) { | 
1718  | 0  |                 reason = TP_REASON_INTERNAL_ERROR("STATELESS_RESET_TOKEN"); | 
1719  | 0  |                 goto malformed;  | 
1720  | 0  |             }  | 
1721  |  |  | 
1722  | 0  |             stateless_reset_token_p     = body;  | 
1723  | 0  |             got_stateless_reset_token   = 1;  | 
1724  | 0  |             break;  | 
1725  |  |  | 
1726  | 0  |         case QUIC_TPARAM_PREFERRED_ADDR:  | 
1727  |  |             /* TODO(QUIC FUTURE): Handle preferred address. */  | 
1728  | 0  |             if (got_preferred_addr) { | 
1729  | 0  |                 reason = TP_REASON_DUP("PREFERRED_ADDR"); | 
1730  | 0  |                 goto malformed;  | 
1731  | 0  |             }  | 
1732  |  |  | 
1733  |  |             /*  | 
1734  |  |              * RFC 9000 s. 18.2: "A server that chooses a zero-length  | 
1735  |  |              * connection ID MUST NOT provide a preferred address.  | 
1736  |  |              * Similarly, a server MUST NOT include a zero-length connection  | 
1737  |  |              * ID in this transport parameter. A client MUST treat a  | 
1738  |  |              * violation of these requirements as a connection error of type  | 
1739  |  |              * TRANSPORT_PARAMETER_ERROR."  | 
1740  |  |              */  | 
1741  | 0  |             if (ch->is_server) { | 
1742  | 0  |                 reason = TP_REASON_SERVER_ONLY("PREFERRED_ADDR"); | 
1743  | 0  |                 goto malformed;  | 
1744  | 0  |             }  | 
1745  |  |  | 
1746  | 0  |             if (ch->cur_remote_dcid.id_len == 0) { | 
1747  | 0  |                 reason = "PREFERRED_ADDR provided for zero-length CID";  | 
1748  | 0  |                 goto malformed;  | 
1749  | 0  |             }  | 
1750  |  |  | 
1751  | 0  |             if (!ossl_quic_wire_decode_transport_param_preferred_addr(&pkt, &pfa)) { | 
1752  | 0  |                 reason = TP_REASON_MALFORMED("PREFERRED_ADDR"); | 
1753  | 0  |                 goto malformed;  | 
1754  | 0  |             }  | 
1755  |  |  | 
1756  | 0  |             if (pfa.cid.id_len == 0) { | 
1757  | 0  |                 reason = "zero-length CID in PREFERRED_ADDR";  | 
1758  | 0  |                 goto malformed;  | 
1759  | 0  |             }  | 
1760  |  |  | 
1761  | 0  |             got_preferred_addr = 1;  | 
1762  | 0  |             break;  | 
1763  |  |  | 
1764  | 0  |         case QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION:  | 
1765  |  |             /* We do not currently handle migration, so nothing to do. */  | 
1766  | 0  |             if (got_disable_active_migration) { | 
1767  |  |                 /* must not appear more than once */  | 
1768  | 0  |                 reason = TP_REASON_DUP("DISABLE_ACTIVE_MIGRATION"); | 
1769  | 0  |                 goto malformed;  | 
1770  | 0  |             }  | 
1771  |  |  | 
1772  | 0  |             body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len);  | 
1773  | 0  |             if (body == NULL || len > 0) { | 
1774  | 0  |                 reason = TP_REASON_MALFORMED("DISABLE_ACTIVE_MIGRATION"); | 
1775  | 0  |                 goto malformed;  | 
1776  | 0  |             }  | 
1777  |  |  | 
1778  | 0  |             got_disable_active_migration = 1;  | 
1779  | 0  |             break;  | 
1780  |  |  | 
1781  | 0  |         default:  | 
1782  |  |             /*  | 
1783  |  |              * Skip over and ignore.  | 
1784  |  |              *  | 
1785  |  |              * RFC 9000 s. 7.4: We SHOULD treat duplicated transport parameters  | 
1786  |  |              * as a connection error, but we are not required to. Currently,  | 
1787  |  |              * handle this programmatically by checking for duplicates in the  | 
1788  |  |              * parameters that we recognise, as above, but don't bother  | 
1789  |  |              * maintaining a list of duplicates for anything we don't recognise.  | 
1790  |  |              */  | 
1791  | 0  |             body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id,  | 
1792  | 0  |                                                                &len);  | 
1793  | 0  |             if (body == NULL)  | 
1794  | 0  |                 goto malformed;  | 
1795  |  |  | 
1796  | 0  |             break;  | 
1797  | 0  |         }  | 
1798  | 0  |     }  | 
1799  |  |  | 
1800  | 0  |     if (!got_initial_scid) { | 
1801  | 0  |         reason = TP_REASON_REQUIRED("INITIAL_SCID"); | 
1802  | 0  |         goto malformed;  | 
1803  | 0  |     }  | 
1804  |  |  | 
1805  | 0  |     if (!ch->is_server) { | 
1806  | 0  |         if (!got_orig_dcid) { | 
1807  | 0  |             reason = TP_REASON_REQUIRED("ORIG_DCID"); | 
1808  | 0  |             goto malformed;  | 
1809  | 0  |         }  | 
1810  |  |  | 
1811  | 0  |         if (ch->doing_retry && !got_retry_scid) { | 
1812  | 0  |             reason = TP_REASON_REQUIRED("RETRY_SCID"); | 
1813  | 0  |             goto malformed;  | 
1814  | 0  |         }  | 
1815  | 0  |     }  | 
1816  |  |  | 
1817  | 0  |     ch->got_remote_transport_params = 1;  | 
1818  |  | 
  | 
1819  | 0  | #ifndef OPENSSL_NO_QLOG  | 
1820  | 0  |     QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set)  | 
1821  | 0  |         QLOG_STR("owner", "remote"); | 
1822  |  | 
  | 
1823  | 0  |         if (got_orig_dcid)  | 
1824  | 0  |             QLOG_CID("original_destination_connection_id", | 
1825  | 0  |                      &ch->init_dcid);  | 
1826  | 0  |         if (got_initial_scid)  | 
1827  | 0  |             QLOG_CID("original_source_connection_id", | 
1828  | 0  |                      &ch->init_dcid);  | 
1829  | 0  |         if (got_retry_scid)  | 
1830  | 0  |             QLOG_CID("retry_source_connection_id", | 
1831  | 0  |                      &ch->retry_scid);  | 
1832  | 0  |         if (got_initial_max_data)  | 
1833  | 0  |             QLOG_U64("initial_max_data", | 
1834  | 0  |                      ossl_quic_txfc_get_cwm(&ch->conn_txfc));  | 
1835  | 0  |         if (got_initial_max_stream_data_bidi_local)  | 
1836  | 0  |             QLOG_U64("initial_max_stream_data_bidi_local", | 
1837  | 0  |                      ch->rx_init_max_stream_data_bidi_local);  | 
1838  | 0  |         if (got_initial_max_stream_data_bidi_remote)  | 
1839  | 0  |             QLOG_U64("initial_max_stream_data_bidi_remote", | 
1840  | 0  |                      ch->rx_init_max_stream_data_bidi_remote);  | 
1841  | 0  |         if (got_initial_max_stream_data_uni)  | 
1842  | 0  |             QLOG_U64("initial_max_stream_data_uni", | 
1843  | 0  |                      ch->rx_init_max_stream_data_uni);  | 
1844  | 0  |         if (got_initial_max_streams_bidi)  | 
1845  | 0  |             QLOG_U64("initial_max_streams_bidi", | 
1846  | 0  |                      ch->max_local_streams_bidi);  | 
1847  | 0  |         if (got_initial_max_streams_uni)  | 
1848  | 0  |             QLOG_U64("initial_max_streams_uni", | 
1849  | 0  |                      ch->max_local_streams_uni);  | 
1850  | 0  |         if (got_ack_delay_exp)  | 
1851  | 0  |             QLOG_U64("ack_delay_exponent", ch->rx_ack_delay_exp); | 
1852  | 0  |         if (got_max_ack_delay)  | 
1853  | 0  |             QLOG_U64("max_ack_delay", ch->rx_max_ack_delay); | 
1854  | 0  |         if (got_max_udp_payload_size)  | 
1855  | 0  |             QLOG_U64("max_udp_payload_size", ch->rx_max_udp_payload_size); | 
1856  | 0  |         if (got_max_idle_timeout)  | 
1857  | 0  |             QLOG_U64("max_idle_timeout", rx_max_idle_timeout); | 
1858  | 0  |         if (got_active_conn_id_limit)  | 
1859  | 0  |             QLOG_U64("active_connection_id_limit", ch->rx_active_conn_id_limit); | 
1860  | 0  |         if (got_stateless_reset_token)  | 
1861  | 0  |             QLOG_BIN("stateless_reset_token", stateless_reset_token_p, | 
1862  | 0  |                      QUIC_STATELESS_RESET_TOKEN_LEN);  | 
1863  | 0  |         if (got_preferred_addr) { | 
1864  | 0  |             QLOG_BEGIN("preferred_addr") | 
1865  | 0  |                 QLOG_U64("port_v4", pfa.ipv4_port); | 
1866  | 0  |                 QLOG_U64("port_v6", pfa.ipv6_port); | 
1867  | 0  |                 QLOG_BIN("ip_v4", pfa.ipv4, sizeof(pfa.ipv4)); | 
1868  | 0  |                 QLOG_BIN("ip_v6", pfa.ipv6, sizeof(pfa.ipv6)); | 
1869  | 0  |                 QLOG_BIN("stateless_reset_token", pfa.stateless_reset.token, | 
1870  | 0  |                          sizeof(pfa.stateless_reset.token));  | 
1871  | 0  |                 QLOG_CID("connection_id", &pfa.cid); | 
1872  | 0  |             QLOG_END()  | 
1873  | 0  |         }  | 
1874  | 0  |         QLOG_BOOL("disable_active_migration", got_disable_active_migration); | 
1875  | 0  |     QLOG_EVENT_END()  | 
1876  | 0  | #endif  | 
1877  |  | 
  | 
1878  | 0  |     if (got_initial_max_data || got_initial_max_stream_data_bidi_remote  | 
1879  | 0  |         || got_initial_max_streams_bidi || got_initial_max_streams_uni)  | 
1880  |  |         /*  | 
1881  |  |          * If FC credit was bumped, we may now be able to send. Update all  | 
1882  |  |          * streams.  | 
1883  |  |          */  | 
1884  | 0  |         ossl_quic_stream_map_visit(&ch->qsm, do_update, ch);  | 
1885  |  |  | 
1886  |  |     /* If we are a server, we now generate our own transport parameters. */  | 
1887  | 0  |     if (ch->is_server && !ch_generate_transport_params(ch)) { | 
1888  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,  | 
1889  | 0  |                                                "internal error");  | 
1890  | 0  |         return 0;  | 
1891  | 0  |     }  | 
1892  |  |  | 
1893  | 0  |     return 1;  | 
1894  |  |  | 
1895  | 0  | malformed:  | 
1896  | 0  |     ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR,  | 
1897  | 0  |                                            0, reason);  | 
1898  | 0  |     return 0;  | 
1899  | 0  | }  | 
1900  |  |  | 
1901  |  | /*  | 
1902  |  |  * Called when we want to generate transport parameters. This is called  | 
1903  |  |  * immediately at instantiation time for a client and after we receive the  | 
1904  |  |  * client's transport parameters for a server.  | 
1905  |  |  */  | 
1906  |  | static int ch_generate_transport_params(QUIC_CHANNEL *ch)  | 
1907  | 0  | { | 
1908  | 0  |     int ok = 0;  | 
1909  | 0  |     BUF_MEM *buf_mem = NULL;  | 
1910  | 0  |     WPACKET wpkt;  | 
1911  | 0  |     int wpkt_valid = 0;  | 
1912  | 0  |     size_t buf_len = 0;  | 
1913  | 0  |     QUIC_CONN_ID *id_to_use = NULL;  | 
1914  |  |  | 
1915  |  |     /*  | 
1916  |  |      * We need to select which connection id to encode in the  | 
1917  |  |      * QUIC_TPARAM_ORIG_DCID transport parameter  | 
1918  |  |      * If we have an odcid, then this connection was established  | 
1919  |  |      * in response to a retry request, and we need to use the connection  | 
1920  |  |      * id sent in the first initial packet.  | 
1921  |  |      * If we don't have an odcid, then this connection was established  | 
1922  |  |      * without a retry and the init_dcid is the connection we should use  | 
1923  |  |      */  | 
1924  | 0  |     if (ch->odcid.id_len == 0)  | 
1925  | 0  |         id_to_use = &ch->init_dcid;  | 
1926  | 0  |     else  | 
1927  | 0  |         id_to_use = &ch->odcid;  | 
1928  |  | 
  | 
1929  | 0  |     if (ch->local_transport_params != NULL || ch->got_local_transport_params)  | 
1930  | 0  |         goto err;  | 
1931  |  |  | 
1932  | 0  |     if ((buf_mem = BUF_MEM_new()) == NULL)  | 
1933  | 0  |         goto err;  | 
1934  |  |  | 
1935  | 0  |     if (!WPACKET_init(&wpkt, buf_mem))  | 
1936  | 0  |         goto err;  | 
1937  |  |  | 
1938  | 0  |     wpkt_valid = 1;  | 
1939  |  | 
  | 
1940  | 0  |     if (ossl_quic_wire_encode_transport_param_bytes(&wpkt, QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION,  | 
1941  | 0  |                                                     NULL, 0) == NULL)  | 
1942  | 0  |         goto err;  | 
1943  |  |  | 
1944  | 0  |     if (ch->is_server) { | 
1945  | 0  |         if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_ORIG_DCID,  | 
1946  | 0  |                                                        id_to_use))  | 
1947  | 0  |             goto err;  | 
1948  |  |  | 
1949  | 0  |         if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_INITIAL_SCID,  | 
1950  | 0  |                                                        &ch->cur_local_cid))  | 
1951  | 0  |             goto err;  | 
1952  | 0  |         if (ch->odcid.id_len != 0)  | 
1953  | 0  |             if (!ossl_quic_wire_encode_transport_param_cid(&wpkt,  | 
1954  | 0  |                                                            QUIC_TPARAM_RETRY_SCID,  | 
1955  | 0  |                                                            &ch->init_dcid))  | 
1956  | 0  |                 goto err;  | 
1957  | 0  |     } else { | 
1958  | 0  |         if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_INITIAL_SCID,  | 
1959  | 0  |                                                        &ch->init_scid))  | 
1960  | 0  |             goto err;  | 
1961  | 0  |     }  | 
1962  |  |  | 
1963  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_IDLE_TIMEOUT,  | 
1964  | 0  |                                                    ch->max_idle_timeout_local_req))  | 
1965  | 0  |         goto err;  | 
1966  |  |  | 
1967  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE,  | 
1968  | 0  |                                                    QUIC_MIN_INITIAL_DGRAM_LEN))  | 
1969  | 0  |         goto err;  | 
1970  |  |  | 
1971  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT,  | 
1972  | 0  |                                                    QUIC_MIN_ACTIVE_CONN_ID_LIMIT))  | 
1973  | 0  |         goto err;  | 
1974  |  |  | 
1975  | 0  |     if (ch->tx_max_ack_delay != QUIC_DEFAULT_MAX_ACK_DELAY  | 
1976  | 0  |         && !ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_ACK_DELAY,  | 
1977  | 0  |                                                       ch->tx_max_ack_delay))  | 
1978  | 0  |         goto err;  | 
1979  |  |  | 
1980  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_DATA,  | 
1981  | 0  |                                                    ossl_quic_rxfc_get_cwm(&ch->conn_rxfc)))  | 
1982  | 0  |         goto err;  | 
1983  |  |  | 
1984  |  |     /* Send the default CWM for a new RXFC. */  | 
1985  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,  | 
1986  | 0  |                                                    ch->tx_init_max_stream_data_bidi_local))  | 
1987  | 0  |         goto err;  | 
1988  |  |  | 
1989  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,  | 
1990  | 0  |                                                    ch->tx_init_max_stream_data_bidi_remote))  | 
1991  | 0  |         goto err;  | 
1992  |  |  | 
1993  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI,  | 
1994  | 0  |                                                    ch->tx_init_max_stream_data_uni))  | 
1995  | 0  |         goto err;  | 
1996  |  |  | 
1997  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI,  | 
1998  | 0  |                                                    ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc)))  | 
1999  | 0  |         goto err;  | 
2000  |  |  | 
2001  | 0  |     if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI,  | 
2002  | 0  |                                                    ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc)))  | 
2003  | 0  |         goto err;  | 
2004  |  |  | 
2005  | 0  |     if (!WPACKET_finish(&wpkt))  | 
2006  | 0  |         goto err;  | 
2007  |  |  | 
2008  | 0  |     wpkt_valid = 0;  | 
2009  |  | 
  | 
2010  | 0  |     if (!WPACKET_get_total_written(&wpkt, &buf_len))  | 
2011  | 0  |         goto err;  | 
2012  |  |  | 
2013  | 0  |     ch->local_transport_params = (unsigned char *)buf_mem->data;  | 
2014  | 0  |     buf_mem->data = NULL;  | 
2015  |  | 
  | 
2016  | 0  |     if (!ossl_quic_tls_set_transport_params(ch->qtls, ch->local_transport_params,  | 
2017  | 0  |                                             buf_len))  | 
2018  | 0  |         goto err;  | 
2019  |  |  | 
2020  | 0  | #ifndef OPENSSL_NO_QLOG  | 
2021  | 0  |     QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set)  | 
2022  | 0  |         QLOG_STR("owner", "local"); | 
2023  | 0  |         QLOG_BOOL("disable_active_migration", 1); | 
2024  | 0  |         if (ch->is_server) { | 
2025  | 0  |             QLOG_CID("original_destination_connection_id", &ch->init_dcid); | 
2026  | 0  |             QLOG_CID("initial_source_connection_id", &ch->cur_local_cid); | 
2027  | 0  |         } else { | 
2028  | 0  |             QLOG_STR("initial_source_connection_id", ""); | 
2029  | 0  |         }  | 
2030  | 0  |         QLOG_U64("max_idle_timeout", ch->max_idle_timeout); | 
2031  | 0  |         QLOG_U64("max_udp_payload_size", QUIC_MIN_INITIAL_DGRAM_LEN); | 
2032  | 0  |         QLOG_U64("active_connection_id_limit", QUIC_MIN_ACTIVE_CONN_ID_LIMIT); | 
2033  | 0  |         QLOG_U64("max_ack_delay", ch->tx_max_ack_delay); | 
2034  | 0  |         QLOG_U64("initial_max_data", ossl_quic_rxfc_get_cwm(&ch->conn_rxfc)); | 
2035  | 0  |         QLOG_U64("initial_max_stream_data_bidi_local", | 
2036  | 0  |                  ch->tx_init_max_stream_data_bidi_local);  | 
2037  | 0  |         QLOG_U64("initial_max_stream_data_bidi_remote", | 
2038  | 0  |                  ch->tx_init_max_stream_data_bidi_remote);  | 
2039  | 0  |         QLOG_U64("initial_max_stream_data_uni", | 
2040  | 0  |                  ch->tx_init_max_stream_data_uni);  | 
2041  | 0  |         QLOG_U64("initial_max_streams_bidi", | 
2042  | 0  |                  ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc));  | 
2043  | 0  |         QLOG_U64("initial_max_streams_uni", | 
2044  | 0  |                  ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc));  | 
2045  | 0  |     QLOG_EVENT_END()  | 
2046  | 0  | #endif  | 
2047  |  | 
  | 
2048  | 0  |     ch->got_local_transport_params = 1;  | 
2049  |  | 
  | 
2050  | 0  |     ok = 1;  | 
2051  | 0  | err:  | 
2052  | 0  |     if (wpkt_valid)  | 
2053  | 0  |         WPACKET_cleanup(&wpkt);  | 
2054  | 0  |     BUF_MEM_free(buf_mem);  | 
2055  | 0  |     return ok;  | 
2056  | 0  | }  | 
2057  |  |  | 
2058  |  | /*  | 
2059  |  |  * QUIC Channel: Ticker-Mutator  | 
2060  |  |  * ============================  | 
2061  |  |  */  | 
2062  |  |  | 
2063  |  | /*  | 
2064  |  |  * The central ticker function called by the reactor. This does everything, or  | 
2065  |  |  * at least everything network I/O related. Best effort - not allowed to fail  | 
2066  |  |  * "loudly".  | 
2067  |  |  */  | 
2068  |  | void ossl_quic_channel_subtick(QUIC_CHANNEL *ch, QUIC_TICK_RESULT *res,  | 
2069  |  |                                uint32_t flags)  | 
2070  | 0  | { | 
2071  | 0  |     OSSL_TIME now, deadline;  | 
2072  | 0  |     int channel_only = (flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0;  | 
2073  | 0  |     int notify_other_threads = 0;  | 
2074  |  |  | 
2075  |  |     /*  | 
2076  |  |      * When we tick the QUIC connection, we do everything we need to do  | 
2077  |  |      * periodically. Network I/O handling will already have been performed  | 
2078  |  |      * as necessary by the QUIC port. Thus, in order, we:  | 
2079  |  |      *  | 
2080  |  |      *   - handle any packets the DEMUX has queued up for us;  | 
2081  |  |      *   - handle any timer events which are due to fire (ACKM, etc.);  | 
2082  |  |      *   - generate any packets which need to be sent;  | 
2083  |  |      *   - determine the time at which we should next be ticked.  | 
2084  |  |      */  | 
2085  |  |  | 
2086  |  |     /*  | 
2087  |  |      * If the connection has not yet started, or we are in the TERMINATED state,  | 
2088  |  |      * there is nothing to do.  | 
2089  |  |      */  | 
2090  | 0  |     if (ch->state == QUIC_CHANNEL_STATE_IDLE  | 
2091  | 0  |             || ossl_quic_channel_is_terminated(ch)) { | 
2092  | 0  |         res->net_read_desired       = 0;  | 
2093  | 0  |         res->net_write_desired      = 0;  | 
2094  | 0  |         res->notify_other_threads   = 0;  | 
2095  | 0  |         res->tick_deadline          = ossl_time_infinite();  | 
2096  | 0  |         return;  | 
2097  | 0  |     }  | 
2098  |  |  | 
2099  |  |     /*  | 
2100  |  |      * If we are in the TERMINATING state, check if the terminating timer has  | 
2101  |  |      * expired.  | 
2102  |  |      */  | 
2103  | 0  |     if (ossl_quic_channel_is_terminating(ch)) { | 
2104  | 0  |         now = get_time(ch);  | 
2105  |  | 
  | 
2106  | 0  |         if (ossl_time_compare(now, ch->terminate_deadline) >= 0) { | 
2107  | 0  |             ch_on_terminating_timeout(ch);  | 
2108  | 0  |             res->net_read_desired       = 0;  | 
2109  | 0  |             res->net_write_desired      = 0;  | 
2110  | 0  |             res->notify_other_threads   = 1;  | 
2111  | 0  |             res->tick_deadline          = ossl_time_infinite();  | 
2112  | 0  |             return; /* abort normal processing, nothing to do */  | 
2113  | 0  |         }  | 
2114  | 0  |     }  | 
2115  |  |  | 
2116  | 0  |     if (!ch->port->engine->inhibit_tick) { | 
2117  |  |         /* Handle RXKU timeouts. */  | 
2118  | 0  |         ch_rxku_tick(ch);  | 
2119  |  | 
  | 
2120  | 0  |         do { | 
2121  |  |             /* Process queued incoming packets. */  | 
2122  | 0  |             ch->did_tls_tick        = 0;  | 
2123  | 0  |             ch->have_new_rx_secret  = 0;  | 
2124  | 0  |             ch_rx(ch, channel_only, ¬ify_other_threads);  | 
2125  |  |  | 
2126  |  |             /*  | 
2127  |  |              * Allow the handshake layer to check for any new incoming data and  | 
2128  |  |              * generate new outgoing data.  | 
2129  |  |              */  | 
2130  | 0  |             if (!ch->did_tls_tick)  | 
2131  | 0  |                 ch_tick_tls(ch, channel_only, ¬ify_other_threads);  | 
2132  |  |  | 
2133  |  |             /*  | 
2134  |  |              * If the handshake layer gave us a new secret, we need to do RX  | 
2135  |  |              * again because packets that were not previously processable and  | 
2136  |  |              * were deferred might now be processable.  | 
2137  |  |              *  | 
2138  |  |              * TODO(QUIC FUTURE): Consider handling this in the yield_secret callback.  | 
2139  |  |              */  | 
2140  | 0  |         } while (ch->have_new_rx_secret);  | 
2141  | 0  |     }  | 
2142  |  |  | 
2143  |  |     /*  | 
2144  |  |      * Handle any timer events which are due to fire; namely, the loss  | 
2145  |  |      * detection deadline and the idle timeout.  | 
2146  |  |      *  | 
2147  |  |      * ACKM ACK generation deadline is polled by TXP, so we don't need to  | 
2148  |  |      * handle it here.  | 
2149  |  |      */  | 
2150  | 0  |     now = get_time(ch);  | 
2151  | 0  |     if (ossl_time_compare(now, ch->idle_deadline) >= 0) { | 
2152  |  |         /*  | 
2153  |  |          * Idle timeout differs from normal protocol violation because we do  | 
2154  |  |          * not send a CONN_CLOSE frame; go straight to TERMINATED.  | 
2155  |  |          */  | 
2156  | 0  |         if (!ch->port->engine->inhibit_tick)  | 
2157  | 0  |             ch_on_idle_timeout(ch);  | 
2158  |  | 
  | 
2159  | 0  |         res->net_read_desired       = 0;  | 
2160  | 0  |         res->net_write_desired      = 0;  | 
2161  | 0  |         res->notify_other_threads   = 1;  | 
2162  | 0  |         res->tick_deadline          = ossl_time_infinite();  | 
2163  | 0  |         return;  | 
2164  | 0  |     }  | 
2165  |  |  | 
2166  | 0  |     if (!ch->port->engine->inhibit_tick) { | 
2167  | 0  |         deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);  | 
2168  | 0  |         if (!ossl_time_is_zero(deadline)  | 
2169  | 0  |             && ossl_time_compare(now, deadline) >= 0)  | 
2170  | 0  |             ossl_ackm_on_timeout(ch->ackm);  | 
2171  |  |  | 
2172  |  |         /* If a ping is due, inform TXP. */  | 
2173  | 0  |         if (ossl_time_compare(now, ch->ping_deadline) >= 0) { | 
2174  | 0  |             int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);  | 
2175  |  | 
  | 
2176  | 0  |             ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);  | 
2177  |  |  | 
2178  |  |             /*  | 
2179  |  |              * If we have no CC budget at this time we cannot process the above  | 
2180  |  |              * PING request immediately. In any case we have scheduled the  | 
2181  |  |              * request so bump the ping deadline. If we don't do this we will  | 
2182  |  |              * busy-loop endlessly as the above deadline comparison condition  | 
2183  |  |              * will still be met.  | 
2184  |  |              */  | 
2185  | 0  |             ch_update_ping_deadline(ch);  | 
2186  | 0  |         }  | 
2187  |  |  | 
2188  |  |         /* Queue any data to be sent for transmission. */  | 
2189  | 0  |         ch_tx(ch, ¬ify_other_threads);  | 
2190  |  |  | 
2191  |  |         /* Do stream GC. */  | 
2192  | 0  |         ossl_quic_stream_map_gc(&ch->qsm);  | 
2193  | 0  |     }  | 
2194  |  |  | 
2195  |  |     /* Determine the time at which we should next be ticked. */  | 
2196  | 0  |     res->tick_deadline = ch_determine_next_tick_deadline(ch);  | 
2197  |  |  | 
2198  |  |     /*  | 
2199  |  |      * Always process network input unless we are now terminated. Although we  | 
2200  |  |      * had not terminated at the beginning of this tick, network errors in  | 
2201  |  |      * ch_tx() may have caused us to transition to the Terminated state.  | 
2202  |  |      */  | 
2203  | 0  |     res->net_read_desired = !ossl_quic_channel_is_terminated(ch);  | 
2204  |  |  | 
2205  |  |     /* We want to write to the network if we have any data in our TX queue. */  | 
2206  | 0  |     res->net_write_desired  | 
2207  | 0  |         = (!ossl_quic_channel_is_terminated(ch)  | 
2208  | 0  |            && ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0);  | 
2209  |  | 
  | 
2210  | 0  |     res->notify_other_threads = notify_other_threads;  | 
2211  | 0  | }  | 
2212  |  |  | 
2213  |  | static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads)  | 
2214  | 0  | { | 
2215  | 0  |     uint64_t error_code;  | 
2216  | 0  |     const char *error_msg;  | 
2217  | 0  |     ERR_STATE *error_state = NULL;  | 
2218  |  | 
  | 
2219  | 0  |     if (channel_only)  | 
2220  | 0  |         return 1;  | 
2221  |  |  | 
2222  | 0  |     ch->did_tls_tick = 1;  | 
2223  | 0  |     ossl_quic_tls_tick(ch->qtls);  | 
2224  |  | 
  | 
2225  | 0  |     if (ossl_quic_tls_get_error(ch->qtls, &error_code, &error_msg,  | 
2226  | 0  |                                 &error_state)) { | 
2227  | 0  |         ossl_quic_channel_raise_protocol_error_state(ch, error_code, 0,  | 
2228  | 0  |                                                      error_msg, error_state);  | 
2229  | 0  |         if (notify_other_threads != NULL)  | 
2230  | 0  |             *notify_other_threads = 1;  | 
2231  |  | 
  | 
2232  | 0  |         return 0;  | 
2233  | 0  |     }  | 
2234  |  |  | 
2235  | 0  |     return 1;  | 
2236  | 0  | }  | 
2237  |  |  | 
2238  |  | /* Check incoming forged packet limit and terminate connection if needed. */  | 
2239  |  | static void ch_rx_check_forged_pkt_limit(QUIC_CHANNEL *ch)  | 
2240  | 0  | { | 
2241  | 0  |     uint32_t enc_level;  | 
2242  | 0  |     uint64_t limit = UINT64_MAX, l;  | 
2243  |  | 
  | 
2244  | 0  |     for (enc_level = QUIC_ENC_LEVEL_INITIAL;  | 
2245  | 0  |          enc_level < QUIC_ENC_LEVEL_NUM;  | 
2246  | 0  |          ++enc_level)  | 
2247  | 0  |     { | 
2248  |  |         /*  | 
2249  |  |          * Different ELs can have different AEADs which can in turn impose  | 
2250  |  |          * different limits, so use the lowest value of any currently valid EL.  | 
2251  |  |          */  | 
2252  | 0  |         if ((ch->el_discarded & (1U << enc_level)) != 0)  | 
2253  | 0  |             continue;  | 
2254  |  |  | 
2255  | 0  |         if (enc_level > ch->rx_enc_level)  | 
2256  | 0  |             break;  | 
2257  |  |  | 
2258  | 0  |         l = ossl_qrx_get_max_forged_pkt_count(ch->qrx, enc_level);  | 
2259  | 0  |         if (l < limit)  | 
2260  | 0  |             limit = l;  | 
2261  | 0  |     }  | 
2262  |  | 
  | 
2263  | 0  |     if (ossl_qrx_get_cur_forged_pkt_count(ch->qrx) < limit)  | 
2264  | 0  |         return;  | 
2265  |  |  | 
2266  | 0  |     ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_AEAD_LIMIT_REACHED, 0,  | 
2267  | 0  |                                            "forgery limit");  | 
2268  | 0  | }  | 
2269  |  |  | 
2270  |  | /* Process queued incoming packets and handle frames, if any. */  | 
2271  |  | static int ch_rx(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads)  | 
2272  | 0  | { | 
2273  | 0  |     int handled_any = 0;  | 
2274  | 0  |     const int closing = ossl_quic_channel_is_closing(ch);  | 
2275  |  | 
  | 
2276  | 0  |     if (!ch->is_server && !ch->have_sent_any_pkt)  | 
2277  |  |         /*  | 
2278  |  |          * We have not sent anything yet, therefore there is no need to check  | 
2279  |  |          * for incoming data.  | 
2280  |  |          */  | 
2281  | 0  |         return 1;  | 
2282  |  |  | 
2283  | 0  |     for (;;) { | 
2284  | 0  |         assert(ch->qrx_pkt == NULL);  | 
2285  |  | 
  | 
2286  | 0  |         if (!ossl_qrx_read_pkt(ch->qrx, &ch->qrx_pkt))  | 
2287  | 0  |             break;  | 
2288  |  |  | 
2289  |  |         /* Track the amount of data received while in the closing state */  | 
2290  | 0  |         if (closing)  | 
2291  | 0  |             ossl_quic_tx_packetiser_record_received_closing_bytes(  | 
2292  | 0  |                     ch->txp, ch->qrx_pkt->hdr->len);  | 
2293  |  | 
  | 
2294  | 0  |         if (!handled_any) { | 
2295  | 0  |             ch_update_idle(ch);  | 
2296  | 0  |             ch_update_ping_deadline(ch);  | 
2297  | 0  |         }  | 
2298  |  | 
  | 
2299  | 0  |         ch_rx_handle_packet(ch, channel_only); /* best effort */  | 
2300  |  |  | 
2301  |  |         /*  | 
2302  |  |          * Regardless of the outcome of frame handling, unref the packet.  | 
2303  |  |          * This will free the packet unless something added another  | 
2304  |  |          * reference to it during frame processing.  | 
2305  |  |          */  | 
2306  | 0  |         ossl_qrx_pkt_release(ch->qrx_pkt);  | 
2307  | 0  |         ch->qrx_pkt = NULL;  | 
2308  |  | 
  | 
2309  | 0  |         ch->have_sent_ack_eliciting_since_rx = 0;  | 
2310  | 0  |         handled_any = 1;  | 
2311  | 0  |     }  | 
2312  |  | 
  | 
2313  | 0  |     ch_rx_check_forged_pkt_limit(ch);  | 
2314  |  | 
  | 
2315  | 0  |     if (handled_any && notify_other_threads != NULL)  | 
2316  | 0  |         *notify_other_threads = 1;  | 
2317  |  |  | 
2318  |  |     /*  | 
2319  |  |      * When in TERMINATING - CLOSING, generate a CONN_CLOSE frame whenever we  | 
2320  |  |      * process one or more incoming packets.  | 
2321  |  |      */  | 
2322  | 0  |     if (handled_any && closing)  | 
2323  | 0  |         ch->conn_close_queued = 1;  | 
2324  |  | 
  | 
2325  | 0  |     return 1;  | 
2326  | 0  | }  | 
2327  |  |  | 
2328  |  | static int bio_addr_eq(const BIO_ADDR *a, const BIO_ADDR *b)  | 
2329  | 0  | { | 
2330  | 0  |     if (BIO_ADDR_family(a) != BIO_ADDR_family(b))  | 
2331  | 0  |         return 0;  | 
2332  |  |  | 
2333  | 0  |     switch (BIO_ADDR_family(a)) { | 
2334  | 0  |         case AF_INET:  | 
2335  | 0  |             return !memcmp(&a->s_in.sin_addr,  | 
2336  | 0  |                            &b->s_in.sin_addr,  | 
2337  | 0  |                            sizeof(a->s_in.sin_addr))  | 
2338  | 0  |                 && a->s_in.sin_port == b->s_in.sin_port;  | 
2339  | 0  | #if OPENSSL_USE_IPV6  | 
2340  | 0  |         case AF_INET6:  | 
2341  | 0  |             return !memcmp(&a->s_in6.sin6_addr,  | 
2342  | 0  |                            &b->s_in6.sin6_addr,  | 
2343  | 0  |                            sizeof(a->s_in6.sin6_addr))  | 
2344  | 0  |                 && a->s_in6.sin6_port == b->s_in6.sin6_port;  | 
2345  | 0  | #endif  | 
2346  | 0  |         default:  | 
2347  | 0  |             return 0; /* not supported */  | 
2348  | 0  |     }  | 
2349  |  |  | 
2350  | 0  |     return 1;  | 
2351  | 0  | }  | 
2352  |  |  | 
2353  |  | /* Handles the packet currently in ch->qrx_pkt->hdr. */  | 
2354  |  | static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)  | 
2355  | 0  | { | 
2356  | 0  |     uint32_t enc_level;  | 
2357  | 0  |     int old_have_processed_any_pkt = ch->have_processed_any_pkt;  | 
2358  | 0  |     OSSL_QTX_IOVEC iovec;  | 
2359  | 0  |     PACKET vpkt;  | 
2360  | 0  |     unsigned long supported_ver;  | 
2361  |  | 
  | 
2362  | 0  |     assert(ch->qrx_pkt != NULL);  | 
2363  |  |  | 
2364  |  |     /*  | 
2365  |  |      * RFC 9000 s. 10.2.1 Closing Connection State:  | 
2366  |  |      *      An endpoint that is closing is not required to process any  | 
2367  |  |      *      received frame.  | 
2368  |  |      */  | 
2369  | 0  |     if (!ossl_quic_channel_is_active(ch))  | 
2370  | 0  |         return;  | 
2371  |  |  | 
2372  | 0  |     if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type)) { | 
2373  | 0  |         if (!ch->have_received_enc_pkt) { | 
2374  | 0  |             ch->cur_remote_dcid = ch->init_scid = ch->qrx_pkt->hdr->src_conn_id;  | 
2375  | 0  |             ch->have_received_enc_pkt = 1;  | 
2376  |  |  | 
2377  |  |             /*  | 
2378  |  |              * We change to using the SCID in the first Initial packet as the  | 
2379  |  |              * DCID.  | 
2380  |  |              */  | 
2381  | 0  |             ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->init_scid);  | 
2382  | 0  |         }  | 
2383  |  | 
  | 
2384  | 0  |         enc_level = ossl_quic_pkt_type_to_enc_level(ch->qrx_pkt->hdr->type);  | 
2385  | 0  |         if ((ch->el_discarded & (1U << enc_level)) != 0)  | 
2386  |  |             /* Do not process packets from ELs we have already discarded. */  | 
2387  | 0  |             return;  | 
2388  | 0  |     }  | 
2389  |  |  | 
2390  |  |     /*  | 
2391  |  |      * RFC 9000 s. 9.6: "If a client receives packets from a new server address  | 
2392  |  |      * when the client has not initiated a migration to that address, the client  | 
2393  |  |      * SHOULD discard these packets."  | 
2394  |  |      *  | 
2395  |  |      * We need to be a bit careful here as due to the BIO abstraction layer an  | 
2396  |  |      * application is liable to be weird and lie to us about peer addresses.  | 
2397  |  |      * Only apply this check if we actually are using a real AF_INET or AF_INET6  | 
2398  |  |      * address.  | 
2399  |  |      */  | 
2400  | 0  |     if (!ch->is_server  | 
2401  | 0  |         && ch->qrx_pkt->peer != NULL  | 
2402  | 0  |         && (  | 
2403  | 0  |                BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET  | 
2404  | 0  | #if OPENSSL_USE_IPV6  | 
2405  | 0  |             || BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET6  | 
2406  | 0  | #endif  | 
2407  | 0  |         )  | 
2408  | 0  |         && !bio_addr_eq(ch->qrx_pkt->peer, &ch->cur_peer_addr))  | 
2409  | 0  |         return;  | 
2410  |  |  | 
2411  | 0  |     if (!ch->is_server  | 
2412  | 0  |         && ch->have_received_enc_pkt  | 
2413  | 0  |         && ossl_quic_pkt_type_has_scid(ch->qrx_pkt->hdr->type)) { | 
2414  |  |         /*  | 
2415  |  |          * RFC 9000 s. 7.2: "Once a client has received a valid Initial packet  | 
2416  |  |          * from the server, it MUST discard any subsequent packet it receives on  | 
2417  |  |          * that connection with a different SCID."  | 
2418  |  |          */  | 
2419  | 0  |         if (!ossl_quic_conn_id_eq(&ch->qrx_pkt->hdr->src_conn_id,  | 
2420  | 0  |                                   &ch->init_scid))  | 
2421  | 0  |             return;  | 
2422  | 0  |     }  | 
2423  |  |  | 
2424  | 0  |     if (ossl_quic_pkt_type_has_version(ch->qrx_pkt->hdr->type)  | 
2425  | 0  |         && ch->qrx_pkt->hdr->version != QUIC_VERSION_1)  | 
2426  |  |         /*  | 
2427  |  |          * RFC 9000 s. 5.2.1: If a client receives a packet that uses a  | 
2428  |  |          * different version than it initially selected, it MUST discard the  | 
2429  |  |          * packet. We only ever use v1, so require it.  | 
2430  |  |          */  | 
2431  | 0  |         return;  | 
2432  |  |  | 
2433  | 0  |     if (ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_VERSION_NEG) { | 
2434  |  |  | 
2435  |  |         /*  | 
2436  |  |          * Sanity check.  Version negotiation packet MUST have a version  | 
2437  |  |          * value of 0 according to the RFC.  We must discard such packets  | 
2438  |  |          */  | 
2439  | 0  |         if (ch->qrx_pkt->hdr->version != 0)  | 
2440  | 0  |             return;  | 
2441  |  |  | 
2442  |  |         /*  | 
2443  |  |          * RFC 9000 s. 6.2: If a client receives a version negotiation  | 
2444  |  |          * packet, we need to do the following:  | 
2445  |  |          * a) If the negotiation packet lists the version we initially sent  | 
2446  |  |          *    then we must abandon this connection attempt  | 
2447  |  |          * b) We have to select a version from the list provided in the  | 
2448  |  |          *    version negotiation packet, and retry the connection attempt  | 
2449  |  |          *    in much the same way that ch_retry does, but we can reuse the  | 
2450  |  |          *    connection id values  | 
2451  |  |          */  | 
2452  |  |  | 
2453  | 0  |         if (old_have_processed_any_pkt == 1) { | 
2454  |  |             /*  | 
2455  |  |              * We've gotten previous packets, need to discard this.  | 
2456  |  |              */  | 
2457  | 0  |             return;  | 
2458  | 0  |         }  | 
2459  |  |  | 
2460  |  |         /*  | 
2461  |  |          * Indicate that we have processed a packet, as any subsequently  | 
2462  |  |          * received version negotiation packet must be discarded above  | 
2463  |  |          */  | 
2464  | 0  |         ch->have_processed_any_pkt = 1;  | 
2465  |  |  | 
2466  |  |         /*  | 
2467  |  |          * Following the header, version negotiation packets  | 
2468  |  |          * contain an array of 32 bit integers representing  | 
2469  |  |          * the supported versions that the server honors  | 
2470  |  |          * this array, bounded by the hdr->len field  | 
2471  |  |          * needs to be traversed so that we can find a matching  | 
2472  |  |          * version  | 
2473  |  |          */  | 
2474  | 0  |         if (!PACKET_buf_init(&vpkt, ch->qrx_pkt->hdr->data,  | 
2475  | 0  |                              ch->qrx_pkt->hdr->len))  | 
2476  | 0  |             return;  | 
2477  |  |  | 
2478  | 0  |         while (PACKET_remaining(&vpkt) > 0) { | 
2479  |  |             /*  | 
2480  |  |              * We only support quic version 1 at the moment, so  | 
2481  |  |              * look to see if that's offered  | 
2482  |  |              */  | 
2483  | 0  |             if (!PACKET_get_net_4(&vpkt, &supported_ver))  | 
2484  | 0  |                 return;  | 
2485  |  |  | 
2486  | 0  |             if (supported_ver == QUIC_VERSION_1) { | 
2487  |  |                 /*  | 
2488  |  |                  * If the server supports version 1, set it as  | 
2489  |  |                  * the packetisers version  | 
2490  |  |                  */  | 
2491  | 0  |                 ossl_quic_tx_packetiser_set_protocol_version(ch->txp, QUIC_VERSION_1);  | 
2492  |  |  | 
2493  |  |                 /*  | 
2494  |  |                  * And then request a restart of the QUIC connection   | 
2495  |  |                  */  | 
2496  | 0  |                 if (!ch_restart(ch))  | 
2497  | 0  |                     ossl_quic_channel_raise_protocol_error(ch,  | 
2498  | 0  |                                                            OSSL_QUIC_ERR_INTERNAL_ERROR,  | 
2499  | 0  |                                                            0, "handling ver negotiation packet");  | 
2500  | 0  |                 return;  | 
2501  | 0  |             }  | 
2502  | 0  |         }  | 
2503  |  |  | 
2504  |  |         /*  | 
2505  |  |          * If we get here, then the server doesn't support a version of the  | 
2506  |  |          * protocol that we can handle, abandon the connection  | 
2507  |  |          */  | 
2508  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CONNECTION_REFUSED,  | 
2509  | 0  |                                                0, "unsupported protocol version");  | 
2510  | 0  |         return;  | 
2511  | 0  |     }  | 
2512  |  |  | 
2513  | 0  |     ch->have_processed_any_pkt = 1;  | 
2514  |  |  | 
2515  |  |     /*  | 
2516  |  |      * RFC 9000 s. 17.2: "An endpoint MUST treat receipt of a packet that has a  | 
2517  |  |      * non-zero value for [the reserved bits] after removing both packet and  | 
2518  |  |      * header protection as a connection error of type PROTOCOL_VIOLATION."  | 
2519  |  |      */  | 
2520  | 0  |     if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type)  | 
2521  | 0  |         && ch->qrx_pkt->hdr->reserved != 0) { | 
2522  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
2523  | 0  |                                                0, "packet header reserved bits");  | 
2524  | 0  |         return;  | 
2525  | 0  |     }  | 
2526  |  |  | 
2527  | 0  |     iovec.buf       = ch->qrx_pkt->hdr->data;  | 
2528  | 0  |     iovec.buf_len   = ch->qrx_pkt->hdr->len;  | 
2529  | 0  |     ossl_qlog_event_transport_packet_received(ch_get_qlog(ch), ch->qrx_pkt->hdr,  | 
2530  | 0  |                                               ch->qrx_pkt->pn, &iovec, 1,  | 
2531  | 0  |                                               ch->qrx_pkt->datagram_id);  | 
2532  |  |  | 
2533  |  |     /* Handle incoming packet. */  | 
2534  | 0  |     switch (ch->qrx_pkt->hdr->type) { | 
2535  | 0  |     case QUIC_PKT_TYPE_RETRY:  | 
2536  | 0  |         if (ch->doing_retry || ch->is_server)  | 
2537  |  |             /*  | 
2538  |  |              * It is not allowed to ask a client to do a retry more than  | 
2539  |  |              * once. Clients may not send retries.  | 
2540  |  |              */  | 
2541  | 0  |             return;  | 
2542  |  |  | 
2543  |  |         /*  | 
2544  |  |          * RFC 9000 s 17.2.5.2: After the client has received and processed an  | 
2545  |  |          * Initial or Retry packet from the server, it MUST discard any  | 
2546  |  |          * subsequent Retry packets that it receives.  | 
2547  |  |          */  | 
2548  | 0  |         if (ch->have_received_enc_pkt)  | 
2549  | 0  |             return;  | 
2550  |  |  | 
2551  | 0  |         if (ch->qrx_pkt->hdr->len <= QUIC_RETRY_INTEGRITY_TAG_LEN)  | 
2552  |  |             /* Packets with zero-length Retry Tokens are invalid. */  | 
2553  | 0  |             return;  | 
2554  |  |  | 
2555  |  |         /*  | 
2556  |  |          * TODO(QUIC FUTURE): Theoretically this should probably be in the QRX.  | 
2557  |  |          * However because validation is dependent on context (namely the  | 
2558  |  |          * client's initial DCID) we can't do this cleanly. In the future we  | 
2559  |  |          * should probably add a callback to the QRX to let it call us (via  | 
2560  |  |          * the DEMUX) and ask us about the correct original DCID, rather  | 
2561  |  |          * than allow the QRX to emit a potentially malformed packet to the  | 
2562  |  |          * upper layers. However, special casing this will do for now.  | 
2563  |  |          */  | 
2564  | 0  |         if (!ossl_quic_validate_retry_integrity_tag(ch->port->engine->libctx,  | 
2565  | 0  |                                                     ch->port->engine->propq,  | 
2566  | 0  |                                                     ch->qrx_pkt->hdr,  | 
2567  | 0  |                                                     &ch->init_dcid))  | 
2568  |  |             /* Malformed retry packet, ignore. */  | 
2569  | 0  |             return;  | 
2570  |  |  | 
2571  | 0  |         if (!ch_retry(ch, ch->qrx_pkt->hdr->data,  | 
2572  | 0  |                       ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN,  | 
2573  | 0  |                       &ch->qrx_pkt->hdr->src_conn_id, old_have_processed_any_pkt))  | 
2574  | 0  |             ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,  | 
2575  | 0  |                                                    0, "handling retry packet");  | 
2576  | 0  |         break;  | 
2577  |  |  | 
2578  | 0  |     case QUIC_PKT_TYPE_0RTT:  | 
2579  | 0  |         if (!ch->is_server)  | 
2580  |  |             /* Clients should never receive 0-RTT packets. */  | 
2581  | 0  |             return;  | 
2582  |  |  | 
2583  |  |         /*  | 
2584  |  |          * TODO(QUIC 0RTT): Implement 0-RTT on the server side. We currently  | 
2585  |  |          * do not need to implement this as a client can only do 0-RTT if we  | 
2586  |  |          * have given it permission to in a previous session.  | 
2587  |  |          */  | 
2588  | 0  |         break;  | 
2589  |  |  | 
2590  | 0  |     case QUIC_PKT_TYPE_INITIAL:  | 
2591  | 0  |     case QUIC_PKT_TYPE_HANDSHAKE:  | 
2592  | 0  |     case QUIC_PKT_TYPE_1RTT:  | 
2593  | 0  |         if (ch->is_server && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_HANDSHAKE)  | 
2594  |  |             /*  | 
2595  |  |              * We automatically drop INITIAL EL keys when first successfully  | 
2596  |  |              * decrypting a HANDSHAKE packet, as per the RFC.  | 
2597  |  |              */  | 
2598  | 0  |             ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);  | 
2599  |  | 
  | 
2600  | 0  |         if (ch->rxku_in_progress  | 
2601  | 0  |             && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_1RTT  | 
2602  | 0  |             && ch->qrx_pkt->pn >= ch->rxku_trigger_pn  | 
2603  | 0  |             && ch->qrx_pkt->key_epoch < ossl_qrx_get_key_epoch(ch->qrx)) { | 
2604  |  |             /*  | 
2605  |  |              * RFC 9001 s. 6.4: Packets with higher packet numbers MUST be  | 
2606  |  |              * protected with either the same or newer packet protection keys  | 
2607  |  |              * than packets with lower packet numbers. An endpoint that  | 
2608  |  |              * successfully removes protection with old keys when newer keys  | 
2609  |  |              * were used for packets with lower packet numbers MUST treat this  | 
2610  |  |              * as a connection error of type KEY_UPDATE_ERROR.  | 
2611  |  |              */  | 
2612  | 0  |             ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR,  | 
2613  | 0  |                                                    0, "new packet with old keys");  | 
2614  | 0  |             break;  | 
2615  | 0  |         }  | 
2616  |  |  | 
2617  | 0  |         if (!ch->is_server  | 
2618  | 0  |             && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_INITIAL  | 
2619  | 0  |             && ch->qrx_pkt->hdr->token_len > 0) { | 
2620  |  |             /*  | 
2621  |  |              * RFC 9000 s. 17.2.2: Clients that receive an Initial packet with a  | 
2622  |  |              * non-zero Token Length field MUST either discard the packet or  | 
2623  |  |              * generate a connection error of type PROTOCOL_VIOLATION.  | 
2624  |  |              *  | 
2625  |  |              * TODO(QUIC FUTURE): consider the implications of RFC 9000 s. 10.2.3  | 
2626  |  |              * Immediate Close during the Handshake:  | 
2627  |  |              *      However, at the cost of reducing feedback about  | 
2628  |  |              *      errors for legitimate peers, some forms of denial of  | 
2629  |  |              *      service can be made more difficult for an attacker  | 
2630  |  |              *      if endpoints discard illegal packets rather than  | 
2631  |  |              *      terminating a connection with CONNECTION_CLOSE. For  | 
2632  |  |              *      this reason, endpoints MAY discard packets rather  | 
2633  |  |              *      than immediately close if errors are detected in  | 
2634  |  |              *      packets that lack authentication.  | 
2635  |  |              * I.e. should we drop this packet instead of closing the connection?  | 
2636  |  |              */  | 
2637  | 0  |             ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
2638  | 0  |                                                    0, "client received initial token");  | 
2639  | 0  |             break;  | 
2640  | 0  |         }  | 
2641  |  |  | 
2642  |  |         /* This packet contains frames, pass to the RXDP. */  | 
2643  | 0  |         ossl_quic_handle_frames(ch, ch->qrx_pkt); /* best effort */  | 
2644  |  | 
  | 
2645  | 0  |         if (ch->did_crypto_frame)  | 
2646  | 0  |             ch_tick_tls(ch, channel_only, NULL);  | 
2647  |  | 
  | 
2648  | 0  |         break;  | 
2649  |  |  | 
2650  | 0  |     case QUIC_PKT_TYPE_VERSION_NEG:  | 
2651  |  |         /*  | 
2652  |  |          * "A client MUST discard any Version Negotiation packet if it has  | 
2653  |  |          * received and successfully processed any other packet."  | 
2654  |  |          */  | 
2655  | 0  |         if (!old_have_processed_any_pkt)  | 
2656  | 0  |             ch_rx_handle_version_neg(ch, ch->qrx_pkt);  | 
2657  |  | 
  | 
2658  | 0  |         break;  | 
2659  |  |  | 
2660  | 0  |     default:  | 
2661  | 0  |         assert(0);  | 
2662  | 0  |         break;  | 
2663  | 0  |     }  | 
2664  |  | 
  | 
2665  | 0  | }  | 
2666  |  |  | 
2667  |  | static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt)  | 
2668  | 0  | { | 
2669  |  |     /*  | 
2670  |  |      * We do not support version negotiation at this time. As per RFC 9000 s.  | 
2671  |  |      * 6.2., we MUST abandon the connection attempt if we receive a Version  | 
2672  |  |      * Negotiation packet, unless we have already successfully processed another  | 
2673  |  |      * incoming packet, or the packet lists the QUIC version we want to use.  | 
2674  |  |      */  | 
2675  | 0  |     PACKET vpkt;  | 
2676  | 0  |     unsigned long v;  | 
2677  |  | 
  | 
2678  | 0  |     if (!PACKET_buf_init(&vpkt, pkt->hdr->data, pkt->hdr->len))  | 
2679  | 0  |         return;  | 
2680  |  |  | 
2681  | 0  |     while (PACKET_remaining(&vpkt) > 0) { | 
2682  | 0  |         if (!PACKET_get_net_4(&vpkt, &v))  | 
2683  | 0  |             break;  | 
2684  |  |  | 
2685  | 0  |         if ((uint32_t)v == QUIC_VERSION_1)  | 
2686  | 0  |             return;  | 
2687  | 0  |     }  | 
2688  |  |  | 
2689  |  |     /* No match, this is a failure case. */  | 
2690  | 0  |     ch_raise_version_neg_failure(ch);  | 
2691  | 0  | }  | 
2692  |  |  | 
2693  |  | static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch)  | 
2694  | 0  | { | 
2695  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
2696  |  | 
  | 
2697  | 0  |     tcause.error_code = OSSL_QUIC_ERR_CONNECTION_REFUSED;  | 
2698  | 0  |     tcause.reason     = "version negotiation failure";  | 
2699  | 0  |     tcause.reason_len = strlen(tcause.reason);  | 
2700  |  |  | 
2701  |  |     /*  | 
2702  |  |      * Skip TERMINATING state; this is not considered a protocol error and we do  | 
2703  |  |      * not send CONNECTION_CLOSE.  | 
2704  |  |      */  | 
2705  | 0  |     ch_start_terminating(ch, &tcause, 1);  | 
2706  | 0  | }  | 
2707  |  |  | 
2708  |  | /* Try to generate packets and if possible, flush them to the network. */  | 
2709  |  | static int ch_tx(QUIC_CHANNEL *ch, int *notify_other_threads)  | 
2710  | 0  | { | 
2711  | 0  |     QUIC_TXP_STATUS status;  | 
2712  | 0  |     int res;  | 
2713  |  |  | 
2714  |  |     /*  | 
2715  |  |      * RFC 9000 s. 10.2.2: Draining Connection State:  | 
2716  |  |      *      While otherwise identical to the closing state, an endpoint  | 
2717  |  |      *      in the draining state MUST NOT send any packets.  | 
2718  |  |      * and:  | 
2719  |  |      *      An endpoint MUST NOT send further packets.  | 
2720  |  |      */  | 
2721  | 0  |     if (ossl_quic_channel_is_draining(ch))  | 
2722  | 0  |         return 0;  | 
2723  |  |  | 
2724  | 0  |     if (ossl_quic_channel_is_closing(ch)) { | 
2725  |  |         /*  | 
2726  |  |          * While closing, only send CONN_CLOSE if we've received more traffic  | 
2727  |  |          * from the peer. Once we tell the TXP to generate CONN_CLOSE, all  | 
2728  |  |          * future calls to it generate CONN_CLOSE frames, so otherwise we would  | 
2729  |  |          * just constantly generate CONN_CLOSE frames.  | 
2730  |  |          *  | 
2731  |  |          * Confirming to RFC 9000 s. 10.2.1 Closing Connection State:  | 
2732  |  |          *      An endpoint SHOULD limit the rate at which it generates  | 
2733  |  |          *      packets in the closing state.  | 
2734  |  |          */  | 
2735  | 0  |         if (!ch->conn_close_queued)  | 
2736  | 0  |             return 0;  | 
2737  |  |  | 
2738  | 0  |         ch->conn_close_queued = 0;  | 
2739  | 0  |     }  | 
2740  |  |  | 
2741  |  |     /* Do TXKU if we need to. */  | 
2742  | 0  |     ch_maybe_trigger_spontaneous_txku(ch);  | 
2743  |  | 
  | 
2744  | 0  |     ch->rxku_pending_confirm_done = 0;  | 
2745  |  |  | 
2746  |  |     /* Loop until we stop generating packets to send */  | 
2747  | 0  |     do { | 
2748  |  |         /*  | 
2749  |  |         * Send packet, if we need to. Best effort. The TXP consults the CC and  | 
2750  |  |         * applies any limitations imposed by it, so we don't need to do it here.  | 
2751  |  |         *  | 
2752  |  |         * Best effort. In particular if TXP fails for some reason we should  | 
2753  |  |         * still flush any queued packets which we already generated.  | 
2754  |  |         */  | 
2755  | 0  |         res = ossl_quic_tx_packetiser_generate(ch->txp, &status);  | 
2756  | 0  |         if (status.sent_pkt > 0) { | 
2757  | 0  |             ch->have_sent_any_pkt = 1; /* Packet(s) were sent */  | 
2758  | 0  |             ch->port->have_sent_any_pkt = 1;  | 
2759  |  |  | 
2760  |  |             /*  | 
2761  |  |             * RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when  | 
2762  |  |             * sending an ack-eliciting packet if no other ack-eliciting packets  | 
2763  |  |             * have been sent since last receiving and processing a packet.'  | 
2764  |  |             */  | 
2765  | 0  |             if (status.sent_ack_eliciting  | 
2766  | 0  |                     && !ch->have_sent_ack_eliciting_since_rx) { | 
2767  | 0  |                 ch_update_idle(ch);  | 
2768  | 0  |                 ch->have_sent_ack_eliciting_since_rx = 1;  | 
2769  | 0  |             }  | 
2770  |  | 
  | 
2771  | 0  |             if (!ch->is_server && status.sent_handshake)  | 
2772  |  |                 /*  | 
2773  |  |                 * RFC 9001 s. 4.9.1: A client MUST discard Initial keys when it  | 
2774  |  |                 * first sends a Handshake packet.  | 
2775  |  |                 */  | 
2776  | 0  |                 ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);  | 
2777  |  | 
  | 
2778  | 0  |             if (ch->rxku_pending_confirm_done)  | 
2779  | 0  |                 ch->rxku_pending_confirm = 0;  | 
2780  |  | 
  | 
2781  | 0  |             ch_update_ping_deadline(ch);  | 
2782  | 0  |         }  | 
2783  |  | 
  | 
2784  | 0  |         if (!res) { | 
2785  |  |             /*  | 
2786  |  |             * One case where TXP can fail is if we reach a TX PN of 2**62 - 1.  | 
2787  |  |             * As per RFC 9000 s. 12.3, if this happens we MUST close the  | 
2788  |  |             * connection without sending a CONNECTION_CLOSE frame. This is  | 
2789  |  |             * actually handled as an emergent consequence of our design, as the  | 
2790  |  |             * TX packetiser will never transmit another packet when the TX PN  | 
2791  |  |             * reaches the limit.  | 
2792  |  |             *  | 
2793  |  |             * Calling the below function terminates the connection; its attempt  | 
2794  |  |             * to schedule a CONNECTION_CLOSE frame will not actually cause a  | 
2795  |  |             * packet to be transmitted for this reason.  | 
2796  |  |             */  | 
2797  | 0  |             ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,  | 
2798  | 0  |                                                    0,  | 
2799  | 0  |                                                    "internal error (txp generate)");  | 
2800  | 0  |             break;  | 
2801  | 0  |         }  | 
2802  | 0  |     } while (status.sent_pkt > 0);  | 
2803  |  |  | 
2804  |  |     /* Flush packets to network. */  | 
2805  | 0  |     switch (ossl_qtx_flush_net(ch->qtx)) { | 
2806  | 0  |     case QTX_FLUSH_NET_RES_OK:  | 
2807  | 0  |     case QTX_FLUSH_NET_RES_TRANSIENT_FAIL:  | 
2808  |  |         /* Best effort, done for now. */  | 
2809  | 0  |         break;  | 
2810  |  |  | 
2811  | 0  |     case QTX_FLUSH_NET_RES_PERMANENT_FAIL:  | 
2812  | 0  |     default:  | 
2813  |  |         /* Permanent underlying network BIO, start terminating. */  | 
2814  | 0  |         ossl_quic_port_raise_net_error(ch->port, ch);  | 
2815  | 0  |         break;  | 
2816  | 0  |     }  | 
2817  |  |  | 
2818  |  |     /*  | 
2819  |  |      * If we have datagrams we have yet to successfully transmit, we need to  | 
2820  |  |      * notify other threads so that they can switch to polling on POLLOUT as  | 
2821  |  |      * well as POLLIN.  | 
2822  |  |      */  | 
2823  | 0  |     if (ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0)  | 
2824  | 0  |         *notify_other_threads = 1;  | 
2825  |  | 
  | 
2826  | 0  |     return 1;  | 
2827  | 0  | }  | 
2828  |  |  | 
2829  |  | /* Determine next tick deadline. */  | 
2830  |  | static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch)  | 
2831  | 0  | { | 
2832  | 0  |     OSSL_TIME deadline;  | 
2833  | 0  |     int i;  | 
2834  |  | 
  | 
2835  | 0  |     if (ossl_quic_channel_is_terminated(ch))  | 
2836  | 0  |         return ossl_time_infinite();  | 
2837  |  |  | 
2838  | 0  |     deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);  | 
2839  | 0  |     if (ossl_time_is_zero(deadline))  | 
2840  | 0  |         deadline = ossl_time_infinite();  | 
2841  |  |  | 
2842  |  |     /*  | 
2843  |  |      * Check the ack deadline for all enc_levels that are actually provisioned.  | 
2844  |  |      * ACKs aren't restricted by CC.  | 
2845  |  |      */  | 
2846  | 0  |     for (i = 0; i < QUIC_ENC_LEVEL_NUM; i++) { | 
2847  | 0  |         if (ossl_qtx_is_enc_level_provisioned(ch->qtx, i)) { | 
2848  | 0  |             deadline = ossl_time_min(deadline,  | 
2849  | 0  |                                      ossl_ackm_get_ack_deadline(ch->ackm,  | 
2850  | 0  |                                                                 ossl_quic_enc_level_to_pn_space(i)));  | 
2851  | 0  |         }  | 
2852  | 0  |     }  | 
2853  |  |  | 
2854  |  |     /*  | 
2855  |  |      * When do we need to send an ACK-eliciting packet to reset the idle  | 
2856  |  |      * deadline timer for the peer?  | 
2857  |  |      */  | 
2858  | 0  |     if (!ossl_time_is_infinite(ch->ping_deadline))  | 
2859  | 0  |         deadline = ossl_time_min(deadline, ch->ping_deadline);  | 
2860  |  |  | 
2861  |  |     /* Apply TXP wakeup deadline. */  | 
2862  | 0  |     deadline = ossl_time_min(deadline,  | 
2863  | 0  |                              ossl_quic_tx_packetiser_get_deadline(ch->txp));  | 
2864  |  |  | 
2865  |  |     /* Is the terminating timer armed? */  | 
2866  | 0  |     if (ossl_quic_channel_is_terminating(ch))  | 
2867  | 0  |         deadline = ossl_time_min(deadline,  | 
2868  | 0  |                                  ch->terminate_deadline);  | 
2869  | 0  |     else if (!ossl_time_is_infinite(ch->idle_deadline))  | 
2870  | 0  |         deadline = ossl_time_min(deadline,  | 
2871  | 0  |                                  ch->idle_deadline);  | 
2872  |  |  | 
2873  |  |     /* When does the RXKU process complete? */  | 
2874  | 0  |     if (ch->rxku_in_progress)  | 
2875  | 0  |         deadline = ossl_time_min(deadline, ch->rxku_update_end_deadline);  | 
2876  |  | 
  | 
2877  | 0  |     return deadline;  | 
2878  | 0  | }  | 
2879  |  |  | 
2880  |  | /*  | 
2881  |  |  * QUIC Channel: Lifecycle Events  | 
2882  |  |  * ==============================  | 
2883  |  |  */  | 
2884  |  |  | 
2885  |  | /*  | 
2886  |  |  * Record a state transition. This is not necessarily a change to ch->state but  | 
2887  |  |  * also includes the handshake becoming complete or confirmed, etc.  | 
2888  |  |  */  | 
2889  |  | static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state)  | 
2890  | 0  | { | 
2891  | 0  |     uint32_t old_state = ch->state;  | 
2892  |  | 
  | 
2893  | 0  |     ch->state = new_state;  | 
2894  |  | 
  | 
2895  | 0  |     ossl_qlog_event_connectivity_connection_state_updated(ch_get_qlog(ch),  | 
2896  | 0  |                                                           old_state,  | 
2897  | 0  |                                                           new_state,  | 
2898  | 0  |                                                           ch->handshake_complete,  | 
2899  | 0  |                                                           ch->handshake_confirmed);  | 
2900  | 0  | }  | 
2901  |  |  | 
2902  |  | static void free_peer_token(const unsigned char *token,  | 
2903  |  |                             size_t token_len, void *arg)  | 
2904  | 0  | { | 
2905  | 0  |     ossl_quic_free_peer_token((QUIC_TOKEN *)arg);  | 
2906  | 0  | }  | 
2907  |  |  | 
2908  |  | int ossl_quic_channel_start(QUIC_CHANNEL *ch)  | 
2909  | 0  | { | 
2910  | 0  |     QUIC_TOKEN *token;  | 
2911  |  | 
  | 
2912  | 0  |     if (ch->is_server)  | 
2913  |  |         /*  | 
2914  |  |          * This is not used by the server. The server moves to active  | 
2915  |  |          * automatically on receiving an incoming connection.  | 
2916  |  |          */  | 
2917  | 0  |         return 0;  | 
2918  |  |  | 
2919  | 0  |     if (ch->state != QUIC_CHANNEL_STATE_IDLE)  | 
2920  |  |         /* Calls to connect are idempotent */  | 
2921  | 0  |         return 1;  | 
2922  |  |  | 
2923  |  |     /* Inform QTX of peer address. */  | 
2924  | 0  |     if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr))  | 
2925  | 0  |         return 0;  | 
2926  |  |  | 
2927  |  |     /*  | 
2928  |  |      * Look to see if we have a token, and if so, set it on the packetiser  | 
2929  |  |      */  | 
2930  | 0  |     if (!ch->is_server  | 
2931  | 0  |         && ossl_quic_get_peer_token(ch->port->channel_ctx,  | 
2932  | 0  |                                     &ch->cur_peer_addr,  | 
2933  | 0  |                                     &token)  | 
2934  | 0  |         && !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token->token,  | 
2935  | 0  |                                                       token->token_len,  | 
2936  | 0  |                                                       free_peer_token,  | 
2937  | 0  |                                                       token))  | 
2938  | 0  |         free_peer_token(NULL, 0, token);  | 
2939  |  |  | 
2940  |  |     /* Plug in secrets for the Initial EL. */  | 
2941  | 0  |     if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,  | 
2942  | 0  |                                           ch->port->engine->propq,  | 
2943  | 0  |                                           &ch->init_dcid,  | 
2944  | 0  |                                           ch->is_server,  | 
2945  | 0  |                                           ch->qrx, ch->qtx))  | 
2946  | 0  |         return 0;  | 
2947  |  |  | 
2948  |  |     /*  | 
2949  |  |      * Determine the QUIC Transport Parameters and serialize the transport  | 
2950  |  |      * parameters block. (For servers, we do this later as we must defer  | 
2951  |  |      * generation until we have received the client's transport parameters.)  | 
2952  |  |      */  | 
2953  | 0  |     if (!ch->is_server && !ch->got_local_transport_params  | 
2954  | 0  |         && !ch_generate_transport_params(ch))  | 
2955  | 0  |         return 0;  | 
2956  |  |  | 
2957  |  |     /* Change state. */  | 
2958  | 0  |     ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE);  | 
2959  | 0  |     ch->doing_proactive_ver_neg = 0; /* not currently supported */  | 
2960  |  | 
  | 
2961  | 0  |     ossl_qlog_event_connectivity_connection_started(ch_get_qlog(ch),  | 
2962  | 0  |                                                     &ch->init_dcid);  | 
2963  |  |  | 
2964  |  |     /* Handshake layer: start (e.g. send CH). */  | 
2965  | 0  |     if (!ch_tick_tls(ch, /*channel_only=*/0, NULL))  | 
2966  | 0  |         return 0;  | 
2967  |  |  | 
2968  | 0  |     ossl_quic_reactor_tick(ossl_quic_port_get0_reactor(ch->port), 0); /* best effort */  | 
2969  | 0  |     return 1;  | 
2970  | 0  | }  | 
2971  |  |  | 
2972  |  | static void free_token(const unsigned char *token, size_t token_len, void *arg)  | 
2973  | 0  | { | 
2974  | 0  |     OPENSSL_free((char *)token);  | 
2975  | 0  | }  | 
2976  |  |  | 
2977  |  | /* Start a locally initiated connection shutdown. */  | 
2978  |  | void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,  | 
2979  |  |                                    const char *app_reason)  | 
2980  | 0  | { | 
2981  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
2982  |  | 
  | 
2983  | 0  |     if (ossl_quic_channel_is_term_any(ch))  | 
2984  | 0  |         return;  | 
2985  |  |  | 
2986  | 0  |     tcause.app          = 1;  | 
2987  | 0  |     tcause.error_code   = app_error_code;  | 
2988  | 0  |     tcause.reason       = app_reason;  | 
2989  | 0  |     tcause.reason_len   = app_reason != NULL ? strlen(app_reason) : 0;  | 
2990  | 0  |     ch_start_terminating(ch, &tcause, 0);  | 
2991  | 0  | }  | 
2992  |  |  | 
2993  |  | /**  | 
2994  |  |  * ch_restart - Restarts the QUIC channel by simulating loss of the initial  | 
2995  |  |  * packet. This forces the packet to be regenerated with the updated protocol  | 
2996  |  |  * version number.  | 
2997  |  |  *  | 
2998  |  |  * @ch: Pointer to the QUIC_CHANNEL structure.  | 
2999  |  |  *  | 
3000  |  |  * Returns 1 on success, 0 on failure.  | 
3001  |  |  */  | 
3002  |  | static int ch_restart(QUIC_CHANNEL *ch)  | 
3003  | 0  | { | 
3004  |  |     /*  | 
3005  |  |      * Just pretend we lost our initial packet, so it gets  | 
3006  |  |      * regenerated, with our updated protocol version number  | 
3007  |  |      */  | 
3008  | 0  |    return ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,  | 
3009  | 0  |                                             /* PN= */ 0);  | 
3010  | 0  | }  | 
3011  |  |  | 
3012  |  | /* Called when a server asks us to do a retry. */  | 
3013  |  | static int ch_retry(QUIC_CHANNEL *ch,  | 
3014  |  |                     const unsigned char *retry_token,  | 
3015  |  |                     size_t retry_token_len,  | 
3016  |  |                     const QUIC_CONN_ID *retry_scid,  | 
3017  |  |                     int drop_later_pn)  | 
3018  | 0  | { | 
3019  | 0  |     void *buf;  | 
3020  | 0  |     QUIC_PN pn = 0;  | 
3021  |  |  | 
3022  |  |     /*  | 
3023  |  |      * RFC 9000 s. 17.2.5.1: "A client MUST discard a Retry packet that contains  | 
3024  |  |      * a SCID field that is identical to the DCID field of its initial packet."  | 
3025  |  |      */  | 
3026  | 0  |     if (ossl_quic_conn_id_eq(&ch->init_dcid, retry_scid))  | 
3027  | 0  |         return 1;  | 
3028  |  |  | 
3029  |  |     /* We change to using the SCID in the Retry packet as the DCID. */  | 
3030  | 0  |     if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, retry_scid))  | 
3031  | 0  |         return 0;  | 
3032  |  |  | 
3033  |  |     /*  | 
3034  |  |      * Now we retry. We will release the Retry packet immediately, so copy  | 
3035  |  |      * the token.  | 
3036  |  |      */  | 
3037  | 0  |     if ((buf = OPENSSL_memdup(retry_token, retry_token_len)) == NULL)  | 
3038  | 0  |         return 0;  | 
3039  |  |  | 
3040  | 0  |     if (!ossl_quic_tx_packetiser_set_initial_token(ch->txp, buf,  | 
3041  | 0  |                                                    retry_token_len,  | 
3042  | 0  |                                                    free_token, NULL)) { | 
3043  |  |         /*  | 
3044  |  |          * This may fail if the token we receive is too big for us to ever be  | 
3045  |  |          * able to transmit in an outgoing Initial packet.  | 
3046  |  |          */  | 
3047  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INVALID_TOKEN, 0,  | 
3048  | 0  |                                                "received oversize token");  | 
3049  | 0  |         OPENSSL_free(buf);  | 
3050  | 0  |         return 0;  | 
3051  | 0  |     }  | 
3052  |  |  | 
3053  | 0  |     ch->retry_scid  = *retry_scid;  | 
3054  | 0  |     ch->doing_retry = 1;  | 
3055  |  |  | 
3056  |  |     /*  | 
3057  |  |      * If a retry isn't our first response, we need to drop packet number  | 
3058  |  |      * one instead (i.e. the case where we did version negotiation first  | 
3059  |  |      */  | 
3060  | 0  |     if (drop_later_pn == 1)  | 
3061  | 0  |         pn = 1;  | 
3062  |  |  | 
3063  |  |     /*  | 
3064  |  |      * We need to stimulate the Initial EL to generate the first CRYPTO frame  | 
3065  |  |      * again. We can do this most cleanly by simply forcing the ACKM to consider  | 
3066  |  |      * the first Initial packet as lost, which it effectively was as the server  | 
3067  |  |      * hasn't processed it. This also maintains the desired behaviour with e.g.  | 
3068  |  |      * PNs not resetting and so on.  | 
3069  |  |      *  | 
3070  |  |      * The PN we used initially is always zero, because QUIC does not allow  | 
3071  |  |      * repeated retries.  | 
3072  |  |      */  | 
3073  | 0  |     if (!ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,  | 
3074  | 0  |                                            pn))  | 
3075  | 0  |         return 0;  | 
3076  |  |  | 
3077  |  |     /*  | 
3078  |  |      * Plug in new secrets for the Initial EL. This is the only time we change  | 
3079  |  |      * the secrets for an EL after we already provisioned it.  | 
3080  |  |      */  | 
3081  | 0  |     if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,  | 
3082  | 0  |                                           ch->port->engine->propq,  | 
3083  | 0  |                                           &ch->retry_scid,  | 
3084  | 0  |                                           /*is_server=*/0,  | 
3085  | 0  |                                           ch->qrx, ch->qtx))  | 
3086  | 0  |         return 0;  | 
3087  |  |  | 
3088  | 0  |     return 1;  | 
3089  | 0  | }  | 
3090  |  |  | 
3091  |  | /* Called when an EL is to be discarded. */  | 
3092  |  | static int ch_discard_el(QUIC_CHANNEL *ch,  | 
3093  |  |                          uint32_t enc_level)  | 
3094  | 0  | { | 
3095  | 0  |     if (!ossl_assert(enc_level < QUIC_ENC_LEVEL_1RTT))  | 
3096  | 0  |         return 0;  | 
3097  |  |  | 
3098  | 0  |     if ((ch->el_discarded & (1U << enc_level)) != 0)  | 
3099  |  |         /* Already done. */  | 
3100  | 0  |         return 1;  | 
3101  |  |  | 
3102  |  |     /* Best effort for all of these. */  | 
3103  | 0  |     ossl_quic_tx_packetiser_discard_enc_level(ch->txp, enc_level);  | 
3104  | 0  |     ossl_qrx_discard_enc_level(ch->qrx, enc_level);  | 
3105  | 0  |     ossl_qtx_discard_enc_level(ch->qtx, enc_level);  | 
3106  |  | 
  | 
3107  | 0  |     if (enc_level != QUIC_ENC_LEVEL_0RTT) { | 
3108  | 0  |         uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);  | 
3109  |  | 
  | 
3110  | 0  |         ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space);  | 
3111  |  |  | 
3112  |  |         /* We should still have crypto streams at this point. */  | 
3113  | 0  |         if (!ossl_assert(ch->crypto_send[pn_space] != NULL)  | 
3114  | 0  |             || !ossl_assert(ch->crypto_recv[pn_space] != NULL))  | 
3115  | 0  |             return 0;  | 
3116  |  |  | 
3117  |  |         /* Get rid of the crypto stream state for the EL. */  | 
3118  | 0  |         ossl_quic_sstream_free(ch->crypto_send[pn_space]);  | 
3119  | 0  |         ch->crypto_send[pn_space] = NULL;  | 
3120  |  | 
  | 
3121  | 0  |         ossl_quic_rstream_free(ch->crypto_recv[pn_space]);  | 
3122  | 0  |         ch->crypto_recv[pn_space] = NULL;  | 
3123  | 0  |     }  | 
3124  |  |  | 
3125  | 0  |     ch->el_discarded |= (1U << enc_level);  | 
3126  | 0  |     return 1;  | 
3127  | 0  | }  | 
3128  |  |  | 
3129  |  | /* Intended to be called by the RXDP. */  | 
3130  |  | int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch)  | 
3131  | 0  | { | 
3132  | 0  |     if (ch->handshake_confirmed)  | 
3133  | 0  |         return 1;  | 
3134  |  |  | 
3135  | 0  |     if (!ch->handshake_complete) { | 
3136  |  |         /*  | 
3137  |  |          * Does not make sense for handshake to be confirmed before it is  | 
3138  |  |          * completed.  | 
3139  |  |          */  | 
3140  | 0  |         ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
3141  | 0  |                                                OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE,  | 
3142  | 0  |                                                "handshake cannot be confirmed "  | 
3143  | 0  |                                                "before it is completed");  | 
3144  | 0  |         return 0;  | 
3145  | 0  |     }  | 
3146  |  |  | 
3147  | 0  |     ch_discard_el(ch, QUIC_ENC_LEVEL_HANDSHAKE);  | 
3148  | 0  |     ch->handshake_confirmed = 1;  | 
3149  | 0  |     ch_record_state_transition(ch, ch->state);  | 
3150  | 0  |     ossl_ackm_on_handshake_confirmed(ch->ackm);  | 
3151  | 0  |     return 1;  | 
3152  | 0  | }  | 
3153  |  |  | 
3154  |  | /*  | 
3155  |  |  * Master function used when we want to start tearing down a connection:  | 
3156  |  |  *  | 
3157  |  |  *   - If the connection is still IDLE we can go straight to TERMINATED;  | 
3158  |  |  *  | 
3159  |  |  *   - If we are already TERMINATED this is a no-op.  | 
3160  |  |  *  | 
3161  |  |  *   - If we are TERMINATING - CLOSING and we have now got a CONNECTION_CLOSE  | 
3162  |  |  *     from the peer (tcause->remote == 1), we move to TERMINATING - DRAINING.  | 
3163  |  |  *  | 
3164  |  |  *   - If we are TERMINATING - DRAINING, we remain here until the terminating  | 
3165  |  |  *     timer expires.  | 
3166  |  |  *  | 
3167  |  |  *   - Otherwise, we are in ACTIVE and move to TERMINATING - CLOSING.  | 
3168  |  |  *     if we caused the termination (e.g. we have sent a CONNECTION_CLOSE). Note  | 
3169  |  |  *     that we are considered to have caused a termination if we sent the first  | 
3170  |  |  *     CONNECTION_CLOSE frame, even if it is caused by a peer protocol  | 
3171  |  |  *     violation. If the peer sent the first CONNECTION_CLOSE frame, we move to  | 
3172  |  |  *     TERMINATING - DRAINING.  | 
3173  |  |  *  | 
3174  |  |  * We record the termination cause structure passed on the first call only.  | 
3175  |  |  * Any successive calls have their termination cause data discarded;  | 
3176  |  |  * once we start sending a CONNECTION_CLOSE frame, we don't change the details  | 
3177  |  |  * in it.  | 
3178  |  |  *  | 
3179  |  |  * This conforms to RFC 9000 s. 10.2.1: Closing Connection State:  | 
3180  |  |  *      To minimize the state that an endpoint maintains for a closing  | 
3181  |  |  *      connection, endpoints MAY send the exact same packet in response  | 
3182  |  |  *      to any received packet.  | 
3183  |  |  *  | 
3184  |  |  * We don't drop any connection state (specifically packet protection keys)  | 
3185  |  |  * even though we are permitted to.  This conforms to RFC 9000 s. 10.2.1:  | 
3186  |  |  * Closing Connection State:  | 
3187  |  |  *       An endpoint MAY retain packet protection keys for incoming  | 
3188  |  |  *       packets to allow it to read and process a CONNECTION_CLOSE frame.  | 
3189  |  |  *  | 
3190  |  |  * Note that we do not conform to these two from the same section:  | 
3191  |  |  *      An endpoint's selected connection ID and the QUIC version  | 
3192  |  |  *      are sufficient information to identify packets for a closing  | 
3193  |  |  *      connection; the endpoint MAY discard all other connection state.  | 
3194  |  |  * and:  | 
3195  |  |  *      An endpoint MAY drop packet protection keys when entering the  | 
3196  |  |  *      closing state and send a packet containing a CONNECTION_CLOSE  | 
3197  |  |  *      frame in response to any UDP datagram that is received.  | 
3198  |  |  */  | 
3199  |  | static void copy_tcause(QUIC_TERMINATE_CAUSE *dst,  | 
3200  |  |                         const QUIC_TERMINATE_CAUSE *src)  | 
3201  | 0  | { | 
3202  |  |     /*  | 
3203  |  |      * do not override reason once it got set.  | 
3204  |  |      */  | 
3205  | 0  |     if (dst->reason != NULL)  | 
3206  | 0  |         return;  | 
3207  |  |  | 
3208  | 0  |     dst->error_code = src->error_code;  | 
3209  | 0  |     dst->frame_type = src->frame_type;  | 
3210  | 0  |     dst->app        = src->app;  | 
3211  | 0  |     dst->remote     = src->remote;  | 
3212  |  | 
  | 
3213  | 0  |     if (src->reason != NULL && src->reason_len > 0) { | 
3214  | 0  |         size_t l = src->reason_len;  | 
3215  | 0  |         char *r;  | 
3216  |  | 
  | 
3217  | 0  |         if (l >= SIZE_MAX)  | 
3218  | 0  |             --l;  | 
3219  |  |  | 
3220  |  |         /*  | 
3221  |  |          * If this fails, dst->reason becomes NULL and we simply do not use a  | 
3222  |  |          * reason. This ensures termination is infallible.  | 
3223  |  |          */  | 
3224  | 0  |         dst->reason = r = OPENSSL_memdup(src->reason, l + 1);  | 
3225  | 0  |         if (r == NULL)  | 
3226  | 0  |             return;  | 
3227  |  |  | 
3228  | 0  |         r[l]  = '\0';  | 
3229  | 0  |         dst->reason_len = l;  | 
3230  | 0  |     }  | 
3231  | 0  | }  | 
3232  |  |  | 
3233  |  | void ossl_quic_channel_set_tcause(QUIC_CHANNEL *ch, uint64_t app_error_code,  | 
3234  |  |                                   const char *app_reason)  | 
3235  | 0  | { | 
3236  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
3237  |  | 
  | 
3238  | 0  |     tcause.app          = 1;  | 
3239  | 0  |     tcause.error_code   = app_error_code;  | 
3240  | 0  |     tcause.reason       = app_reason;  | 
3241  | 0  |     tcause.reason_len   = app_reason != NULL ? strlen(app_reason) : 0;  | 
3242  | 0  |     copy_tcause(&ch->terminate_cause, &tcause);  | 
3243  | 0  | }  | 
3244  |  |  | 
3245  |  | static void ch_start_terminating(QUIC_CHANNEL *ch,  | 
3246  |  |                                  const QUIC_TERMINATE_CAUSE *tcause,  | 
3247  |  |                                  int force_immediate)  | 
3248  | 0  | { | 
3249  |  |     /* No point sending anything if we haven't sent anything yet. */  | 
3250  | 0  |     if (!ch->have_sent_any_pkt)  | 
3251  | 0  |         force_immediate = 1;  | 
3252  |  | 
  | 
3253  | 0  |     switch (ch->state) { | 
3254  | 0  |     default:  | 
3255  | 0  |     case QUIC_CHANNEL_STATE_IDLE:  | 
3256  | 0  |         copy_tcause(&ch->terminate_cause, tcause);  | 
3257  | 0  |         ch_on_terminating_timeout(ch);  | 
3258  | 0  |         break;  | 
3259  |  |  | 
3260  | 0  |     case QUIC_CHANNEL_STATE_ACTIVE:  | 
3261  | 0  |         copy_tcause(&ch->terminate_cause, tcause);  | 
3262  |  | 
  | 
3263  | 0  |         ossl_qlog_event_connectivity_connection_closed(ch_get_qlog(ch), tcause);  | 
3264  |  | 
  | 
3265  | 0  |         if (!force_immediate) { | 
3266  | 0  |             ossl_quic_channel_notify_flush_done(ch);  | 
3267  | 0  |         } else { | 
3268  | 0  |             ch_on_terminating_timeout(ch);  | 
3269  | 0  |         }  | 
3270  | 0  |         break;  | 
3271  |  |  | 
3272  | 0  |     case QUIC_CHANNEL_STATE_TERMINATING_CLOSING:  | 
3273  | 0  |         if (force_immediate)  | 
3274  | 0  |             ch_on_terminating_timeout(ch);  | 
3275  | 0  |         else if (tcause->remote)  | 
3276  |  |             /*  | 
3277  |  |              * RFC 9000 s. 10.2.2 Draining Connection State:  | 
3278  |  |              *  An endpoint MAY enter the draining state from the  | 
3279  |  |              *  closing state if it receives a CONNECTION_CLOSE frame,  | 
3280  |  |              *  which indicates that the peer is also closing or draining.  | 
3281  |  |              */  | 
3282  | 0  |             ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATING_DRAINING);  | 
3283  |  | 
  | 
3284  | 0  |         break;  | 
3285  |  |  | 
3286  | 0  |     case QUIC_CHANNEL_STATE_TERMINATING_DRAINING:  | 
3287  |  |         /*  | 
3288  |  |          * Other than in the force-immediate case, we remain here until the  | 
3289  |  |          * timeout expires.  | 
3290  |  |          */  | 
3291  | 0  |         if (force_immediate)  | 
3292  | 0  |             ch_on_terminating_timeout(ch);  | 
3293  |  | 
  | 
3294  | 0  |         break;  | 
3295  |  |  | 
3296  | 0  |     case QUIC_CHANNEL_STATE_TERMINATED:  | 
3297  |  |         /* No-op. */  | 
3298  | 0  |         break;  | 
3299  | 0  |     }  | 
3300  | 0  | }  | 
3301  |  |  | 
3302  |  | /* For RXDP use. */  | 
3303  |  | void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,  | 
3304  |  |                                             OSSL_QUIC_FRAME_CONN_CLOSE *f)  | 
3305  | 0  | { | 
3306  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
3307  |  | 
  | 
3308  | 0  |     if (!ossl_quic_channel_is_active(ch))  | 
3309  | 0  |         return;  | 
3310  |  |  | 
3311  | 0  |     tcause.remote     = 1;  | 
3312  | 0  |     tcause.app        = f->is_app;  | 
3313  | 0  |     tcause.error_code = f->error_code;  | 
3314  | 0  |     tcause.frame_type = f->frame_type;  | 
3315  | 0  |     tcause.reason     = f->reason;  | 
3316  | 0  |     tcause.reason_len = f->reason_len;  | 
3317  | 0  |     ch_start_terminating(ch, &tcause, 0);  | 
3318  | 0  | }  | 
3319  |  |  | 
3320  |  | static void free_frame_data(unsigned char *buf, size_t buf_len, void *arg)  | 
3321  | 0  | { | 
3322  | 0  |     OPENSSL_free(buf);  | 
3323  | 0  | }  | 
3324  |  |  | 
3325  |  | static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num)  | 
3326  | 0  | { | 
3327  | 0  |     BUF_MEM *buf_mem = NULL;  | 
3328  | 0  |     WPACKET wpkt;  | 
3329  | 0  |     size_t l;  | 
3330  |  | 
  | 
3331  | 0  |     ossl_quic_srtm_remove(ch->srtm, ch, seq_num);  | 
3332  |  | 
  | 
3333  | 0  |     if ((buf_mem = BUF_MEM_new()) == NULL)  | 
3334  | 0  |         goto err;  | 
3335  |  |  | 
3336  | 0  |     if (!WPACKET_init(&wpkt, buf_mem))  | 
3337  | 0  |         goto err;  | 
3338  |  |  | 
3339  | 0  |     if (!ossl_quic_wire_encode_frame_retire_conn_id(&wpkt, seq_num)) { | 
3340  | 0  |         WPACKET_cleanup(&wpkt);  | 
3341  | 0  |         goto err;  | 
3342  | 0  |     }  | 
3343  |  |  | 
3344  | 0  |     WPACKET_finish(&wpkt);  | 
3345  | 0  |     if (!WPACKET_get_total_written(&wpkt, &l))  | 
3346  | 0  |         goto err;  | 
3347  |  |  | 
3348  | 0  |     if (ossl_quic_cfq_add_frame(ch->cfq, 1, QUIC_PN_SPACE_APP,  | 
3349  | 0  |                                 OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, 0,  | 
3350  | 0  |                                 (unsigned char *)buf_mem->data, l,  | 
3351  | 0  |                                 free_frame_data, NULL) == NULL)  | 
3352  | 0  |         goto err;  | 
3353  |  |  | 
3354  | 0  |     buf_mem->data = NULL;  | 
3355  | 0  |     BUF_MEM_free(buf_mem);  | 
3356  | 0  |     return 1;  | 
3357  |  |  | 
3358  | 0  | err:  | 
3359  | 0  |     ossl_quic_channel_raise_protocol_error(ch,  | 
3360  | 0  |                                            OSSL_QUIC_ERR_INTERNAL_ERROR,  | 
3361  | 0  |                                            OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,  | 
3362  | 0  |                                            "internal error enqueueing retire conn id");  | 
3363  | 0  |     BUF_MEM_free(buf_mem);  | 
3364  | 0  |     return 0;  | 
3365  | 0  | }  | 
3366  |  |  | 
3367  |  | void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,  | 
3368  |  |                                       OSSL_QUIC_FRAME_NEW_CONN_ID *f)  | 
3369  | 0  | { | 
3370  | 0  |     uint64_t new_remote_seq_num = ch->cur_remote_seq_num;  | 
3371  | 0  |     uint64_t new_retire_prior_to = ch->cur_retire_prior_to;  | 
3372  |  | 
  | 
3373  | 0  |     if (!ossl_quic_channel_is_active(ch))  | 
3374  | 0  |         return;  | 
3375  |  |  | 
3376  |  |     /* We allow only two active connection ids; first check some constraints */  | 
3377  | 0  |     if (ch->cur_remote_dcid.id_len == 0) { | 
3378  |  |         /* Changing from 0 length connection id is disallowed */  | 
3379  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
3380  | 0  |                                                OSSL_QUIC_ERR_PROTOCOL_VIOLATION,  | 
3381  | 0  |                                                OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,  | 
3382  | 0  |                                                "zero length connection id in use");  | 
3383  |  | 
  | 
3384  | 0  |         return;  | 
3385  | 0  |     }  | 
3386  |  |  | 
3387  | 0  |     if (f->seq_num > new_remote_seq_num)  | 
3388  | 0  |         new_remote_seq_num = f->seq_num;  | 
3389  | 0  |     if (f->retire_prior_to > new_retire_prior_to)  | 
3390  | 0  |         new_retire_prior_to = f->retire_prior_to;  | 
3391  |  |  | 
3392  |  |     /*  | 
3393  |  |      * RFC 9000-5.1.1: An endpoint MUST NOT provide more connection IDs  | 
3394  |  |      * than the peer's limit.  | 
3395  |  |      *  | 
3396  |  |      * After processing a NEW_CONNECTION_ID frame and adding and retiring  | 
3397  |  |      * active connection IDs, if the number of active connection IDs exceeds  | 
3398  |  |      * the value advertised in its active_connection_id_limit transport  | 
3399  |  |      * parameter, an endpoint MUST close the connection with an error of  | 
3400  |  |      * type CONNECTION_ID_LIMIT_ERROR.  | 
3401  |  |      */  | 
3402  | 0  |     if (new_remote_seq_num - new_retire_prior_to > 1) { | 
3403  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
3404  | 0  |                                                OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,  | 
3405  | 0  |                                                OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,  | 
3406  | 0  |                                                "active_connection_id limit violated");  | 
3407  | 0  |         return;  | 
3408  | 0  |     }  | 
3409  |  |  | 
3410  |  |     /*  | 
3411  |  |      * RFC 9000-5.1.1: An endpoint MAY send connection IDs that temporarily  | 
3412  |  |      * exceed a peer's limit if the NEW_CONNECTION_ID frame also requires  | 
3413  |  |      * the retirement of any excess, by including a sufficiently large  | 
3414  |  |      * value in the Retire Prior To field.  | 
3415  |  |      *  | 
3416  |  |      * RFC 9000-5.1.2: An endpoint SHOULD allow for sending and tracking  | 
3417  |  |      * a number of RETIRE_CONNECTION_ID frames of at least twice the value  | 
3418  |  |      * of the active_connection_id_limit transport parameter.  An endpoint  | 
3419  |  |      * MUST NOT forget a connection ID without retiring it, though it MAY  | 
3420  |  |      * choose to treat having connection IDs in need of retirement that  | 
3421  |  |      * exceed this limit as a connection error of type CONNECTION_ID_LIMIT_ERROR.  | 
3422  |  |      *  | 
3423  |  |      * We are a little bit more liberal than the minimum mandated.  | 
3424  |  |      */  | 
3425  | 0  |     if (new_retire_prior_to - ch->cur_retire_prior_to > 10) { | 
3426  | 0  |         ossl_quic_channel_raise_protocol_error(ch,  | 
3427  | 0  |                                                OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,  | 
3428  | 0  |                                                OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,  | 
3429  | 0  |                                                "retiring connection id limit violated");  | 
3430  |  | 
  | 
3431  | 0  |         return;  | 
3432  | 0  |     }  | 
3433  |  |  | 
3434  | 0  |     if (new_remote_seq_num > ch->cur_remote_seq_num) { | 
3435  |  |         /* Add new stateless reset token */  | 
3436  | 0  |         if (!ossl_quic_srtm_add(ch->srtm, ch, new_remote_seq_num,  | 
3437  | 0  |                                 &f->stateless_reset)) { | 
3438  | 0  |             ossl_quic_channel_raise_protocol_error(  | 
3439  | 0  |                     ch, OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,  | 
3440  | 0  |                     OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,  | 
3441  | 0  |                     "unable to store stateless reset token");  | 
3442  |  | 
  | 
3443  | 0  |             return;  | 
3444  | 0  |         }  | 
3445  | 0  |         ch->cur_remote_seq_num = new_remote_seq_num;  | 
3446  | 0  |         ch->cur_remote_dcid = f->conn_id;  | 
3447  | 0  |         ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid);  | 
3448  | 0  |     }  | 
3449  |  |  | 
3450  |  |     /*  | 
3451  |  |      * RFC 9000-5.1.2: Upon receipt of an increased Retire Prior To  | 
3452  |  |      * field, the peer MUST stop using the corresponding connection IDs  | 
3453  |  |      * and retire them with RETIRE_CONNECTION_ID frames before adding the  | 
3454  |  |      * newly provided connection ID to the set of active connection IDs.  | 
3455  |  |      */  | 
3456  |  |  | 
3457  |  |     /*  | 
3458  |  |      * Note: RFC 9000 s. 19.15 says:  | 
3459  |  |      *   "An endpoint that receives a NEW_CONNECTION_ID frame with a sequence  | 
3460  |  |      *    number smaller than the Retire Prior To field of a previously received  | 
3461  |  |      *    NEW_CONNECTION_ID frame MUST send a corresponding  | 
3462  |  |      *    RETIRE_CONNECTION_ID frame that retires the newly received connection  | 
3463  |  |      *    ID, unless it has already done so for that sequence number."  | 
3464  |  |      *  | 
3465  |  |      * Since we currently always queue RETIRE_CONN_ID frames based on the Retire  | 
3466  |  |      * Prior To field of a NEW_CONNECTION_ID frame immediately upon receiving  | 
3467  |  |      * that NEW_CONNECTION_ID frame, by definition this will always be met.  | 
3468  |  |      * This may change in future when we change our CID handling.  | 
3469  |  |      */  | 
3470  | 0  |     while (new_retire_prior_to > ch->cur_retire_prior_to) { | 
3471  | 0  |         if (!ch_enqueue_retire_conn_id(ch, ch->cur_retire_prior_to))  | 
3472  | 0  |             break;  | 
3473  | 0  |         ++ch->cur_retire_prior_to;  | 
3474  | 0  |     }  | 
3475  | 0  | }  | 
3476  |  |  | 
3477  |  | static void ch_save_err_state(QUIC_CHANNEL *ch)  | 
3478  | 0  | { | 
3479  | 0  |     if (ch->err_state == NULL)  | 
3480  | 0  |         ch->err_state = OSSL_ERR_STATE_new();  | 
3481  |  | 
  | 
3482  | 0  |     if (ch->err_state == NULL)  | 
3483  | 0  |         return;  | 
3484  |  |  | 
3485  | 0  |     OSSL_ERR_STATE_save(ch->err_state);  | 
3486  | 0  | }  | 
3487  |  |  | 
3488  |  | void ossl_quic_channel_inject(QUIC_CHANNEL *ch, QUIC_URXE *e)  | 
3489  | 0  | { | 
3490  | 0  |     ossl_qrx_inject_urxe(ch->qrx, e);  | 
3491  | 0  | }  | 
3492  |  |  | 
3493  |  | void ossl_quic_channel_inject_pkt(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpkt)  | 
3494  | 0  | { | 
3495  | 0  |     ossl_qrx_inject_pkt(ch->qrx, qpkt);  | 
3496  | 0  | }  | 
3497  |  |  | 
3498  |  | void ossl_quic_channel_on_stateless_reset(QUIC_CHANNEL *ch)  | 
3499  | 0  | { | 
3500  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
3501  |  | 
  | 
3502  | 0  |     tcause.error_code   = OSSL_QUIC_ERR_NO_ERROR;  | 
3503  | 0  |     tcause.remote       = 1;  | 
3504  | 0  |     ch_start_terminating(ch, &tcause, 0);  | 
3505  | 0  | }  | 
3506  |  |  | 
3507  |  | void ossl_quic_channel_raise_net_error(QUIC_CHANNEL *ch)  | 
3508  | 0  | { | 
3509  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
3510  |  | 
  | 
3511  | 0  |     if (ch->net_error)  | 
3512  | 0  |         return;  | 
3513  |  |  | 
3514  | 0  |     ch->net_error = 1;  | 
3515  |  | 
  | 
3516  | 0  |     tcause.error_code = OSSL_QUIC_ERR_INTERNAL_ERROR;  | 
3517  | 0  |     tcause.reason     = "network BIO I/O error";  | 
3518  | 0  |     tcause.reason_len = strlen(tcause.reason);  | 
3519  |  |  | 
3520  |  |     /*  | 
3521  |  |      * Skip Terminating state and go directly to Terminated, no point trying to  | 
3522  |  |      * send CONNECTION_CLOSE if we cannot communicate.  | 
3523  |  |      */  | 
3524  | 0  |     ch_start_terminating(ch, &tcause, 1);  | 
3525  | 0  | }  | 
3526  |  |  | 
3527  |  | int ossl_quic_channel_net_error(QUIC_CHANNEL *ch)  | 
3528  | 0  | { | 
3529  | 0  |     return ch->net_error;  | 
3530  | 0  | }  | 
3531  |  |  | 
3532  |  | void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch)  | 
3533  | 0  | { | 
3534  | 0  |     if (ch == NULL)  | 
3535  | 0  |         return;  | 
3536  |  |  | 
3537  | 0  |     if (!ossl_quic_port_is_running(ch->port))  | 
3538  | 0  |         ossl_quic_port_restore_err_state(ch->port);  | 
3539  | 0  |     else  | 
3540  | 0  |         OSSL_ERR_STATE_restore(ch->err_state);  | 
3541  | 0  | }  | 
3542  |  |  | 
3543  |  | void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,  | 
3544  |  |                                                 uint64_t error_code,  | 
3545  |  |                                                 uint64_t frame_type,  | 
3546  |  |                                                 const char *reason,  | 
3547  |  |                                                 ERR_STATE *err_state,  | 
3548  |  |                                                 const char *src_file,  | 
3549  |  |                                                 int src_line,  | 
3550  |  |                                                 const char *src_func)  | 
3551  | 0  | { | 
3552  | 0  |     QUIC_TERMINATE_CAUSE tcause = {0}; | 
3553  | 0  |     int err_reason = error_code == OSSL_QUIC_ERR_INTERNAL_ERROR  | 
3554  | 0  |                      ? ERR_R_INTERNAL_ERROR : SSL_R_QUIC_PROTOCOL_ERROR;  | 
3555  | 0  |     const char *err_str = ossl_quic_err_to_string(error_code);  | 
3556  | 0  |     const char *err_str_pfx = " (", *err_str_sfx = ")"; | 
3557  | 0  |     const char *ft_str = NULL;  | 
3558  | 0  |     const char *ft_str_pfx = " (", *ft_str_sfx = ")"; | 
3559  |  | 
  | 
3560  | 0  |     if (ch->protocol_error)  | 
3561  |  |         /* Only the first call to this function matters. */  | 
3562  | 0  |         return;  | 
3563  |  |  | 
3564  | 0  |     if (err_str == NULL) { | 
3565  | 0  |         err_str     = "";  | 
3566  | 0  |         err_str_pfx = "";  | 
3567  | 0  |         err_str_sfx = "";  | 
3568  | 0  |     }  | 
3569  |  |  | 
3570  |  |     /*  | 
3571  |  |      * If we were provided an underlying error state, restore it and then append  | 
3572  |  |      * our ERR on top as a "cover letter" error.  | 
3573  |  |      */  | 
3574  | 0  |     if (err_state != NULL)  | 
3575  | 0  |         OSSL_ERR_STATE_restore(err_state);  | 
3576  |  | 
  | 
3577  | 0  |     if (frame_type != 0) { | 
3578  | 0  |         ft_str = ossl_quic_frame_type_to_string(frame_type);  | 
3579  | 0  |         if (ft_str == NULL) { | 
3580  | 0  |             ft_str      = "";  | 
3581  | 0  |             ft_str_pfx  = "";  | 
3582  | 0  |             ft_str_sfx  = "";  | 
3583  | 0  |         }  | 
3584  |  | 
  | 
3585  | 0  |         ERR_raise_data(ERR_LIB_SSL, err_reason,  | 
3586  | 0  |                        "QUIC error code: 0x%llx%s%s%s "  | 
3587  | 0  |                        "(triggered by frame type: 0x%llx%s%s%s), reason: \"%s\"",  | 
3588  | 0  |                        (unsigned long long) error_code,  | 
3589  | 0  |                        err_str_pfx, err_str, err_str_sfx,  | 
3590  | 0  |                        (unsigned long long) frame_type,  | 
3591  | 0  |                        ft_str_pfx, ft_str, ft_str_sfx,  | 
3592  | 0  |                        reason);  | 
3593  | 0  |     } else { | 
3594  | 0  |         ERR_raise_data(ERR_LIB_SSL, err_reason,  | 
3595  | 0  |                        "QUIC error code: 0x%llx%s%s%s, reason: \"%s\"",  | 
3596  | 0  |                        (unsigned long long) error_code,  | 
3597  | 0  |                        err_str_pfx, err_str, err_str_sfx,  | 
3598  | 0  |                        reason);  | 
3599  | 0  |     }  | 
3600  |  | 
  | 
3601  | 0  |     if (src_file != NULL)  | 
3602  | 0  |         ERR_set_debug(src_file, src_line, src_func);  | 
3603  |  | 
  | 
3604  | 0  |     ch_save_err_state(ch);  | 
3605  |  | 
  | 
3606  | 0  |     tcause.error_code = error_code;  | 
3607  | 0  |     tcause.frame_type = frame_type;  | 
3608  | 0  |     tcause.reason     = reason;  | 
3609  | 0  |     tcause.reason_len = strlen(reason);  | 
3610  |  | 
  | 
3611  | 0  |     ch->protocol_error = 1;  | 
3612  | 0  |     ch_start_terminating(ch, &tcause, 0);  | 
3613  | 0  | }  | 
3614  |  |  | 
3615  |  | /*  | 
3616  |  |  * Called once the terminating timer expires, meaning we move from TERMINATING  | 
3617  |  |  * to TERMINATED.  | 
3618  |  |  */  | 
3619  |  | static void ch_on_terminating_timeout(QUIC_CHANNEL *ch)  | 
3620  | 0  | { | 
3621  | 0  |     ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED);  | 
3622  | 0  | }  | 
3623  |  |  | 
3624  |  | /*  | 
3625  |  |  * Determines the effective idle timeout duration. This is based on the idle  | 
3626  |  |  * timeout values that we and our peer signalled in transport parameters  | 
3627  |  |  * but have some limits applied.  | 
3628  |  |  */  | 
3629  |  | static OSSL_TIME ch_get_effective_idle_timeout_duration(QUIC_CHANNEL *ch)  | 
3630  | 0  | { | 
3631  | 0  |     OSSL_TIME pto;  | 
3632  |  | 
  | 
3633  | 0  |     if (ch->max_idle_timeout == 0)  | 
3634  | 0  |         return ossl_time_infinite();  | 
3635  |  |  | 
3636  |  |     /*  | 
3637  |  |      * RFC 9000 s. 10.1: Idle Timeout  | 
3638  |  |      *  To avoid excessively small idle timeout periods, endpoints  | 
3639  |  |      *  MUST increase the idle timeout period to be at least three  | 
3640  |  |      *  times the current Probe Timeout (PTO). This allows for  | 
3641  |  |      *  multiple PTOs to expire, and therefore multiple probes to  | 
3642  |  |      *  be sent and lost, prior to idle timeout.  | 
3643  |  |      */  | 
3644  | 0  |     pto = ossl_ackm_get_pto_duration(ch->ackm);  | 
3645  | 0  |     return ossl_time_max(ossl_ms2time(ch->max_idle_timeout),  | 
3646  | 0  |                                       ossl_time_multiply(pto, 3));  | 
3647  | 0  | }  | 
3648  |  |  | 
3649  |  | /*  | 
3650  |  |  * Updates our idle deadline. Called when an event happens which should bump the  | 
3651  |  |  * idle timeout.  | 
3652  |  |  */  | 
3653  |  | static void ch_update_idle(QUIC_CHANNEL *ch)  | 
3654  | 0  | { | 
3655  | 0  |     ch->idle_deadline = ossl_time_add(get_time(ch),  | 
3656  | 0  |                                       ch_get_effective_idle_timeout_duration(ch));  | 
3657  | 0  | }  | 
3658  |  |  | 
3659  |  | /*  | 
3660  |  |  * Updates our ping deadline, which determines when we next generate a ping if  | 
3661  |  |  * we don't have any other ACK-eliciting frames to send.  | 
3662  |  |  */  | 
3663  |  | static void ch_update_ping_deadline(QUIC_CHANNEL *ch)  | 
3664  | 0  | { | 
3665  | 0  |     OSSL_TIME max_span, idle_duration;  | 
3666  |  | 
  | 
3667  | 0  |     idle_duration = ch_get_effective_idle_timeout_duration(ch);  | 
3668  | 0  |     if (ossl_time_is_infinite(idle_duration)) { | 
3669  | 0  |         ch->ping_deadline = ossl_time_infinite();  | 
3670  | 0  |         return;  | 
3671  | 0  |     }  | 
3672  |  |  | 
3673  |  |     /*  | 
3674  |  |      * Maximum amount of time without traffic before we send a PING to keep  | 
3675  |  |      * the connection open. Usually we use max_idle_timeout/2, but ensure  | 
3676  |  |      * the period never exceeds the assumed NAT interval to ensure NAT  | 
3677  |  |      * devices don't have their state time out (RFC 9000 s. 10.1.2).  | 
3678  |  |      */  | 
3679  | 0  |     max_span = ossl_time_divide(idle_duration, 2);  | 
3680  | 0  |     max_span = ossl_time_min(max_span, MAX_NAT_INTERVAL);  | 
3681  | 0  |     ch->ping_deadline = ossl_time_add(get_time(ch), max_span);  | 
3682  | 0  | }  | 
3683  |  |  | 
3684  |  | /* Called when the idle timeout expires. */  | 
3685  |  | static void ch_on_idle_timeout(QUIC_CHANNEL *ch)  | 
3686  | 0  | { | 
3687  |  |     /*  | 
3688  |  |      * Idle timeout does not have an error code associated with it because a  | 
3689  |  |      * CONN_CLOSE is never sent for it. We shouldn't use this data once we reach  | 
3690  |  |      * TERMINATED anyway.  | 
3691  |  |      */  | 
3692  | 0  |     ch->terminate_cause.app         = 0;  | 
3693  | 0  |     ch->terminate_cause.error_code  = OSSL_QUIC_LOCAL_ERR_IDLE_TIMEOUT;  | 
3694  | 0  |     ch->terminate_cause.frame_type  = 0;  | 
3695  |  | 
  | 
3696  | 0  |     ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED);  | 
3697  | 0  | }  | 
3698  |  |  | 
3699  |  | /**  | 
3700  |  |  * @brief Common handler for initializing a new QUIC connection.  | 
3701  |  |  *  | 
3702  |  |  * This function configures a QUIC channel (`QUIC_CHANNEL *ch`) for a new  | 
3703  |  |  * connection by setting the peer address, connection IDs, and necessary  | 
3704  |  |  * callbacks. It establishes initial secrets, sets up logging, and performs  | 
3705  |  |  * required transitions for the channel state.  | 
3706  |  |  *  | 
3707  |  |  * @param ch       Pointer to the QUIC channel being initialized.  | 
3708  |  |  * @param peer     Address of the peer to which the channel connects.  | 
3709  |  |  * @param peer_scid Peer-specified source connection ID.  | 
3710  |  |  * @param peer_dcid Peer-specified destination connection ID.  | 
3711  |  |  * @param peer_odcid Peer-specified original destination connection ID  | 
3712  |  |  *                   may be NULL if retry frame not sent to client  | 
3713  |  |  * @return         1 on success, 0 on failure to set required elements.  | 
3714  |  |  */  | 
3715  |  | static int ch_on_new_conn_common(QUIC_CHANNEL *ch, const BIO_ADDR *peer,  | 
3716  |  |                                  const QUIC_CONN_ID *peer_scid,  | 
3717  |  |                                  const QUIC_CONN_ID *peer_dcid,  | 
3718  |  |                                  const QUIC_CONN_ID *peer_odcid)  | 
3719  | 0  | { | 
3720  |  |     /* Note our newly learnt peer address and CIDs. */  | 
3721  | 0  |     if (!ossl_quic_channel_set_peer_addr(ch, peer))  | 
3722  | 0  |         return 0;  | 
3723  |  |  | 
3724  | 0  |     ch->init_dcid       = *peer_dcid;  | 
3725  | 0  |     ch->cur_remote_dcid = *peer_scid;  | 
3726  | 0  |     ch->odcid.id_len = 0;  | 
3727  |  | 
  | 
3728  | 0  |     if (peer_odcid != NULL)  | 
3729  | 0  |         ch->odcid = *peer_odcid;  | 
3730  |  |  | 
3731  |  |     /* Inform QTX of peer address. */  | 
3732  | 0  |     if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr))  | 
3733  | 0  |         return 0;  | 
3734  |  |  | 
3735  |  |     /* Inform TXP of desired CIDs. */  | 
3736  | 0  |     if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid))  | 
3737  | 0  |         return 0;  | 
3738  |  |  | 
3739  | 0  |     if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid))  | 
3740  | 0  |         return 0;  | 
3741  |  |  | 
3742  |  |     /* Setup QLOG, which did not happen earlier due to lacking an Initial ODCID. */  | 
3743  | 0  |     ossl_qtx_set_qlog_cb(ch->qtx, ch_get_qlog_cb, ch);  | 
3744  | 0  |     ossl_quic_tx_packetiser_set_qlog_cb(ch->txp, ch_get_qlog_cb, ch);  | 
3745  |  |  | 
3746  |  |     /*  | 
3747  |  |      * Plug in secrets for the Initial EL. secrets for QRX were created in  | 
3748  |  |      * port_default_packet_handler() already.  | 
3749  |  |      */  | 
3750  | 0  |     if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,  | 
3751  | 0  |                                           ch->port->engine->propq,  | 
3752  | 0  |                                           &ch->init_dcid,  | 
3753  | 0  |                                           /*is_server=*/1,  | 
3754  | 0  |                                           NULL, ch->qtx))  | 
3755  | 0  |         return 0;  | 
3756  |  |  | 
3757  |  |     /* Register the peer ODCID in the LCIDM. */  | 
3758  | 0  |     if (!ossl_quic_lcidm_enrol_odcid(ch->lcidm, ch, peer_odcid == NULL ?  | 
3759  | 0  |                                      &ch->init_dcid :  | 
3760  | 0  |                                      peer_odcid))  | 
3761  | 0  |         return 0;  | 
3762  |  |  | 
3763  |  |     /* Change state. */  | 
3764  | 0  |     ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE);  | 
3765  | 0  |     ch->doing_proactive_ver_neg = 0; /* not currently supported */  | 
3766  | 0  |     return 1;  | 
3767  | 0  | }  | 
3768  |  |  | 
3769  |  | /* Called when we, as a server, get a new incoming connection. */  | 
3770  |  | int ossl_quic_channel_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer,  | 
3771  |  |                                   const QUIC_CONN_ID *peer_scid,  | 
3772  |  |                                   const QUIC_CONN_ID *peer_dcid)  | 
3773  | 0  | { | 
3774  | 0  |     if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server))  | 
3775  | 0  |         return 0;  | 
3776  |  |  | 
3777  |  |     /* Generate an Initial LCID we will use for the connection. */  | 
3778  | 0  |     if (!ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &ch->cur_local_cid))  | 
3779  | 0  |         return 0;  | 
3780  |  |  | 
3781  | 0  |     return ch_on_new_conn_common(ch, peer, peer_scid, peer_dcid, NULL);  | 
3782  | 0  | }  | 
3783  |  |  | 
3784  |  | /**  | 
3785  |  |  * Binds a QUIC channel to a specific peer's address and connection IDs.  | 
3786  |  |  *  | 
3787  |  |  * This function is used to establish a binding between a QUIC channel and a  | 
3788  |  |  * peer's address and connection IDs. The binding is performed only if the  | 
3789  |  |  * channel is idle and is on the server side. The peer's destination connection  | 
3790  |  |  * ID (`peer_dcid`) is mandatory, and the channel's current local connection ID  | 
3791  |  |  * is set to this value.  | 
3792  |  |  *  | 
3793  |  |  * @param ch          Pointer to the QUIC_CHANNEL structure representing the  | 
3794  |  |  *                    channel to be bound.  | 
3795  |  |  * @param peer        Pointer to a BIO_ADDR structure representing the peer's  | 
3796  |  |  *                    address.  | 
3797  |  |  * @param peer_scid   Pointer to the peer's source connection ID (QUIC_CONN_ID).  | 
3798  |  |  * @param peer_dcid   Pointer to the peer's destination connection ID  | 
3799  |  |  *                    (QUIC_CONN_ID). This must not be NULL.  | 
3800  |  |  * @param peer_odcid  Pointer to the original destination connection ID  | 
3801  |  |  *                    (QUIC_CONN_ID) chosen by the peer in its first initial  | 
3802  |  |  *                    packet received without a token.  | 
3803  |  |  *  | 
3804  |  |  * @return 1 on success, or 0 on failure if the conditions for binding are not  | 
3805  |  |  *         met (e.g., channel is not idle or not a server, or binding fails).  | 
3806  |  |  */  | 
3807  |  | int ossl_quic_bind_channel(QUIC_CHANNEL *ch, const BIO_ADDR *peer,  | 
3808  |  |                            const QUIC_CONN_ID *peer_scid,  | 
3809  |  |                            const QUIC_CONN_ID *peer_dcid,  | 
3810  |  |                            const QUIC_CONN_ID *peer_odcid)  | 
3811  | 0  | { | 
3812  | 0  |     if (peer_dcid == NULL)  | 
3813  | 0  |         return 0;  | 
3814  |  |  | 
3815  | 0  |     if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server))  | 
3816  | 0  |         return 0;  | 
3817  |  |  | 
3818  | 0  |     if (!ossl_quic_lcidm_bind_channel(ch->lcidm, ch, peer_dcid))  | 
3819  | 0  |         return 0;  | 
3820  |  |  | 
3821  | 0  |     ch->cur_local_cid = *peer_dcid;  | 
3822  |  |  | 
3823  |  |     /*  | 
3824  |  |      * peer_odcid <=> is initial dst conn id chosen by peer in its  | 
3825  |  |      * first initial packet we received without token.  | 
3826  |  |      */  | 
3827  | 0  |     return ch_on_new_conn_common(ch, peer, peer_scid, peer_dcid, peer_odcid);  | 
3828  | 0  | }  | 
3829  |  |  | 
3830  |  | SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch)  | 
3831  | 0  | { | 
3832  | 0  |     return ch->tls;  | 
3833  | 0  | }  | 
3834  |  |  | 
3835  |  | static int ch_init_new_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs,  | 
3836  |  |                               int can_send, int can_recv)  | 
3837  | 0  | { | 
3838  | 0  |     uint64_t rxfc_wnd;  | 
3839  | 0  |     int server_init = ossl_quic_stream_is_server_init(qs);  | 
3840  | 0  |     int local_init = (ch->is_server == server_init);  | 
3841  | 0  |     int is_uni = !ossl_quic_stream_is_bidi(qs);  | 
3842  |  | 
  | 
3843  | 0  |     if (can_send)  | 
3844  | 0  |         if ((qs->sstream = ossl_quic_sstream_new(INIT_APP_BUF_LEN)) == NULL)  | 
3845  | 0  |             goto err;  | 
3846  |  |  | 
3847  | 0  |     if (can_recv)  | 
3848  | 0  |         if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, 0)) == NULL)  | 
3849  | 0  |             goto err;  | 
3850  |  |  | 
3851  |  |     /* TXFC */  | 
3852  | 0  |     if (!ossl_quic_txfc_init(&qs->txfc, &ch->conn_txfc))  | 
3853  | 0  |         goto err;  | 
3854  |  |  | 
3855  | 0  |     if (ch->got_remote_transport_params) { | 
3856  |  |         /*  | 
3857  |  |          * If we already got peer TPs we need to apply the initial CWM credit  | 
3858  |  |          * now. If we didn't already get peer TPs this will be done  | 
3859  |  |          * automatically for all extant streams when we do.  | 
3860  |  |          */  | 
3861  | 0  |         if (can_send) { | 
3862  | 0  |             uint64_t cwm;  | 
3863  |  | 
  | 
3864  | 0  |             if (is_uni)  | 
3865  | 0  |                 cwm = ch->rx_init_max_stream_data_uni;  | 
3866  | 0  |             else if (local_init)  | 
3867  | 0  |                 cwm = ch->rx_init_max_stream_data_bidi_local;  | 
3868  | 0  |             else  | 
3869  | 0  |                 cwm = ch->rx_init_max_stream_data_bidi_remote;  | 
3870  |  | 
  | 
3871  | 0  |             ossl_quic_txfc_bump_cwm(&qs->txfc, cwm);  | 
3872  | 0  |         }  | 
3873  | 0  |     }  | 
3874  |  |  | 
3875  |  |     /* RXFC */  | 
3876  | 0  |     if (!can_recv)  | 
3877  | 0  |         rxfc_wnd = 0;  | 
3878  | 0  |     else if (is_uni)  | 
3879  | 0  |         rxfc_wnd = ch->tx_init_max_stream_data_uni;  | 
3880  | 0  |     else if (local_init)  | 
3881  | 0  |         rxfc_wnd = ch->tx_init_max_stream_data_bidi_local;  | 
3882  | 0  |     else  | 
3883  | 0  |         rxfc_wnd = ch->tx_init_max_stream_data_bidi_remote;  | 
3884  |  | 
  | 
3885  | 0  |     if (!ossl_quic_rxfc_init(&qs->rxfc, &ch->conn_rxfc,  | 
3886  | 0  |                              rxfc_wnd,  | 
3887  | 0  |                              DEFAULT_STREAM_RXFC_MAX_WND_MUL * rxfc_wnd,  | 
3888  | 0  |                              get_time, ch))  | 
3889  | 0  |         goto err;  | 
3890  |  |  | 
3891  | 0  |     return 1;  | 
3892  |  |  | 
3893  | 0  | err:  | 
3894  | 0  |     ossl_quic_sstream_free(qs->sstream);  | 
3895  | 0  |     qs->sstream = NULL;  | 
3896  | 0  |     ossl_quic_rstream_free(qs->rstream);  | 
3897  | 0  |     qs->rstream = NULL;  | 
3898  | 0  |     return 0;  | 
3899  | 0  | }  | 
3900  |  |  | 
3901  |  | static uint64_t *ch_get_local_stream_next_ordinal_ptr(QUIC_CHANNEL *ch,  | 
3902  |  |                                                       int is_uni)  | 
3903  | 0  | { | 
3904  | 0  |     return is_uni ? &ch->next_local_stream_ordinal_uni  | 
3905  | 0  |                   : &ch->next_local_stream_ordinal_bidi;  | 
3906  | 0  | }  | 
3907  |  |  | 
3908  |  | static const uint64_t *ch_get_local_stream_max_ptr(const QUIC_CHANNEL *ch,  | 
3909  |  |                                                    int is_uni)  | 
3910  | 0  | { | 
3911  | 0  |     return is_uni ? &ch->max_local_streams_uni  | 
3912  | 0  |                   : &ch->max_local_streams_bidi;  | 
3913  | 0  | }  | 
3914  |  |  | 
3915  |  | static const QUIC_RXFC *ch_get_remote_stream_count_rxfc(const QUIC_CHANNEL *ch,  | 
3916  |  |                                                         int is_uni)  | 
3917  | 0  | { | 
3918  | 0  |     return is_uni ? &ch->max_streams_uni_rxfc  | 
3919  | 0  |                   : &ch->max_streams_bidi_rxfc;  | 
3920  | 0  | }  | 
3921  |  |  | 
3922  |  | int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch,  | 
3923  |  |                                                      int is_uni)  | 
3924  | 0  | { | 
3925  | 0  |     const uint64_t *p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni);  | 
3926  |  | 
  | 
3927  | 0  |     return ossl_quic_stream_map_is_local_allowed_by_stream_limit(&ch->qsm,  | 
3928  | 0  |                                                                  *p_next_ordinal,  | 
3929  | 0  |                                                                  is_uni);  | 
3930  | 0  | }  | 
3931  |  |  | 
3932  |  | uint64_t ossl_quic_channel_get_local_stream_count_avail(const QUIC_CHANNEL *ch,  | 
3933  |  |                                                         int is_uni)  | 
3934  | 0  | { | 
3935  | 0  |     const uint64_t *p_next_ordinal, *p_max;  | 
3936  |  | 
  | 
3937  | 0  |     p_next_ordinal  = ch_get_local_stream_next_ordinal_ptr((QUIC_CHANNEL *)ch,  | 
3938  | 0  |                                                            is_uni);  | 
3939  | 0  |     p_max           = ch_get_local_stream_max_ptr(ch, is_uni);  | 
3940  |  | 
  | 
3941  | 0  |     return *p_max - *p_next_ordinal;  | 
3942  | 0  | }  | 
3943  |  |  | 
3944  |  | uint64_t ossl_quic_channel_get_remote_stream_count_avail(const QUIC_CHANNEL *ch,  | 
3945  |  |                                                          int is_uni)  | 
3946  | 0  | { | 
3947  | 0  |     return ossl_quic_rxfc_get_credit(ch_get_remote_stream_count_rxfc(ch, is_uni));  | 
3948  | 0  | }  | 
3949  |  |  | 
3950  |  | QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni)  | 
3951  | 0  | { | 
3952  | 0  |     QUIC_STREAM *qs;  | 
3953  | 0  |     int type;  | 
3954  | 0  |     uint64_t stream_id;  | 
3955  | 0  |     uint64_t *p_next_ordinal;  | 
3956  |  | 
  | 
3957  | 0  |     type = ch->is_server ? QUIC_STREAM_INITIATOR_SERVER  | 
3958  | 0  |                          : QUIC_STREAM_INITIATOR_CLIENT;  | 
3959  |  | 
  | 
3960  | 0  |     p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni);  | 
3961  |  | 
  | 
3962  | 0  |     if (is_uni)  | 
3963  | 0  |         type |= QUIC_STREAM_DIR_UNI;  | 
3964  | 0  |     else  | 
3965  | 0  |         type |= QUIC_STREAM_DIR_BIDI;  | 
3966  |  | 
  | 
3967  | 0  |     if (*p_next_ordinal >= ((uint64_t)1) << 62)  | 
3968  | 0  |         return NULL;  | 
3969  |  |  | 
3970  | 0  |     stream_id = ((*p_next_ordinal) << 2) | type;  | 
3971  |  | 
  | 
3972  | 0  |     if ((qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id, type)) == NULL)  | 
3973  | 0  |         return NULL;  | 
3974  |  |  | 
3975  |  |     /* Locally-initiated stream, so we always want a send buffer. */  | 
3976  | 0  |     if (!ch_init_new_stream(ch, qs, /*can_send=*/1, /*can_recv=*/!is_uni))  | 
3977  | 0  |         goto err;  | 
3978  |  |  | 
3979  | 0  |     ++*p_next_ordinal;  | 
3980  | 0  |     return qs;  | 
3981  |  |  | 
3982  | 0  | err:  | 
3983  | 0  |     ossl_quic_stream_map_release(&ch->qsm, qs);  | 
3984  | 0  |     return NULL;  | 
3985  | 0  | }  | 
3986  |  |  | 
3987  |  | QUIC_STREAM *ossl_quic_channel_new_stream_remote(QUIC_CHANNEL *ch,  | 
3988  |  |                                                  uint64_t stream_id)  | 
3989  | 0  | { | 
3990  | 0  |     uint64_t peer_role;  | 
3991  | 0  |     int is_uni;  | 
3992  | 0  |     QUIC_STREAM *qs;  | 
3993  |  | 
  | 
3994  | 0  |     peer_role = ch->is_server  | 
3995  | 0  |         ? QUIC_STREAM_INITIATOR_CLIENT  | 
3996  | 0  |         : QUIC_STREAM_INITIATOR_SERVER;  | 
3997  |  | 
  | 
3998  | 0  |     if ((stream_id & QUIC_STREAM_INITIATOR_MASK) != peer_role)  | 
3999  | 0  |         return NULL;  | 
4000  |  |  | 
4001  | 0  |     is_uni = ((stream_id & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_UNI);  | 
4002  |  | 
  | 
4003  | 0  |     qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id,  | 
4004  | 0  |                                     stream_id & (QUIC_STREAM_INITIATOR_MASK  | 
4005  | 0  |                                                  | QUIC_STREAM_DIR_MASK));  | 
4006  | 0  |     if (qs == NULL)  | 
4007  | 0  |         return NULL;  | 
4008  |  |  | 
4009  | 0  |     if (!ch_init_new_stream(ch, qs, /*can_send=*/!is_uni, /*can_recv=*/1))  | 
4010  | 0  |         goto err;  | 
4011  |  |  | 
4012  | 0  |     if (ch->incoming_stream_auto_reject)  | 
4013  | 0  |         ossl_quic_channel_reject_stream(ch, qs);  | 
4014  | 0  |     else  | 
4015  | 0  |         ossl_quic_stream_map_push_accept_queue(&ch->qsm, qs);  | 
4016  |  | 
  | 
4017  | 0  |     return qs;  | 
4018  |  |  | 
4019  | 0  | err:  | 
4020  | 0  |     ossl_quic_stream_map_release(&ch->qsm, qs);  | 
4021  | 0  |     return NULL;  | 
4022  | 0  | }  | 
4023  |  |  | 
4024  |  | void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch,  | 
4025  |  |                                                        int enable,  | 
4026  |  |                                                        uint64_t aec)  | 
4027  | 0  | { | 
4028  | 0  |     ch->incoming_stream_auto_reject     = (enable != 0);  | 
4029  | 0  |     ch->incoming_stream_auto_reject_aec = aec;  | 
4030  | 0  | }  | 
4031  |  |  | 
4032  |  | void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs)  | 
4033  | 0  | { | 
4034  | 0  |     ossl_quic_stream_map_stop_sending_recv_part(&ch->qsm, qs,  | 
4035  | 0  |                                                 ch->incoming_stream_auto_reject_aec);  | 
4036  |  | 
  | 
4037  | 0  |     ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, qs,  | 
4038  | 0  |                                                 ch->incoming_stream_auto_reject_aec);  | 
4039  | 0  |     qs->deleted = 1;  | 
4040  |  | 
  | 
4041  | 0  |     ossl_quic_stream_map_update_state(&ch->qsm, qs);  | 
4042  | 0  | }  | 
4043  |  |  | 
4044  |  | /* Replace local connection ID in TXP and DEMUX for testing purposes. */  | 
4045  |  | int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch,  | 
4046  |  |                                         const QUIC_CONN_ID *conn_id)  | 
4047  | 0  | { | 
4048  |  |     /* Remove the current LCID from the LCIDM. */  | 
4049  | 0  |     if (!ossl_quic_lcidm_debug_remove(ch->lcidm, &ch->cur_local_cid))  | 
4050  | 0  |         return 0;  | 
4051  | 0  |     ch->cur_local_cid = *conn_id;  | 
4052  |  |     /* Set in the TXP, used only for long header packets. */  | 
4053  | 0  |     if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid))  | 
4054  | 0  |         return 0;  | 
4055  |  |     /* Add the new LCID to the LCIDM. */  | 
4056  | 0  |     if (!ossl_quic_lcidm_debug_add(ch->lcidm, ch, &ch->cur_local_cid,  | 
4057  | 0  |                                    100))  | 
4058  | 0  |         return 0;  | 
4059  | 0  |     return 1;  | 
4060  | 0  | }  | 
4061  |  |  | 
4062  |  | void ossl_quic_channel_set_msg_callback(QUIC_CHANNEL *ch,  | 
4063  |  |                                         ossl_msg_cb msg_callback,  | 
4064  |  |                                         SSL *msg_callback_ssl)  | 
4065  | 0  | { | 
4066  | 0  |     ch->msg_callback = msg_callback;  | 
4067  | 0  |     ch->msg_callback_ssl = msg_callback_ssl;  | 
4068  | 0  |     ossl_qtx_set_msg_callback(ch->qtx, msg_callback, msg_callback_ssl);  | 
4069  | 0  |     ossl_quic_tx_packetiser_set_msg_callback(ch->txp, msg_callback,  | 
4070  | 0  |                                              msg_callback_ssl);  | 
4071  |  |     /*  | 
4072  |  |      * postpone msg callback setting for tserver until port calls  | 
4073  |  |      * port_bind_channel().  | 
4074  |  |      */  | 
4075  | 0  |     if (ch->is_tserver_ch == 0)  | 
4076  | 0  |         ossl_qrx_set_msg_callback(ch->qrx, msg_callback, msg_callback_ssl);  | 
4077  | 0  | }  | 
4078  |  |  | 
4079  |  | void ossl_quic_channel_set_msg_callback_arg(QUIC_CHANNEL *ch,  | 
4080  |  |                                             void *msg_callback_arg)  | 
4081  | 0  | { | 
4082  | 0  |     ch->msg_callback_arg = msg_callback_arg;  | 
4083  | 0  |     ossl_qtx_set_msg_callback_arg(ch->qtx, msg_callback_arg);  | 
4084  | 0  |     ossl_quic_tx_packetiser_set_msg_callback_arg(ch->txp, msg_callback_arg);  | 
4085  |  |  | 
4086  |  |     /*  | 
4087  |  |      * postpone msg callback setting for tserver until port calls  | 
4088  |  |      * port_bind_channel().  | 
4089  |  |      */  | 
4090  | 0  |     if (ch->is_tserver_ch == 0)  | 
4091  | 0  |         ossl_qrx_set_msg_callback_arg(ch->qrx, msg_callback_arg);  | 
4092  | 0  | }  | 
4093  |  |  | 
4094  |  | void ossl_quic_channel_set_txku_threshold_override(QUIC_CHANNEL *ch,  | 
4095  |  |                                                    uint64_t tx_pkt_threshold)  | 
4096  | 0  | { | 
4097  | 0  |     ch->txku_threshold_override = tx_pkt_threshold;  | 
4098  | 0  | }  | 
4099  |  |  | 
4100  |  | uint64_t ossl_quic_channel_get_tx_key_epoch(QUIC_CHANNEL *ch)  | 
4101  | 0  | { | 
4102  | 0  |     return ossl_qtx_get_key_epoch(ch->qtx);  | 
4103  | 0  | }  | 
4104  |  |  | 
4105  |  | uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch)  | 
4106  | 0  | { | 
4107  | 0  |     return ossl_qrx_get_key_epoch(ch->qrx);  | 
4108  | 0  | }  | 
4109  |  |  | 
4110  |  | int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch)  | 
4111  | 0  | { | 
4112  | 0  |     if (!txku_allowed(ch))  | 
4113  | 0  |         return 0;  | 
4114  |  |  | 
4115  | 0  |     ch->ku_locally_initiated = 1;  | 
4116  | 0  |     ch_trigger_txku(ch);  | 
4117  | 0  |     return 1;  | 
4118  | 0  | }  | 
4119  |  |  | 
4120  |  | int ossl_quic_channel_ping(QUIC_CHANNEL *ch)  | 
4121  | 0  | { | 
4122  | 0  |     int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);  | 
4123  |  | 
  | 
4124  | 0  |     ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);  | 
4125  |  | 
  | 
4126  | 0  |     return 1;  | 
4127  | 0  | }  | 
4128  |  |  | 
4129  |  | uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch)  | 
4130  | 0  | { | 
4131  | 0  |     return ch->diag_num_rx_ack;  | 
4132  | 0  | }  | 
4133  |  |  | 
4134  |  | void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid)  | 
4135  | 0  | { | 
4136  | 0  |     *cid = ch->cur_local_cid;  | 
4137  | 0  | }  | 
4138  |  |  | 
4139  |  | int ossl_quic_channel_have_generated_transport_params(const QUIC_CHANNEL *ch)  | 
4140  | 0  | { | 
4141  | 0  |     return ch->got_local_transport_params;  | 
4142  | 0  | }  | 
4143  |  |  | 
4144  |  | void ossl_quic_channel_set_max_idle_timeout_request(QUIC_CHANNEL *ch, uint64_t ms)  | 
4145  | 0  | { | 
4146  | 0  |     ch->max_idle_timeout_local_req = ms;  | 
4147  | 0  | }  | 
4148  |  | uint64_t ossl_quic_channel_get_max_idle_timeout_request(const QUIC_CHANNEL *ch)  | 
4149  | 0  | { | 
4150  | 0  |     return ch->max_idle_timeout_local_req;  | 
4151  | 0  | }  | 
4152  |  |  | 
4153  |  | uint64_t ossl_quic_channel_get_max_idle_timeout_peer_request(const QUIC_CHANNEL *ch)  | 
4154  | 0  | { | 
4155  | 0  |     return ch->max_idle_timeout_remote_req;  | 
4156  | 0  | }  | 
4157  |  |  | 
4158  |  | uint64_t ossl_quic_channel_get_max_idle_timeout_actual(const QUIC_CHANNEL *ch)  | 
4159  | 0  | { | 
4160  | 0  |     return ch->max_idle_timeout;  | 
4161  | 0  | }  |