]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: tcpcheck: Allow connection reuse without prior traffic
authorDaniel Lenar <dlenar@vailsys.com>
Sat, 18 Apr 2026 02:29:45 +0000 (21:29 -0500)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 24 Apr 2026 09:39:51 +0000 (11:39 +0200)
New connections created by tcpcheck for are marked as private, making
them ineligible for insertion into the server-side connection pool, even
when check-reuse-pool is activated. Thus, connection reuse for health
checks would only work when the pool had already been populated by
regular (non-check) traffic.

Change this behavior so that a new check connection is not flagged as
private anymore when check-reuse-pool is requested. As a result, on
detach, instead of being freed, the connection will be inserted in the
idle pool and will be eligible for reuse, both for regular traffic and
checks.

This change can be useful to ensure that a server idle pool is never
completely empty when check-reuse-pool is active. Additionnally, it is
also necessary to ensure that check reuse is really effective when
connection parameters are different between checks and regular traffic,
resulting in a different reuse hash.

The previous behavior could be considered as a bug to a certain extents.
The current patch should be harmless for default configuration, but it
can be a significant improvment for users who want to perform reuse for
checks. Thus, it should be backported up to 3.2.

src/tcpcheck.c

index 5331619f126ea12d1a59713f7713258f5cf25d59..9822f2cdc97ee1aaff557e66695b729e7d35ecf3 100644 (file)
@@ -1284,7 +1284,8 @@ 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;
+       int check_type, check_reuse;
+       int64_t hash = 0;
 #ifdef USE_OPENSSL
        struct ist sni = IST_NULL;
 #endif
@@ -1292,6 +1293,11 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
        TRACE_ENTER(CHK_EV_TCPCHK_CONN, check);
 
        check_type = check->tcpcheck->rs->flags & TCPCHK_RULES_PROTO_CHK;
+       /* Determine if reuse can be used for this check. */
+       check_reuse =
+         check_type == TCPCHK_RULES_HTTP_CHK && check->reuse_pool &&
+         !tcpcheck_use_nondefault_connect(check, connect) &&
+         !srv_is_transparent(s) ? 1 : 0;
 
        next = get_next_tcpcheck_rule(check->tcpcheck->rs, rule);
 
@@ -1329,13 +1335,9 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
                }
        }
 
-       /* 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)) {
+       if (check_reuse) {
                struct ist pool_conn_name = IST_NULL;
                struct sockaddr_storage *dst, dst_tmp;
-               int64_t hash;
                int conn_err;
 
                TRACE_DEVEL("trying connection reuse for check", CHK_EV_TCPCHK_CONN, check);
@@ -1517,7 +1519,11 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
        if (status != SF_ERR_NONE)
                goto fail_check;
 
-       conn_set_private(conn);
+       if (check_reuse)
+               conn->hash_node.key = hash;
+       else
+               conn_set_private(conn);
+
        conn->ctx = check->sc;
 
 #ifdef USE_OPENSSL