]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: check: only try connection reuse for http-check rulesets
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 29 Oct 2025 15:20:11 +0000 (16:20 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 14 Nov 2025 09:44:03 +0000 (10:44 +0100)
In 3.2, a new server keyword "check-reuse-pool" has been introduced. It
allows to reuse a connection for a new check, instead of always
initializing a new one. This is only performed if the check does not
rely on specific connection parameters differing from the server.

This patch further restricts reuse for checks only when an HTTP ruleset
is used at the backend level. Indeed, reusing a connection outside of
HTTP is an undefined behavior. The impact of this bug is unknown and
depends on the proxy/server configuration. In the case of an HTTP
backend with non-HTTP checks, check-reuse-pool would probably cause a
drop in reuse rate.

Along this change, implement a new diagnostic warning on servers to
report that check-reuse-pool cannot apply due to an incompatible check
type.

This must be backported up to 3.2.

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

index ceeb947612f853516044d3aad5e464ec40f40b55..8987d9fec9ea3a72de1fff2f202f7c4dd078ffd4 100644 (file)
@@ -17829,11 +17829,12 @@ check-reuse-pool
   This option permits checks to reuse idle connections if available instead of
   opening a dedicated one. The connection is reinserted in the pool on check
   completion. The main objective is to limit the number of connections opening
-  and closure on a specific server.
+  and closure on a specific server. This feature is compatible only with
+  http-check rulesets. It is silently ignored for other check types.
 
-  Note that for configuration simplicity, this option is silently ignored if
-  any specific check connect option is defined, either on the server line or
-  via a custom tcp-check connect rule.
+  For configuration simplicity, this option is silently ignored if any specific
+  check connect option is defined, either on the server line or via a custom
+  tcp-check connect rule.
 
   This option is automatically enabled for servers acting as passive reverse
   HTTP gateway, as for those servers connect is only supported through reuse.
index c3b05e5d6c37f34fca9ab7c814c88551b2532218..80c277ac182df384570ff00c1a13913110d92558 100644 (file)
@@ -65,6 +65,19 @@ static void srv_diag_cookies(int *ret, struct server *srv, struct eb_root *cooki
        }
 }
 
+/* Reports a diag if check-reuse-pool is active while backend check ruleset is
+ * non HTTP.
+ */
+static void srv_diag_check_reuse(int *ret, struct server *srv, struct proxy *px)
+{
+       if (srv->do_check && srv->check.reuse_pool) {
+               if ((px->tcpcheck_rules.flags & TCPCHK_RULES_PROTO_CHK) != TCPCHK_RULES_HTTP_CHK) {
+                       diag_warning(ret, "parsing [%s:%d] : 'server %s': check-reuse-pool is ineffective for non http-check rulesets.\n",
+                                    srv->conf.file, srv->conf.line, srv->id);
+               }
+       }
+}
+
 /* Perform a series of diagnostics on every servers from the configuration. */
 static void run_servers_diag(int *ret)
 {
@@ -74,8 +87,10 @@ static void run_servers_diag(int *ret)
        struct server *srv;
 
        for (px = proxies_list; px; px = px->next) {
-               for (srv = px->srv; srv; srv = srv->next)
+               for (srv = px->srv; srv; srv = srv->next) {
                        srv_diag_cookies(ret, srv, &cookies_tree);
+                       srv_diag_check_reuse(ret, srv, px);
+               }
 
                /* clear the cookies tree before passing to the next proxy */
                while ((cookie_node = ebpt_first(&cookies_tree))) {
index 5be4a12eaea68a4f7febdc0019b8861e548714b1..fa45f6d139592f30f1777b47c42445364d97a686 100644 (file)
@@ -1270,9 +1270,12 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
        struct tcpcheck_rule *next;
        struct buffer *auto_sni = NULL;
        int status, port;
+       int check_type;
 
        TRACE_ENTER(CHK_EV_TCPCHK_CONN, check);
 
+       check_type = check->tcpcheck_rules->flags & TCPCHK_RULES_PROTO_CHK;
+
        next = get_next_tcpcheck_rule(check->tcpcheck_rules, rule);
 
        /* current connection already created, check if it is established or not */
@@ -1309,8 +1312,8 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
                }
        }
 
-
-       if (!(check->state & CHK_ST_AGENT) && check->reuse_pool &&
+       /* For http-check rulesets connection reuse may be used (check-reuse-pool). */
+       if (check_type == TCPCHK_RULES_HTTP_CHK && check->reuse_pool &&
            !tcpcheck_use_nondefault_connect(check, connect) &&
            !srv_is_transparent(s)) {
                struct ist pool_conn_name = IST_NULL;