]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic: count quic_conn for global sslconns
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 25 Oct 2023 13:38:50 +0000 (15:38 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 26 Oct 2023 13:35:58 +0000 (15:35 +0200)
Similar to the previous commit which check for maxconn before allocating
a QUIC connection, this patch checks for maxsslconn at the same step.
This is necessary as a QUIC connection cannot run without a SSL context.

This should be backported up to 2.6. It relies on the following patch :
  "BUG/MINOR: ssl: use a thread-safe sslconns increment"

include/haproxy/quic_ssl.h
src/quic_rx.c
src/quic_ssl.c

index f31cafc3d83f3c4dc89a80962f4bb80fc34e72de..f2518ba8a0fba2bcc47a56f0a449e1164751b2d7 100644 (file)
@@ -43,6 +43,8 @@ static inline void qc_free_ssl_sock_ctx(struct ssl_sock_ctx **ctx)
        SSL_free((*ctx)->ssl);
        pool_free(pool_head_quic_ssl_sock_ctx, *ctx);
        *ctx = NULL;
+
+       _HA_ATOMIC_DEC(&global.sslconns);
 }
 
 #endif /* _HAPROXY_QUIC_SSL_H */
index b421c6cd973747abd54a516e8162f28272a0a831..ad6f62c81213e73d41c63556a5161a54f8b7ac99 100644 (file)
@@ -26,6 +26,7 @@
 #include <haproxy/quic_tls.h>
 #include <haproxy/quic_trace.h>
 #include <haproxy/quic_tx.h>
+#include <haproxy/ssl_sock.h>
 #include <haproxy/trace.h>
 
 DECLARE_POOL(pool_head_quic_conn_rxbuf, "quic_conn_rxbuf", QUIC_CONN_RX_BUFSZ);
@@ -1902,7 +1903,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
        struct quic_conn *qc = NULL;
        struct proxy *prx;
        struct quic_counters *prx_counters;
-       unsigned int next_actconn = 0;
+       unsigned int next_actconn = 0, next_sslconn = 0;
 
        TRACE_ENTER(QUIC_EV_CONN_LPKT);
 
@@ -1968,6 +1969,13 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
                                goto err;
                        }
 
+                       next_sslconn = increment_sslconn();
+                       if (!next_sslconn) {
+                               TRACE_STATE("drop packet on sslconn reached",
+                                           QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
+                               goto err;
+                       }
+
                        /* Generate the first connection CID. This is derived from the client
                         * ODCID and address. This allows to retrieve the connection from the
                         * ODCID without storing it in the CID tree. This is an interesting
@@ -1988,10 +1996,10 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
 
                        /* Now quic_conn is allocated. If a future error
                         * occurred it will be freed with quic_conn_release()
-                        * which also ensure actconn is decremented.
-                        * Reset guard value to prevent a double decrement.
+                        * which also ensure actconn/sslconns is decremented.
+                        * Reset guard values to prevent a double decrement.
                         */
-                       next_actconn = 0;
+                       next_sslconn = next_actconn = 0;
 
                        /* Compute and store into the quic_conn the hash used to compute extra CIDs */
                        if (quic_hash64_from_cid)
@@ -2046,6 +2054,8 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
        /* Reset active conn counter if needed. */
        if (next_actconn)
                _HA_ATOMIC_DEC(&actconn);
+       if (next_sslconn)
+               _HA_ATOMIC_DEC(&global.sslconns);
 
        TRACE_LEAVE(QUIC_EV_CONN_LPKT);
        return NULL;
index 9cf9b85fff17a95e36a373b17daac2f8386adadf..1a0d5d64dfb9cc31eaa54248ddb7251162d08ed6 100644 (file)
@@ -726,6 +726,9 @@ int qc_alloc_ssl_sock_ctx(struct quic_conn *qc)
        /* Store the allocated context in <qc>. */
        qc->xprt_ctx = ctx;
 
+       /* global.sslconns is already incremented on INITIAL packet parsing. */
+       _HA_ATOMIC_INC(&global.totalsslconns);
+
        ret = 1;
  leave:
        TRACE_LEAVE(QUIC_EV_CONN_NEW, qc);