diff options
author | Hugo Landau <hlandau@openssl.org> | 2024-04-04 11:50:51 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2024-04-19 09:33:53 +0100 |
commit | bb691573dfce225ece81a8cb8f56e53703e0973a (patch) | |
tree | 552e42f0aaafa2dbc633a6822cb1293e2f3d5f2b | |
parent | a0fbdcc537fbee90ad03a75d74ca01950011ab4b (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.h | 3 | ||||
-rw-r--r-- | ssl/quic/quic_impl.c | 37 | ||||
-rw-r--r-- | ssl/quic/quic_port.c | 5 |
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; |