]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: stream: Fix custom timeouts initialization when setting backend
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 7 Jul 2026 07:03:46 +0000 (09:03 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 8 Jul 2026 06:52:07 +0000 (08:52 +0200)
Timeouts may be overwritten via the action "set-timeout". Client timeout is
supported on frontends, connect/queue/tunnel/server timeouts are supported
on backends and tarpit timeout is supported on both.

However, there is an issue with the listener. In that case, the action is
always executed in the frontend context and the backend-side timeouts are
then reset, when the backend is selected. If it is another backend, it is
logical. But most of time, the backend is unchanged. And in that case, these
timeouts must be preserved.

Documentation of set-timeout action was improved.

This patch should be backported to all supported versions. Be carefull, all
timeouts are not supported in 3.3 and lower (3.3->3.0: server/tunnel/client
- 2.8->2.6: server/tunnel)

doc/configuration.txt
src/stream.c

index 5ff19f9262d5c3ffdcda0f2983a85c4c30a57854..4e269c488a8acb9ba8ced948d8ad891ed17c6ad6 100644 (file)
@@ -16679,7 +16679,11 @@ set-timeout { client | connect | queue | server | tarpit | tunnel } { <timeout>
   the backend side and thus this rule is only available for the proxies with
   backend capabilities. Likewise, client timeout is only relevant for frontend
   side. Tarpit timeout is available to both sides. The timeout value must be
-  non-null to obtain the expected results.
+  non-null to obtain the expected results. When the action is used for a
+  listener, it is evaluated in the frontend context. So custom values for
+  backend-side timeouts are conserved only if stream is not routed to a
+  different backend, via a use-backend rule for instance. Otherwise the default
+  values of the selected backend will be preset.
 
   Example:
     http-request set-timeout tunnel 5s
index 2f8dacd1c1a3d44b142f307c2fc62a2e3cb71032..24cdb723061c21ab1ff0b914d046c582e5a3e906 100644 (file)
@@ -1263,17 +1263,25 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an
 
        /* Se the max connection retries for the stream. may be overwritten later */
        s->max_retries = s->be->conn_retries;
-
-       /* Set the queue and connect timeouts. May be overwritten later */
-       s->connect_timeout = s->be->timeout.connect;
-       s->queue_timeout = s->be->timeout.queue;
-
-       /* we don't want to run the TCP or HTTP filters again if the backend has not changed */
        if (fe == s->be) {
+               /* we don't want to run the TCP or HTTP filters again if the backend has not changed */
                s->req.analysers &= ~AN_REQ_INSPECT_BE;
                s->req.analysers &= ~AN_REQ_HTTP_PROCESS_BE;
                s->req.analysers &= ~AN_REQ_FLT_START_BE;
        }
+       else {
+               s->scb->ioto = TICK_ETERNITY;
+               s->connect_timeout = TICK_ETERNITY;
+               s->queue_timeout = TICK_ETERNITY;
+               s->tunnel_timeout = TICK_ETERNITY;
+       }
+
+
+       /* Set the queue and connect timeouts if not set. May be overwritten later if backend has changed */
+       if (!tick_isset(s->connect_timeout))
+               s->connect_timeout = s->be->timeout.connect;
+       if (!tick_isset(s->queue_timeout))
+               s->queue_timeout = s->be->timeout.queue;
 
        /* as soon as we know the backend, we must check if we have a matching forced or ignored
         * persistence rule, and report that in the stream.