]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: mux: add sctl MUX_SCTL_GET_HDNG_FOUND/FIXED to report hardening results
authorWilly Tarreau <w@1wt.eu>
Tue, 10 Nov 2026 10:19:20 +0000 (11:19 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 12 Nov 2026 17:12:23 +0000 (18:12 +0100)
The H1, H2 and H3 streams store in their http_hdng_chk what HTTP hardening
conditions were met (found) and what rules were enforced (fixed). This adds
two new mux stream controls to retrieve them as uint32_t, so that they can
be reported by sample fetches and logged:

  - MUX_SCTL_GET_HDNG_FOUND returns hdng_chk.found
  - MUX_SCTL_GET_HDNG_FIXED returns hdng_chk.fixed

They're implemented in the H1 and H2 muxes. The QUIC mux passes them to
the application layer's sctl() after checking that it's H3, and h3_sctl()
implements them. Other muxes return -1 as they don't support hardening.

include/haproxy/connection-t.h
src/h3.c
src/mux_h1.c
src/mux_h2.c
src/mux_quic.c

index 075152d2fbe8091db68e0d6fd392a5cac05c63fe..45c404fcafa6362817d103b47489bbbd02f559fd 100644 (file)
@@ -400,6 +400,8 @@ enum mux_sctl_type {
        MUX_SCTL_SID, /* Return the mux stream ID as output, as a signed 64bits integer */
        MUX_SCTL_DBG_STR,    /* takes a mux_sctl_dbg_str_ctx argument, reads flags and returns debug info */
        MUX_SCTL_TEVTS, /* Return the termination events log of the mux stream */
+       MUX_SCTL_GET_HDNG_FOUND, /* Return in output the HTTP_HRD_* hardening conditions met, as an uint32_t */
+       MUX_SCTL_GET_HDNG_FIXED, /* Return in output the HTTP_HRD_* hardening rules enforced, as an uint32_t */
 };
 
 #define MUX_SCTL_DBG_STR_L_MUXS  0x00000001  // info from mux stream
index 323952162b8a10d0aaf3fd94f88cc726327b0152..32a7055c294193438a02159bbe6644f9e61cd951 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -3939,7 +3939,19 @@ static void h3_stats_inc_err_cnt(void *ctx, int err_code)
  */
 static int h3_sctl(struct qcs *qcs, enum mux_sctl_type mux_sctl, void *output)
 {
+       const struct h3s *h3s = qcs->ctx;
+
        switch (mux_sctl) {
+       case MUX_SCTL_GET_HDNG_FOUND:
+               if (!h3s)
+                       return -1;
+               *((uint32_t *)output) = h3s->hdng_chk.found;
+               return 0;
+       case MUX_SCTL_GET_HDNG_FIXED:
+               if (!h3s)
+                       return -1;
+               *((uint32_t *)output) = h3s->hdng_chk.fixed;
+               return 0;
        default:
                return -1;
        }
index 032e1865d1429cbe76f98d022b9506b52a4c787d..55115878bfef32335434697ee679a56a772a06a0 100644 (file)
@@ -5770,6 +5770,12 @@ static int h1_sctl(struct stconn *sc, enum mux_sctl_type mux_sctl, void *output)
                return ret;
        case MUX_SCTL_TEVTS:
                return h1s->sd->term_evts_log;
+       case MUX_SCTL_GET_HDNG_FOUND:
+               *((uint32_t *)output) = h1s->hdng_chk.found;
+               return ret;
+       case MUX_SCTL_GET_HDNG_FIXED:
+               *((uint32_t *)output) = h1s->hdng_chk.fixed;
+               return ret;
        default:
                return -1;
        }
index 39fd6cfb4fa73af0c75753a3b087ab9ca7243f2e..1a4fa4b5e949c8c1ba20ce70933f0c737cdbe417 100644 (file)
@@ -5809,6 +5809,12 @@ static int h2_sctl(struct stconn *sc, enum mux_sctl_type mux_sctl, void *output)
                return ret;
        case MUX_SCTL_TEVTS:
                return h2s->sd->term_evts_log;
+       case MUX_SCTL_GET_HDNG_FOUND:
+               *((uint32_t *)output) = h2s->hdng_chk.found;
+               return ret;
+       case MUX_SCTL_GET_HDNG_FIXED:
+               *((uint32_t *)output) = h2s->hdng_chk.fixed;
+               return ret;
 
        default:
                return -1;
index ba9d4599973db12999dadd1724b52310f51a61c3..9a72d7ca54b4bae427b54b7ed6150190de52cb41 100644 (file)
@@ -4920,7 +4920,7 @@ static int qcm_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *out
 static int qcm_sctl(struct stconn *sc, enum mux_sctl_type mux_sctl, void *output)
 {
        int ret = 0;
-       const struct qcs *qcs = __sc_mux_strm(sc);
+       struct qcs *qcs = __sc_mux_strm(sc);
        const struct qcc *qcc = qcs->qcc;
        const struct connection *conn = qcc->conn;
        union mux_sctl_dbg_str_ctx *dbg_ctx;
@@ -4957,6 +4957,13 @@ static int qcm_sctl(struct stconn *sc, enum mux_sctl_type mux_sctl, void *output
        case MUX_SCTL_TEVTS:
                return qcs->sd->term_evts_log;
 
+       case MUX_SCTL_GET_HDNG_FOUND:
+       case MUX_SCTL_GET_HDNG_FIXED:
+               /* only known to the H3 layer */
+               if (qcc->app_ops != &h3_ops || !qcc->app_ops->sctl)
+                       return -1;
+               return qcc->app_ops->sctl(qcs, mux_sctl, output);
+
        default:
                return -1;
        }