From 5d021c028eb5a2cec2af844cc597b69d39fc12c8 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 29 Oct 2025 16:20:11 +0100 Subject: [PATCH] BUG/MINOR: check: only try connection reuse for http-check rulesets 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 | 9 +++++---- src/cfgdiag.c | 17 ++++++++++++++++- src/tcpcheck.c | 7 +++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index ceeb94761..8987d9fec 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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. diff --git a/src/cfgdiag.c b/src/cfgdiag.c index c3b05e5d6..80c277ac1 100644 --- a/src/cfgdiag.c +++ b/src/cfgdiag.c @@ -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))) { diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 5be4a12ea..fa45f6d13 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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;