MINOR: quic-be: SSL sessions initializations

Modify qc_alloc_ssl_sock_ctx() to pass the connection object as parameter. It is
NULL for a QUIC listener, not NULL for a QUIC server. This connection object is
set as value for ->conn quic_conn struct member. Initialise the SSL session object from
this function for QUIC servers.
qc_ssl_set_quic_transport_params() is also modified to pass the SSL object as parameter.
This is the unique parameter this function needs. <qc> parameter is used only for
the trace.
SSL_do_handshake() must be calle as soon as the SSL object is initialized for
the QUIC backend connection. This triggers the TLS CRYPTO data delivery.
tasklet_wakeup() is also called to send asap these CRYPTO data.
Modify the QUIC_EV_CONN_NEW event trace to dump the potential errors returned by
SSL_do_handshake().
This commit is contained in:
Frederic Lecaille 2023-12-19 08:16:42 +01:00 committed by Amaury Denoyelle
parent 1408d94bc4
commit f49bbd36b9
6 changed files with 52 additions and 12 deletions

View File

@ -69,7 +69,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
struct quic_connection_id *conn_id,
struct sockaddr_storage *local_addr,
struct sockaddr_storage *peer_addr,
int server, int token, void *owner);
int server, int token, void *owner,
struct connection *conn);
int quic_build_post_handshake_frames(struct quic_conn *qc);
const struct quic_version *qc_supported_version(uint32_t version);
int quic_peer_validated_addr(struct quic_conn *qc);

View File

@ -35,7 +35,7 @@
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
SSL_CTX *ssl_quic_srv_new_ssl_ctx(void);
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc);
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn);
int qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
int quic_ssl_set_tls_cbs(SSL *ssl);

View File

@ -1032,7 +1032,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
struct quic_connection_id *conn_id,
struct sockaddr_storage *local_addr,
struct sockaddr_storage *peer_addr,
int server, int token, void *owner)
int server, int token, void *owner,
struct connection *conn)
{
struct quic_conn *qc = NULL;
struct listener *l = server ? owner : NULL;
@ -1263,7 +1264,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
qc->wait_event.events = 0;
qc->subs = NULL;
if (qc_alloc_ssl_sock_ctx(qc) ||
if (qc_alloc_ssl_sock_ctx(qc, conn) ||
!quic_conn_init_timer(qc) ||
!quic_conn_init_idle_timer_task(qc, prx))
goto err;

View File

@ -1820,7 +1820,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
qc = qc_new_conn(pkt->version, ipv4, &pkt->dcid, &pkt->scid, &token_odcid,
conn_id, &dgram->daddr, &pkt->saddr, 1,
!!pkt->token_len, l);
!!pkt->token_len, l, NULL);
if (qc == NULL) {
pool_free(pool_head_quic_connection_id, conn_id);
goto err;

View File

@ -17,7 +17,7 @@ DECLARE_POOL(pool_head_quic_ssl_sock_ctx, "quic_ssl_sock_ctx", sizeof(struct ssl
* be set to 1 for a QUIC server, 0 for a client.
* Return 1 if succeeded, 0 if not.
*/
static int qc_ssl_set_quic_transport_params(struct quic_conn *qc,
static int qc_ssl_set_quic_transport_params(SSL *ssl, struct quic_conn *qc,
const struct quic_version *ver, int server)
{
int ret = 0;
@ -40,7 +40,7 @@ static int qc_ssl_set_quic_transport_params(struct quic_conn *qc,
goto leave;
}
if (!SSL_set_quic_transport_params(qc->xprt_ctx->ssl, in, *enclen)) {
if (!SSL_set_quic_transport_params(ssl, in, *enclen)) {
TRACE_ERROR("SSL_set_quic_transport_params() failed", QUIC_EV_CONN_RWSEC);
goto leave;
}
@ -274,7 +274,7 @@ write:
/* Set the transport parameters in the TLS stack. */
if (level == ssl_encryption_handshake && qc_is_listener(qc) &&
!qc_ssl_set_quic_transport_params(qc, ver, 1))
!qc_ssl_set_quic_transport_params(qc->xprt_ctx->ssl, qc, ver, 1))
goto leave;
keyupdate_init:
@ -570,7 +570,7 @@ static int ha_quic_ossl_got_transport_params(SSL *ssl, const unsigned char *para
}
else {
if (!quic_transport_params_store(qc, 0, params, params + params_len) ||
!qc_ssl_set_quic_transport_params(qc, ver, 1))
!qc_ssl_set_quic_transport_params(ssl, qc, ver, 1))
goto err;
}
@ -1150,10 +1150,9 @@ static int qc_set_quic_early_data_enabled(struct quic_conn *qc, SSL *ssl)
*
* Returns 0 on success else non-zero.
*/
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
int qc_alloc_ssl_sock_ctx(struct quic_conn *qc, struct connection *conn)
{
int ret = 0;
struct bind_conf *bc = qc->li->bind_conf;
struct ssl_sock_ctx *ctx = NULL;
TRACE_ENTER(QUIC_EV_CONN_NEW, qc);
@ -1164,7 +1163,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
goto err;
}
ctx->conn = NULL;
ctx->conn = conn;
ctx->bio = NULL;
ctx->xprt = NULL;
ctx->xprt_ctx = NULL;
@ -1177,6 +1176,8 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
ctx->qc = qc;
if (qc_is_listener(qc)) {
struct bind_conf *bc = qc->li->bind_conf;
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl) == -1)
goto err;
#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) && defined(HAVE_SSL_0RTT_QUIC)
@ -1187,6 +1188,36 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
SSL_set_accept_state(ctx->ssl);
}
else {
int ssl_err;
struct server *srv = __objt_server(ctx->conn->target);
if (qc_ssl_sess_init(qc, srv->ssl_ctx.ctx, &ctx->ssl) == -1)
goto err;
if (!qc_ssl_set_quic_transport_params(ctx->ssl, qc, quic_version_1, 0))
goto err;
SSL_set_connect_state(ctx->ssl);
ssl_err = SSL_do_handshake(ctx->ssl);
TRACE_PROTO("SSL_do_handshake() called", QUIC_EV_CONN_NEW, qc, &ssl_err);
if (ssl_err != 1) {
ssl_err = SSL_get_error(ctx->ssl, ssl_err);
if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
TRACE_PROTO("SSL handshake in progress", QUIC_EV_CONN_NEW, qc, &ssl_err);
}
else {
TRACE_ERROR("SSL handshake error", QUIC_EV_CONN_NEW, qc, &ssl_err);
HA_ATOMIC_INC(&qc->prx_counters->hdshk_fail);
qc_ssl_dump_errors(ctx->conn);
ERR_clear_error();
goto err;
}
}
/* Wakeup the handshake I/O handler tasklet asap to send data */
tasklet_wakeup(qc->wait_event.tasklet);
}
ctx->xprt = xprt_get(XPRT_QUIC);

View File

@ -117,6 +117,13 @@ static void quic_trace(enum trace_level level, uint64_t mask, const struct trace
chunk_appendf(&trace_buf, " : qc@%p idle_timer_task@%p flags=0x%x",
qc, qc->idle_timer_task, qc->flags);
if (mask & QUIC_EV_CONN_NEW) {
const int *ssl_err = a2;
if (ssl_err)
chunk_appendf(&trace_buf, " ssl_err=%d", *ssl_err);
}
if (mask & QUIC_EV_CONN_INIT) {
chunk_appendf(&trace_buf, "\n odcid");
quic_cid_dump(&trace_buf, &qc->odcid);