From 0225d42bceca561a5d678b0cc4fa982b6afabfea Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Thu, 9 Nov 2023 10:27:14 +0000 Subject: [PATCH] QUIC PORT: Formalise states of a port Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22674) --- include/internal/quic_port.h | 3 +++ ssl/quic/quic_port.c | 22 +++++++++++++++++++--- ssl/quic/quic_port_local.h | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h index 0b24338c2f..ea97b93392 100644 --- a/include/internal/quic_port.h +++ b/include/internal/quic_port.h @@ -130,6 +130,9 @@ int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port); /* For testing use. While enabled, ticking is not performed. */ void ossl_quic_port_set_inhibit_tick(QUIC_PORT *port, int inhibit); +/* Returns 1 if the port is running/healthy, 0 if it has failed. */ +int ossl_quic_port_is_running(const QUIC_PORT *port); + /* * Events * ====== diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 2b1e518c68..db1a352adf 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -88,6 +88,7 @@ static int port_init(QUIC_PORT *port) ossl_quic_reactor_init(&port->rtor, port_tick, port, ossl_time_zero()); port->rx_short_dcid_len = (unsigned char)rx_short_dcid_len; port->tx_init_dcid_len = INIT_DCID_LEN; + port->state = QUIC_PORT_STATE_RUNNING; return 1; err: @@ -109,6 +110,19 @@ static void port_cleanup(QUIC_PORT *port) port->lcidm = NULL; } +static void port_transition_failed(QUIC_PORT *port) +{ + if (port->state == QUIC_PORT_STATE_FAILED) + return; + + port->state = QUIC_PORT_STATE_FAILED; +} + +int ossl_quic_port_is_running(const QUIC_PORT *port) +{ + return port->state == QUIC_PORT_STATE_RUNNING; +} + QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port) { return &port->rtor; @@ -438,6 +452,10 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, QUIC_PKT_HDR hdr; QUIC_CHANNEL *ch = NULL, *new_ch = NULL; + /* Don't handle anything if we are no longer running. */ + if (!ossl_quic_port_is_running(port)) + goto undesirable; + if (dcid != NULL && ossl_quic_lcidm_lookup(port->lcidm, dcid, NULL, (void **)&ch)) { @@ -461,8 +479,6 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, if (port->tserver_ch == NULL) goto undesirable; - // TODO fsm - /* * We have got a packet for an unknown DCID. This might be an attempt to * open a new connection. @@ -526,7 +542,7 @@ void ossl_quic_port_raise_net_error(QUIC_PORT *port) { QUIC_CHANNEL *ch; - // TODO fsm + port_transition_failed(port); LIST_FOREACH(ch, ch, &port->channel_list) ossl_quic_channel_raise_net_error(ch); diff --git a/ssl/quic/quic_port_local.h b/ssl/quic/quic_port_local.h index bfcc5896e1..a2937beeaf 100644 --- a/ssl/quic/quic_port_local.h +++ b/ssl/quic/quic_port_local.h @@ -18,6 +18,19 @@ */ DECLARE_LIST_OF(ch, QUIC_CHANNEL); +/* A port is always in one of the following states: */ +enum { + /* Initial and steady state. */ + QUIC_PORT_STATE_RUNNING, + + /* + * Terminal state indicating port is no longer functioning. There are no + * transitions out of this state. May be triggered by e.g. a permanent + * network BIO error. + */ + QUIC_PORT_STATE_FAILED +}; + struct quic_port_st { OSSL_LIB_CTX *libctx; const char *propq; @@ -63,6 +76,9 @@ struct quic_port_st { /* For clients, CID length used for outgoing Initial packets. */ unsigned char tx_init_dcid_len; + /* Port state (QUIC_PORT_STATE_*). */ + unsigned int state : 1; + /* Is this port created to support multiple connections? */ unsigned int is_multi_conn : 1;