summaryrefslogtreecommitdiffstats
path: root/ssl/quic/quic_impl.c
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2024-01-11 09:06:55 +0000
committerHugo Landau <hlandau@openssl.org>2024-04-19 09:29:02 +0100
commit99af2fc5c2da0feeaa8e61b7c04d5123eab41453 (patch)
treedd9f55a47a7b41a429aad651549879d259cba657 /ssl/quic/quic_impl.c
parent989dd4e055db7b3243f303cc18842d7f349abee2 (diff)
QUIC APL: Make use of QUIC_OBJ infrastructure
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> (Merged from https://github.com/openssl/openssl/pull/23334)
Diffstat (limited to 'ssl/quic/quic_impl.c')
-rw-r--r--ssl/quic/quic_impl.c133
1 files changed, 75 insertions, 58 deletions
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index 2043af1e95..44e28f9e85 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -22,8 +22,9 @@
typedef struct qctx_st QCTX;
+static void qc_cleanup(QUIC_CONNECTION *qc, int have_lock);
static void aon_write_finish(QUIC_XSO *xso);
-static int create_channel(QUIC_CONNECTION *qc);
+static int create_channel(QUIC_CONNECTION *qc, SSL_CTX *ctx);
static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs);
static int qc_try_create_default_xso_for_write(QCTX *ctx);
static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek);
@@ -381,7 +382,6 @@ static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active)
SSL *ossl_quic_new(SSL_CTX *ctx)
{
QUIC_CONNECTION *qc = NULL;
- SSL *ssl_base = NULL;
SSL_CONNECTION *sc = NULL;
qc = OPENSSL_zalloc(sizeof(*qc));
@@ -389,6 +389,8 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);
return NULL;
}
+
+ /* Create the QUIC domain mutex. */
#if defined(OPENSSL_THREADS)
if ((qc->mutex = ossl_crypto_mutex_new()) == NULL) {
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_CRYPTO_LIB, NULL);
@@ -396,14 +398,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
}
#endif
- /* Initialise the QUIC_CONNECTION's stub header. */
- ssl_base = &qc->ssl;
- if (!ossl_ssl_init(ssl_base, ctx, ctx->method, SSL_TYPE_QUIC_CONNECTION)) {
- ssl_base = NULL;
- QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
- goto err;
- }
-
+ /* Create the handshake layer. */
qc->tls = ossl_ssl_connection_new_int(ctx, TLS_method());
if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) {
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
@@ -417,28 +412,37 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
sc->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN;
sc->pha_enabled = 0;
+ /* Determine mode of operation. */
#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST)
qc->is_thread_assisted
- = (ssl_base->method == OSSL_QUIC_client_thread_method());
+ = (ctx->method == OSSL_QUIC_client_thread_method());
#endif
qc->as_server = 0; /* TODO(QUIC SERVER): add server support */
qc->as_server_state = qc->as_server;
+ if (!create_channel(qc, ctx))
+ goto err;
+
+ ossl_quic_channel_set_msg_callback(qc->ch, ctx->msg_callback, &qc->obj.ssl);
+ ossl_quic_channel_set_msg_callback_arg(qc->ch, ctx->msg_callback_arg);
+
+ /* Initialise the QUIC_CONNECTION's QUIC_OBJ base. */
+ if (!ossl_quic_obj_init(&qc->obj, ctx, SSL_TYPE_QUIC_CONNECTION, NULL,
+ qc->engine, qc->port)) {
+ QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
+ goto err;
+ }
+
+ /* Initialise libssl APL-related state. */
qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
- qc->default_ssl_mode = qc->ssl.ctx->mode;
- qc->default_ssl_options = qc->ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
+ qc->default_ssl_mode = qc->obj.ssl.ctx->mode;
+ qc->default_ssl_options = qc->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
qc->desires_blocking = 1;
qc->blocking = 0;
qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;
qc->last_error = SSL_ERROR_NONE;
- if (!create_channel(qc))
- goto err;
-
- ossl_quic_channel_set_msg_callback(qc->ch, ctx->msg_callback, ssl_base);
- ossl_quic_channel_set_msg_callback_arg(qc->ch, ctx->msg_callback_arg);
-
qc_update_reject_policy(qc);
/*
@@ -451,20 +455,45 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
* we take that as a cue that the client is expecting a server-initiated
* stream, and vice versa if SSL_write() is called first.
*/
- return ssl_base;
+ return &qc->obj.ssl;
err:
- if (ssl_base == NULL) {
-#if defined(OPENSSL_THREADS)
- ossl_crypto_mutex_free(&qc->mutex);
-#endif
+ if (qc != NULL) {
+ qc_cleanup(qc, /*have_lock=*/0);
OPENSSL_free(qc);
- } else {
- SSL_free(ssl_base);
}
return NULL;
}
+QUIC_NEEDS_LOCK
+static void qc_cleanup(QUIC_CONNECTION *qc, int have_lock)
+{
+ ossl_quic_channel_free(qc->ch);
+ qc->ch = NULL;
+
+ ossl_quic_port_free(qc->port);
+ qc->port = NULL;
+
+ ossl_quic_engine_free(qc->engine);
+ qc->engine = NULL;
+
+ BIO_free_all(qc->net_rbio);
+ qc->net_rbio = NULL;
+
+ BIO_free_all(qc->net_wbio);
+ qc->net_wbio = NULL;
+
+ SSL_free(qc->tls);
+ qc->tls = NULL;
+
+ if (have_lock)
+ quic_unlock(qc); /* tsan doesn't like freeing locked mutexes */
+
+#if defined(OPENSSL_THREADS)
+ ossl_crypto_mutex_free(&qc->mutex);
+#endif
+}
+
/* SSL_free */
QUIC_TAKES_LOCK
void ossl_quic_free(SSL *s)
@@ -518,7 +547,7 @@ void ossl_quic_free(SSL *s)
* so don't call SSL_free(qc) as we are already in it.
*/
if (!is_default)
- SSL_free(&ctx.qc->ssl);
+ SSL_free(&ctx.qc->obj.ssl);
/* Note: SSL_free calls OPENSSL_free(xso) for us */
return;
@@ -532,7 +561,7 @@ void ossl_quic_free(SSL *s)
QUIC_XSO *xso = ctx.qc->default_xso;
quic_unlock(ctx.qc);
- SSL_free(&xso->ssl);
+ SSL_free(&xso->obj.ssl);
quic_lock(ctx.qc);
ctx.qc->default_xso = NULL;
}
@@ -547,24 +576,11 @@ void ossl_quic_free(SSL *s)
}
#endif
- SSL_free(ctx.qc->tls);
-
- ossl_quic_channel_free(ctx.qc->ch);
- ossl_quic_port_free(ctx.qc->port);
- ossl_quic_engine_free(ctx.qc->engine);
-
- BIO_free_all(ctx.qc->net_rbio);
- BIO_free_all(ctx.qc->net_wbio);
-
- quic_unlock(ctx.qc); /* tsan doesn't like freeing locked mutexes */
-#if defined(OPENSSL_THREADS)
- ossl_crypto_mutex_free(&ctx.qc->mutex);
-#endif
-
/*
* Note: SSL_free (that called this function) calls OPENSSL_free(ctx.qc) for
* us
*/
+ qc_cleanup(ctx.qc, /*have_lock=*/1);
}
/* SSL method init */
@@ -665,7 +681,7 @@ static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso,
* Changing to not having a default XSO. XSO becomes standalone and
* now has a ref to the QC.
*/
- if (!ossl_assert(SSL_up_ref(&qc->ssl)))
+ if (!ossl_assert(SSL_up_ref(&qc->obj.ssl)))
return;
} else {
/*
@@ -679,7 +695,7 @@ static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso,
*/
assert(*old_xso == NULL);
- CRYPTO_DOWN_REF(&qc->ssl.references, &refs);
+ CRYPTO_DOWN_REF(&qc->obj.ssl.references, &refs);
assert(refs > 0);
}
}
@@ -700,7 +716,7 @@ static void qc_set_default_xso(QUIC_CONNECTION *qc, QUIC_XSO *xso, int touch)
qc_set_default_xso_keep_ref(qc, xso, touch, &old_xso);
if (old_xso != NULL)
- SSL_free(&old_xso->ssl);
+ SSL_free(&old_xso->obj.ssl);
}
QUIC_NEEDS_LOCK
@@ -1416,7 +1432,7 @@ long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg)
* supported by anything, the handshake layer's ctrl method will finally
* return 0.
*/
- return ossl_ctrl_internal(&ctx.qc->ssl, cmd, larg, parg, /*no_quic=*/1);
+ return ossl_ctrl_internal(&ctx.qc->obj.ssl, cmd, larg, parg, /*no_quic=*/1);
}
}
@@ -1496,13 +1512,13 @@ static int configure_channel(QUIC_CONNECTION *qc)
}
QUIC_NEEDS_LOCK
-static int create_channel(QUIC_CONNECTION *qc)
+static int create_channel(QUIC_CONNECTION *qc, SSL_CTX *ctx)
{
QUIC_ENGINE_ARGS engine_args = {0};
QUIC_PORT_ARGS port_args = {0};
- engine_args.libctx = qc->ssl.ctx->libctx;
- engine_args.propq = qc->ssl.ctx->propq;
+ engine_args.libctx = ctx->libctx;
+ engine_args.propq = ctx->propq;
engine_args.mutex = qc->mutex;
engine_args.now_cb = get_time_cb;
engine_args.now_cb_arg = qc;
@@ -1512,7 +1528,7 @@ static int create_channel(QUIC_CONNECTION *qc)
return 0;
}
- port_args.channel_ctx = qc->ssl.ctx;
+ port_args.channel_ctx = ctx;
qc->port = ossl_quic_engine_create_port(qc->engine, &port_args);
if (qc->port == NULL) {
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
@@ -1946,13 +1962,14 @@ static QUIC_XSO *create_xso_from_stream(QUIC_CONNECTION *qc, QUIC_STREAM *qs)
goto err;
}
- if (!ossl_ssl_init(&xso->ssl, qc->ssl.ctx, qc->ssl.method, SSL_TYPE_QUIC_XSO)) {
+ if (!ossl_quic_obj_init(&xso->obj, qc->obj.ssl.ctx, SSL_TYPE_QUIC_XSO,
+ &qc->obj.ssl, NULL, NULL)) {
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
goto err;
}
/* XSO refs QC */
- if (!SSL_up_ref(&qc->ssl)) {
+ if (!SSL_up_ref(&qc->obj.ssl)) {
QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_SSL_LIB, NULL);
goto err;
}
@@ -2053,7 +2070,7 @@ static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock)
if (need_lock)
quic_unlock(qc);
- return &xso->ssl;
+ return &xso->obj.ssl;
err:
OPENSSL_free(xso);
@@ -2978,7 +2995,7 @@ SSL *ossl_quic_get0_connection(SSL *s)
if (!expect_quic(s, &ctx))
return NULL;
- return &ctx.qc->ssl;
+ return &ctx.qc->obj.ssl;
}
/*
@@ -3111,7 +3128,7 @@ SSL *ossl_quic_detach_stream(SSL *s)
quic_unlock(ctx.qc);
- return xso != NULL ? &xso->ssl : NULL;
+ return xso != NULL ? &xso->obj.ssl : NULL;
}
/*
@@ -3146,7 +3163,7 @@ int ossl_quic_attach_stream(SSL *conn, SSL *stream)
* It is a caller error for the XSO being attached as a default XSO to have
* more than one ref.
*/
- if (!CRYPTO_GET_REF(&xso->ssl.references, &nref)) {
+ if (!CRYPTO_GET_REF(&xso->obj.ssl.references, &nref)) {
quic_unlock(ctx.qc);
return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_INTERNAL_ERROR,
"ref");
@@ -3598,7 +3615,7 @@ SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)
ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ctx.qc->ch), &rtt_info);
ossl_quic_stream_map_remove_from_accept_queue(qsm, qs,
rtt_info.smoothed_rtt);
- new_s = &xso->ssl;
+ new_s = &xso->obj.ssl;
/* Calling this function inhibits default XSO autocreation. */
qc_touch_default_xso(ctx.qc); /* inhibits default XSO */
@@ -3940,7 +3957,7 @@ long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
switch (cmd) {
case SSL_CTRL_SET_MSG_CALLBACK:
ossl_quic_channel_set_msg_callback(ctx.qc->ch, (ossl_msg_cb)fp,
- &ctx.qc->ssl);
+ &ctx.qc->obj.ssl);
/* This callback also needs to be set on the internal SSL object */
return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp);;