From dc04a11ccacb507beed7de1e9301660d4a630adf Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 8 Jan 2025 13:23:55 -0500 Subject: [PATCH] Add callback to get user ssl on channel creation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/26361) --- include/internal/quic_port.h | 8 ++++++++ ssl/quic/quic_impl.c | 30 ++++++++++++++++++++++++++++++ ssl/quic/quic_port.c | 2 ++ ssl/quic/quic_port_local.h | 3 +++ 4 files changed, 43 insertions(+) diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h index 4229cc25be3..faad3357a2d 100644 --- a/include/internal/quic_port.h +++ b/include/internal/quic_port.h @@ -42,6 +42,14 @@ typedef struct quic_port_args_st { /* The engine which the QUIC port is to be a child of. */ QUIC_ENGINE *engine; + /* + * This callback allows port_new_handshake_layer to pre-create a quic + * connection object for the incomming channel + * user_ssl_arg is expected to point to a quic listener object + */ + SSL *(*get_conn_user_ssl)(QUIC_CHANNEL *ch, void *arg); + void *user_ssl_arg; + /* * This SSL_CTX will be used when constructing the handshake layer object * inside newly created channels. diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 0fb72cd3caa..7ad493d462f 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -4189,6 +4189,32 @@ int ossl_quic_get_key_update_type(const SSL *s) return SSL_KEY_UPDATE_NONE; } +/** + * @brief Allocates an SSL object for a user from a QUIC channel. + * + * This function creates a new QUIC_CONNECTION object based on an incoming + * connection associated with the provided QUIC_LISTENER. If the connection + * creation fails, the function returns NULL. Otherwise, it returns a pointer + * to the SSL object associated with the newly created connection. + * + * Note: This function is a registered port callback made from + * ossl_quic_new_listener and ossl_quic_new_listener_from, and allows for + * pre-allocation of the user_ssl object when a channel is created, rather than + * when it is accepted + * + * @param ch Pointer to the QUIC_CHANNEL representing the incoming connection. + * @param arg Pointer to a QUIC_LISTENER used to create the connection. + * + * @return Pointer to the SSL object on success, or NULL on failure. + */ +static SSL *alloc_port_user_ssl(QUIC_CHANNEL *ch, void *arg) +{ + QUIC_LISTENER *ql = arg; + QUIC_CONNECTION *qc = create_qc_from_incoming_conn(ql, ch); + + return (qc == NULL) ? NULL : &qc->obj.ssl; +} + /* * QUIC Front-End I/O API: Listeners * ================================= @@ -4232,6 +4258,8 @@ SSL *ossl_quic_new_listener(SSL_CTX *ctx, uint64_t flags) port_args.channel_ctx = ctx; port_args.is_multi_conn = 1; + port_args.get_conn_user_ssl = alloc_port_user_ssl; + port_args.user_ssl_arg = ql; if ((flags & SSL_LISTENER_FLAG_NO_VALIDATE) == 0) port_args.do_addr_validation = 1; ql->port = ossl_quic_engine_create_port(ql->engine, &port_args); @@ -4287,6 +4315,8 @@ SSL *ossl_quic_new_listener_from(SSL *ssl, uint64_t flags) port_args.channel_ctx = ssl->ctx; port_args.is_multi_conn = 1; + port_args.get_conn_user_ssl = alloc_port_user_ssl; + port_args.user_ssl_arg = ql; if ((flags & SSL_LISTENER_FLAG_NO_VALIDATE) == 0) port_args.do_addr_validation = 1; ql->port = ossl_quic_engine_create_port(ctx.qd->engine, &port_args); diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index d477f64b1cb..4377fb1d3e7 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -107,6 +107,8 @@ QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args) port->channel_ctx = args->channel_ctx; port->is_multi_conn = args->is_multi_conn; port->validate_addr = args->do_addr_validation; + port->get_conn_user_ssl = args->get_conn_user_ssl; + port->user_ssl_arg = args->user_ssl_arg; if (!port_init(port)) { OPENSSL_free(port); diff --git a/ssl/quic/quic_port_local.h b/ssl/quic/quic_port_local.h index 5b08266360f..0c18b5cce2d 100644 --- a/ssl/quic/quic_port_local.h +++ b/ssl/quic/quic_port_local.h @@ -51,6 +51,9 @@ struct quic_port_st { */ OSSL_LIST_MEMBER(port, QUIC_PORT); + SSL * (*get_conn_user_ssl)(QUIC_CHANNEL *ch, void *arg); + void *user_ssl_arg; + /* Used to create handshake layer objects inside newly created channels. */ SSL_CTX *channel_ctx; -- 2.47.2