]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: check: ensure QUIC checks configuration coherency
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 30 Oct 2025 16:29:47 +0000 (17:29 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 14 Nov 2025 12:42:08 +0000 (13:42 +0100)
QUIC is now supported on the backend side, thus it is possible to use it
with server checks. However, checks configuration can be quite
extensive, differing greatly from the server settings.

This patch ensures that QUIC checks are always performed under a
controlled context. Objectives are to avoid any crashes and ensure that
there is no suprise for users in respect to the configuration.

The first part of this patch ensures that QUIC checks can only be
activated on QUIC servers. Indeed, QUIC requires dedicated
initialization steps prior to its usage.

The other part of this patch disables QUIC usage when one or multiple
specific check connection settings are specified in the configuration,
diverging from the server settings. This is the simplest solution for
now and ensure that there is no hidden behavior to users. This means
that it's currently impossible to perform QUIC checks if other endpoints
that the server itself. However for now there is no real use-case for
this scenario.

Along with these changes, check-proto documentation is updated to
clarify QUIC checks behavior.

doc/configuration.txt
src/check.c
src/tcpcheck.c

index a88a72391b17ada54ebea9ee86bf6a04b88f1756..8b2cee98f84be5bbc0aaa7a80a97d93a1447b5fd 100644 (file)
@@ -17918,11 +17918,17 @@ check-proto <name>
     fcgi : mode=HTTP  side=BE     mux=FCGI  flags=HTX|HOL_RISK|NO_UPG
     h1   : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
     none : mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG
+    quic : mode=HTTP  side=FE|BE  mux=QUIC  flags=HTX|NO_UPG|FRAMED
 
   Idea behind this option is to bypass the selection of the best multiplexer's
   protocol for health-check connections established to this server.
   If not defined, the server one will be used, if set.
 
+  QUIC check configuration is not fully implemented yet. First, QUIC checks may
+  only be performed for QUIC servers. Second, if one or more check specific
+  connection parameters is specified on a QUIC server, check protocol will
+  fallback to TCP usage.
+
 check-sni-auto
   May be used in the following contexts: tcp, http, log
 
index 25b8920993fd8301ad375e6f4c9711397ffa059e..ba15a7283dd5934c22d77421657099574b63d0df 100644 (file)
@@ -1876,6 +1876,14 @@ int init_srv_check(struct server *srv)
                        ret |= ERR_ALERT | ERR_FATAL;
                }
        }
+       else {
+               if (srv->check.mux_proto == get_mux_proto(ist("quic"))) {
+                       ha_alert("config: %s '%s': QUIC checks on non-QUIC server '%s' is not yet supported.\n",
+                                proxy_type_str(srv->proxy), srv->proxy->id, srv->id);
+                       ret |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+       }
 
        /* We need at least a service port, a check port or the first tcp-check
         * rule must be a 'connect' one when checking an IPv4/IPv6 server.
index e353ef62de1df55cf402590d01dac9d5a6c99869..815a84099c80f38f9dddff50a8b2b7f6c97199d7 100644 (file)
@@ -1411,9 +1411,21 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
        *conn->dst = (is_addr(&connect->addr)
                      ? connect->addr
                      : (is_addr(&check->addr) ? check->addr : s->addr));
-       proto = s ?
-         protocol_lookup(conn->dst->ss_family, s->addr_type.proto_type, s->alt_proto) :
-         protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
+
+       if (s && srv_is_quic(s) && tcpcheck_use_nondefault_connect(check, connect)) {
+               /* For QUIC servers, fallback to TCP checks if any specific
+                * check connection parameter is set.
+                */
+               proto = protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
+               /* Also reset MUX protocol if set to QUIC. */
+               if (check->mux_proto == s->mux_proto)
+                       check->mux_proto = NULL;
+       }
+       else {
+               proto = s ?
+                 protocol_lookup(conn->dst->ss_family, s->addr_type.proto_type, s->alt_proto) :
+                 protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
+       }
 
        port = 0;
        if (connect->port)