Commit 03e4ecf92e for openssl.org

commit 03e4ecf92e7b2cee2de34656a2afa682cba13801
Author: Neil Horman <nhorman@openssl.org>
Date:   Thu Apr 10 10:05:59 2025 -0400

    Start implementing SSL_listen_ex

    Reviewed-by: Saša NedvÄ›dický <sashan@openssl.org>
    Reviewed-by: Matt Caswell <matt@openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/27397)

diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h
index 0df73c2200..2fedff9d78 100644
--- a/include/internal/quic_ssl.h
+++ b/include/internal/quic_ssl.h
@@ -121,6 +121,7 @@ __owur SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags);
 __owur size_t ossl_quic_get_accept_connection_queue_len(SSL *ssl);
 __owur int ossl_quic_listen(SSL *ssl);
 __owur int ossl_quic_get_peer_addr(SSL *ssl, BIO_ADDR *peer_addr);
+__owur int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn);

 __owur int ossl_quic_stream_reset(SSL *ssl,
                                   const SSL_STREAM_RESET_ARGS *args,
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index 26dcd98e07..6f642746dd 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -2578,6 +2578,9 @@ void SSL_trace(int write_p, int version, int content_type,
 int DTLSv1_listen(SSL *s, BIO_ADDR *client);
 # endif

+
+__owur int SSL_listen_ex(SSL *listener, SSL *new_conn);
+
 # ifndef OPENSSL_NO_CT

 /*
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index 0ca07589af..51cabf3fd9 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -4628,6 +4628,31 @@ int ossl_quic_listen(SSL *ssl)
     return ret;
 }

+QUIC_TAKES_LOCK
+int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn)
+{
+    QCTX lctx;
+    QCTX cctx;
+    QUIC_CHANNEL *new_ch;
+    int ret = 0;
+
+    if (!expect_quic_listener(listener, &lctx))
+        return 0;
+
+    if (!expect_quic_cs(new_conn, &cctx))
+        return 0;
+
+    qctx_lock_for_io(&lctx);
+    new_ch = ossl_quic_port_pop_incoming(lctx.ql->port);
+    if (new_ch != NULL) {
+        /*
+         * Do our cloning work here
+         */
+    }
+    qctx_unlock(&lctx);
+    return ret;
+}
+
 /*
  * SSL_accept_connection
  * ---------------------
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 488b68f828..502d450b5e 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -8059,6 +8059,15 @@ int SSL_get_peer_addr(SSL *ssl, BIO_ADDR *peer_addr)
     return ossl_quic_get_peer_addr(ssl, peer_addr);
 #else
     return 0;
+}
+
+int SSL_listen_ex(SSL *listener, SSL *new_conn)
+{
+#ifndef OPENSSL_NO_QUIC
+    if (!IS_QUIC(listener) || !IS_QUIC(new_conn))
+        return ossl_quic_peeloff_conn(listener, new_conn);
+#else
+    return 0;
 #endif
 }