QUIC PORT: Formalise states of a port
authorHugo Landau <hlandau@openssl.org>
Thu, 9 Nov 2023 10:27:14 +0000 (10:27 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 21 Dec 2023 08:12:06 +0000 (08:12 +0000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22674)

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

index 0b24338c2fcbbb4c35f88c189b2e17f14b3a6e89..ea97b9339211050437b75c60c87aed0e76bb7ea5 100644 (file)
@@ -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
  * ======
index 2b1e518c681210f0543fb7d0922b51e6aacc782b..db1a352adffe935e07673bfea21fdb394502c51a 100644 (file)
@@ -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);
index bfcc5896e1411f1dd895f0cc17881cde862977ca..a2937beeaf9184dff61eb4774f99769f3c4ec7b0 100644 (file)
  */
 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;