]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC APL: Support blocking connection acceptance
authorHugo Landau <hlandau@openssl.org>
Thu, 4 Apr 2024 10:50:51 +0000 (11:50 +0100)
committerNeil Horman <nhorman@openssl.org>
Mon, 17 Feb 2025 16:27:32 +0000 (11:27 -0500)
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24037)

include/internal/quic_port.h
ssl/quic/quic_impl.c
ssl/quic/quic_port.c

index a150eff90d304676a005d7ee291d38b591421c0d..48a2ecfa09c681ac3bfd944262dc563f469ccf3c 100644 (file)
@@ -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.
  */
index db547ba8a2906a5c2eebb189f0afa65f94a72bb8..d6a39fc9f8bb7c1c674bcf23ade402eb7a3d9e87 100644 (file)
@@ -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);
 
index 8cba36f627459a07b4d2b4ff614e7d8ac69858b6..52f17d3b3172701f4ab0877db6b59c955bdba1aa 100644 (file)
@@ -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;