summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2024-04-04 11:30:15 +0100
committerHugo Landau <hlandau@openssl.org>2024-04-19 09:33:53 +0100
commit08cc2f41a4b573220dd82c66c1b2a0df28ecb1db (patch)
tree446ff2f43e74ecd67a0e5492808025e729770001
parentae859d7c723c82410799581cff03b0078d6db6d7 (diff)
QUIC APL: Unify blocking mode handling for all object types
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_engine.h8
-rw-r--r--include/internal/quic_port.h7
-rw-r--r--ssl/quic/quic_engine.c18
-rw-r--r--ssl/quic/quic_impl.c128
-rw-r--r--ssl/quic/quic_local.h24
-rw-r--r--ssl/quic/quic_obj.c36
-rw-r--r--ssl/quic/quic_obj_local.h38
-rw-r--r--ssl/quic/quic_port.c14
-rw-r--r--ssl/quic/quic_port_local.h6
9 files changed, 149 insertions, 130 deletions
diff --git a/include/internal/quic_engine.h b/include/internal/quic_engine.h
index e19ee5fb73..454c4bfaaa 100644
--- a/include/internal/quic_engine.h
+++ b/include/internal/quic_engine.h
@@ -82,6 +82,14 @@ QUIC_REACTOR *ossl_quic_engine_get0_reactor(QUIC_ENGINE *qeng);
OSSL_LIB_CTX *ossl_quic_engine_get0_libctx(QUIC_ENGINE *qeng);
const char *ossl_quic_engine_get0_propq(QUIC_ENGINE *qeng);
+/*
+ * Look through all the engine's ports and determine if any of them have had a
+ * BIO changed. If so, update the blocking support detection data in the
+ * QUIC_REACTOR. If force is 1, always do the update even if nothing seems
+ * to have changed.
+ */
+void ossl_quic_engine_update_poll_descriptors(QUIC_ENGINE *qeng, int force);
+
# endif
#endif
diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h
index 9c74390ab2..a150eff90d 100644
--- a/include/internal/quic_port.h
+++ b/include/internal/quic_port.h
@@ -99,10 +99,11 @@ int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio);
int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio);
/*
- * Re-poll the network BIOs already set to determine if their support
- * for polling has changed.
+ * Re-poll the network BIOs already set to determine if their support for
+ * polling has changed. If force is 0, only check again if the BIOs have been
+ * changed.
*/
-int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port);
+int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port, int force);
/* Gets the engine which this port is a child of. */
QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port);
diff --git a/ssl/quic/quic_engine.c b/ssl/quic/quic_engine.c
index 932ac2a7f0..679ef051a0 100644
--- a/ssl/quic/quic_engine.c
+++ b/ssl/quic/quic_engine.c
@@ -97,6 +97,24 @@ const char *ossl_quic_engine_get0_propq(QUIC_ENGINE *qeng)
return qeng->propq;
}
+void ossl_quic_engine_update_poll_descriptors(QUIC_ENGINE *qeng, int force)
+{
+ QUIC_PORT *port;
+
+ /*
+ * TODO(QUIC MULTIPORT): The implementation of
+ * ossl_quic_port_update_poll_descriptors assumes an engine only ever has a
+ * single port for now due to reactor limitations. This limitation will be
+ * removed in future.
+ *
+ * TODO(QUIC MULTIPORT): Consider only iterating the port list when dirty at
+ * the engine level in future when we can have multiple ports. This is not
+ * important currently as the port list has a single entry.
+ */
+ LIST_FOREACH(port, port, &qeng->port_list)
+ ossl_quic_port_update_poll_descriptors(port, force);
+}
+
/*
* QUIC Engine: Child Object Lifecycle Management
* ==============================================
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index c9151d9522..a45adb0949 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -41,8 +41,6 @@ static void qc_set_default_xso_keep_ref(QUIC_CONNECTION *qc, QUIC_XSO *xso,
static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock);
static int quic_validate_for_write(QUIC_XSO *xso, int *err);
static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active);
-static int qc_blocking_mode(const QUIC_CONNECTION *qc);
-static int xso_blocking_mode(const QUIC_XSO *xso);
static void qctx_maybe_autotick(QCTX *ctx);
static int qctx_should_autotick(QCTX *ctx);
@@ -480,6 +478,16 @@ static int quic_mutation_allowed(QUIC_CONNECTION *qc, int req_active)
return 1;
}
+static int qctx_is_top_level(QCTX *ctx)
+{
+ return ctx->obj->parent_obj == NULL;
+}
+
+static int qctx_blocking(QCTX *ctx)
+{
+ return ossl_quic_obj_blocking(ctx->obj);
+}
+
/*
* Block until a predicate is met.
*
@@ -585,11 +593,8 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
qc->default_ssl_mode = qc->obj.ssl.ctx->mode;
qc->default_ssl_options = qc->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
- qc->desires_blocking = 1;
- qc->blocking = 0;
qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;
qc->last_error = SSL_ERROR_NONE;
- qc->last_net_bio_epoch = UINT64_MAX;
qc_update_reject_policy(qc);
@@ -1051,24 +1056,6 @@ static int csm_analyse_init_peer_addr(BIO *net_wbio, BIO_ADDR *peer)
return 1;
}
-static int qc_can_support_blocking_cached(QUIC_CONNECTION *qc)
-{
- QUIC_REACTOR *rtor = ossl_quic_channel_get_reactor(qc->ch);
-
- return ossl_quic_reactor_can_poll_r(rtor)
- && ossl_quic_reactor_can_poll_w(rtor);
-}
-
-static void qc_update_can_support_blocking(QUIC_CONNECTION *qc)
-{
- ossl_quic_port_update_poll_descriptors(qc->port); /* best effort */
-}
-
-static void qc_update_blocking_mode(QUIC_CONNECTION *qc)
-{
- qc->blocking = qc->desires_blocking && qc_can_support_blocking_cached(qc);
-}
-
static int
quic_set0_net_rbio(QUIC_OBJ *obj, BIO *net_rbio)
{
@@ -1165,22 +1152,20 @@ int ossl_quic_conn_get_blocking_mode(const SSL *s)
{
QCTX ctx;
- if (!expect_quic_cs(s, &ctx))
+ if (!expect_quic_csl(s, &ctx))
return 0;
- if (ctx.is_stream)
- return xso_blocking_mode(ctx.xso);
-
- return qc_blocking_mode(ctx.qc);
+ return qctx_blocking(&ctx);
}
QUIC_TAKES_LOCK
int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)
{
int ret = 0;
+ unsigned int mode;
QCTX ctx;
- if (!expect_quic_cs(s, &ctx))
+ if (!expect_quic_csl(s, &ctx))
return 0;
qctx_lock(&ctx);
@@ -1188,38 +1173,27 @@ int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)
/* Sanity check - can we support the request given the current network BIO? */
if (blocking) {
/*
- * If called directly on a QCSO, update our information on network BIO
- * capabilities.
+ * If called directly on a top-level object (QCSO or QLSO), update our
+ * information on network BIO capabilities.
*/
- if (!ctx.is_stream)
- qc_update_can_support_blocking(ctx.qc);
+ if (qctx_is_top_level(&ctx))
+ ossl_quic_engine_update_poll_descriptors(ctx.obj->engine, /*force=*/1);
/* Cannot enable blocking mode if we do not have pollable FDs. */
- if (!qc_can_support_blocking_cached(ctx.qc)) {
+ if (!ossl_quic_obj_can_support_blocking(ctx.obj)) {
ret = QUIC_RAISE_NON_NORMAL_ERROR(&ctx, ERR_R_UNSUPPORTED, NULL);
goto out;
}
}
- if (!ctx.is_stream)
- /*
- * If called directly on a QCSO, update default and connection-level
- * blocking modes.
- */
- ctx.qc->desires_blocking = (blocking != 0);
+ mode = (blocking != 0)
+ ? QUIC_BLOCKING_MODE_BLOCKING
+ : QUIC_BLOCKING_MODE_NONBLOCKING;
- if (ctx.xso != NULL) {
- /*
- * If called on a QSSO or a QCSO with a default XSO, update the blocking
- * mode.
- */
- ctx.xso->desires_blocking = (blocking != 0);
- ctx.xso->desires_blocking_set = 1;
- }
+ ossl_quic_obj_set_blocking_mode(ctx.obj, mode);
ret = 1;
out:
- qc_update_blocking_mode(ctx.qc);
qctx_unlock(&ctx);
return ret;
}
@@ -1254,34 +1228,6 @@ int ossl_quic_conn_set_initial_peer_addr(SSL *s,
* (BIO/)SSL_get_poll_fd => ossl_quic_get_poll_fd
*
*/
-static void qc_try_update_blocking(QUIC_CONNECTION *qc)
-{
- uint64_t cur_epoch;
-
- cur_epoch = ossl_quic_port_get_net_bio_epoch(qc->port);
- if (qc->last_net_bio_epoch == cur_epoch)
- return;
-
- qc_update_can_support_blocking(qc);
- qc_update_blocking_mode(qc);
- qc->last_net_bio_epoch = cur_epoch;
-}
-
-/* Returns 1 if the connection is being used in blocking mode. */
-static int qc_blocking_mode(const QUIC_CONNECTION *qc)
-{
- qc_try_update_blocking((QUIC_CONNECTION *)qc);
- return qc->blocking;
-}
-
-static int xso_blocking_mode(const QUIC_XSO *xso)
-{
- if (xso->desires_blocking_set)
- return xso->desires_blocking && qc_can_support_blocking_cached(xso->conn);
- else
- /* Only ever set if we can support blocking. */
- return xso->conn->blocking;
-}
/* SSL_handle_events; performs QUIC I/O and timeout processing. */
QUIC_TAKES_LOCK
@@ -1501,7 +1447,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
qc_shutdown_flush_init(ctx.qc);
if (!qc_shutdown_flush_finished(ctx.qc)) {
- if (!no_block && qc_blocking_mode(ctx.qc)) {
+ if (!no_block && qctx_blocking(&ctx)) {
ret = block_until_pred(&ctx, quic_shutdown_flush_wait, ctx.qc, 0);
if (ret < 1) {
ret = 0;
@@ -1520,7 +1466,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
/* Phase 2: Connection Closure */
if (wait_peer && !ossl_quic_channel_is_term_any(ctx.qc->ch)) {
- if (!no_block && qc_blocking_mode(ctx.qc)) {
+ if (!no_block && qctx_blocking(&ctx)) {
ret = block_until_pred(&ctx, quic_shutdown_peer_wait, ctx.qc, 0);
if (ret < 1) {
ret = 0;
@@ -1560,7 +1506,7 @@ int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
}
/* Phase 3: Terminating Wait Time */
- if (!no_block && qc_blocking_mode(ctx.qc)
+ if (!no_block && qctx_blocking(&ctx)
&& (flags & SSL_SHUTDOWN_FLAG_RAPID) == 0) {
ret = block_until_pred(&ctx, quic_shutdown_wait, ctx.qc, 0);
if (ret < 1) {
@@ -1889,7 +1835,7 @@ static int quic_do_handshake(QCTX *ctx)
/* The handshake is now done. */
return 1;
- if (!qc_blocking_mode(qc)) {
+ if (!qctx_blocking(ctx)) {
/* Try to advance the reactor. */
qctx_maybe_autotick(ctx);
@@ -1900,7 +1846,7 @@ static int quic_do_handshake(QCTX *ctx)
if (ossl_quic_channel_is_term_any(qc->ch)) {
QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
return 0;
- } else if (qc->desires_blocking) {
+ } else if (ossl_quic_obj_desires_blocking(&qc->obj)) {
/*
* As a special case when doing a handshake when blocking mode is
* desired yet not available, see if the network BIOs have become
@@ -1908,16 +1854,14 @@ static int quic_do_handshake(QCTX *ctx)
* which do late creation of socket FDs and therefore cannot expose
* a poll descriptor until after a network BIO is set on the QCSO.
*/
- assert(!qc->blocking);
- qc_update_can_support_blocking(qc);
- qc_update_blocking_mode(qc);
+ ossl_quic_engine_update_poll_descriptors(qc->obj.engine, /*force=*/1);
}
}
/*
* We are either in blocking mode or just entered it due to the code above.
*/
- if (qc_blocking_mode(qc)) {
+ if (qctx_blocking(ctx)) {
/* In blocking mode, wait for the handshake to complete. */
struct quic_handshake_wait_args args;
@@ -2107,7 +2051,7 @@ static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek)
if (peek)
return 0;
- if (!qc_blocking_mode(qc))
+ if (!qctx_blocking(ctx))
/* Non-blocking mode, so just bail immediately. */
return QUIC_RAISE_NORMAL_ERROR(ctx, SSL_ERROR_WANT_READ);
@@ -2231,7 +2175,7 @@ static SSL *quic_conn_stream_new(QCTX *ctx, uint64_t flags, int need_lock)
* Stream count flow control currently doesn't permit this stream to be
* opened.
*/
- if (no_blocking || !qc_blocking_mode(qc)) {
+ if (no_blocking || !qctx_blocking(ctx)) {
QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_COUNT_LIMITED, NULL);
goto err;
}
@@ -2792,7 +2736,7 @@ int ossl_quic_write_flags(SSL *s, const void *buf, size_t len,
goto out;
}
- if (xso_blocking_mode(ctx.xso))
+ if (qctx_blocking(&ctx))
ret = quic_write_blocking(&ctx, buf, len, flags, written);
else if (partial_write)
ret = quic_write_nonblocking_epw(&ctx, buf, len, flags, written);
@@ -3002,7 +2946,7 @@ static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek
*/
qctx_maybe_autotick(&ctx);
ret = 1;
- } else if (xso_blocking_mode(ctx.xso)) {
+ } else if (qctx_blocking(&ctx)) {
/*
* We were not able to read anything immediately, so our stream
* buffer is empty. This means we need to block until we get
@@ -3802,7 +3746,7 @@ SSL *ossl_quic_accept_stream(SSL *s, uint64_t flags)
qs = ossl_quic_stream_map_peek_accept_queue(qsm);
if (qs == NULL) {
- if (qc_blocking_mode(ctx.qc)
+ if (qctx_blocking(&ctx)
&& (flags & SSL_ACCEPT_STREAM_NO_BLOCK) == 0) {
struct wait_for_incoming_stream_args args;
@@ -4333,11 +4277,9 @@ static QUIC_CONNECTION *create_qc_from_incoming_conn(QUIC_LISTENER *ql, QUIC_CHA
qc->mutex = ql->mutex;
#endif
qc->tls = ossl_quic_channel_get0_tls(ch);
- qc->last_net_bio_epoch = UINT64_MAX;
qc->started = 1;
qc->as_server = 1;
qc->as_server_state = 1;
- qc->desires_blocking = 1;
qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
qc->default_ssl_options = ql->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;
diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h
index 85c73fe6c7..f75d128362 100644
--- a/ssl/quic/quic_local.h
+++ b/ssl/quic/quic_local.h
@@ -42,19 +42,6 @@ struct quic_xso_st {
/* The stream object. Always non-NULL for as long as the XSO exists. */
QUIC_STREAM *stream;
- /*
- * Has this stream been logically configured into blocking mode? Only
- * meaningful if desires_blocking_set is 1. Ignored if blocking is not
- * currently possible given QUIC_CONNECTION configuration.
- */
- unsigned int desires_blocking : 1;
-
- /*
- * Has SSL_set_blocking_mode been called on this stream? If not set, we
- * inherit from the QUIC_CONNECTION blocking state.
- */
- unsigned int desires_blocking_set : 1;
-
/* The application has retired a FIN (i.e. SSL_ERROR_ZERO_RETURN). */
unsigned int retired_fin : 1;
@@ -205,12 +192,6 @@ struct quic_conn_st {
/* Are we using thread assisted mode? Never changes after init. */
unsigned int is_thread_assisted : 1;
- /* Do connection-level operations (e.g. handshakes) run in blocking mode? */
- unsigned int blocking : 1;
-
- /* Does the application want blocking mode? */
- unsigned int desires_blocking : 1;
-
/* Have we created a default XSO yet? */
unsigned int default_xso_created : 1;
@@ -245,11 +226,6 @@ struct quic_conn_st {
uint64_t incoming_stream_aec;
/*
- * Last network BIO epoch at which blocking mode compatibility was checked.
- */
- uint64_t last_net_bio_epoch;
-
- /*
* Last 'normal' error during an app-level I/O operation, used by
* SSL_get_error(); used to track data-path errors like SSL_ERROR_WANT_READ
* and SSL_ERROR_WANT_WRITE.
diff --git a/ssl/quic/quic_obj.c b/ssl/quic/quic_obj.c
index ffe6b1bcda..827b0c38b0 100644
--- a/ssl/quic/quic_obj.c
+++ b/ssl/quic/quic_obj.c
@@ -39,6 +39,7 @@ int ossl_quic_obj_init(QUIC_OBJ *obj,
obj->is_port_leader = is_port_leader;
obj->engine = engine;
obj->port = port;
+ obj->req_blocking_mode = QUIC_BLOCKING_MODE_INHERIT;
if (!obj_update_cache(obj))
goto err;
@@ -87,3 +88,38 @@ SSL_CONNECTION *ossl_quic_obj_get0_handshake_layer(QUIC_OBJ *obj)
return SSL_CONNECTION_FROM_SSL_ONLY(((QUIC_CONNECTION *)obj)->tls);
}
+
+/* (Returns a cached result.) */
+int ossl_quic_obj_can_support_blocking(const QUIC_OBJ *obj)
+{
+ QUIC_REACTOR *rtor = ossl_quic_obj_get0_reactor(obj);
+
+ return ossl_quic_reactor_can_poll_r(rtor)
+ || ossl_quic_reactor_can_poll_w(rtor);
+}
+
+int ossl_quic_obj_desires_blocking(const QUIC_OBJ *obj)
+{
+ unsigned int req_blocking_mode;
+
+ for (; (req_blocking_mode = obj->req_blocking_mode)
+ == QUIC_BLOCKING_MODE_INHERIT && obj->parent_obj != NULL;
+ obj = obj->parent_obj);
+
+ return req_blocking_mode != QUIC_BLOCKING_MODE_NONBLOCKING;
+}
+
+int ossl_quic_obj_blocking(const QUIC_OBJ *obj)
+{
+ if (!ossl_quic_obj_desires_blocking(obj))
+ return 0;
+
+ ossl_quic_engine_update_poll_descriptors(ossl_quic_obj_get0_engine(obj),
+ /*force=*/0);
+ return ossl_quic_obj_can_support_blocking(obj);
+}
+
+void ossl_quic_obj_set_blocking_mode(QUIC_OBJ *obj, unsigned int mode)
+{
+ obj->req_blocking_mode = mode;
+}
diff --git a/ssl/quic/quic_obj_local.h b/ssl/quic/quic_obj_local.h
index fa5b33f265..efd11bac25 100644
--- a/ssl/quic/quic_obj_local.h
+++ b/ssl/quic/quic_obj_local.h
@@ -103,6 +103,18 @@ struct quic_obj_st {
unsigned int init_done : 1;
unsigned int is_event_leader : 1;
unsigned int is_port_leader : 1;
+
+ /*
+ * Blocking mode configuration is handled generically through QUIC_OBJ as it
+ * by default inherits from the parent SSL object.
+ */
+ unsigned int req_blocking_mode : 2; /* QUIC_BLOCKING_MODE */
+};
+
+enum {
+ QUIC_BLOCKING_MODE_INHERIT,
+ QUIC_BLOCKING_MODE_NONBLOCKING,
+ QUIC_BLOCKING_MODE_BLOCKING
};
/*
@@ -220,6 +232,32 @@ ossl_quic_obj_get0_port_local(const QUIC_OBJ *obj)
}
/*
+ * Return 1 if we are currently capable of supporting blocking mode (regardless
+ * of whether it is actually turned on).
+ */
+int ossl_quic_obj_can_support_blocking(const QUIC_OBJ *obj);
+
+/*
+ * Returns 1 if we *desire* to do blocking I/O, regardless of whether it will
+ * actually be used (e.g. because it cannot currently be supported).
+ */
+int ossl_quic_obj_desires_blocking(const QUIC_OBJ *obj);
+
+/*
+ * Return 1 if an API call directly to the given object should use blocking mode
+ * and 0 otherwise.
+ */
+int ossl_quic_obj_blocking(const QUIC_OBJ *obj);
+
+/*
+ * Set the (requested) blocking mode, which might or might not be honoured
+ * depending on whether the BIO configuration can support it. Argument is a
+ * QUIC_BLOCKING_MODE value. If the top-level object in a QSO hierarchy is set
+ * to QUIC_BLOCKING_MODE_INHERIT, defaults to blocking mode.
+ */
+void ossl_quic_obj_set_blocking_mode(QUIC_OBJ *obj, unsigned int mode);
+
+/*
* Convenience Inlines
* ===================
*
diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c
index 64323c1c6e..936b97b5fe 100644
--- a/ssl/quic/quic_port.c
+++ b/ssl/quic/quic_port.c
@@ -95,6 +95,7 @@ static int port_init(QUIC_PORT *port)
ossl_list_port_insert_tail(&port->engine->port_list, port);
port->on_engine_list = 1;
+ port->bio_changed = 1;
return 1;
err:
@@ -238,16 +239,20 @@ static int port_update_poll_desc(QUIC_PORT *port, BIO *net_bio, int for_write)
return 1;
}
-int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port)
+int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port, int force)
{
int ok = 1;
+ if (!force && !port->bio_changed)
+ return 0;
+
if (!port_update_poll_desc(port, port->net_rbio, /*for_write=*/0))
ok = 0;
if (!port_update_poll_desc(port, port->net_wbio, /*for_write=*/1))
ok = 0;
+ port->bio_changed = 0;
return ok;
}
@@ -292,7 +297,7 @@ static void port_update_addressing_mode(QUIC_PORT *port)
port->addressed_mode_r = ((rcaps & BIO_DGRAM_CAP_PROVIDES_SRC_ADDR) != 0);
port->addressed_mode_w = ((wcaps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) != 0);
- ++port->net_bio_epoch;
+ port->bio_changed = 1;
}
int ossl_quic_port_is_addressed_r(const QUIC_PORT *port)
@@ -348,11 +353,6 @@ int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio)
return 1;
}
-uint64_t ossl_quic_port_get_net_bio_epoch(const QUIC_PORT *port)
-{
- return port->net_bio_epoch;
-}
-
/*
* QUIC Port: Channel Lifecycle
* ============================
diff --git a/ssl/quic/quic_port_local.h b/ssl/quic/quic_port_local.h
index 79336ebef5..0b954d6d1c 100644
--- a/ssl/quic/quic_port_local.h
+++ b/ssl/quic/quic_port_local.h
@@ -81,9 +81,6 @@ struct quic_port_st {
/* Port-level permanent errors (causing failure state) are stored here. */
ERR_STATE *err_state;
- /* Network BIO epoch. Increments whenever network BIO config changes. */
- uint64_t net_bio_epoch;
-
/* DCID length used for incoming short header packets. */
unsigned char rx_short_dcid_len;
/* For clients, CID length used for outgoing Initial packets. */
@@ -107,6 +104,9 @@ struct quic_port_st {
/* Are we using addressed mode (BIO_sendmmsg with non-NULL peer)? */
unsigned int addressed_mode_w : 1;
unsigned int addressed_mode_r : 1;
+
+ /* Has the BIO been changed since we last updated reactor pollability? */
+ unsigned int bio_changed : 1;
};
# endif