From: Hugo Landau Date: Thu, 4 Apr 2024 10:50:51 +0000 (+0100) Subject: QUIC APL: Support blocking connection acceptance X-Git-Tag: openssl-3.5.0-alpha1~412 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e73a3ca9f244d97fbc091265321f3627f9e033f;p=thirdparty%2Fopenssl.git QUIC APL: Support blocking connection acceptance Reviewed-by: Neil Horman Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/24037) --- diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h index a150eff90d3..48a2ecfa09c 100644 --- a/include/internal/quic_port.h +++ b/include/internal/quic_port.h @@ -82,6 +82,9 @@ QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls); */ QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port); +/* Returns 1 if there is at least one connection incoming. */ +int ossl_quic_port_have_incoming(QUIC_PORT *port); + /* * Delete any channels which are pending acceptance. */ diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index db547ba8a29..d6a39fc9f8b 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -4218,12 +4218,27 @@ int ossl_quic_listen(SSL *ssl) * SSL_accept_connection * --------------------- */ +static int quic_accept_connection_wait(void *arg) +{ + QUIC_PORT *port = arg; + + if (!ossl_quic_port_is_running(port)) + return -1; + + if (ossl_quic_port_have_incoming(port)) + return 1; + + return 0; +} + QUIC_TAKES_LOCK SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags) { + int ret; QCTX ctx; QUIC_CONNECTION *qc = NULL; QUIC_CHANNEL *new_ch = NULL; + int no_block = ((flags & SSL_ACCEPT_CONNECTION_NO_BLOCK) != 0); if (!expect_quic_listener(ssl, &ctx)) return NULL; @@ -4233,11 +4248,25 @@ SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags) if (!ql_listen(ctx.ql)) goto out; - /* TODO(QUIC SERVER): Autotick */ - /* TODO(QUIC SERVER): Implement blocking and SSL_ACCEPT_CONNECTION_NO_BLOCK */ - + /* Wait for an incoming connection if needed. */ new_ch = ossl_quic_port_pop_incoming(ctx.ql->port); - if (new_ch == NULL) { + if (new_ch == NULL && ossl_quic_port_is_running(ctx.ql->port)) { + if (!no_block && qctx_blocking(&ctx)) { + ret = block_until_pred(&ctx, quic_accept_connection_wait, + ctx.ql->port, 0); + if (ret < 1) + goto out; + } else { + qctx_maybe_autotick(&ctx); + } + + if (!ossl_quic_port_is_running(ctx.ql->port)) + goto out; + + new_ch = ossl_quic_port_pop_incoming(ctx.ql->port); + } + + if (new_ch == NULL && ossl_quic_port_is_running(ctx.ql->port)) { /* No connections already queued. */ ossl_quic_reactor_tick(ossl_quic_engine_get0_reactor(ctx.ql->engine), 0); diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 8cba36f6274..52f17d3b317 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -440,6 +440,11 @@ QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port) return ch; } +int ossl_quic_port_have_incoming(QUIC_PORT *port) +{ + return ossl_list_incoming_ch_head(&port->incoming_channel_list) != NULL; +} + void ossl_quic_port_drop_incoming(QUIC_PORT *port) { QUIC_CHANNEL *ch;