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:
parent
1408d94bc4
commit
f49bbd36b9
@ -69,7 +69,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
|||||||
struct quic_connection_id *conn_id,
|
struct quic_connection_id *conn_id,
|
||||||
struct sockaddr_storage *local_addr,
|
struct sockaddr_storage *local_addr,
|
||||||
struct sockaddr_storage *peer_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);
|
int quic_build_post_handshake_frames(struct quic_conn *qc);
|
||||||
const struct quic_version *qc_supported_version(uint32_t version);
|
const struct quic_version *qc_supported_version(uint32_t version);
|
||||||
int quic_peer_validated_addr(struct quic_conn *qc);
|
int quic_peer_validated_addr(struct quic_conn *qc);
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
int ssl_quic_initial_ctx(struct bind_conf *bind_conf);
|
||||||
SSL_CTX *ssl_quic_srv_new_ssl_ctx(void);
|
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 qc_ssl_provide_all_quic_data(struct quic_conn *qc, struct ssl_sock_ctx *ctx);
|
||||||
int quic_ssl_set_tls_cbs(SSL *ssl);
|
int quic_ssl_set_tls_cbs(SSL *ssl);
|
||||||
|
|
||||||
|
@ -1032,7 +1032,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
|||||||
struct quic_connection_id *conn_id,
|
struct quic_connection_id *conn_id,
|
||||||
struct sockaddr_storage *local_addr,
|
struct sockaddr_storage *local_addr,
|
||||||
struct sockaddr_storage *peer_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 quic_conn *qc = NULL;
|
||||||
struct listener *l = server ? owner : 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->wait_event.events = 0;
|
||||||
qc->subs = NULL;
|
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_timer(qc) ||
|
||||||
!quic_conn_init_idle_timer_task(qc, prx))
|
!quic_conn_init_idle_timer_task(qc, prx))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -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,
|
qc = qc_new_conn(pkt->version, ipv4, &pkt->dcid, &pkt->scid, &token_odcid,
|
||||||
conn_id, &dgram->daddr, &pkt->saddr, 1,
|
conn_id, &dgram->daddr, &pkt->saddr, 1,
|
||||||
!!pkt->token_len, l);
|
!!pkt->token_len, l, NULL);
|
||||||
if (qc == NULL) {
|
if (qc == NULL) {
|
||||||
pool_free(pool_head_quic_connection_id, conn_id);
|
pool_free(pool_head_quic_connection_id, conn_id);
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -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.
|
* be set to 1 for a QUIC server, 0 for a client.
|
||||||
* Return 1 if succeeded, 0 if not.
|
* 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)
|
const struct quic_version *ver, int server)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -40,7 +40,7 @@ static int qc_ssl_set_quic_transport_params(struct quic_conn *qc,
|
|||||||
goto leave;
|
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);
|
TRACE_ERROR("SSL_set_quic_transport_params() failed", QUIC_EV_CONN_RWSEC);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ write:
|
|||||||
|
|
||||||
/* Set the transport parameters in the TLS stack. */
|
/* Set the transport parameters in the TLS stack. */
|
||||||
if (level == ssl_encryption_handshake && qc_is_listener(qc) &&
|
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;
|
goto leave;
|
||||||
|
|
||||||
keyupdate_init:
|
keyupdate_init:
|
||||||
@ -570,7 +570,7 @@ static int ha_quic_ossl_got_transport_params(SSL *ssl, const unsigned char *para
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!quic_transport_params_store(qc, 0, params, params + params_len) ||
|
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;
|
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.
|
* 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;
|
int ret = 0;
|
||||||
struct bind_conf *bc = qc->li->bind_conf;
|
|
||||||
struct ssl_sock_ctx *ctx = NULL;
|
struct ssl_sock_ctx *ctx = NULL;
|
||||||
|
|
||||||
TRACE_ENTER(QUIC_EV_CONN_NEW, qc);
|
TRACE_ENTER(QUIC_EV_CONN_NEW, qc);
|
||||||
@ -1164,7 +1163,7 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->conn = NULL;
|
ctx->conn = conn;
|
||||||
ctx->bio = NULL;
|
ctx->bio = NULL;
|
||||||
ctx->xprt = NULL;
|
ctx->xprt = NULL;
|
||||||
ctx->xprt_ctx = NULL;
|
ctx->xprt_ctx = NULL;
|
||||||
@ -1177,6 +1176,8 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
|
|||||||
ctx->qc = qc;
|
ctx->qc = qc;
|
||||||
|
|
||||||
if (qc_is_listener(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)
|
if (qc_ssl_sess_init(qc, bc->initial_ctx, &ctx->ssl) == -1)
|
||||||
goto err;
|
goto err;
|
||||||
#if (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L) && defined(HAVE_SSL_0RTT_QUIC)
|
#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);
|
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);
|
ctx->xprt = xprt_get(XPRT_QUIC);
|
||||||
|
|
||||||
|
@ -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",
|
chunk_appendf(&trace_buf, " : qc@%p idle_timer_task@%p flags=0x%x",
|
||||||
qc, qc->idle_timer_task, qc->flags);
|
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) {
|
if (mask & QUIC_EV_CONN_INIT) {
|
||||||
chunk_appendf(&trace_buf, "\n odcid");
|
chunk_appendf(&trace_buf, "\n odcid");
|
||||||
quic_cid_dump(&trace_buf, &qc->odcid);
|
quic_cid_dump(&trace_buf, &qc->odcid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user