summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2024-04-04 11:50:51 +0100
committerHugo Landau <hlandau@openssl.org>2024-04-19 09:33:53 +0100
commitbb691573dfce225ece81a8cb8f56e53703e0973a (patch)
tree552e42f0aaafa2dbc633a6822cb1293e2f3d5f2b
parenta0fbdcc537fbee90ad03a75d74ca01950011ab4b (diff)
QUIC APL: Support blocking connection acceptance
Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/24037)
-rw-r--r--include/internal/quic_port.h3
-rw-r--r--ssl/quic/quic_impl.c37
-rw-r--r--ssl/quic/quic_port.c5
3 files changed, 41 insertions, 4 deletions
diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h
index a150eff90d..48a2ecfa09 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 18715c3621..a2036843dc 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -4200,12 +4200,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;
@@ -4215,11 +4230,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 936b97b5fe..6f5fb0f5b3 100644
--- a/ssl/quic/quic_port.c
+++ b/ssl/quic/quic_port.c
@@ -435,6 +435,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;