#include <haproxy/connection.h>
#include <haproxy/fd.h>
#include <haproxy/freq_ctr.h>
+#include <haproxy/frontend.h>
#include <haproxy/global.h>
#include <haproxy/h3.h>
#include <haproxy/hq_interop.h>
int server, int token, void *owner)
{
int i;
- struct quic_conn *qc;
+ struct quic_conn *qc = NULL;
struct listener *l = NULL;
struct quic_cc_algo *cc_algo = NULL;
+ unsigned int next_actconn = 0;
TRACE_ENTER(QUIC_EV_CONN_INIT);
+ next_actconn = increment_actconn();
+ if (!next_actconn) {
+ _HA_ATOMIC_INC(&maxconn_reached);
+ TRACE_STATE("maxconn reached", QUIC_EV_CONN_INIT);
+ goto err;
+ }
+
qc = pool_alloc(pool_head_quic_conn);
if (!qc) {
TRACE_ERROR("Could not allocate a new connection", QUIC_EV_CONN_INIT);
goto err;
}
+ /* Now that quic_conn instance is allocated, quic_conn_release() will
+ * ensure global accounting is decremented.
+ */
+ next_actconn = 0;
+
/* Initialize in priority qc members required for a safe dealloc. */
qc->nictx = NULL;
/* Prevents these CID to be dumped by TRACE() calls */
err:
quic_conn_release(qc);
+
+ /* Decrement global counters. Done only for errors happening before or
+ * on pool_head_quic_conn alloc. All other cases are covered by
+ * quic_conn_release().
+ */
+ if (next_actconn)
+ _HA_ATOMIC_DEC(&actconn);
+
TRACE_LEAVE(QUIC_EV_CONN_INIT);
return NULL;
}
qc_free_ssl_sock_ctx(&qc->xprt_ctx);
}
- /* Decrement on quic_conn free. quic_cc_conn instances are not counted
- * into global counters because they are designed to run for a limited
- * time with a limited memory.
- */
- _HA_ATOMIC_DEC(&actconn);
-
/* in the unlikely (but possible) case the connection was just added to
* the accept_list we must delete it from there.
*/
pool_free(pool_head_quic_conn, qc);
qc = NULL;
+ /* Decrement global counters when quic_conn is deallocated.
+ * quic_cc_conn instances are not accounted as they run for a short
+ * time with limited ressources.
+ */
+ _HA_ATOMIC_DEC(&actconn);
+
TRACE_PROTO("QUIC conn. freed", QUIC_EV_CONN_FREED, qc);
leave:
TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
#include <haproxy/quic_rx.h>
-#include <haproxy/frontend.h>
#include <haproxy/h3.h>
#include <haproxy/list.h>
#include <haproxy/ncbuf.h>
struct quic_conn *qc = NULL;
struct proxy *prx;
struct quic_counters *prx_counters;
- unsigned int next_actconn = 0, next_sslconn = 0;
+ unsigned int next_sslconn = 0;
TRACE_ENTER(QUIC_EV_CONN_LPKT);
pkt->saddr = dgram->saddr;
ipv4 = dgram->saddr.ss_family == AF_INET;
- next_actconn = increment_actconn();
- if (!next_actconn) {
- _HA_ATOMIC_INC(&maxconn_reached);
- TRACE_STATE("drop packet on maxconn reached",
- QUIC_EV_CONN_LPKT, NULL, NULL, NULL, pkt->version);
- goto err;
- }
-
next_sslconn = increment_sslconn();
if (!next_sslconn) {
TRACE_STATE("drop packet on sslconn reached",
goto err;
}
- /* Now quic_conn is allocated. If a future error
- * occurred it will be freed with quic_conn_release()
- * which also ensure actconn/sslconns is decremented.
- * Reset guard values to prevent a double decrement.
- */
- next_sslconn = next_actconn = 0;
-
+ next_sslconn = 0;
/* Compute and store into the quic_conn the hash used to compute extra CIDs */
if (quic_hash64_from_cid)
qc->hash64 = quic_hash64_from_cid(conn_id->cid.data, conn_id->cid.len,
else
HA_ATOMIC_INC(&prx_counters->dropped_pkt);
- /* Reset active conn counter if needed. */
- if (next_actconn)
- _HA_ATOMIC_DEC(&actconn);
if (next_sslconn)
_HA_ATOMIC_DEC(&global.sslconns);