Path: blob/main/crypto/openssl/ssl/quic/quic_channel.c
48261 views
/*1* Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <openssl/rand.h>10#include <openssl/err.h>11#include "internal/ssl_unwrap.h"12#include "internal/quic_channel.h"13#include "internal/quic_error.h"14#include "internal/quic_rx_depack.h"15#include "internal/quic_lcidm.h"16#include "internal/quic_srtm.h"17#include "internal/qlog_event_helpers.h"18#include "internal/quic_txp.h"19#include "internal/quic_tls.h"20#include "internal/quic_ssl.h"21#include "../ssl_local.h"22#include "quic_channel_local.h"23#include "quic_port_local.h"24#include "quic_engine_local.h"2526#define INIT_CRYPTO_RECV_BUF_LEN 1638427#define INIT_CRYPTO_SEND_BUF_LEN 1638428#define INIT_APP_BUF_LEN 81922930/*31* Interval before we force a PING to ensure NATs don't timeout. This is based32* on the lowest commonly seen value of 30 seconds as cited in RFC 9000 s.33* 10.1.2.34*/35#define MAX_NAT_INTERVAL (ossl_ms2time(25000))3637/*38* Our maximum ACK delay on the TX side. This is up to us to choose. Note that39* this could differ from QUIC_DEFAULT_MAX_DELAY in future as that is a protocol40* value which determines the value of the maximum ACK delay if the41* max_ack_delay transport parameter is not set.42*/43#define DEFAULT_MAX_ACK_DELAY QUIC_DEFAULT_MAX_ACK_DELAY4445DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL);4647static void ch_save_err_state(QUIC_CHANNEL *ch);48static int ch_rx(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads);49static int ch_tx(QUIC_CHANNEL *ch, int *notify_other_threads);50static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads);51static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only);52static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch);53static int ch_retry(QUIC_CHANNEL *ch,54const unsigned char *retry_token,55size_t retry_token_len,56const QUIC_CONN_ID *retry_scid,57int drop_later_pn);58static int ch_restart(QUIC_CHANNEL *ch);5960static void ch_cleanup(QUIC_CHANNEL *ch);61static int ch_generate_transport_params(QUIC_CHANNEL *ch);62static int ch_on_transport_params(const unsigned char *params,63size_t params_len,64void *arg);65static int ch_on_handshake_alert(void *arg, unsigned char alert_code);66static int ch_on_handshake_complete(void *arg);67static int ch_on_handshake_yield_secret(uint32_t prot_level, int direction,68uint32_t suite_id, EVP_MD *md,69const unsigned char *secret,70size_t secret_len,71void *arg);72static int ch_on_crypto_recv_record(const unsigned char **buf,73size_t *bytes_read, void *arg);74static int ch_on_crypto_release_record(size_t bytes_read, void *arg);75static int crypto_ensure_empty(QUIC_RSTREAM *rstream);76static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len,77size_t *consumed, void *arg);78static OSSL_TIME get_time(void *arg);79static uint64_t get_stream_limit(int uni, void *arg);80static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg);81static void rxku_detected(QUIC_PN pn, void *arg);82static int ch_retry(QUIC_CHANNEL *ch,83const unsigned char *retry_token,84size_t retry_token_len,85const QUIC_CONN_ID *retry_scid,86int drop_later_pn);87static void ch_update_idle(QUIC_CHANNEL *ch);88static int ch_discard_el(QUIC_CHANNEL *ch,89uint32_t enc_level);90static void ch_on_idle_timeout(QUIC_CHANNEL *ch);91static void ch_update_idle(QUIC_CHANNEL *ch);92static void ch_update_ping_deadline(QUIC_CHANNEL *ch);93static void ch_on_terminating_timeout(QUIC_CHANNEL *ch);94static void ch_start_terminating(QUIC_CHANNEL *ch,95const QUIC_TERMINATE_CAUSE *tcause,96int force_immediate);97static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space,98void *arg);99static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt);100static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch);101static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state);102103DEFINE_LHASH_OF_EX(QUIC_SRT_ELEM);104105QUIC_NEEDS_LOCK106static QLOG *ch_get_qlog(QUIC_CHANNEL *ch)107{108#ifndef OPENSSL_NO_QLOG109QLOG_TRACE_INFO qti = {0};110111if (ch->qlog != NULL)112return ch->qlog;113114if (!ch->use_qlog)115return NULL;116117if (ch->is_server && ch->init_dcid.id_len == 0)118return NULL;119120qti.odcid = ch->init_dcid;121qti.title = ch->qlog_title;122qti.description = NULL;123qti.group_id = NULL;124qti.is_server = ch->is_server;125qti.now_cb = get_time;126qti.now_cb_arg = ch;127if ((ch->qlog = ossl_qlog_new_from_env(&qti)) == NULL) {128ch->use_qlog = 0; /* don't try again */129return NULL;130}131132return ch->qlog;133#else134return NULL;135#endif136}137138QUIC_NEEDS_LOCK139static QLOG *ch_get_qlog_cb(void *arg)140{141QUIC_CHANNEL *ch = arg;142143return ch_get_qlog(ch);144}145146/*147* QUIC Channel Initialization and Teardown148* ========================================149*/150#define DEFAULT_INIT_CONN_RXFC_WND (768 * 1024)151#define DEFAULT_CONN_RXFC_MAX_WND_MUL 20152153#define DEFAULT_INIT_STREAM_RXFC_WND (512 * 1024)154#define DEFAULT_STREAM_RXFC_MAX_WND_MUL 12155156#define DEFAULT_INIT_CONN_MAX_STREAMS 100157158static int ch_init(QUIC_CHANNEL *ch)159{160OSSL_QUIC_TX_PACKETISER_ARGS txp_args = {0};161OSSL_QTX_ARGS qtx_args = {0};162OSSL_QRX_ARGS qrx_args = {0};163QUIC_TLS_ARGS tls_args = {0};164uint32_t pn_space;165size_t rx_short_dcid_len;166size_t tx_init_dcid_len;167168if (ch->port == NULL || ch->lcidm == NULL || ch->srtm == NULL)169goto err;170171rx_short_dcid_len = ossl_quic_port_get_rx_short_dcid_len(ch->port);172tx_init_dcid_len = ossl_quic_port_get_tx_init_dcid_len(ch->port);173174/* For clients, generate our initial DCID. */175if (!ch->is_server176&& !ossl_quic_gen_rand_conn_id(ch->port->engine->libctx, tx_init_dcid_len,177&ch->init_dcid))178goto err;179180/* We plug in a network write BIO to the QTX later when we get one. */181qtx_args.libctx = ch->port->engine->libctx;182qtx_args.get_qlog_cb = ch_get_qlog_cb;183qtx_args.get_qlog_cb_arg = ch;184qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN;185ch->rx_max_udp_payload_size = qtx_args.mdpl;186187ch->ping_deadline = ossl_time_infinite();188189ch->qtx = ossl_qtx_new(&qtx_args);190if (ch->qtx == NULL)191goto err;192193ch->txpim = ossl_quic_txpim_new();194if (ch->txpim == NULL)195goto err;196197ch->cfq = ossl_quic_cfq_new();198if (ch->cfq == NULL)199goto err;200201if (!ossl_quic_txfc_init(&ch->conn_txfc, NULL))202goto err;203204/*205* Note: The TP we transmit governs what the peer can transmit and thus206* applies to the RXFC.207*/208ch->tx_init_max_stream_data_bidi_local = DEFAULT_INIT_STREAM_RXFC_WND;209ch->tx_init_max_stream_data_bidi_remote = DEFAULT_INIT_STREAM_RXFC_WND;210ch->tx_init_max_stream_data_uni = DEFAULT_INIT_STREAM_RXFC_WND;211212if (!ossl_quic_rxfc_init(&ch->conn_rxfc, NULL,213DEFAULT_INIT_CONN_RXFC_WND,214DEFAULT_CONN_RXFC_MAX_WND_MUL *215DEFAULT_INIT_CONN_RXFC_WND,216get_time, ch))217goto err;218219for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space)220if (!ossl_quic_rxfc_init_standalone(&ch->crypto_rxfc[pn_space],221INIT_CRYPTO_RECV_BUF_LEN,222get_time, ch))223goto err;224225if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_bidi_rxfc,226DEFAULT_INIT_CONN_MAX_STREAMS,227get_time, ch))228goto err;229230if (!ossl_quic_rxfc_init_standalone(&ch->max_streams_uni_rxfc,231DEFAULT_INIT_CONN_MAX_STREAMS,232get_time, ch))233goto err;234235if (!ossl_statm_init(&ch->statm))236goto err;237238ch->have_statm = 1;239ch->cc_method = &ossl_cc_newreno_method;240if ((ch->cc_data = ch->cc_method->new(get_time, ch)) == NULL)241goto err;242243if ((ch->ackm = ossl_ackm_new(get_time, ch, &ch->statm,244ch->cc_method, ch->cc_data,245ch->is_server)) == NULL)246goto err;247248if (!ossl_quic_stream_map_init(&ch->qsm, get_stream_limit, ch,249&ch->max_streams_bidi_rxfc,250&ch->max_streams_uni_rxfc,251ch->is_server))252goto err;253254ch->have_qsm = 1;255256if (!ch->is_server257&& !ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &ch->init_scid))258goto err;259260txp_args.cur_scid = ch->init_scid;261txp_args.cur_dcid = ch->init_dcid;262txp_args.ack_delay_exponent = 3;263txp_args.qtx = ch->qtx;264txp_args.txpim = ch->txpim;265txp_args.cfq = ch->cfq;266txp_args.ackm = ch->ackm;267txp_args.qsm = &ch->qsm;268txp_args.conn_txfc = &ch->conn_txfc;269txp_args.conn_rxfc = &ch->conn_rxfc;270txp_args.max_streams_bidi_rxfc = &ch->max_streams_bidi_rxfc;271txp_args.max_streams_uni_rxfc = &ch->max_streams_uni_rxfc;272txp_args.cc_method = ch->cc_method;273txp_args.cc_data = ch->cc_data;274txp_args.now = get_time;275txp_args.now_arg = ch;276txp_args.get_qlog_cb = ch_get_qlog_cb;277txp_args.get_qlog_cb_arg = ch;278txp_args.protocol_version = QUIC_VERSION_1;279280for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) {281ch->crypto_send[pn_space] = ossl_quic_sstream_new(INIT_CRYPTO_SEND_BUF_LEN);282if (ch->crypto_send[pn_space] == NULL)283goto err;284285txp_args.crypto[pn_space] = ch->crypto_send[pn_space];286}287288ch->txp = ossl_quic_tx_packetiser_new(&txp_args);289if (ch->txp == NULL)290goto err;291292/* clients have no amplification limit, so are considered always valid */293if (!ch->is_server)294ossl_quic_tx_packetiser_set_validated(ch->txp);295296ossl_quic_tx_packetiser_set_ack_tx_cb(ch->txp, ch_on_txp_ack_tx, ch);297298/*299* qrx does not exist yet, then we must be dealing with client channel300* (QUIC connection initiator).301* If qrx exists already, then we are dealing with server channel which302* qrx gets created by port_default_packet_handler() before303* port_default_packet_handler() accepts connection and creates channel304* for it.305* The exception here is tserver which always creates channel,306* before the first packet is ever seen.307*/308if (ch->qrx == NULL && ch->is_tserver_ch == 0) {309/* we are regular client, create channel */310qrx_args.libctx = ch->port->engine->libctx;311qrx_args.demux = ch->port->demux;312qrx_args.short_conn_id_len = rx_short_dcid_len;313qrx_args.max_deferred = 32;314315if ((ch->qrx = ossl_qrx_new(&qrx_args)) == NULL)316goto err;317}318319if (ch->qrx != NULL) {320/*321* callbacks for channels associated with tserver's port322* are set up later when we call ossl_quic_channel_bind_qrx()323* in port_default_packet_handler()324*/325if (!ossl_qrx_set_late_validation_cb(ch->qrx,326rx_late_validate,327ch))328goto err;329330if (!ossl_qrx_set_key_update_cb(ch->qrx,331rxku_detected,332ch))333goto err;334}335336337for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) {338ch->crypto_recv[pn_space] = ossl_quic_rstream_new(NULL, NULL, 0);339if (ch->crypto_recv[pn_space] == NULL)340goto err;341}342343/* Plug in the TLS handshake layer. */344tls_args.s = ch->tls;345tls_args.crypto_send_cb = ch_on_crypto_send;346tls_args.crypto_send_cb_arg = ch;347tls_args.crypto_recv_rcd_cb = ch_on_crypto_recv_record;348tls_args.crypto_recv_rcd_cb_arg = ch;349tls_args.crypto_release_rcd_cb = ch_on_crypto_release_record;350tls_args.crypto_release_rcd_cb_arg = ch;351tls_args.yield_secret_cb = ch_on_handshake_yield_secret;352tls_args.yield_secret_cb_arg = ch;353tls_args.got_transport_params_cb = ch_on_transport_params;354tls_args.got_transport_params_cb_arg= ch;355tls_args.handshake_complete_cb = ch_on_handshake_complete;356tls_args.handshake_complete_cb_arg = ch;357tls_args.alert_cb = ch_on_handshake_alert;358tls_args.alert_cb_arg = ch;359tls_args.is_server = ch->is_server;360tls_args.ossl_quic = 1;361362if ((ch->qtls = ossl_quic_tls_new(&tls_args)) == NULL)363goto err;364365ch->tx_max_ack_delay = DEFAULT_MAX_ACK_DELAY;366ch->rx_max_ack_delay = QUIC_DEFAULT_MAX_ACK_DELAY;367ch->rx_ack_delay_exp = QUIC_DEFAULT_ACK_DELAY_EXP;368ch->rx_active_conn_id_limit = QUIC_MIN_ACTIVE_CONN_ID_LIMIT;369ch->tx_enc_level = QUIC_ENC_LEVEL_INITIAL;370ch->rx_enc_level = QUIC_ENC_LEVEL_INITIAL;371ch->txku_threshold_override = UINT64_MAX;372373ch->max_idle_timeout_local_req = QUIC_DEFAULT_IDLE_TIMEOUT;374ch->max_idle_timeout_remote_req = 0;375ch->max_idle_timeout = ch->max_idle_timeout_local_req;376377ossl_ackm_set_tx_max_ack_delay(ch->ackm, ossl_ms2time(ch->tx_max_ack_delay));378ossl_ackm_set_rx_max_ack_delay(ch->ackm, ossl_ms2time(ch->rx_max_ack_delay));379380ch_update_idle(ch);381ossl_list_ch_insert_tail(&ch->port->channel_list, ch);382ch->on_port_list = 1;383return 1;384385err:386ch_cleanup(ch);387return 0;388}389390static void ch_cleanup(QUIC_CHANNEL *ch)391{392uint32_t pn_space;393394if (ch->ackm != NULL)395for (pn_space = QUIC_PN_SPACE_INITIAL;396pn_space < QUIC_PN_SPACE_NUM;397++pn_space)398ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space);399400ossl_quic_lcidm_cull(ch->lcidm, ch);401ossl_quic_srtm_cull(ch->srtm, ch);402ossl_quic_tx_packetiser_free(ch->txp);403ossl_quic_txpim_free(ch->txpim);404ossl_quic_cfq_free(ch->cfq);405ossl_qtx_free(ch->qtx);406if (ch->cc_data != NULL)407ch->cc_method->free(ch->cc_data);408if (ch->have_statm)409ossl_statm_destroy(&ch->statm);410ossl_ackm_free(ch->ackm);411412if (ch->have_qsm)413ossl_quic_stream_map_cleanup(&ch->qsm);414415for (pn_space = QUIC_PN_SPACE_INITIAL; pn_space < QUIC_PN_SPACE_NUM; ++pn_space) {416ossl_quic_sstream_free(ch->crypto_send[pn_space]);417ossl_quic_rstream_free(ch->crypto_recv[pn_space]);418}419420ossl_qrx_pkt_release(ch->qrx_pkt);421ch->qrx_pkt = NULL;422423ossl_quic_tls_free(ch->qtls);424ossl_qrx_free(ch->qrx);425OPENSSL_free(ch->local_transport_params);426OPENSSL_free((char *)ch->terminate_cause.reason);427OSSL_ERR_STATE_free(ch->err_state);428OPENSSL_free(ch->ack_range_scratch);429OPENSSL_free(ch->pending_new_token);430431if (ch->on_port_list) {432ossl_list_ch_remove(&ch->port->channel_list, ch);433ch->on_port_list = 0;434}435436#ifndef OPENSSL_NO_QLOG437if (ch->qlog != NULL)438ossl_qlog_flush(ch->qlog); /* best effort */439440OPENSSL_free(ch->qlog_title);441ossl_qlog_free(ch->qlog);442#endif443}444445int ossl_quic_channel_init(QUIC_CHANNEL *ch)446{447return ch_init(ch);448}449450void ossl_quic_channel_bind_qrx(QUIC_CHANNEL *tserver_ch, OSSL_QRX *qrx)451{452if (tserver_ch->qrx == NULL && tserver_ch->is_tserver_ch == 1) {453tserver_ch->qrx = qrx;454ossl_qrx_set_late_validation_cb(tserver_ch->qrx, rx_late_validate,455tserver_ch);456ossl_qrx_set_key_update_cb(tserver_ch->qrx, rxku_detected,457tserver_ch);458}459}460461QUIC_CHANNEL *ossl_quic_channel_alloc(const QUIC_CHANNEL_ARGS *args)462{463QUIC_CHANNEL *ch = NULL;464465if ((ch = OPENSSL_zalloc(sizeof(*ch))) == NULL)466return NULL;467468ch->port = args->port;469ch->is_server = args->is_server;470ch->tls = args->tls;471ch->lcidm = args->lcidm;472ch->srtm = args->srtm;473ch->qrx = args->qrx;474ch->is_tserver_ch = args->is_tserver_ch;475#ifndef OPENSSL_NO_QLOG476ch->use_qlog = args->use_qlog;477478if (ch->use_qlog && args->qlog_title != NULL) {479if ((ch->qlog_title = OPENSSL_strdup(args->qlog_title)) == NULL) {480OPENSSL_free(ch);481return NULL;482}483}484#endif485486return ch;487}488489void ossl_quic_channel_free(QUIC_CHANNEL *ch)490{491if (ch == NULL)492return;493494ch_cleanup(ch);495OPENSSL_free(ch);496}497498/* Set mutator callbacks for test framework support */499int ossl_quic_channel_set_mutator(QUIC_CHANNEL *ch,500ossl_mutate_packet_cb mutatecb,501ossl_finish_mutate_cb finishmutatecb,502void *mutatearg)503{504if (ch->qtx == NULL)505return 0;506507ossl_qtx_set_mutator(ch->qtx, mutatecb, finishmutatecb, mutatearg);508return 1;509}510511int ossl_quic_channel_get_peer_addr(QUIC_CHANNEL *ch, BIO_ADDR *peer_addr)512{513if (!ch->addressed_mode)514return 0;515516return BIO_ADDR_copy(peer_addr, &ch->cur_peer_addr);517}518519int ossl_quic_channel_set_peer_addr(QUIC_CHANNEL *ch, const BIO_ADDR *peer_addr)520{521if (ch->state != QUIC_CHANNEL_STATE_IDLE)522return 0;523524if (peer_addr == NULL || BIO_ADDR_family(peer_addr) == AF_UNSPEC) {525BIO_ADDR_clear(&ch->cur_peer_addr);526ch->addressed_mode = 0;527return 1;528}529530if (!BIO_ADDR_copy(&ch->cur_peer_addr, peer_addr)) {531ch->addressed_mode = 0;532return 0;533}534ch->addressed_mode = 1;535536return 1;537}538539QUIC_REACTOR *ossl_quic_channel_get_reactor(QUIC_CHANNEL *ch)540{541return ossl_quic_port_get0_reactor(ch->port);542}543544QUIC_STREAM_MAP *ossl_quic_channel_get_qsm(QUIC_CHANNEL *ch)545{546return &ch->qsm;547}548549OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch)550{551return &ch->statm;552}553554SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch)555{556return ch->tls;557}558559static void free_buf_mem(unsigned char *buf, size_t buf_len, void *arg)560{561BUF_MEM_free((BUF_MEM *)arg);562}563564int ossl_quic_channel_schedule_new_token(QUIC_CHANNEL *ch,565const unsigned char *token,566size_t token_len)567{568int rc = 0;569QUIC_CFQ_ITEM *cfq_item;570WPACKET wpkt;571BUF_MEM *buf_mem = NULL;572size_t l = 0;573574buf_mem = BUF_MEM_new();575if (buf_mem == NULL)576goto err;577578if (!WPACKET_init(&wpkt, buf_mem))579goto err;580581if (!ossl_quic_wire_encode_frame_new_token(&wpkt, token,582token_len)) {583WPACKET_cleanup(&wpkt);584goto err;585}586587WPACKET_finish(&wpkt);588589if (!WPACKET_get_total_written(&wpkt, &l))590goto err;591592cfq_item = ossl_quic_cfq_add_frame(ch->cfq, 1,593QUIC_PN_SPACE_APP,594OSSL_QUIC_FRAME_TYPE_NEW_TOKEN, 0,595(unsigned char *)buf_mem->data, l,596free_buf_mem,597buf_mem);598if (cfq_item == NULL)599goto err;600601rc = 1;602err:603if (!rc)604BUF_MEM_free(buf_mem);605return rc;606}607608size_t ossl_quic_channel_get_short_header_conn_id_len(QUIC_CHANNEL *ch)609{610return ossl_quic_port_get_rx_short_dcid_len(ch->port);611}612613QUIC_STREAM *ossl_quic_channel_get_stream_by_id(QUIC_CHANNEL *ch,614uint64_t stream_id)615{616return ossl_quic_stream_map_get_by_id(&ch->qsm, stream_id);617}618619int ossl_quic_channel_is_active(const QUIC_CHANNEL *ch)620{621return ch != NULL && ch->state == QUIC_CHANNEL_STATE_ACTIVE;622}623624int ossl_quic_channel_is_closing(const QUIC_CHANNEL *ch)625{626return ch->state == QUIC_CHANNEL_STATE_TERMINATING_CLOSING;627}628629static int ossl_quic_channel_is_draining(const QUIC_CHANNEL *ch)630{631return ch->state == QUIC_CHANNEL_STATE_TERMINATING_DRAINING;632}633634static int ossl_quic_channel_is_terminating(const QUIC_CHANNEL *ch)635{636return ossl_quic_channel_is_closing(ch)637|| ossl_quic_channel_is_draining(ch);638}639640int ossl_quic_channel_is_terminated(const QUIC_CHANNEL *ch)641{642return ch->state == QUIC_CHANNEL_STATE_TERMINATED;643}644645int ossl_quic_channel_is_term_any(const QUIC_CHANNEL *ch)646{647return ossl_quic_channel_is_terminating(ch)648|| ossl_quic_channel_is_terminated(ch);649}650651const QUIC_TERMINATE_CAUSE *652ossl_quic_channel_get_terminate_cause(const QUIC_CHANNEL *ch)653{654return ossl_quic_channel_is_term_any(ch) ? &ch->terminate_cause : NULL;655}656657int ossl_quic_channel_is_handshake_complete(const QUIC_CHANNEL *ch)658{659return ch->handshake_complete;660}661662int ossl_quic_channel_is_handshake_confirmed(const QUIC_CHANNEL *ch)663{664return ch->handshake_confirmed;665}666667QUIC_DEMUX *ossl_quic_channel_get0_demux(QUIC_CHANNEL *ch)668{669return ch->port->demux;670}671672QUIC_PORT *ossl_quic_channel_get0_port(QUIC_CHANNEL *ch)673{674return ch->port;675}676677QUIC_ENGINE *ossl_quic_channel_get0_engine(QUIC_CHANNEL *ch)678{679return ossl_quic_port_get0_engine(ch->port);680}681682CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch)683{684return ossl_quic_port_get0_mutex(ch->port);685}686687int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch)688{689return ossl_quic_demux_has_pending(ch->port->demux)690|| ossl_qrx_processed_read_pending(ch->qrx);691}692693/*694* QUIC Channel: Callbacks from Miscellaneous Subsidiary Components695* ================================================================696*/697698/* Used by various components. */699static OSSL_TIME get_time(void *arg)700{701QUIC_CHANNEL *ch = arg;702703return ossl_quic_port_get_time(ch->port);704}705706/* Used by QSM. */707static uint64_t get_stream_limit(int uni, void *arg)708{709QUIC_CHANNEL *ch = arg;710711return uni ? ch->max_local_streams_uni : ch->max_local_streams_bidi;712}713714/*715* Called by QRX to determine if a packet is potentially invalid before trying716* to decrypt it.717*/718static int rx_late_validate(QUIC_PN pn, int pn_space, void *arg)719{720QUIC_CHANNEL *ch = arg;721722/* Potential duplicates should not be processed. */723if (!ossl_ackm_is_rx_pn_processable(ch->ackm, pn, pn_space))724return 0;725726return 1;727}728729/*730* Triggers a TXKU (whether spontaneous or solicited). Does not check whether731* spontaneous TXKU is currently allowed.732*/733QUIC_NEEDS_LOCK734static void ch_trigger_txku(QUIC_CHANNEL *ch)735{736uint64_t next_pn737= ossl_quic_tx_packetiser_get_next_pn(ch->txp, QUIC_PN_SPACE_APP);738739if (!ossl_quic_pn_valid(next_pn)740|| !ossl_qtx_trigger_key_update(ch->qtx)) {741ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,742"key update");743return;744}745746ch->txku_in_progress = 1;747ch->txku_pn = next_pn;748ch->rxku_expected = ch->ku_locally_initiated;749}750751QUIC_NEEDS_LOCK752static int txku_in_progress(QUIC_CHANNEL *ch)753{754if (ch->txku_in_progress755&& ossl_ackm_get_largest_acked(ch->ackm, QUIC_PN_SPACE_APP) >= ch->txku_pn) {756OSSL_TIME pto = ossl_ackm_get_pto_duration(ch->ackm);757758/*759* RFC 9001 s. 6.5: Endpoints SHOULD wait three times the PTO before760* initiating a key update after receiving an acknowledgment that761* confirms that the previous key update was received.762*763* Note that by the above wording, this period starts from when we get764* the ack for a TXKU-triggering packet, not when the TXKU is initiated.765* So we defer TXKU cooldown deadline calculation to this point.766*/767ch->txku_in_progress = 0;768ch->txku_cooldown_deadline = ossl_time_add(get_time(ch),769ossl_time_multiply(pto, 3));770}771772return ch->txku_in_progress;773}774775QUIC_NEEDS_LOCK776static int txku_allowed(QUIC_CHANNEL *ch)777{778return ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT /* Sanity check. */779/* Strict RFC 9001 criterion for TXKU. */780&& ch->handshake_confirmed781&& !txku_in_progress(ch);782}783784QUIC_NEEDS_LOCK785static int txku_recommendable(QUIC_CHANNEL *ch)786{787if (!txku_allowed(ch))788return 0;789790return791/* Recommended RFC 9001 criterion for TXKU. */792ossl_time_compare(get_time(ch), ch->txku_cooldown_deadline) >= 0793/* Some additional sensible criteria. */794&& !ch->rxku_in_progress795&& !ch->rxku_pending_confirm;796}797798QUIC_NEEDS_LOCK799static int txku_desirable(QUIC_CHANNEL *ch)800{801uint64_t cur_pkt_count, max_pkt_count, thresh_pkt_count;802const uint32_t enc_level = QUIC_ENC_LEVEL_1RTT;803804/* Check AEAD limit to determine if we should perform a spontaneous TXKU. */805cur_pkt_count = ossl_qtx_get_cur_epoch_pkt_count(ch->qtx, enc_level);806max_pkt_count = ossl_qtx_get_max_epoch_pkt_count(ch->qtx, enc_level);807808thresh_pkt_count = max_pkt_count / 2;809if (ch->txku_threshold_override != UINT64_MAX)810thresh_pkt_count = ch->txku_threshold_override;811812return cur_pkt_count >= thresh_pkt_count;813}814815QUIC_NEEDS_LOCK816static void ch_maybe_trigger_spontaneous_txku(QUIC_CHANNEL *ch)817{818if (!txku_recommendable(ch) || !txku_desirable(ch))819return;820821ch->ku_locally_initiated = 1;822ch_trigger_txku(ch);823}824825QUIC_NEEDS_LOCK826static int rxku_allowed(QUIC_CHANNEL *ch)827{828/*829* RFC 9001 s. 6.1: An endpoint MUST NOT initiate a key update prior to830* having confirmed the handshake (Section 4.1.2).831*832* RFC 9001 s. 6.1: An endpoint MUST NOT initiate a subsequent key update833* unless it has received an acknowledgment for a packet that was sent834* protected with keys from the current key phase.835*836* RFC 9001 s. 6.2: If an endpoint detects a second update before it has837* sent any packets with updated keys containing an acknowledgment for the838* packet that initiated the key update, it indicates that its peer has839* updated keys twice without awaiting confirmation. An endpoint MAY treat840* such consecutive key updates as a connection error of type841* KEY_UPDATE_ERROR.842*/843return ch->handshake_confirmed && !ch->rxku_pending_confirm;844}845846/*847* Called when the QRX detects a new RX key update event.848*/849enum rxku_decision {850DECISION_RXKU_ONLY,851DECISION_PROTOCOL_VIOLATION,852DECISION_SOLICITED_TXKU853};854855/* Called when the QRX detects a key update has occurred. */856QUIC_NEEDS_LOCK857static void rxku_detected(QUIC_PN pn, void *arg)858{859QUIC_CHANNEL *ch = arg;860enum rxku_decision decision;861OSSL_TIME pto;862863/*864* Note: rxku_in_progress is always 0 here as an RXKU cannot be detected865* when we are still in UPDATING or COOLDOWN (see quic_record_rx.h).866*/867assert(!ch->rxku_in_progress);868869if (!rxku_allowed(ch))870/* Is RXKU even allowed at this time? */871decision = DECISION_PROTOCOL_VIOLATION;872873else if (ch->ku_locally_initiated)874/*875* If this key update was locally initiated (meaning that this detected876* RXKU event is a result of our own spontaneous TXKU), we do not877* trigger another TXKU; after all, to do so would result in an infinite878* ping-pong of key updates. We still process it as an RXKU.879*/880decision = DECISION_RXKU_ONLY;881882else883/*884* Otherwise, a peer triggering a KU means we have to trigger a KU also.885*/886decision = DECISION_SOLICITED_TXKU;887888if (decision == DECISION_PROTOCOL_VIOLATION) {889ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR,8900, "RX key update again too soon");891return;892}893894pto = ossl_ackm_get_pto_duration(ch->ackm);895896ch->ku_locally_initiated = 0;897ch->rxku_in_progress = 1;898ch->rxku_pending_confirm = 1;899ch->rxku_trigger_pn = pn;900ch->rxku_update_end_deadline = ossl_time_add(get_time(ch), pto);901ch->rxku_expected = 0;902903if (decision == DECISION_SOLICITED_TXKU)904/* NOT gated by usual txku_allowed() */905ch_trigger_txku(ch);906907/*908* Ordinarily, we only generate ACK when some ACK-eliciting frame has been909* received. In some cases, this may not occur for a long time, for example910* if transmission of application data is going in only one direction and911* nothing else is happening with the connection. However, since the peer912* cannot initiate a subsequent (spontaneous) TXKU until its prior913* (spontaneous or solicited) TXKU has completed - meaning that prior914* TXKU's trigger packet (or subsequent packet) has been acknowledged, this915* can lead to very long times before a TXKU is considered 'completed'.916* Optimise this by forcing ACK generation after triggering TXKU.917* (Basically, we consider a RXKU event something that is 'ACK-eliciting',918* which it more or less should be; it is necessarily separate from ordinary919* processing of ACK-eliciting frames as key update is not indicated via a920* frame.)921*/922ossl_quic_tx_packetiser_schedule_ack(ch->txp, QUIC_PN_SPACE_APP);923}924925/* Called per tick to handle RXKU timer events. */926QUIC_NEEDS_LOCK927static void ch_rxku_tick(QUIC_CHANNEL *ch)928{929if (!ch->rxku_in_progress930|| ossl_time_compare(get_time(ch), ch->rxku_update_end_deadline) < 0)931return;932933ch->rxku_update_end_deadline = ossl_time_infinite();934ch->rxku_in_progress = 0;935936if (!ossl_qrx_key_update_timeout(ch->qrx, /*normal=*/1))937ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,938"RXKU cooldown internal error");939}940941QUIC_NEEDS_LOCK942static void ch_on_txp_ack_tx(const OSSL_QUIC_FRAME_ACK *ack, uint32_t pn_space,943void *arg)944{945QUIC_CHANNEL *ch = arg;946947if (pn_space != QUIC_PN_SPACE_APP || !ch->rxku_pending_confirm948|| !ossl_quic_frame_ack_contains_pn(ack, ch->rxku_trigger_pn))949return;950951/*952* Defer clearing rxku_pending_confirm until TXP generate call returns953* successfully.954*/955ch->rxku_pending_confirm_done = 1;956}957958/*959* QUIC Channel: Handshake Layer Event Handling960* ============================================961*/962static int ch_on_crypto_send(const unsigned char *buf, size_t buf_len,963size_t *consumed, void *arg)964{965int ret;966QUIC_CHANNEL *ch = arg;967uint32_t enc_level = ch->tx_enc_level;968uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);969QUIC_SSTREAM *sstream = ch->crypto_send[pn_space];970971if (!ossl_assert(sstream != NULL))972return 0;973974ret = ossl_quic_sstream_append(sstream, buf, buf_len, consumed);975return ret;976}977978static int crypto_ensure_empty(QUIC_RSTREAM *rstream)979{980size_t avail = 0;981int is_fin = 0;982983if (rstream == NULL)984return 1;985986if (!ossl_quic_rstream_available(rstream, &avail, &is_fin))987return 0;988989return avail == 0;990}991992static int ch_on_crypto_recv_record(const unsigned char **buf,993size_t *bytes_read, void *arg)994{995QUIC_CHANNEL *ch = arg;996QUIC_RSTREAM *rstream;997int is_fin = 0; /* crypto stream is never finished, so we don't use this */998uint32_t i;9991000/*1001* After we move to a later EL we must not allow our peer to send any new1002* bytes in the crypto stream on a previous EL. Retransmissions of old bytes1003* are allowed.1004*1005* In practice we will only move to a new EL when we have consumed all bytes1006* which should be sent on the crypto stream at a previous EL. For example,1007* the Handshake EL should not be provisioned until we have completely1008* consumed a TLS 1.3 ServerHello. Thus when we provision an EL the output1009* of ossl_quic_rstream_available() should be 0 for all lower ELs. Thus if a1010* given EL is available we simply ensure we have not received any further1011* bytes at a lower EL.1012*/1013for (i = QUIC_ENC_LEVEL_INITIAL; i < ch->rx_enc_level; ++i)1014if (i != QUIC_ENC_LEVEL_0RTT &&1015!crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) {1016/* Protocol violation (RFC 9001 s. 4.1.3) */1017ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,1018OSSL_QUIC_FRAME_TYPE_CRYPTO,1019"crypto stream data in wrong EL");1020return 0;1021}10221023rstream = ch->crypto_recv[ossl_quic_enc_level_to_pn_space(ch->rx_enc_level)];1024if (rstream == NULL)1025return 0;10261027return ossl_quic_rstream_get_record(rstream, buf, bytes_read,1028&is_fin);1029}10301031static int ch_on_crypto_release_record(size_t bytes_read, void *arg)1032{1033QUIC_CHANNEL *ch = arg;1034QUIC_RSTREAM *rstream;1035OSSL_RTT_INFO rtt_info;1036uint32_t rx_pn_space = ossl_quic_enc_level_to_pn_space(ch->rx_enc_level);10371038rstream = ch->crypto_recv[rx_pn_space];1039if (rstream == NULL)1040return 0;10411042ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info);1043if (!ossl_quic_rxfc_on_retire(&ch->crypto_rxfc[rx_pn_space], bytes_read,1044rtt_info.smoothed_rtt))1045return 0;10461047return ossl_quic_rstream_release_record(rstream, bytes_read);1048}10491050static int ch_on_handshake_yield_secret(uint32_t prot_level, int direction,1051uint32_t suite_id, EVP_MD *md,1052const unsigned char *secret,1053size_t secret_len,1054void *arg)1055{1056QUIC_CHANNEL *ch = arg;1057uint32_t i;1058uint32_t enc_level;10591060/* Convert TLS protection level to QUIC encryption level */1061switch (prot_level) {1062case OSSL_RECORD_PROTECTION_LEVEL_EARLY:1063enc_level = QUIC_ENC_LEVEL_0RTT;1064break;10651066case OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE:1067enc_level = QUIC_ENC_LEVEL_HANDSHAKE;1068break;10691070case OSSL_RECORD_PROTECTION_LEVEL_APPLICATION:1071enc_level = QUIC_ENC_LEVEL_1RTT;1072break;10731074default:1075return 0;1076}10771078if (enc_level < QUIC_ENC_LEVEL_HANDSHAKE || enc_level >= QUIC_ENC_LEVEL_NUM)1079/* Invalid EL. */1080return 0;108110821083if (direction) {1084/* TX */1085if (enc_level <= ch->tx_enc_level)1086/*1087* Does not make sense for us to try and provision an EL we have already1088* attained.1089*/1090return 0;10911092if (!ossl_qtx_provide_secret(ch->qtx, enc_level,1093suite_id, md,1094secret, secret_len))1095return 0;10961097ch->tx_enc_level = enc_level;1098} else {1099/* RX */1100if (enc_level <= ch->rx_enc_level)1101/*1102* Does not make sense for us to try and provision an EL we have already1103* attained.1104*/1105return 0;11061107/*1108* Ensure all crypto streams for previous ELs are now empty of available1109* data.1110*/1111for (i = QUIC_ENC_LEVEL_INITIAL; i < enc_level; ++i)1112if (!crypto_ensure_empty(ch->crypto_recv[ossl_quic_enc_level_to_pn_space(i)])) {1113/* Protocol violation (RFC 9001 s. 4.1.3) */1114ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,1115OSSL_QUIC_FRAME_TYPE_CRYPTO,1116"crypto stream data in wrong EL");1117return 0;1118}11191120if (!ossl_qrx_provide_secret(ch->qrx, enc_level,1121suite_id, md,1122secret, secret_len))1123return 0;11241125ch->have_new_rx_secret = 1;1126ch->rx_enc_level = enc_level;1127}11281129return 1;1130}11311132static int ch_on_handshake_complete(void *arg)1133{1134QUIC_CHANNEL *ch = arg;11351136if (!ossl_assert(!ch->handshake_complete))1137return 0; /* this should not happen twice */11381139if (!ossl_assert(ch->tx_enc_level == QUIC_ENC_LEVEL_1RTT))1140return 0;11411142/*1143* When handshake is complete, we no longer need to abide by the1144* 3x amplification limit, though we should be validated as soon1145* as we see a handshake key encrypted packet (see ossl_quic_handle_packet)1146*/1147ossl_quic_tx_packetiser_set_validated(ch->txp);11481149if (!ch->got_remote_transport_params) {1150/*1151* Was not a valid QUIC handshake if we did not get valid transport1152* params.1153*/1154ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CRYPTO_MISSING_EXT,1155OSSL_QUIC_FRAME_TYPE_CRYPTO,1156"no transport parameters received");1157return 0;1158}11591160/* Don't need transport parameters anymore. */1161OPENSSL_free(ch->local_transport_params);1162ch->local_transport_params = NULL;11631164/* Tell the QRX it can now process 1-RTT packets. */1165ossl_qrx_allow_1rtt_processing(ch->qrx);11661167/* Tell TXP the handshake is complete. */1168ossl_quic_tx_packetiser_notify_handshake_complete(ch->txp);11691170ch->handshake_complete = 1;11711172if (ch->pending_new_token != NULL) {1173/*1174* Note this is a best effort operation here1175* If scheduling a new token fails, the worst outcome is that1176* a client, not having received it, will just have to go through1177* an extra roundtrip on a subsequent connection via the retry frame1178* path, at which point we get another opportunity to schedule another1179* new token. As a result, we don't need to handle any errors here1180*/1181ossl_quic_channel_schedule_new_token(ch,1182ch->pending_new_token,1183ch->pending_new_token_len);1184OPENSSL_free(ch->pending_new_token);1185ch->pending_new_token = NULL;1186ch->pending_new_token_len = 0;1187}11881189if (ch->is_server) {1190/*1191* On the server, the handshake is confirmed as soon as it is complete.1192*/1193ossl_quic_channel_on_handshake_confirmed(ch);11941195ossl_quic_tx_packetiser_schedule_handshake_done(ch->txp);1196}11971198ch_record_state_transition(ch, ch->state);1199return 1;1200}12011202static int ch_on_handshake_alert(void *arg, unsigned char alert_code)1203{1204QUIC_CHANNEL *ch = arg;12051206/*1207* RFC 9001 s. 4.4: More specifically, servers MUST NOT send post-handshake1208* TLS CertificateRequest messages, and clients MUST treat receipt of such1209* messages as a connection error of type PROTOCOL_VIOLATION.1210*/1211if (alert_code == SSL_AD_UNEXPECTED_MESSAGE1212&& ch->handshake_complete1213&& ossl_quic_tls_is_cert_request(ch->qtls))1214ossl_quic_channel_raise_protocol_error(ch,1215OSSL_QUIC_ERR_PROTOCOL_VIOLATION,12160,1217"Post-handshake TLS "1218"CertificateRequest received");1219/*1220* RFC 9001 s. 4.6.1: Servers MUST NOT send the early_data extension with a1221* max_early_data_size field set to any value other than 0xffffffff. A1222* client MUST treat receipt of a NewSessionTicket that contains an1223* early_data extension with any other value as a connection error of type1224* PROTOCOL_VIOLATION.1225*/1226else if (alert_code == SSL_AD_ILLEGAL_PARAMETER1227&& ch->handshake_complete1228&& ossl_quic_tls_has_bad_max_early_data(ch->qtls))1229ossl_quic_channel_raise_protocol_error(ch,1230OSSL_QUIC_ERR_PROTOCOL_VIOLATION,12310,1232"Bad max_early_data received");1233else1234ossl_quic_channel_raise_protocol_error(ch,1235OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN1236+ alert_code,12370, "handshake alert");12381239return 1;1240}12411242/*1243* QUIC Channel: Transport Parameter Handling1244* ==========================================1245*/12461247/*1248* Called by handshake layer when we receive QUIC Transport Parameters from the1249* peer. Note that these are not authenticated until the handshake is marked1250* as complete.1251*/1252#define TP_REASON_SERVER_ONLY(x) \1253x " may not be sent by a client"1254#define TP_REASON_DUP(x) \1255x " appears multiple times"1256#define TP_REASON_MALFORMED(x) \1257x " is malformed"1258#define TP_REASON_EXPECTED_VALUE(x) \1259x " does not match expected value"1260#define TP_REASON_NOT_RETRY(x) \1261x " sent when not performing a retry"1262#define TP_REASON_REQUIRED(x) \1263x " was not sent but is required"1264#define TP_REASON_INTERNAL_ERROR(x) \1265x " encountered internal error"12661267static void txfc_bump_cwm_bidi(QUIC_STREAM *s, void *arg)1268{1269if (!ossl_quic_stream_is_bidi(s)1270|| ossl_quic_stream_is_server_init(s))1271return;12721273ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg);1274}12751276static void txfc_bump_cwm_uni(QUIC_STREAM *s, void *arg)1277{1278if (ossl_quic_stream_is_bidi(s)1279|| ossl_quic_stream_is_server_init(s))1280return;12811282ossl_quic_txfc_bump_cwm(&s->txfc, *(uint64_t *)arg);1283}12841285static void do_update(QUIC_STREAM *s, void *arg)1286{1287QUIC_CHANNEL *ch = arg;12881289ossl_quic_stream_map_update_state(&ch->qsm, s);1290}12911292static uint64_t min_u64_ignore_0(uint64_t a, uint64_t b)1293{1294if (a == 0)1295return b;1296if (b == 0)1297return a;12981299return a < b ? a : b;1300}13011302static int ch_on_transport_params(const unsigned char *params,1303size_t params_len,1304void *arg)1305{1306QUIC_CHANNEL *ch = arg;1307PACKET pkt;1308uint64_t id, v;1309size_t len;1310const unsigned char *body;1311int got_orig_dcid = 0;1312int got_initial_scid = 0;1313int got_retry_scid = 0;1314int got_initial_max_data = 0;1315int got_initial_max_stream_data_bidi_local = 0;1316int got_initial_max_stream_data_bidi_remote = 0;1317int got_initial_max_stream_data_uni = 0;1318int got_initial_max_streams_bidi = 0;1319int got_initial_max_streams_uni = 0;1320int got_stateless_reset_token = 0;1321int got_preferred_addr = 0;1322int got_ack_delay_exp = 0;1323int got_max_ack_delay = 0;1324int got_max_udp_payload_size = 0;1325int got_max_idle_timeout = 0;1326int got_active_conn_id_limit = 0;1327int got_disable_active_migration = 0;1328QUIC_CONN_ID cid;1329const char *reason = "bad transport parameter";1330ossl_unused uint64_t rx_max_idle_timeout = 0;1331ossl_unused const void *stateless_reset_token_p = NULL;1332QUIC_PREFERRED_ADDR pfa;1333SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ch->tls);13341335/*1336* When HRR happens the client sends the transport params in the new client1337* hello again. Reset the transport params here and load them again.1338*/1339if (ch->is_server && sc->hello_retry_request != SSL_HRR_NONE1340&& ch->got_remote_transport_params) {1341ch->max_local_streams_bidi = 0;1342ch->max_local_streams_uni = 0;1343ch->got_local_transport_params = 0;1344OPENSSL_free(ch->local_transport_params);1345ch->local_transport_params = NULL;1346} else if (ch->got_remote_transport_params) {1347reason = "multiple transport parameter extensions";1348goto malformed;1349}13501351if (!PACKET_buf_init(&pkt, params, params_len)) {1352ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,1353"internal error (packet buf init)");1354return 0;1355}13561357while (PACKET_remaining(&pkt) > 0) {1358if (!ossl_quic_wire_peek_transport_param(&pkt, &id))1359goto malformed;13601361switch (id) {1362case QUIC_TPARAM_ORIG_DCID:1363if (got_orig_dcid) {1364reason = TP_REASON_DUP("ORIG_DCID");1365goto malformed;1366}13671368if (ch->is_server) {1369reason = TP_REASON_SERVER_ONLY("ORIG_DCID");1370goto malformed;1371}13721373if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) {1374reason = TP_REASON_MALFORMED("ORIG_DCID");1375goto malformed;1376}13771378#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION1379/* Must match our initial DCID. */1380if (!ossl_quic_conn_id_eq(&ch->init_dcid, &cid)) {1381reason = TP_REASON_EXPECTED_VALUE("ORIG_DCID");1382goto malformed;1383}1384#endif13851386got_orig_dcid = 1;1387break;13881389case QUIC_TPARAM_RETRY_SCID:1390if (ch->is_server) {1391reason = TP_REASON_SERVER_ONLY("RETRY_SCID");1392goto malformed;1393}13941395if (got_retry_scid) {1396reason = TP_REASON_DUP("RETRY_SCID");1397goto malformed;1398}13991400if (!ch->doing_retry) {1401reason = TP_REASON_NOT_RETRY("RETRY_SCID");1402goto malformed;1403}14041405if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) {1406reason = TP_REASON_MALFORMED("RETRY_SCID");1407goto malformed;1408}14091410/* Must match Retry packet SCID. */1411if (!ossl_quic_conn_id_eq(&ch->retry_scid, &cid)) {1412reason = TP_REASON_EXPECTED_VALUE("RETRY_SCID");1413goto malformed;1414}14151416got_retry_scid = 1;1417break;14181419case QUIC_TPARAM_INITIAL_SCID:1420if (got_initial_scid) {1421/* must not appear more than once */1422reason = TP_REASON_DUP("INITIAL_SCID");1423goto malformed;1424}14251426if (!ossl_quic_wire_decode_transport_param_cid(&pkt, NULL, &cid)) {1427reason = TP_REASON_MALFORMED("INITIAL_SCID");1428goto malformed;1429}14301431if (!ossl_quic_conn_id_eq(&ch->init_scid, &cid)) {1432reason = TP_REASON_EXPECTED_VALUE("INITIAL_SCID");1433goto malformed;1434}14351436got_initial_scid = 1;1437break;14381439case QUIC_TPARAM_INITIAL_MAX_DATA:1440if (got_initial_max_data) {1441/* must not appear more than once */1442reason = TP_REASON_DUP("INITIAL_MAX_DATA");1443goto malformed;1444}14451446if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) {1447reason = TP_REASON_MALFORMED("INITIAL_MAX_DATA");1448goto malformed;1449}14501451ossl_quic_txfc_bump_cwm(&ch->conn_txfc, v);1452got_initial_max_data = 1;1453break;14541455case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL:1456if (got_initial_max_stream_data_bidi_local) {1457/* must not appear more than once */1458reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL");1459goto malformed;1460}14611462if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) {1463reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_LOCAL");1464goto malformed;1465}14661467/*1468* This is correct; the BIDI_LOCAL TP governs streams created by1469* the endpoint which sends the TP, i.e., our peer.1470*/1471ch->rx_init_max_stream_data_bidi_remote = v;1472got_initial_max_stream_data_bidi_local = 1;1473break;14741475case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE:1476if (got_initial_max_stream_data_bidi_remote) {1477/* must not appear more than once */1478reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE");1479goto malformed;1480}14811482if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) {1483reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_BIDI_REMOTE");1484goto malformed;1485}14861487/*1488* This is correct; the BIDI_REMOTE TP governs streams created1489* by the endpoint which receives the TP, i.e., us.1490*/1491ch->rx_init_max_stream_data_bidi_local = v;14921493/* Apply to all existing streams. */1494ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_bidi, &v);1495got_initial_max_stream_data_bidi_remote = 1;1496break;14971498case QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI:1499if (got_initial_max_stream_data_uni) {1500/* must not appear more than once */1501reason = TP_REASON_DUP("INITIAL_MAX_STREAM_DATA_UNI");1502goto malformed;1503}15041505if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) {1506reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAM_DATA_UNI");1507goto malformed;1508}15091510ch->rx_init_max_stream_data_uni = v;15111512/* Apply to all existing streams. */1513ossl_quic_stream_map_visit(&ch->qsm, txfc_bump_cwm_uni, &v);1514got_initial_max_stream_data_uni = 1;1515break;15161517case QUIC_TPARAM_ACK_DELAY_EXP:1518if (got_ack_delay_exp) {1519/* must not appear more than once */1520reason = TP_REASON_DUP("ACK_DELAY_EXP");1521goto malformed;1522}15231524if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1525|| v > QUIC_MAX_ACK_DELAY_EXP) {1526reason = TP_REASON_MALFORMED("ACK_DELAY_EXP");1527goto malformed;1528}15291530ch->rx_ack_delay_exp = (unsigned char)v;1531got_ack_delay_exp = 1;1532break;15331534case QUIC_TPARAM_MAX_ACK_DELAY:1535if (got_max_ack_delay) {1536/* must not appear more than once */1537reason = TP_REASON_DUP("MAX_ACK_DELAY");1538goto malformed;1539}15401541if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1542|| v >= (((uint64_t)1) << 14)) {1543reason = TP_REASON_MALFORMED("MAX_ACK_DELAY");1544goto malformed;1545}15461547ch->rx_max_ack_delay = v;1548ossl_ackm_set_rx_max_ack_delay(ch->ackm,1549ossl_ms2time(ch->rx_max_ack_delay));15501551got_max_ack_delay = 1;1552break;15531554case QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI:1555if (got_initial_max_streams_bidi) {1556/* must not appear more than once */1557reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_BIDI");1558goto malformed;1559}15601561if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1562|| v > (((uint64_t)1) << 60)) {1563reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_BIDI");1564goto malformed;1565}15661567assert(ch->max_local_streams_bidi == 0);1568ch->max_local_streams_bidi = v;1569got_initial_max_streams_bidi = 1;1570break;15711572case QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI:1573if (got_initial_max_streams_uni) {1574/* must not appear more than once */1575reason = TP_REASON_DUP("INITIAL_MAX_STREAMS_UNI");1576goto malformed;1577}15781579if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1580|| v > (((uint64_t)1) << 60)) {1581reason = TP_REASON_MALFORMED("INITIAL_MAX_STREAMS_UNI");1582goto malformed;1583}15841585assert(ch->max_local_streams_uni == 0);1586ch->max_local_streams_uni = v;1587got_initial_max_streams_uni = 1;1588break;15891590case QUIC_TPARAM_MAX_IDLE_TIMEOUT:1591if (got_max_idle_timeout) {1592/* must not appear more than once */1593reason = TP_REASON_DUP("MAX_IDLE_TIMEOUT");1594goto malformed;1595}15961597if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)) {1598reason = TP_REASON_MALFORMED("MAX_IDLE_TIMEOUT");1599goto malformed;1600}16011602ch->max_idle_timeout_remote_req = v;16031604ch->max_idle_timeout = min_u64_ignore_0(ch->max_idle_timeout_local_req,1605ch->max_idle_timeout_remote_req);160616071608ch_update_idle(ch);1609got_max_idle_timeout = 1;1610rx_max_idle_timeout = v;1611break;16121613case QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE:1614if (got_max_udp_payload_size) {1615/* must not appear more than once */1616reason = TP_REASON_DUP("MAX_UDP_PAYLOAD_SIZE");1617goto malformed;1618}16191620if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1621|| v < QUIC_MIN_INITIAL_DGRAM_LEN) {1622reason = TP_REASON_MALFORMED("MAX_UDP_PAYLOAD_SIZE");1623goto malformed;1624}16251626ch->rx_max_udp_payload_size = v;1627got_max_udp_payload_size = 1;1628break;16291630case QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT:1631if (got_active_conn_id_limit) {1632/* must not appear more than once */1633reason = TP_REASON_DUP("ACTIVE_CONN_ID_LIMIT");1634goto malformed;1635}16361637if (!ossl_quic_wire_decode_transport_param_int(&pkt, &id, &v)1638|| v < QUIC_MIN_ACTIVE_CONN_ID_LIMIT) {1639reason = TP_REASON_MALFORMED("ACTIVE_CONN_ID_LIMIT");1640goto malformed;1641}16421643ch->rx_active_conn_id_limit = v;1644got_active_conn_id_limit = 1;1645break;16461647case QUIC_TPARAM_STATELESS_RESET_TOKEN:1648if (got_stateless_reset_token) {1649reason = TP_REASON_DUP("STATELESS_RESET_TOKEN");1650goto malformed;1651}16521653/*1654* RFC 9000 s. 18.2: This transport parameter MUST NOT be sent1655* by a client but MAY be sent by a server.1656*/1657if (ch->is_server) {1658reason = TP_REASON_SERVER_ONLY("STATELESS_RESET_TOKEN");1659goto malformed;1660}16611662body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len);1663if (body == NULL || len != QUIC_STATELESS_RESET_TOKEN_LEN) {1664reason = TP_REASON_MALFORMED("STATELESS_RESET_TOKEN");1665goto malformed;1666}1667if (!ossl_quic_srtm_add(ch->srtm, ch, ch->cur_remote_seq_num,1668(const QUIC_STATELESS_RESET_TOKEN *)body)) {1669reason = TP_REASON_INTERNAL_ERROR("STATELESS_RESET_TOKEN");1670goto malformed;1671}16721673stateless_reset_token_p = body;1674got_stateless_reset_token = 1;1675break;16761677case QUIC_TPARAM_PREFERRED_ADDR:1678/* TODO(QUIC FUTURE): Handle preferred address. */1679if (got_preferred_addr) {1680reason = TP_REASON_DUP("PREFERRED_ADDR");1681goto malformed;1682}16831684/*1685* RFC 9000 s. 18.2: "A server that chooses a zero-length1686* connection ID MUST NOT provide a preferred address.1687* Similarly, a server MUST NOT include a zero-length connection1688* ID in this transport parameter. A client MUST treat a1689* violation of these requirements as a connection error of type1690* TRANSPORT_PARAMETER_ERROR."1691*/1692if (ch->is_server) {1693reason = TP_REASON_SERVER_ONLY("PREFERRED_ADDR");1694goto malformed;1695}16961697if (ch->cur_remote_dcid.id_len == 0) {1698reason = "PREFERRED_ADDR provided for zero-length CID";1699goto malformed;1700}17011702if (!ossl_quic_wire_decode_transport_param_preferred_addr(&pkt, &pfa)) {1703reason = TP_REASON_MALFORMED("PREFERRED_ADDR");1704goto malformed;1705}17061707if (pfa.cid.id_len == 0) {1708reason = "zero-length CID in PREFERRED_ADDR";1709goto malformed;1710}17111712got_preferred_addr = 1;1713break;17141715case QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION:1716/* We do not currently handle migration, so nothing to do. */1717if (got_disable_active_migration) {1718/* must not appear more than once */1719reason = TP_REASON_DUP("DISABLE_ACTIVE_MIGRATION");1720goto malformed;1721}17221723body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id, &len);1724if (body == NULL || len > 0) {1725reason = TP_REASON_MALFORMED("DISABLE_ACTIVE_MIGRATION");1726goto malformed;1727}17281729got_disable_active_migration = 1;1730break;17311732default:1733/*1734* Skip over and ignore.1735*1736* RFC 9000 s. 7.4: We SHOULD treat duplicated transport parameters1737* as a connection error, but we are not required to. Currently,1738* handle this programmatically by checking for duplicates in the1739* parameters that we recognise, as above, but don't bother1740* maintaining a list of duplicates for anything we don't recognise.1741*/1742body = ossl_quic_wire_decode_transport_param_bytes(&pkt, &id,1743&len);1744if (body == NULL)1745goto malformed;17461747break;1748}1749}17501751if (!got_initial_scid) {1752reason = TP_REASON_REQUIRED("INITIAL_SCID");1753goto malformed;1754}17551756if (!ch->is_server) {1757if (!got_orig_dcid) {1758reason = TP_REASON_REQUIRED("ORIG_DCID");1759goto malformed;1760}17611762if (ch->doing_retry && !got_retry_scid) {1763reason = TP_REASON_REQUIRED("RETRY_SCID");1764goto malformed;1765}1766}17671768ch->got_remote_transport_params = 1;17691770#ifndef OPENSSL_NO_QLOG1771QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set)1772QLOG_STR("owner", "remote");17731774if (got_orig_dcid)1775QLOG_CID("original_destination_connection_id",1776&ch->init_dcid);1777if (got_initial_scid)1778QLOG_CID("original_source_connection_id",1779&ch->init_dcid);1780if (got_retry_scid)1781QLOG_CID("retry_source_connection_id",1782&ch->retry_scid);1783if (got_initial_max_data)1784QLOG_U64("initial_max_data",1785ossl_quic_txfc_get_cwm(&ch->conn_txfc));1786if (got_initial_max_stream_data_bidi_local)1787QLOG_U64("initial_max_stream_data_bidi_local",1788ch->rx_init_max_stream_data_bidi_local);1789if (got_initial_max_stream_data_bidi_remote)1790QLOG_U64("initial_max_stream_data_bidi_remote",1791ch->rx_init_max_stream_data_bidi_remote);1792if (got_initial_max_stream_data_uni)1793QLOG_U64("initial_max_stream_data_uni",1794ch->rx_init_max_stream_data_uni);1795if (got_initial_max_streams_bidi)1796QLOG_U64("initial_max_streams_bidi",1797ch->max_local_streams_bidi);1798if (got_initial_max_streams_uni)1799QLOG_U64("initial_max_streams_uni",1800ch->max_local_streams_uni);1801if (got_ack_delay_exp)1802QLOG_U64("ack_delay_exponent", ch->rx_ack_delay_exp);1803if (got_max_ack_delay)1804QLOG_U64("max_ack_delay", ch->rx_max_ack_delay);1805if (got_max_udp_payload_size)1806QLOG_U64("max_udp_payload_size", ch->rx_max_udp_payload_size);1807if (got_max_idle_timeout)1808QLOG_U64("max_idle_timeout", rx_max_idle_timeout);1809if (got_active_conn_id_limit)1810QLOG_U64("active_connection_id_limit", ch->rx_active_conn_id_limit);1811if (got_stateless_reset_token)1812QLOG_BIN("stateless_reset_token", stateless_reset_token_p,1813QUIC_STATELESS_RESET_TOKEN_LEN);1814if (got_preferred_addr) {1815QLOG_BEGIN("preferred_addr")1816QLOG_U64("port_v4", pfa.ipv4_port);1817QLOG_U64("port_v6", pfa.ipv6_port);1818QLOG_BIN("ip_v4", pfa.ipv4, sizeof(pfa.ipv4));1819QLOG_BIN("ip_v6", pfa.ipv6, sizeof(pfa.ipv6));1820QLOG_BIN("stateless_reset_token", pfa.stateless_reset.token,1821sizeof(pfa.stateless_reset.token));1822QLOG_CID("connection_id", &pfa.cid);1823QLOG_END()1824}1825QLOG_BOOL("disable_active_migration", got_disable_active_migration);1826QLOG_EVENT_END()1827#endif18281829if (got_initial_max_data || got_initial_max_stream_data_bidi_remote1830|| got_initial_max_streams_bidi || got_initial_max_streams_uni)1831/*1832* If FC credit was bumped, we may now be able to send. Update all1833* streams.1834*/1835ossl_quic_stream_map_visit(&ch->qsm, do_update, ch);18361837/* If we are a server, we now generate our own transport parameters. */1838if (ch->is_server && !ch_generate_transport_params(ch)) {1839ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR, 0,1840"internal error");1841return 0;1842}18431844return 1;18451846malformed:1847ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR,18480, reason);1849return 0;1850}18511852/*1853* Called when we want to generate transport parameters. This is called1854* immediately at instantiation time for a client and after we receive the1855* client's transport parameters for a server.1856*/1857static int ch_generate_transport_params(QUIC_CHANNEL *ch)1858{1859int ok = 0;1860BUF_MEM *buf_mem = NULL;1861WPACKET wpkt;1862int wpkt_valid = 0;1863size_t buf_len = 0;1864QUIC_CONN_ID *id_to_use = NULL;18651866/*1867* We need to select which connection id to encode in the1868* QUIC_TPARAM_ORIG_DCID transport parameter1869* If we have an odcid, then this connection was established1870* in response to a retry request, and we need to use the connection1871* id sent in the first initial packet.1872* If we don't have an odcid, then this connection was established1873* without a retry and the init_dcid is the connection we should use1874*/1875if (ch->odcid.id_len == 0)1876id_to_use = &ch->init_dcid;1877else1878id_to_use = &ch->odcid;18791880if (ch->local_transport_params != NULL || ch->got_local_transport_params)1881goto err;18821883if ((buf_mem = BUF_MEM_new()) == NULL)1884goto err;18851886if (!WPACKET_init(&wpkt, buf_mem))1887goto err;18881889wpkt_valid = 1;18901891if (ossl_quic_wire_encode_transport_param_bytes(&wpkt, QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION,1892NULL, 0) == NULL)1893goto err;18941895if (ch->is_server) {1896if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_ORIG_DCID,1897id_to_use))1898goto err;18991900if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_INITIAL_SCID,1901&ch->cur_local_cid))1902goto err;1903if (ch->odcid.id_len != 0)1904if (!ossl_quic_wire_encode_transport_param_cid(&wpkt,1905QUIC_TPARAM_RETRY_SCID,1906&ch->init_dcid))1907goto err;1908} else {1909if (!ossl_quic_wire_encode_transport_param_cid(&wpkt, QUIC_TPARAM_INITIAL_SCID,1910&ch->init_scid))1911goto err;1912}19131914if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_IDLE_TIMEOUT,1915ch->max_idle_timeout_local_req))1916goto err;19171918if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE,1919QUIC_MIN_INITIAL_DGRAM_LEN))1920goto err;19211922if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT,1923QUIC_MIN_ACTIVE_CONN_ID_LIMIT))1924goto err;19251926if (ch->tx_max_ack_delay != QUIC_DEFAULT_MAX_ACK_DELAY1927&& !ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_MAX_ACK_DELAY,1928ch->tx_max_ack_delay))1929goto err;19301931if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_DATA,1932ossl_quic_rxfc_get_cwm(&ch->conn_rxfc)))1933goto err;19341935/* Send the default CWM for a new RXFC. */1936if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,1937ch->tx_init_max_stream_data_bidi_local))1938goto err;19391940if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,1941ch->tx_init_max_stream_data_bidi_remote))1942goto err;19431944if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI,1945ch->tx_init_max_stream_data_uni))1946goto err;19471948if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI,1949ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc)))1950goto err;19511952if (!ossl_quic_wire_encode_transport_param_int(&wpkt, QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI,1953ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc)))1954goto err;19551956if (!WPACKET_finish(&wpkt))1957goto err;19581959wpkt_valid = 0;19601961if (!WPACKET_get_total_written(&wpkt, &buf_len))1962goto err;19631964ch->local_transport_params = (unsigned char *)buf_mem->data;1965buf_mem->data = NULL;19661967if (!ossl_quic_tls_set_transport_params(ch->qtls, ch->local_transport_params,1968buf_len))1969goto err;19701971#ifndef OPENSSL_NO_QLOG1972QLOG_EVENT_BEGIN(ch_get_qlog(ch), transport, parameters_set)1973QLOG_STR("owner", "local");1974QLOG_BOOL("disable_active_migration", 1);1975if (ch->is_server) {1976QLOG_CID("original_destination_connection_id", &ch->init_dcid);1977QLOG_CID("initial_source_connection_id", &ch->cur_local_cid);1978} else {1979QLOG_STR("initial_source_connection_id", "");1980}1981QLOG_U64("max_idle_timeout", ch->max_idle_timeout);1982QLOG_U64("max_udp_payload_size", QUIC_MIN_INITIAL_DGRAM_LEN);1983QLOG_U64("active_connection_id_limit", QUIC_MIN_ACTIVE_CONN_ID_LIMIT);1984QLOG_U64("max_ack_delay", ch->tx_max_ack_delay);1985QLOG_U64("initial_max_data", ossl_quic_rxfc_get_cwm(&ch->conn_rxfc));1986QLOG_U64("initial_max_stream_data_bidi_local",1987ch->tx_init_max_stream_data_bidi_local);1988QLOG_U64("initial_max_stream_data_bidi_remote",1989ch->tx_init_max_stream_data_bidi_remote);1990QLOG_U64("initial_max_stream_data_uni",1991ch->tx_init_max_stream_data_uni);1992QLOG_U64("initial_max_streams_bidi",1993ossl_quic_rxfc_get_cwm(&ch->max_streams_bidi_rxfc));1994QLOG_U64("initial_max_streams_uni",1995ossl_quic_rxfc_get_cwm(&ch->max_streams_uni_rxfc));1996QLOG_EVENT_END()1997#endif19981999ch->got_local_transport_params = 1;20002001ok = 1;2002err:2003if (wpkt_valid)2004WPACKET_cleanup(&wpkt);2005BUF_MEM_free(buf_mem);2006return ok;2007}20082009/*2010* QUIC Channel: Ticker-Mutator2011* ============================2012*/20132014/*2015* The central ticker function called by the reactor. This does everything, or2016* at least everything network I/O related. Best effort - not allowed to fail2017* "loudly".2018*/2019void ossl_quic_channel_subtick(QUIC_CHANNEL *ch, QUIC_TICK_RESULT *res,2020uint32_t flags)2021{2022OSSL_TIME now, deadline;2023int channel_only = (flags & QUIC_REACTOR_TICK_FLAG_CHANNEL_ONLY) != 0;2024int notify_other_threads = 0;20252026/*2027* When we tick the QUIC connection, we do everything we need to do2028* periodically. Network I/O handling will already have been performed2029* as necessary by the QUIC port. Thus, in order, we:2030*2031* - handle any packets the DEMUX has queued up for us;2032* - handle any timer events which are due to fire (ACKM, etc.);2033* - generate any packets which need to be sent;2034* - determine the time at which we should next be ticked.2035*/20362037/*2038* If the connection has not yet started, or we are in the TERMINATED state,2039* there is nothing to do.2040*/2041if (ch->state == QUIC_CHANNEL_STATE_IDLE2042|| ossl_quic_channel_is_terminated(ch)) {2043res->net_read_desired = 0;2044res->net_write_desired = 0;2045res->notify_other_threads = 0;2046res->tick_deadline = ossl_time_infinite();2047return;2048}20492050/*2051* If we are in the TERMINATING state, check if the terminating timer has2052* expired.2053*/2054if (ossl_quic_channel_is_terminating(ch)) {2055now = get_time(ch);20562057if (ossl_time_compare(now, ch->terminate_deadline) >= 0) {2058ch_on_terminating_timeout(ch);2059res->net_read_desired = 0;2060res->net_write_desired = 0;2061res->notify_other_threads = 1;2062res->tick_deadline = ossl_time_infinite();2063return; /* abort normal processing, nothing to do */2064}2065}20662067if (!ch->port->engine->inhibit_tick) {2068/* Handle RXKU timeouts. */2069ch_rxku_tick(ch);20702071do {2072/* Process queued incoming packets. */2073ch->did_tls_tick = 0;2074ch->have_new_rx_secret = 0;2075ch_rx(ch, channel_only, ¬ify_other_threads);20762077/*2078* Allow the handshake layer to check for any new incoming data and2079* generate new outgoing data.2080*/2081if (!ch->did_tls_tick)2082ch_tick_tls(ch, channel_only, ¬ify_other_threads);20832084/*2085* If the handshake layer gave us a new secret, we need to do RX2086* again because packets that were not previously processable and2087* were deferred might now be processable.2088*2089* TODO(QUIC FUTURE): Consider handling this in the yield_secret callback.2090*/2091} while (ch->have_new_rx_secret);2092}20932094/*2095* Handle any timer events which are due to fire; namely, the loss2096* detection deadline and the idle timeout.2097*2098* ACKM ACK generation deadline is polled by TXP, so we don't need to2099* handle it here.2100*/2101now = get_time(ch);2102if (ossl_time_compare(now, ch->idle_deadline) >= 0) {2103/*2104* Idle timeout differs from normal protocol violation because we do2105* not send a CONN_CLOSE frame; go straight to TERMINATED.2106*/2107if (!ch->port->engine->inhibit_tick)2108ch_on_idle_timeout(ch);21092110res->net_read_desired = 0;2111res->net_write_desired = 0;2112res->notify_other_threads = 1;2113res->tick_deadline = ossl_time_infinite();2114return;2115}21162117if (!ch->port->engine->inhibit_tick) {2118deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);2119if (!ossl_time_is_zero(deadline)2120&& ossl_time_compare(now, deadline) >= 0)2121ossl_ackm_on_timeout(ch->ackm);21222123/* If a ping is due, inform TXP. */2124if (ossl_time_compare(now, ch->ping_deadline) >= 0) {2125int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);21262127ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);21282129/*2130* If we have no CC budget at this time we cannot process the above2131* PING request immediately. In any case we have scheduled the2132* request so bump the ping deadline. If we don't do this we will2133* busy-loop endlessly as the above deadline comparison condition2134* will still be met.2135*/2136ch_update_ping_deadline(ch);2137}21382139/* Queue any data to be sent for transmission. */2140ch_tx(ch, ¬ify_other_threads);21412142/* Do stream GC. */2143ossl_quic_stream_map_gc(&ch->qsm);2144}21452146/* Determine the time at which we should next be ticked. */2147res->tick_deadline = ch_determine_next_tick_deadline(ch);21482149/*2150* Always process network input unless we are now terminated. Although we2151* had not terminated at the beginning of this tick, network errors in2152* ch_tx() may have caused us to transition to the Terminated state.2153*/2154res->net_read_desired = !ossl_quic_channel_is_terminated(ch);21552156/* We want to write to the network if we have any data in our TX queue. */2157res->net_write_desired2158= (!ossl_quic_channel_is_terminated(ch)2159&& ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0);21602161res->notify_other_threads = notify_other_threads;2162}21632164static int ch_tick_tls(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads)2165{2166uint64_t error_code;2167const char *error_msg;2168ERR_STATE *error_state = NULL;21692170if (channel_only)2171return 1;21722173ch->did_tls_tick = 1;2174ossl_quic_tls_tick(ch->qtls);21752176if (ossl_quic_tls_get_error(ch->qtls, &error_code, &error_msg,2177&error_state)) {2178ossl_quic_channel_raise_protocol_error_state(ch, error_code, 0,2179error_msg, error_state);2180if (notify_other_threads != NULL)2181*notify_other_threads = 1;21822183return 0;2184}21852186return 1;2187}21882189/* Check incoming forged packet limit and terminate connection if needed. */2190static void ch_rx_check_forged_pkt_limit(QUIC_CHANNEL *ch)2191{2192uint32_t enc_level;2193uint64_t limit = UINT64_MAX, l;21942195for (enc_level = QUIC_ENC_LEVEL_INITIAL;2196enc_level < QUIC_ENC_LEVEL_NUM;2197++enc_level)2198{2199/*2200* Different ELs can have different AEADs which can in turn impose2201* different limits, so use the lowest value of any currently valid EL.2202*/2203if ((ch->el_discarded & (1U << enc_level)) != 0)2204continue;22052206if (enc_level > ch->rx_enc_level)2207break;22082209l = ossl_qrx_get_max_forged_pkt_count(ch->qrx, enc_level);2210if (l < limit)2211limit = l;2212}22132214if (ossl_qrx_get_cur_forged_pkt_count(ch->qrx) < limit)2215return;22162217ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_AEAD_LIMIT_REACHED, 0,2218"forgery limit");2219}22202221/* Process queued incoming packets and handle frames, if any. */2222static int ch_rx(QUIC_CHANNEL *ch, int channel_only, int *notify_other_threads)2223{2224int handled_any = 0;2225const int closing = ossl_quic_channel_is_closing(ch);22262227if (!ch->is_server && !ch->have_sent_any_pkt)2228/*2229* We have not sent anything yet, therefore there is no need to check2230* for incoming data.2231*/2232return 1;22332234for (;;) {2235assert(ch->qrx_pkt == NULL);22362237if (!ossl_qrx_read_pkt(ch->qrx, &ch->qrx_pkt))2238break;22392240/* Track the amount of data received while in the closing state */2241if (closing)2242ossl_quic_tx_packetiser_record_received_closing_bytes(2243ch->txp, ch->qrx_pkt->hdr->len);22442245if (!handled_any) {2246ch_update_idle(ch);2247ch_update_ping_deadline(ch);2248}22492250ch_rx_handle_packet(ch, channel_only); /* best effort */22512252/*2253* Regardless of the outcome of frame handling, unref the packet.2254* This will free the packet unless something added another2255* reference to it during frame processing.2256*/2257ossl_qrx_pkt_release(ch->qrx_pkt);2258ch->qrx_pkt = NULL;22592260ch->have_sent_ack_eliciting_since_rx = 0;2261handled_any = 1;2262}22632264ch_rx_check_forged_pkt_limit(ch);22652266if (handled_any && notify_other_threads != NULL)2267*notify_other_threads = 1;22682269/*2270* When in TERMINATING - CLOSING, generate a CONN_CLOSE frame whenever we2271* process one or more incoming packets.2272*/2273if (handled_any && closing)2274ch->conn_close_queued = 1;22752276return 1;2277}22782279static int bio_addr_eq(const BIO_ADDR *a, const BIO_ADDR *b)2280{2281if (BIO_ADDR_family(a) != BIO_ADDR_family(b))2282return 0;22832284switch (BIO_ADDR_family(a)) {2285case AF_INET:2286return !memcmp(&a->s_in.sin_addr,2287&b->s_in.sin_addr,2288sizeof(a->s_in.sin_addr))2289&& a->s_in.sin_port == b->s_in.sin_port;2290#if OPENSSL_USE_IPV62291case AF_INET6:2292return !memcmp(&a->s_in6.sin6_addr,2293&b->s_in6.sin6_addr,2294sizeof(a->s_in6.sin6_addr))2295&& a->s_in6.sin6_port == b->s_in6.sin6_port;2296#endif2297default:2298return 0; /* not supported */2299}23002301return 1;2302}23032304/* Handles the packet currently in ch->qrx_pkt->hdr. */2305static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)2306{2307uint32_t enc_level;2308int old_have_processed_any_pkt = ch->have_processed_any_pkt;2309OSSL_QTX_IOVEC iovec;2310PACKET vpkt;2311unsigned long supported_ver;23122313assert(ch->qrx_pkt != NULL);23142315/*2316* RFC 9000 s. 10.2.1 Closing Connection State:2317* An endpoint that is closing is not required to process any2318* received frame.2319*/2320if (!ossl_quic_channel_is_active(ch))2321return;23222323if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type)) {2324if (!ch->have_received_enc_pkt) {2325ch->cur_remote_dcid = ch->init_scid = ch->qrx_pkt->hdr->src_conn_id;2326ch->have_received_enc_pkt = 1;23272328/*2329* We change to using the SCID in the first Initial packet as the2330* DCID.2331*/2332ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->init_scid);2333}23342335enc_level = ossl_quic_pkt_type_to_enc_level(ch->qrx_pkt->hdr->type);2336if ((ch->el_discarded & (1U << enc_level)) != 0)2337/* Do not process packets from ELs we have already discarded. */2338return;2339}23402341/*2342* RFC 9000 s. 9.6: "If a client receives packets from a new server address2343* when the client has not initiated a migration to that address, the client2344* SHOULD discard these packets."2345*2346* We need to be a bit careful here as due to the BIO abstraction layer an2347* application is liable to be weird and lie to us about peer addresses.2348* Only apply this check if we actually are using a real AF_INET or AF_INET62349* address.2350*/2351if (!ch->is_server2352&& ch->qrx_pkt->peer != NULL2353&& (2354BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET2355#if OPENSSL_USE_IPV62356|| BIO_ADDR_family(&ch->cur_peer_addr) == AF_INET62357#endif2358)2359&& !bio_addr_eq(ch->qrx_pkt->peer, &ch->cur_peer_addr))2360return;23612362if (!ch->is_server2363&& ch->have_received_enc_pkt2364&& ossl_quic_pkt_type_has_scid(ch->qrx_pkt->hdr->type)) {2365/*2366* RFC 9000 s. 7.2: "Once a client has received a valid Initial packet2367* from the server, it MUST discard any subsequent packet it receives on2368* that connection with a different SCID."2369*/2370if (!ossl_quic_conn_id_eq(&ch->qrx_pkt->hdr->src_conn_id,2371&ch->init_scid))2372return;2373}23742375if (ossl_quic_pkt_type_has_version(ch->qrx_pkt->hdr->type)2376&& ch->qrx_pkt->hdr->version != QUIC_VERSION_1)2377/*2378* RFC 9000 s. 5.2.1: If a client receives a packet that uses a2379* different version than it initially selected, it MUST discard the2380* packet. We only ever use v1, so require it.2381*/2382return;23832384if (ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_VERSION_NEG) {23852386/*2387* Sanity check. Version negotiation packet MUST have a version2388* value of 0 according to the RFC. We must discard such packets2389*/2390if (ch->qrx_pkt->hdr->version != 0)2391return;23922393/*2394* RFC 9000 s. 6.2: If a client receives a version negotiation2395* packet, we need to do the following:2396* a) If the negotiation packet lists the version we initially sent2397* then we must abandon this connection attempt2398* b) We have to select a version from the list provided in the2399* version negotiation packet, and retry the connection attempt2400* in much the same way that ch_retry does, but we can reuse the2401* connection id values2402*/24032404if (old_have_processed_any_pkt == 1) {2405/*2406* We've gotten previous packets, need to discard this.2407*/2408return;2409}24102411/*2412* Indicate that we have processed a packet, as any subsequently2413* received version negotiation packet must be discarded above2414*/2415ch->have_processed_any_pkt = 1;24162417/*2418* Following the header, version negotiation packets2419* contain an array of 32 bit integers representing2420* the supported versions that the server honors2421* this array, bounded by the hdr->len field2422* needs to be traversed so that we can find a matching2423* version2424*/2425if (!PACKET_buf_init(&vpkt, ch->qrx_pkt->hdr->data,2426ch->qrx_pkt->hdr->len))2427return;24282429while (PACKET_remaining(&vpkt) > 0) {2430/*2431* We only support quic version 1 at the moment, so2432* look to see if thats offered2433*/2434if (!PACKET_get_net_4(&vpkt, &supported_ver))2435return;24362437if (supported_ver == QUIC_VERSION_1) {2438/*2439* If the server supports version 1, set it as2440* the packetisers version2441*/2442ossl_quic_tx_packetiser_set_protocol_version(ch->txp, QUIC_VERSION_1);24432444/*2445* And then request a restart of the QUIC connection2446*/2447if (!ch_restart(ch))2448ossl_quic_channel_raise_protocol_error(ch,2449OSSL_QUIC_ERR_INTERNAL_ERROR,24500, "handling ver negotiation packet");2451return;2452}2453}24542455/*2456* If we get here, then the server doesn't support a version of the2457* protocol that we can handle, abandon the connection2458*/2459ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CONNECTION_REFUSED,24600, "unsupported protocol version");2461return;2462}24632464ch->have_processed_any_pkt = 1;24652466/*2467* RFC 9000 s. 17.2: "An endpoint MUST treat receipt of a packet that has a2468* non-zero value for [the reserved bits] after removing both packet and2469* header protection as a connection error of type PROTOCOL_VIOLATION."2470*/2471if (ossl_quic_pkt_type_is_encrypted(ch->qrx_pkt->hdr->type)2472&& ch->qrx_pkt->hdr->reserved != 0) {2473ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,24740, "packet header reserved bits");2475return;2476}24772478iovec.buf = ch->qrx_pkt->hdr->data;2479iovec.buf_len = ch->qrx_pkt->hdr->len;2480ossl_qlog_event_transport_packet_received(ch_get_qlog(ch), ch->qrx_pkt->hdr,2481ch->qrx_pkt->pn, &iovec, 1,2482ch->qrx_pkt->datagram_id);24832484/* Handle incoming packet. */2485switch (ch->qrx_pkt->hdr->type) {2486case QUIC_PKT_TYPE_RETRY:2487if (ch->doing_retry || ch->is_server)2488/*2489* It is not allowed to ask a client to do a retry more than2490* once. Clients may not send retries.2491*/2492return;24932494/*2495* RFC 9000 s 17.2.5.2: After the client has received and processed an2496* Initial or Retry packet from the server, it MUST discard any2497* subsequent Retry packets that it receives.2498*/2499if (ch->have_received_enc_pkt)2500return;25012502if (ch->qrx_pkt->hdr->len <= QUIC_RETRY_INTEGRITY_TAG_LEN)2503/* Packets with zero-length Retry Tokens are invalid. */2504return;25052506/*2507* TODO(QUIC FUTURE): Theoretically this should probably be in the QRX.2508* However because validation is dependent on context (namely the2509* client's initial DCID) we can't do this cleanly. In the future we2510* should probably add a callback to the QRX to let it call us (via2511* the DEMUX) and ask us about the correct original DCID, rather2512* than allow the QRX to emit a potentially malformed packet to the2513* upper layers. However, special casing this will do for now.2514*/2515if (!ossl_quic_validate_retry_integrity_tag(ch->port->engine->libctx,2516ch->port->engine->propq,2517ch->qrx_pkt->hdr,2518&ch->init_dcid))2519/* Malformed retry packet, ignore. */2520return;25212522if (!ch_retry(ch, ch->qrx_pkt->hdr->data,2523ch->qrx_pkt->hdr->len - QUIC_RETRY_INTEGRITY_TAG_LEN,2524&ch->qrx_pkt->hdr->src_conn_id, old_have_processed_any_pkt))2525ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,25260, "handling retry packet");2527break;25282529case QUIC_PKT_TYPE_0RTT:2530if (!ch->is_server)2531/* Clients should never receive 0-RTT packets. */2532return;25332534/*2535* TODO(QUIC 0RTT): Implement 0-RTT on the server side. We currently2536* do not need to implement this as a client can only do 0-RTT if we2537* have given it permission to in a previous session.2538*/2539break;25402541case QUIC_PKT_TYPE_INITIAL:2542case QUIC_PKT_TYPE_HANDSHAKE:2543case QUIC_PKT_TYPE_1RTT:2544if (ch->is_server && ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_HANDSHAKE)2545/*2546* We automatically drop INITIAL EL keys when first successfully2547* decrypting a HANDSHAKE packet, as per the RFC.2548*/2549ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);25502551if (ch->rxku_in_progress2552&& ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_1RTT2553&& ch->qrx_pkt->pn >= ch->rxku_trigger_pn2554&& ch->qrx_pkt->key_epoch < ossl_qrx_get_key_epoch(ch->qrx)) {2555/*2556* RFC 9001 s. 6.4: Packets with higher packet numbers MUST be2557* protected with either the same or newer packet protection keys2558* than packets with lower packet numbers. An endpoint that2559* successfully removes protection with old keys when newer keys2560* were used for packets with lower packet numbers MUST treat this2561* as a connection error of type KEY_UPDATE_ERROR.2562*/2563ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_KEY_UPDATE_ERROR,25640, "new packet with old keys");2565break;2566}25672568if (!ch->is_server2569&& ch->qrx_pkt->hdr->type == QUIC_PKT_TYPE_INITIAL2570&& ch->qrx_pkt->hdr->token_len > 0) {2571/*2572* RFC 9000 s. 17.2.2: Clients that receive an Initial packet with a2573* non-zero Token Length field MUST either discard the packet or2574* generate a connection error of type PROTOCOL_VIOLATION.2575*2576* TODO(QUIC FUTURE): consider the implications of RFC 9000 s. 10.2.32577* Immediate Close during the Handshake:2578* However, at the cost of reducing feedback about2579* errors for legitimate peers, some forms of denial of2580* service can be made more difficult for an attacker2581* if endpoints discard illegal packets rather than2582* terminating a connection with CONNECTION_CLOSE. For2583* this reason, endpoints MAY discard packets rather2584* than immediately close if errors are detected in2585* packets that lack authentication.2586* I.e. should we drop this packet instead of closing the connection?2587*/2588ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,25890, "client received initial token");2590break;2591}25922593/* This packet contains frames, pass to the RXDP. */2594ossl_quic_handle_frames(ch, ch->qrx_pkt); /* best effort */25952596if (ch->did_crypto_frame)2597ch_tick_tls(ch, channel_only, NULL);25982599break;26002601case QUIC_PKT_TYPE_VERSION_NEG:2602/*2603* "A client MUST discard any Version Negotiation packet if it has2604* received and successfully processed any other packet."2605*/2606if (!old_have_processed_any_pkt)2607ch_rx_handle_version_neg(ch, ch->qrx_pkt);26082609break;26102611default:2612assert(0);2613break;2614}26152616}26172618static void ch_rx_handle_version_neg(QUIC_CHANNEL *ch, OSSL_QRX_PKT *pkt)2619{2620/*2621* We do not support version negotiation at this time. As per RFC 9000 s.2622* 6.2., we MUST abandon the connection attempt if we receive a Version2623* Negotiation packet, unless we have already successfully processed another2624* incoming packet, or the packet lists the QUIC version we want to use.2625*/2626PACKET vpkt;2627unsigned long v;26282629if (!PACKET_buf_init(&vpkt, pkt->hdr->data, pkt->hdr->len))2630return;26312632while (PACKET_remaining(&vpkt) > 0) {2633if (!PACKET_get_net_4(&vpkt, &v))2634break;26352636if ((uint32_t)v == QUIC_VERSION_1)2637return;2638}26392640/* No match, this is a failure case. */2641ch_raise_version_neg_failure(ch);2642}26432644static void ch_raise_version_neg_failure(QUIC_CHANNEL *ch)2645{2646QUIC_TERMINATE_CAUSE tcause = {0};26472648tcause.error_code = OSSL_QUIC_ERR_CONNECTION_REFUSED;2649tcause.reason = "version negotiation failure";2650tcause.reason_len = strlen(tcause.reason);26512652/*2653* Skip TERMINATING state; this is not considered a protocol error and we do2654* not send CONNECTION_CLOSE.2655*/2656ch_start_terminating(ch, &tcause, 1);2657}26582659/* Try to generate packets and if possible, flush them to the network. */2660static int ch_tx(QUIC_CHANNEL *ch, int *notify_other_threads)2661{2662QUIC_TXP_STATUS status;2663int res;26642665/*2666* RFC 9000 s. 10.2.2: Draining Connection State:2667* While otherwise identical to the closing state, an endpoint2668* in the draining state MUST NOT send any packets.2669* and:2670* An endpoint MUST NOT send further packets.2671*/2672if (ossl_quic_channel_is_draining(ch))2673return 0;26742675if (ossl_quic_channel_is_closing(ch)) {2676/*2677* While closing, only send CONN_CLOSE if we've received more traffic2678* from the peer. Once we tell the TXP to generate CONN_CLOSE, all2679* future calls to it generate CONN_CLOSE frames, so otherwise we would2680* just constantly generate CONN_CLOSE frames.2681*2682* Confirming to RFC 9000 s. 10.2.1 Closing Connection State:2683* An endpoint SHOULD limit the rate at which it generates2684* packets in the closing state.2685*/2686if (!ch->conn_close_queued)2687return 0;26882689ch->conn_close_queued = 0;2690}26912692/* Do TXKU if we need to. */2693ch_maybe_trigger_spontaneous_txku(ch);26942695ch->rxku_pending_confirm_done = 0;26962697/* Loop until we stop generating packets to send */2698do {2699/*2700* Send packet, if we need to. Best effort. The TXP consults the CC and2701* applies any limitations imposed by it, so we don't need to do it here.2702*2703* Best effort. In particular if TXP fails for some reason we should2704* still flush any queued packets which we already generated.2705*/2706res = ossl_quic_tx_packetiser_generate(ch->txp, &status);2707if (status.sent_pkt > 0) {2708ch->have_sent_any_pkt = 1; /* Packet(s) were sent */2709ch->port->have_sent_any_pkt = 1;27102711/*2712* RFC 9000 s. 10.1. 'An endpoint also restarts its idle timer when2713* sending an ack-eliciting packet if no other ack-eliciting packets2714* have been sent since last receiving and processing a packet.'2715*/2716if (status.sent_ack_eliciting2717&& !ch->have_sent_ack_eliciting_since_rx) {2718ch_update_idle(ch);2719ch->have_sent_ack_eliciting_since_rx = 1;2720}27212722if (!ch->is_server && status.sent_handshake)2723/*2724* RFC 9001 s. 4.9.1: A client MUST discard Initial keys when it2725* first sends a Handshake packet.2726*/2727ch_discard_el(ch, QUIC_ENC_LEVEL_INITIAL);27282729if (ch->rxku_pending_confirm_done)2730ch->rxku_pending_confirm = 0;27312732ch_update_ping_deadline(ch);2733}27342735if (!res) {2736/*2737* One case where TXP can fail is if we reach a TX PN of 2**62 - 1.2738* As per RFC 9000 s. 12.3, if this happens we MUST close the2739* connection without sending a CONNECTION_CLOSE frame. This is2740* actually handled as an emergent consequence of our design, as the2741* TX packetiser will never transmit another packet when the TX PN2742* reaches the limit.2743*2744* Calling the below function terminates the connection; its attempt2745* to schedule a CONNECTION_CLOSE frame will not actually cause a2746* packet to be transmitted for this reason.2747*/2748ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,27490,2750"internal error (txp generate)");2751break;2752}2753} while (status.sent_pkt > 0);27542755/* Flush packets to network. */2756switch (ossl_qtx_flush_net(ch->qtx)) {2757case QTX_FLUSH_NET_RES_OK:2758case QTX_FLUSH_NET_RES_TRANSIENT_FAIL:2759/* Best effort, done for now. */2760break;27612762case QTX_FLUSH_NET_RES_PERMANENT_FAIL:2763default:2764/* Permanent underlying network BIO, start terminating. */2765ossl_quic_port_raise_net_error(ch->port, ch);2766break;2767}27682769/*2770* If we have datagrams we have yet to successfully transmit, we need to2771* notify other threads so that they can switch to polling on POLLOUT as2772* well as POLLIN.2773*/2774if (ossl_qtx_get_queue_len_datagrams(ch->qtx) > 0)2775*notify_other_threads = 1;27762777return 1;2778}27792780/* Determine next tick deadline. */2781static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch)2782{2783OSSL_TIME deadline;2784int i;27852786if (ossl_quic_channel_is_terminated(ch))2787return ossl_time_infinite();27882789deadline = ossl_ackm_get_loss_detection_deadline(ch->ackm);2790if (ossl_time_is_zero(deadline))2791deadline = ossl_time_infinite();27922793/*2794* Check the ack deadline for all enc_levels that are actually provisioned.2795* ACKs aren't restricted by CC.2796*/2797for (i = 0; i < QUIC_ENC_LEVEL_NUM; i++) {2798if (ossl_qtx_is_enc_level_provisioned(ch->qtx, i)) {2799deadline = ossl_time_min(deadline,2800ossl_ackm_get_ack_deadline(ch->ackm,2801ossl_quic_enc_level_to_pn_space(i)));2802}2803}28042805/*2806* When do we need to send an ACK-eliciting packet to reset the idle2807* deadline timer for the peer?2808*/2809if (!ossl_time_is_infinite(ch->ping_deadline))2810deadline = ossl_time_min(deadline, ch->ping_deadline);28112812/* Apply TXP wakeup deadline. */2813deadline = ossl_time_min(deadline,2814ossl_quic_tx_packetiser_get_deadline(ch->txp));28152816/* Is the terminating timer armed? */2817if (ossl_quic_channel_is_terminating(ch))2818deadline = ossl_time_min(deadline,2819ch->terminate_deadline);2820else if (!ossl_time_is_infinite(ch->idle_deadline))2821deadline = ossl_time_min(deadline,2822ch->idle_deadline);28232824/* When does the RXKU process complete? */2825if (ch->rxku_in_progress)2826deadline = ossl_time_min(deadline, ch->rxku_update_end_deadline);28272828return deadline;2829}28302831/*2832* QUIC Channel: Lifecycle Events2833* ==============================2834*/28352836/*2837* Record a state transition. This is not necessarily a change to ch->state but2838* also includes the handshake becoming complete or confirmed, etc.2839*/2840static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state)2841{2842uint32_t old_state = ch->state;28432844ch->state = new_state;28452846ossl_qlog_event_connectivity_connection_state_updated(ch_get_qlog(ch),2847old_state,2848new_state,2849ch->handshake_complete,2850ch->handshake_confirmed);2851}28522853static void free_peer_token(const unsigned char *token,2854size_t token_len, void *arg)2855{2856ossl_quic_free_peer_token((QUIC_TOKEN *)arg);2857}28582859int ossl_quic_channel_start(QUIC_CHANNEL *ch)2860{2861QUIC_TOKEN *token;28622863if (ch->is_server)2864/*2865* This is not used by the server. The server moves to active2866* automatically on receiving an incoming connection.2867*/2868return 0;28692870if (ch->state != QUIC_CHANNEL_STATE_IDLE)2871/* Calls to connect are idempotent */2872return 1;28732874/* Inform QTX of peer address. */2875if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr))2876return 0;28772878/*2879* Look to see if we have a token, and if so, set it on the packetiser2880*/2881if (!ch->is_server2882&& ossl_quic_get_peer_token(ch->port->channel_ctx,2883&ch->cur_peer_addr,2884&token)2885&& !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token->token,2886token->token_len,2887free_peer_token,2888token))2889free_peer_token(NULL, 0, token);28902891/* Plug in secrets for the Initial EL. */2892if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,2893ch->port->engine->propq,2894&ch->init_dcid,2895ch->is_server,2896ch->qrx, ch->qtx))2897return 0;28982899/*2900* Determine the QUIC Transport Parameters and serialize the transport2901* parameters block. (For servers, we do this later as we must defer2902* generation until we have received the client's transport parameters.)2903*/2904if (!ch->is_server && !ch->got_local_transport_params2905&& !ch_generate_transport_params(ch))2906return 0;29072908/* Change state. */2909ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE);2910ch->doing_proactive_ver_neg = 0; /* not currently supported */29112912ossl_qlog_event_connectivity_connection_started(ch_get_qlog(ch),2913&ch->init_dcid);29142915/* Handshake layer: start (e.g. send CH). */2916if (!ch_tick_tls(ch, /*channel_only=*/0, NULL))2917return 0;29182919ossl_quic_reactor_tick(ossl_quic_port_get0_reactor(ch->port), 0); /* best effort */2920return 1;2921}29222923static void free_token(const unsigned char *token, size_t token_len, void *arg)2924{2925OPENSSL_free((char *)token);2926}29272928/* Start a locally initiated connection shutdown. */2929void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,2930const char *app_reason)2931{2932QUIC_TERMINATE_CAUSE tcause = {0};29332934if (ossl_quic_channel_is_term_any(ch))2935return;29362937tcause.app = 1;2938tcause.error_code = app_error_code;2939tcause.reason = app_reason;2940tcause.reason_len = app_reason != NULL ? strlen(app_reason) : 0;2941ch_start_terminating(ch, &tcause, 0);2942}29432944/**2945* ch_restart - Restarts the QUIC channel by simulating loss of the initial2946* packet. This forces the packet to be regenerated with the updated protocol2947* version number.2948*2949* @ch: Pointer to the QUIC_CHANNEL structure.2950*2951* Returns 1 on success, 0 on failure.2952*/2953static int ch_restart(QUIC_CHANNEL *ch)2954{2955/*2956* Just pretend we lost our initial packet, so it gets2957* regenerated, with our updated protocol version number2958*/2959return ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,2960/* PN= */ 0);2961}29622963/* Called when a server asks us to do a retry. */2964static int ch_retry(QUIC_CHANNEL *ch,2965const unsigned char *retry_token,2966size_t retry_token_len,2967const QUIC_CONN_ID *retry_scid,2968int drop_later_pn)2969{2970void *buf;2971QUIC_PN pn = 0;29722973/*2974* RFC 9000 s. 17.2.5.1: "A client MUST discard a Retry packet that contains2975* a SCID field that is identical to the DCID field of its initial packet."2976*/2977if (ossl_quic_conn_id_eq(&ch->init_dcid, retry_scid))2978return 1;29792980/* We change to using the SCID in the Retry packet as the DCID. */2981if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, retry_scid))2982return 0;29832984/*2985* Now we retry. We will release the Retry packet immediately, so copy2986* the token.2987*/2988if ((buf = OPENSSL_memdup(retry_token, retry_token_len)) == NULL)2989return 0;29902991if (!ossl_quic_tx_packetiser_set_initial_token(ch->txp, buf,2992retry_token_len,2993free_token, NULL)) {2994/*2995* This may fail if the token we receive is too big for us to ever be2996* able to transmit in an outgoing Initial packet.2997*/2998ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INVALID_TOKEN, 0,2999"received oversize token");3000OPENSSL_free(buf);3001return 0;3002}30033004ch->retry_scid = *retry_scid;3005ch->doing_retry = 1;30063007/*3008* If a retry isn't our first response, we need to drop packet number3009* one instead (i.e. the case where we did version negotiation first3010*/3011if (drop_later_pn == 1)3012pn = 1;30133014/*3015* We need to stimulate the Initial EL to generate the first CRYPTO frame3016* again. We can do this most cleanly by simply forcing the ACKM to consider3017* the first Initial packet as lost, which it effectively was as the server3018* hasn't processed it. This also maintains the desired behaviour with e.g.3019* PNs not resetting and so on.3020*3021* The PN we used initially is always zero, because QUIC does not allow3022* repeated retries.3023*/3024if (!ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,3025pn))3026return 0;30273028/*3029* Plug in new secrets for the Initial EL. This is the only time we change3030* the secrets for an EL after we already provisioned it.3031*/3032if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,3033ch->port->engine->propq,3034&ch->retry_scid,3035/*is_server=*/0,3036ch->qrx, ch->qtx))3037return 0;30383039return 1;3040}30413042/* Called when an EL is to be discarded. */3043static int ch_discard_el(QUIC_CHANNEL *ch,3044uint32_t enc_level)3045{3046if (!ossl_assert(enc_level < QUIC_ENC_LEVEL_1RTT))3047return 0;30483049if ((ch->el_discarded & (1U << enc_level)) != 0)3050/* Already done. */3051return 1;30523053/* Best effort for all of these. */3054ossl_quic_tx_packetiser_discard_enc_level(ch->txp, enc_level);3055ossl_qrx_discard_enc_level(ch->qrx, enc_level);3056ossl_qtx_discard_enc_level(ch->qtx, enc_level);30573058if (enc_level != QUIC_ENC_LEVEL_0RTT) {3059uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level);30603061ossl_ackm_on_pkt_space_discarded(ch->ackm, pn_space);30623063/* We should still have crypto streams at this point. */3064if (!ossl_assert(ch->crypto_send[pn_space] != NULL)3065|| !ossl_assert(ch->crypto_recv[pn_space] != NULL))3066return 0;30673068/* Get rid of the crypto stream state for the EL. */3069ossl_quic_sstream_free(ch->crypto_send[pn_space]);3070ch->crypto_send[pn_space] = NULL;30713072ossl_quic_rstream_free(ch->crypto_recv[pn_space]);3073ch->crypto_recv[pn_space] = NULL;3074}30753076ch->el_discarded |= (1U << enc_level);3077return 1;3078}30793080/* Intended to be called by the RXDP. */3081int ossl_quic_channel_on_handshake_confirmed(QUIC_CHANNEL *ch)3082{3083if (ch->handshake_confirmed)3084return 1;30853086if (!ch->handshake_complete) {3087/*3088* Does not make sense for handshake to be confirmed before it is3089* completed.3090*/3091ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_PROTOCOL_VIOLATION,3092OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE,3093"handshake cannot be confirmed "3094"before it is completed");3095return 0;3096}30973098ch_discard_el(ch, QUIC_ENC_LEVEL_HANDSHAKE);3099ch->handshake_confirmed = 1;3100ch_record_state_transition(ch, ch->state);3101ossl_ackm_on_handshake_confirmed(ch->ackm);3102return 1;3103}31043105/*3106* Master function used when we want to start tearing down a connection:3107*3108* - If the connection is still IDLE we can go straight to TERMINATED;3109*3110* - If we are already TERMINATED this is a no-op.3111*3112* - If we are TERMINATING - CLOSING and we have now got a CONNECTION_CLOSE3113* from the peer (tcause->remote == 1), we move to TERMINATING - DRAINING.3114*3115* - If we are TERMINATING - DRAINING, we remain here until the terminating3116* timer expires.3117*3118* - Otherwise, we are in ACTIVE and move to TERMINATING - CLOSING.3119* if we caused the termination (e.g. we have sent a CONNECTION_CLOSE). Note3120* that we are considered to have caused a termination if we sent the first3121* CONNECTION_CLOSE frame, even if it is caused by a peer protocol3122* violation. If the peer sent the first CONNECTION_CLOSE frame, we move to3123* TERMINATING - DRAINING.3124*3125* We record the termination cause structure passed on the first call only.3126* Any successive calls have their termination cause data discarded;3127* once we start sending a CONNECTION_CLOSE frame, we don't change the details3128* in it.3129*3130* This conforms to RFC 9000 s. 10.2.1: Closing Connection State:3131* To minimize the state that an endpoint maintains for a closing3132* connection, endpoints MAY send the exact same packet in response3133* to any received packet.3134*3135* We don't drop any connection state (specifically packet protection keys)3136* even though we are permitted to. This conforms to RFC 9000 s. 10.2.1:3137* Closing Connection State:3138* An endpoint MAY retain packet protection keys for incoming3139* packets to allow it to read and process a CONNECTION_CLOSE frame.3140*3141* Note that we do not conform to these two from the same section:3142* An endpoint's selected connection ID and the QUIC version3143* are sufficient information to identify packets for a closing3144* connection; the endpoint MAY discard all other connection state.3145* and:3146* An endpoint MAY drop packet protection keys when entering the3147* closing state and send a packet containing a CONNECTION_CLOSE3148* frame in response to any UDP datagram that is received.3149*/3150static void copy_tcause(QUIC_TERMINATE_CAUSE *dst,3151const QUIC_TERMINATE_CAUSE *src)3152{3153dst->error_code = src->error_code;3154dst->frame_type = src->frame_type;3155dst->app = src->app;3156dst->remote = src->remote;31573158dst->reason = NULL;3159dst->reason_len = 0;31603161if (src->reason != NULL && src->reason_len > 0) {3162size_t l = src->reason_len;3163char *r;31643165if (l >= SIZE_MAX)3166--l;31673168/*3169* If this fails, dst->reason becomes NULL and we simply do not use a3170* reason. This ensures termination is infallible.3171*/3172dst->reason = r = OPENSSL_memdup(src->reason, l + 1);3173if (r == NULL)3174return;31753176r[l] = '\0';3177dst->reason_len = l;3178}3179}31803181static void ch_start_terminating(QUIC_CHANNEL *ch,3182const QUIC_TERMINATE_CAUSE *tcause,3183int force_immediate)3184{3185/* No point sending anything if we haven't sent anything yet. */3186if (!ch->have_sent_any_pkt)3187force_immediate = 1;31883189switch (ch->state) {3190default:3191case QUIC_CHANNEL_STATE_IDLE:3192copy_tcause(&ch->terminate_cause, tcause);3193ch_on_terminating_timeout(ch);3194break;31953196case QUIC_CHANNEL_STATE_ACTIVE:3197copy_tcause(&ch->terminate_cause, tcause);31983199ossl_qlog_event_connectivity_connection_closed(ch_get_qlog(ch), tcause);32003201if (!force_immediate) {3202ch_record_state_transition(ch, tcause->remote3203? QUIC_CHANNEL_STATE_TERMINATING_DRAINING3204: QUIC_CHANNEL_STATE_TERMINATING_CLOSING);3205/*3206* RFC 9000 s. 10.2 Immediate Close3207* These states SHOULD persist for at least three times3208* the current PTO interval as defined in [QUIC-RECOVERY].3209*/3210ch->terminate_deadline3211= ossl_time_add(get_time(ch),3212ossl_time_multiply(ossl_ackm_get_pto_duration(ch->ackm),32133));32143215if (!tcause->remote) {3216OSSL_QUIC_FRAME_CONN_CLOSE f = {0};32173218/* best effort */3219f.error_code = ch->terminate_cause.error_code;3220f.frame_type = ch->terminate_cause.frame_type;3221f.is_app = ch->terminate_cause.app;3222f.reason = (char *)ch->terminate_cause.reason;3223f.reason_len = ch->terminate_cause.reason_len;3224ossl_quic_tx_packetiser_schedule_conn_close(ch->txp, &f);3225/*3226* RFC 9000 s. 10.2.2 Draining Connection State:3227* An endpoint that receives a CONNECTION_CLOSE frame MAY3228* send a single packet containing a CONNECTION_CLOSE3229* frame before entering the draining state, using a3230* NO_ERROR code if appropriate3231*/3232ch->conn_close_queued = 1;3233}3234} else {3235ch_on_terminating_timeout(ch);3236}3237break;32383239case QUIC_CHANNEL_STATE_TERMINATING_CLOSING:3240if (force_immediate)3241ch_on_terminating_timeout(ch);3242else if (tcause->remote)3243/*3244* RFC 9000 s. 10.2.2 Draining Connection State:3245* An endpoint MAY enter the draining state from the3246* closing state if it receives a CONNECTION_CLOSE frame,3247* which indicates that the peer is also closing or draining.3248*/3249ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATING_DRAINING);32503251break;32523253case QUIC_CHANNEL_STATE_TERMINATING_DRAINING:3254/*3255* Other than in the force-immediate case, we remain here until the3256* timeout expires.3257*/3258if (force_immediate)3259ch_on_terminating_timeout(ch);32603261break;32623263case QUIC_CHANNEL_STATE_TERMINATED:3264/* No-op. */3265break;3266}3267}32683269/* For RXDP use. */3270void ossl_quic_channel_on_remote_conn_close(QUIC_CHANNEL *ch,3271OSSL_QUIC_FRAME_CONN_CLOSE *f)3272{3273QUIC_TERMINATE_CAUSE tcause = {0};32743275if (!ossl_quic_channel_is_active(ch))3276return;32773278tcause.remote = 1;3279tcause.app = f->is_app;3280tcause.error_code = f->error_code;3281tcause.frame_type = f->frame_type;3282tcause.reason = f->reason;3283tcause.reason_len = f->reason_len;3284ch_start_terminating(ch, &tcause, 0);3285}32863287static void free_frame_data(unsigned char *buf, size_t buf_len, void *arg)3288{3289OPENSSL_free(buf);3290}32913292static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num)3293{3294BUF_MEM *buf_mem = NULL;3295WPACKET wpkt;3296size_t l;32973298ossl_quic_srtm_remove(ch->srtm, ch, seq_num);32993300if ((buf_mem = BUF_MEM_new()) == NULL)3301goto err;33023303if (!WPACKET_init(&wpkt, buf_mem))3304goto err;33053306if (!ossl_quic_wire_encode_frame_retire_conn_id(&wpkt, seq_num)) {3307WPACKET_cleanup(&wpkt);3308goto err;3309}33103311WPACKET_finish(&wpkt);3312if (!WPACKET_get_total_written(&wpkt, &l))3313goto err;33143315if (ossl_quic_cfq_add_frame(ch->cfq, 1, QUIC_PN_SPACE_APP,3316OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID, 0,3317(unsigned char *)buf_mem->data, l,3318free_frame_data, NULL) == NULL)3319goto err;33203321buf_mem->data = NULL;3322BUF_MEM_free(buf_mem);3323return 1;33243325err:3326ossl_quic_channel_raise_protocol_error(ch,3327OSSL_QUIC_ERR_INTERNAL_ERROR,3328OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,3329"internal error enqueueing retire conn id");3330BUF_MEM_free(buf_mem);3331return 0;3332}33333334void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,3335OSSL_QUIC_FRAME_NEW_CONN_ID *f)3336{3337uint64_t new_remote_seq_num = ch->cur_remote_seq_num;3338uint64_t new_retire_prior_to = ch->cur_retire_prior_to;33393340if (!ossl_quic_channel_is_active(ch))3341return;33423343/* We allow only two active connection ids; first check some constraints */3344if (ch->cur_remote_dcid.id_len == 0) {3345/* Changing from 0 length connection id is disallowed */3346ossl_quic_channel_raise_protocol_error(ch,3347OSSL_QUIC_ERR_PROTOCOL_VIOLATION,3348OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,3349"zero length connection id in use");33503351return;3352}33533354if (f->seq_num > new_remote_seq_num)3355new_remote_seq_num = f->seq_num;3356if (f->retire_prior_to > new_retire_prior_to)3357new_retire_prior_to = f->retire_prior_to;33583359/*3360* RFC 9000-5.1.1: An endpoint MUST NOT provide more connection IDs3361* than the peer's limit.3362*3363* After processing a NEW_CONNECTION_ID frame and adding and retiring3364* active connection IDs, if the number of active connection IDs exceeds3365* the value advertised in its active_connection_id_limit transport3366* parameter, an endpoint MUST close the connection with an error of3367* type CONNECTION_ID_LIMIT_ERROR.3368*/3369if (new_remote_seq_num - new_retire_prior_to > 1) {3370ossl_quic_channel_raise_protocol_error(ch,3371OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,3372OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,3373"active_connection_id limit violated");3374return;3375}33763377/*3378* RFC 9000-5.1.1: An endpoint MAY send connection IDs that temporarily3379* exceed a peer's limit if the NEW_CONNECTION_ID frame also requires3380* the retirement of any excess, by including a sufficiently large3381* value in the Retire Prior To field.3382*3383* RFC 9000-5.1.2: An endpoint SHOULD allow for sending and tracking3384* a number of RETIRE_CONNECTION_ID frames of at least twice the value3385* of the active_connection_id_limit transport parameter. An endpoint3386* MUST NOT forget a connection ID without retiring it, though it MAY3387* choose to treat having connection IDs in need of retirement that3388* exceed this limit as a connection error of type CONNECTION_ID_LIMIT_ERROR.3389*3390* We are a little bit more liberal than the minimum mandated.3391*/3392if (new_retire_prior_to - ch->cur_retire_prior_to > 10) {3393ossl_quic_channel_raise_protocol_error(ch,3394OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,3395OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,3396"retiring connection id limit violated");33973398return;3399}34003401if (new_remote_seq_num > ch->cur_remote_seq_num) {3402/* Add new stateless reset token */3403if (!ossl_quic_srtm_add(ch->srtm, ch, new_remote_seq_num,3404&f->stateless_reset)) {3405ossl_quic_channel_raise_protocol_error(3406ch, OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,3407OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,3408"unable to store stateless reset token");34093410return;3411}3412ch->cur_remote_seq_num = new_remote_seq_num;3413ch->cur_remote_dcid = f->conn_id;3414ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid);3415}34163417/*3418* RFC 9000-5.1.2: Upon receipt of an increased Retire Prior To3419* field, the peer MUST stop using the corresponding connection IDs3420* and retire them with RETIRE_CONNECTION_ID frames before adding the3421* newly provided connection ID to the set of active connection IDs.3422*/34233424/*3425* Note: RFC 9000 s. 19.15 says:3426* "An endpoint that receives a NEW_CONNECTION_ID frame with a sequence3427* number smaller than the Retire Prior To field of a previously received3428* NEW_CONNECTION_ID frame MUST send a corresponding3429* RETIRE_CONNECTION_ID frame that retires the newly received connection3430* ID, unless it has already done so for that sequence number."3431*3432* Since we currently always queue RETIRE_CONN_ID frames based on the Retire3433* Prior To field of a NEW_CONNECTION_ID frame immediately upon receiving3434* that NEW_CONNECTION_ID frame, by definition this will always be met.3435* This may change in future when we change our CID handling.3436*/3437while (new_retire_prior_to > ch->cur_retire_prior_to) {3438if (!ch_enqueue_retire_conn_id(ch, ch->cur_retire_prior_to))3439break;3440++ch->cur_retire_prior_to;3441}3442}34433444static void ch_save_err_state(QUIC_CHANNEL *ch)3445{3446if (ch->err_state == NULL)3447ch->err_state = OSSL_ERR_STATE_new();34483449if (ch->err_state == NULL)3450return;34513452OSSL_ERR_STATE_save(ch->err_state);3453}34543455void ossl_quic_channel_inject(QUIC_CHANNEL *ch, QUIC_URXE *e)3456{3457ossl_qrx_inject_urxe(ch->qrx, e);3458}34593460void ossl_quic_channel_inject_pkt(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpkt)3461{3462ossl_qrx_inject_pkt(ch->qrx, qpkt);3463}34643465void ossl_quic_channel_on_stateless_reset(QUIC_CHANNEL *ch)3466{3467QUIC_TERMINATE_CAUSE tcause = {0};34683469tcause.error_code = OSSL_QUIC_ERR_NO_ERROR;3470tcause.remote = 1;3471ch_start_terminating(ch, &tcause, 0);3472}34733474void ossl_quic_channel_raise_net_error(QUIC_CHANNEL *ch)3475{3476QUIC_TERMINATE_CAUSE tcause = {0};34773478if (ch->net_error)3479return;34803481ch->net_error = 1;34823483tcause.error_code = OSSL_QUIC_ERR_INTERNAL_ERROR;3484tcause.reason = "network BIO I/O error";3485tcause.reason_len = strlen(tcause.reason);34863487/*3488* Skip Terminating state and go directly to Terminated, no point trying to3489* send CONNECTION_CLOSE if we cannot communicate.3490*/3491ch_start_terminating(ch, &tcause, 1);3492}34933494int ossl_quic_channel_net_error(QUIC_CHANNEL *ch)3495{3496return ch->net_error;3497}34983499void ossl_quic_channel_restore_err_state(QUIC_CHANNEL *ch)3500{3501if (ch == NULL)3502return;35033504if (!ossl_quic_port_is_running(ch->port))3505ossl_quic_port_restore_err_state(ch->port);3506else3507OSSL_ERR_STATE_restore(ch->err_state);3508}35093510void ossl_quic_channel_raise_protocol_error_loc(QUIC_CHANNEL *ch,3511uint64_t error_code,3512uint64_t frame_type,3513const char *reason,3514ERR_STATE *err_state,3515const char *src_file,3516int src_line,3517const char *src_func)3518{3519QUIC_TERMINATE_CAUSE tcause = {0};3520int err_reason = error_code == OSSL_QUIC_ERR_INTERNAL_ERROR3521? ERR_R_INTERNAL_ERROR : SSL_R_QUIC_PROTOCOL_ERROR;3522const char *err_str = ossl_quic_err_to_string(error_code);3523const char *err_str_pfx = " (", *err_str_sfx = ")";3524const char *ft_str = NULL;3525const char *ft_str_pfx = " (", *ft_str_sfx = ")";35263527if (ch->protocol_error)3528/* Only the first call to this function matters. */3529return;35303531if (err_str == NULL) {3532err_str = "";3533err_str_pfx = "";3534err_str_sfx = "";3535}35363537/*3538* If we were provided an underlying error state, restore it and then append3539* our ERR on top as a "cover letter" error.3540*/3541if (err_state != NULL)3542OSSL_ERR_STATE_restore(err_state);35433544if (frame_type != 0) {3545ft_str = ossl_quic_frame_type_to_string(frame_type);3546if (ft_str == NULL) {3547ft_str = "";3548ft_str_pfx = "";3549ft_str_sfx = "";3550}35513552ERR_raise_data(ERR_LIB_SSL, err_reason,3553"QUIC error code: 0x%llx%s%s%s "3554"(triggered by frame type: 0x%llx%s%s%s), reason: \"%s\"",3555(unsigned long long) error_code,3556err_str_pfx, err_str, err_str_sfx,3557(unsigned long long) frame_type,3558ft_str_pfx, ft_str, ft_str_sfx,3559reason);3560} else {3561ERR_raise_data(ERR_LIB_SSL, err_reason,3562"QUIC error code: 0x%llx%s%s%s, reason: \"%s\"",3563(unsigned long long) error_code,3564err_str_pfx, err_str, err_str_sfx,3565reason);3566}35673568if (src_file != NULL)3569ERR_set_debug(src_file, src_line, src_func);35703571ch_save_err_state(ch);35723573tcause.error_code = error_code;3574tcause.frame_type = frame_type;3575tcause.reason = reason;3576tcause.reason_len = strlen(reason);35773578ch->protocol_error = 1;3579ch_start_terminating(ch, &tcause, 0);3580}35813582/*3583* Called once the terminating timer expires, meaning we move from TERMINATING3584* to TERMINATED.3585*/3586static void ch_on_terminating_timeout(QUIC_CHANNEL *ch)3587{3588ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED);3589}35903591/*3592* Determines the effective idle timeout duration. This is based on the idle3593* timeout values that we and our peer signalled in transport parameters3594* but have some limits applied.3595*/3596static OSSL_TIME ch_get_effective_idle_timeout_duration(QUIC_CHANNEL *ch)3597{3598OSSL_TIME pto;35993600if (ch->max_idle_timeout == 0)3601return ossl_time_infinite();36023603/*3604* RFC 9000 s. 10.1: Idle Timeout3605* To avoid excessively small idle timeout periods, endpoints3606* MUST increase the idle timeout period to be at least three3607* times the current Probe Timeout (PTO). This allows for3608* multiple PTOs to expire, and therefore multiple probes to3609* be sent and lost, prior to idle timeout.3610*/3611pto = ossl_ackm_get_pto_duration(ch->ackm);3612return ossl_time_max(ossl_ms2time(ch->max_idle_timeout),3613ossl_time_multiply(pto, 3));3614}36153616/*3617* Updates our idle deadline. Called when an event happens which should bump the3618* idle timeout.3619*/3620static void ch_update_idle(QUIC_CHANNEL *ch)3621{3622ch->idle_deadline = ossl_time_add(get_time(ch),3623ch_get_effective_idle_timeout_duration(ch));3624}36253626/*3627* Updates our ping deadline, which determines when we next generate a ping if3628* we don't have any other ACK-eliciting frames to send.3629*/3630static void ch_update_ping_deadline(QUIC_CHANNEL *ch)3631{3632OSSL_TIME max_span, idle_duration;36333634idle_duration = ch_get_effective_idle_timeout_duration(ch);3635if (ossl_time_is_infinite(idle_duration)) {3636ch->ping_deadline = ossl_time_infinite();3637return;3638}36393640/*3641* Maximum amount of time without traffic before we send a PING to keep3642* the connection open. Usually we use max_idle_timeout/2, but ensure3643* the period never exceeds the assumed NAT interval to ensure NAT3644* devices don't have their state time out (RFC 9000 s. 10.1.2).3645*/3646max_span = ossl_time_divide(idle_duration, 2);3647max_span = ossl_time_min(max_span, MAX_NAT_INTERVAL);3648ch->ping_deadline = ossl_time_add(get_time(ch), max_span);3649}36503651/* Called when the idle timeout expires. */3652static void ch_on_idle_timeout(QUIC_CHANNEL *ch)3653{3654/*3655* Idle timeout does not have an error code associated with it because a3656* CONN_CLOSE is never sent for it. We shouldn't use this data once we reach3657* TERMINATED anyway.3658*/3659ch->terminate_cause.app = 0;3660ch->terminate_cause.error_code = OSSL_QUIC_LOCAL_ERR_IDLE_TIMEOUT;3661ch->terminate_cause.frame_type = 0;36623663ch_record_state_transition(ch, QUIC_CHANNEL_STATE_TERMINATED);3664}36653666/**3667* @brief Common handler for initializing a new QUIC connection.3668*3669* This function configures a QUIC channel (`QUIC_CHANNEL *ch`) for a new3670* connection by setting the peer address, connection IDs, and necessary3671* callbacks. It establishes initial secrets, sets up logging, and performs3672* required transitions for the channel state.3673*3674* @param ch Pointer to the QUIC channel being initialized.3675* @param peer Address of the peer to which the channel connects.3676* @param peer_scid Peer-specified source connection ID.3677* @param peer_dcid Peer-specified destination connection ID.3678* @param peer_odcid Peer-specified original destination connection ID3679* may be NULL if retry frame not sent to client3680* @return 1 on success, 0 on failure to set required elements.3681*/3682static int ch_on_new_conn_common(QUIC_CHANNEL *ch, const BIO_ADDR *peer,3683const QUIC_CONN_ID *peer_scid,3684const QUIC_CONN_ID *peer_dcid,3685const QUIC_CONN_ID *peer_odcid)3686{3687/* Note our newly learnt peer address and CIDs. */3688if (!BIO_ADDR_copy(&ch->cur_peer_addr, peer))3689return 0;36903691ch->init_dcid = *peer_dcid;3692ch->cur_remote_dcid = *peer_scid;3693ch->odcid.id_len = 0;36943695if (peer_odcid != NULL)3696ch->odcid = *peer_odcid;36973698/* Inform QTX of peer address. */3699if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr))3700return 0;37013702/* Inform TXP of desired CIDs. */3703if (!ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid))3704return 0;37053706if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid))3707return 0;37083709/* Setup QLOG, which did not happen earlier due to lacking an Initial ODCID. */3710ossl_qtx_set_qlog_cb(ch->qtx, ch_get_qlog_cb, ch);3711ossl_quic_tx_packetiser_set_qlog_cb(ch->txp, ch_get_qlog_cb, ch);37123713/*3714* Plug in secrets for the Initial EL. secrets for QRX were created in3715* port_default_packet_handler() already.3716*/3717if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,3718ch->port->engine->propq,3719&ch->init_dcid,3720/*is_server=*/1,3721NULL, ch->qtx))3722return 0;37233724/* Register the peer ODCID in the LCIDM. */3725if (!ossl_quic_lcidm_enrol_odcid(ch->lcidm, ch, peer_odcid == NULL ?3726&ch->init_dcid :3727peer_odcid))3728return 0;37293730/* Change state. */3731ch_record_state_transition(ch, QUIC_CHANNEL_STATE_ACTIVE);3732ch->doing_proactive_ver_neg = 0; /* not currently supported */3733return 1;3734}37353736/* Called when we, as a server, get a new incoming connection. */3737int ossl_quic_channel_on_new_conn(QUIC_CHANNEL *ch, const BIO_ADDR *peer,3738const QUIC_CONN_ID *peer_scid,3739const QUIC_CONN_ID *peer_dcid)3740{3741if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server))3742return 0;37433744/* Generate an Initial LCID we will use for the connection. */3745if (!ossl_quic_lcidm_generate_initial(ch->lcidm, ch, &ch->cur_local_cid))3746return 0;37473748return ch_on_new_conn_common(ch, peer, peer_scid, peer_dcid, NULL);3749}37503751/**3752* Binds a QUIC channel to a specific peer's address and connection IDs.3753*3754* This function is used to establish a binding between a QUIC channel and a3755* peer's address and connection IDs. The binding is performed only if the3756* channel is idle and is on the server side. The peer's destination connection3757* ID (`peer_dcid`) is mandatory, and the channel's current local connection ID3758* is set to this value.3759*3760* @param ch Pointer to the QUIC_CHANNEL structure representing the3761* channel to be bound.3762* @param peer Pointer to a BIO_ADDR structure representing the peer's3763* address.3764* @param peer_scid Pointer to the peer's source connection ID (QUIC_CONN_ID).3765* @param peer_dcid Pointer to the peer's destination connection ID3766* (QUIC_CONN_ID). This must not be NULL.3767* @param peer_odcid Pointer to the original destination connection ID3768* (QUIC_CONN_ID) chosen by the peer in its first initial3769* packet received without a token.3770*3771* @return 1 on success, or 0 on failure if the conditions for binding are not3772* met (e.g., channel is not idle or not a server, or binding fails).3773*/3774int ossl_quic_bind_channel(QUIC_CHANNEL *ch, const BIO_ADDR *peer,3775const QUIC_CONN_ID *peer_scid,3776const QUIC_CONN_ID *peer_dcid,3777const QUIC_CONN_ID *peer_odcid)3778{3779if (peer_dcid == NULL)3780return 0;37813782if (!ossl_assert(ch->state == QUIC_CHANNEL_STATE_IDLE && ch->is_server))3783return 0;37843785ch->cur_local_cid = *peer_dcid;3786if (!ossl_quic_lcidm_bind_channel(ch->lcidm, ch, peer_dcid))3787return 0;37883789/*3790* peer_odcid <=> is initial dst conn id chosen by peer in its3791* first initial packet we received without token.3792*/3793return ch_on_new_conn_common(ch, peer, peer_scid, peer_dcid, peer_odcid);3794}37953796SSL *ossl_quic_channel_get0_ssl(QUIC_CHANNEL *ch)3797{3798return ch->tls;3799}38003801static int ch_init_new_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs,3802int can_send, int can_recv)3803{3804uint64_t rxfc_wnd;3805int server_init = ossl_quic_stream_is_server_init(qs);3806int local_init = (ch->is_server == server_init);3807int is_uni = !ossl_quic_stream_is_bidi(qs);38083809if (can_send)3810if ((qs->sstream = ossl_quic_sstream_new(INIT_APP_BUF_LEN)) == NULL)3811goto err;38123813if (can_recv)3814if ((qs->rstream = ossl_quic_rstream_new(NULL, NULL, 0)) == NULL)3815goto err;38163817/* TXFC */3818if (!ossl_quic_txfc_init(&qs->txfc, &ch->conn_txfc))3819goto err;38203821if (ch->got_remote_transport_params) {3822/*3823* If we already got peer TPs we need to apply the initial CWM credit3824* now. If we didn't already get peer TPs this will be done3825* automatically for all extant streams when we do.3826*/3827if (can_send) {3828uint64_t cwm;38293830if (is_uni)3831cwm = ch->rx_init_max_stream_data_uni;3832else if (local_init)3833cwm = ch->rx_init_max_stream_data_bidi_local;3834else3835cwm = ch->rx_init_max_stream_data_bidi_remote;38363837ossl_quic_txfc_bump_cwm(&qs->txfc, cwm);3838}3839}38403841/* RXFC */3842if (!can_recv)3843rxfc_wnd = 0;3844else if (is_uni)3845rxfc_wnd = ch->tx_init_max_stream_data_uni;3846else if (local_init)3847rxfc_wnd = ch->tx_init_max_stream_data_bidi_local;3848else3849rxfc_wnd = ch->tx_init_max_stream_data_bidi_remote;38503851if (!ossl_quic_rxfc_init(&qs->rxfc, &ch->conn_rxfc,3852rxfc_wnd,3853DEFAULT_STREAM_RXFC_MAX_WND_MUL * rxfc_wnd,3854get_time, ch))3855goto err;38563857return 1;38583859err:3860ossl_quic_sstream_free(qs->sstream);3861qs->sstream = NULL;3862ossl_quic_rstream_free(qs->rstream);3863qs->rstream = NULL;3864return 0;3865}38663867static uint64_t *ch_get_local_stream_next_ordinal_ptr(QUIC_CHANNEL *ch,3868int is_uni)3869{3870return is_uni ? &ch->next_local_stream_ordinal_uni3871: &ch->next_local_stream_ordinal_bidi;3872}38733874static const uint64_t *ch_get_local_stream_max_ptr(const QUIC_CHANNEL *ch,3875int is_uni)3876{3877return is_uni ? &ch->max_local_streams_uni3878: &ch->max_local_streams_bidi;3879}38803881static const QUIC_RXFC *ch_get_remote_stream_count_rxfc(const QUIC_CHANNEL *ch,3882int is_uni)3883{3884return is_uni ? &ch->max_streams_uni_rxfc3885: &ch->max_streams_bidi_rxfc;3886}38873888int ossl_quic_channel_is_new_local_stream_admissible(QUIC_CHANNEL *ch,3889int is_uni)3890{3891const uint64_t *p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni);38923893return ossl_quic_stream_map_is_local_allowed_by_stream_limit(&ch->qsm,3894*p_next_ordinal,3895is_uni);3896}38973898uint64_t ossl_quic_channel_get_local_stream_count_avail(const QUIC_CHANNEL *ch,3899int is_uni)3900{3901const uint64_t *p_next_ordinal, *p_max;39023903p_next_ordinal = ch_get_local_stream_next_ordinal_ptr((QUIC_CHANNEL *)ch,3904is_uni);3905p_max = ch_get_local_stream_max_ptr(ch, is_uni);39063907return *p_max - *p_next_ordinal;3908}39093910uint64_t ossl_quic_channel_get_remote_stream_count_avail(const QUIC_CHANNEL *ch,3911int is_uni)3912{3913return ossl_quic_rxfc_get_credit(ch_get_remote_stream_count_rxfc(ch, is_uni));3914}39153916QUIC_STREAM *ossl_quic_channel_new_stream_local(QUIC_CHANNEL *ch, int is_uni)3917{3918QUIC_STREAM *qs;3919int type;3920uint64_t stream_id;3921uint64_t *p_next_ordinal;39223923type = ch->is_server ? QUIC_STREAM_INITIATOR_SERVER3924: QUIC_STREAM_INITIATOR_CLIENT;39253926p_next_ordinal = ch_get_local_stream_next_ordinal_ptr(ch, is_uni);39273928if (is_uni)3929type |= QUIC_STREAM_DIR_UNI;3930else3931type |= QUIC_STREAM_DIR_BIDI;39323933if (*p_next_ordinal >= ((uint64_t)1) << 62)3934return NULL;39353936stream_id = ((*p_next_ordinal) << 2) | type;39373938if ((qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id, type)) == NULL)3939return NULL;39403941/* Locally-initiated stream, so we always want a send buffer. */3942if (!ch_init_new_stream(ch, qs, /*can_send=*/1, /*can_recv=*/!is_uni))3943goto err;39443945++*p_next_ordinal;3946return qs;39473948err:3949ossl_quic_stream_map_release(&ch->qsm, qs);3950return NULL;3951}39523953QUIC_STREAM *ossl_quic_channel_new_stream_remote(QUIC_CHANNEL *ch,3954uint64_t stream_id)3955{3956uint64_t peer_role;3957int is_uni;3958QUIC_STREAM *qs;39593960peer_role = ch->is_server3961? QUIC_STREAM_INITIATOR_CLIENT3962: QUIC_STREAM_INITIATOR_SERVER;39633964if ((stream_id & QUIC_STREAM_INITIATOR_MASK) != peer_role)3965return NULL;39663967is_uni = ((stream_id & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_UNI);39683969qs = ossl_quic_stream_map_alloc(&ch->qsm, stream_id,3970stream_id & (QUIC_STREAM_INITIATOR_MASK3971| QUIC_STREAM_DIR_MASK));3972if (qs == NULL)3973return NULL;39743975if (!ch_init_new_stream(ch, qs, /*can_send=*/!is_uni, /*can_recv=*/1))3976goto err;39773978if (ch->incoming_stream_auto_reject)3979ossl_quic_channel_reject_stream(ch, qs);3980else3981ossl_quic_stream_map_push_accept_queue(&ch->qsm, qs);39823983return qs;39843985err:3986ossl_quic_stream_map_release(&ch->qsm, qs);3987return NULL;3988}39893990void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch,3991int enable,3992uint64_t aec)3993{3994ch->incoming_stream_auto_reject = (enable != 0);3995ch->incoming_stream_auto_reject_aec = aec;3996}39973998void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs)3999{4000ossl_quic_stream_map_stop_sending_recv_part(&ch->qsm, qs,4001ch->incoming_stream_auto_reject_aec);40024003ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, qs,4004ch->incoming_stream_auto_reject_aec);4005qs->deleted = 1;40064007ossl_quic_stream_map_update_state(&ch->qsm, qs);4008}40094010/* Replace local connection ID in TXP and DEMUX for testing purposes. */4011int ossl_quic_channel_replace_local_cid(QUIC_CHANNEL *ch,4012const QUIC_CONN_ID *conn_id)4013{4014/* Remove the current LCID from the LCIDM. */4015if (!ossl_quic_lcidm_debug_remove(ch->lcidm, &ch->cur_local_cid))4016return 0;4017ch->cur_local_cid = *conn_id;4018/* Set in the TXP, used only for long header packets. */4019if (!ossl_quic_tx_packetiser_set_cur_scid(ch->txp, &ch->cur_local_cid))4020return 0;4021/* Add the new LCID to the LCIDM. */4022if (!ossl_quic_lcidm_debug_add(ch->lcidm, ch, &ch->cur_local_cid,4023100))4024return 0;4025return 1;4026}40274028void ossl_quic_channel_set_msg_callback(QUIC_CHANNEL *ch,4029ossl_msg_cb msg_callback,4030SSL *msg_callback_ssl)4031{4032ch->msg_callback = msg_callback;4033ch->msg_callback_ssl = msg_callback_ssl;4034ossl_qtx_set_msg_callback(ch->qtx, msg_callback, msg_callback_ssl);4035ossl_quic_tx_packetiser_set_msg_callback(ch->txp, msg_callback,4036msg_callback_ssl);4037/*4038* postpone msg callback setting for tserver until port calls4039* port_bind_channel().4040*/4041if (ch->is_tserver_ch == 0)4042ossl_qrx_set_msg_callback(ch->qrx, msg_callback, msg_callback_ssl);4043}40444045void ossl_quic_channel_set_msg_callback_arg(QUIC_CHANNEL *ch,4046void *msg_callback_arg)4047{4048ch->msg_callback_arg = msg_callback_arg;4049ossl_qtx_set_msg_callback_arg(ch->qtx, msg_callback_arg);4050ossl_quic_tx_packetiser_set_msg_callback_arg(ch->txp, msg_callback_arg);40514052/*4053* postpone msg callback setting for tserver until port calls4054* port_bind_channel().4055*/4056if (ch->is_tserver_ch == 0)4057ossl_qrx_set_msg_callback_arg(ch->qrx, msg_callback_arg);4058}40594060void ossl_quic_channel_set_txku_threshold_override(QUIC_CHANNEL *ch,4061uint64_t tx_pkt_threshold)4062{4063ch->txku_threshold_override = tx_pkt_threshold;4064}40654066uint64_t ossl_quic_channel_get_tx_key_epoch(QUIC_CHANNEL *ch)4067{4068return ossl_qtx_get_key_epoch(ch->qtx);4069}40704071uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch)4072{4073return ossl_qrx_get_key_epoch(ch->qrx);4074}40754076int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch)4077{4078if (!txku_allowed(ch))4079return 0;40804081ch->ku_locally_initiated = 1;4082ch_trigger_txku(ch);4083return 1;4084}40854086int ossl_quic_channel_ping(QUIC_CHANNEL *ch)4087{4088int pn_space = ossl_quic_enc_level_to_pn_space(ch->tx_enc_level);40894090ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, pn_space);40914092return 1;4093}40944095uint16_t ossl_quic_channel_get_diag_num_rx_ack(QUIC_CHANNEL *ch)4096{4097return ch->diag_num_rx_ack;4098}40994100void ossl_quic_channel_get_diag_local_cid(QUIC_CHANNEL *ch, QUIC_CONN_ID *cid)4101{4102*cid = ch->cur_local_cid;4103}41044105int ossl_quic_channel_have_generated_transport_params(const QUIC_CHANNEL *ch)4106{4107return ch->got_local_transport_params;4108}41094110void ossl_quic_channel_set_max_idle_timeout_request(QUIC_CHANNEL *ch, uint64_t ms)4111{4112ch->max_idle_timeout_local_req = ms;4113}4114uint64_t ossl_quic_channel_get_max_idle_timeout_request(const QUIC_CHANNEL *ch)4115{4116return ch->max_idle_timeout_local_req;4117}41184119uint64_t ossl_quic_channel_get_max_idle_timeout_peer_request(const QUIC_CHANNEL *ch)4120{4121return ch->max_idle_timeout_remote_req;4122}41234124uint64_t ossl_quic_channel_get_max_idle_timeout_actual(const QUIC_CHANNEL *ch)4125{4126return ch->max_idle_timeout;4127}412841294130