diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 16d66f35b..8501e3faf 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -4446,6 +4446,51 @@ static int quic_conn_unsubscribe(struct connection *conn, void *xprt_ctx, int ev return conn_unsubscribe(conn, xprt_ctx, event_type, es); } +/* Try to allocate the <*ssl> SSL session object for QUIC connection + * with as SSL context inherited settings. Also set the transport + * parameters of this session. + * This is the responsibility of the caller to check the validity of all the + * pointers passed as parameter to this function. + * Return 0 if succeeded, -1 if not. If failed, sets the ->err_code member of conn> to + * CO_ER_SSL_NO_MEM. + */ +static int qc_ssl_sess_init(struct quic_conn *qc, SSL_CTX *ssl_ctx, SSL **ssl, + unsigned char *params, size_t params_len) +{ + int retry; + + retry = 1; + retry: + *ssl = SSL_new(ssl_ctx); + if (!*ssl) { + if (!retry--) + goto err; + + pool_gc(NULL); + goto retry; + } + + if (!SSL_set_quic_method(*ssl, &ha_quic_method) || + !SSL_set_ex_data(*ssl, ssl_app_data_index, qc->conn) || + !SSL_set_quic_transport_params(*ssl, qc->enc_params, qc->enc_params_len)) { + goto err; + + SSL_free(*ssl); + *ssl = NULL; + if (!retry--) + goto err; + + pool_gc(NULL); + goto retry; + } + + return 0; + + err: + qc->conn->err_code = CO_ER_SSL_NO_MEM; + return -1; +} + /* Initialize a QUIC connection (quic_conn struct) to be attached to * connection with as address of the xprt context. * Returns 1 if succeeded, 0 if not. @@ -4505,10 +4550,6 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx) dcid, sizeof dcid, 0)) goto err; - if (ssl_bio_and_sess_init(conn, srv->ssl_ctx.ctx, - &ctx->ssl, &ctx->bio, ha_quic_meth, ctx) == -1) - goto err; - qc->rx.params = srv->quic_params; /* Copy the initial source connection ID. */ quic_cid_cpy(&qc->rx.params.initial_source_connection_id, &qc->scid); @@ -4518,6 +4559,10 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx) if (!qc->enc_params_len) goto err; + if (qc_ssl_sess_init(qc, srv->ssl_ctx.ctx, &ctx->ssl, + qc->enc_params, qc->enc_params_len) == -1) + goto err; + SSL_set_quic_transport_params(ctx->ssl, qc->enc_params, qc->enc_params_len); SSL_set_connect_state(ctx->ssl); ssl_err = SSL_do_handshake(ctx->ssl); @@ -4541,11 +4586,10 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx) struct quic_conn *qc = ctx->conn->qc; ctx->wait_event.tasklet->tid = quic_get_cid_tid(&qc->scid); - if (ssl_bio_and_sess_init(conn, bc->initial_ctx, - &ctx->ssl, &ctx->bio, ha_quic_meth, ctx) == -1) + if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl, + qc->enc_params, qc->enc_params_len) == -1) goto err; - SSL_set_quic_transport_params(ctx->ssl, qc->enc_params, qc->enc_params_len); SSL_set_accept_state(ctx->ssl); }