diff options
author | Hugo Landau <hlandau@openssl.org> | 2024-01-11 09:06:55 +0000 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2024-04-19 09:29:02 +0100 |
commit | 99af2fc5c2da0feeaa8e61b7c04d5123eab41453 (patch) | |
tree | dd9f55a47a7b41a429aad651549879d259cba657 /ssl/quic/quic_impl.c | |
parent | 989dd4e055db7b3243f303cc18842d7f349abee2 (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.c | 133 |
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);; |