From: Christopher Faulet Date: Tue, 7 Jul 2026 07:03:46 +0000 (+0200) Subject: BUG/MINOR: stream: Fix custom timeouts initialization when setting backend X-Git-Tag: v3.5-dev2~19 X-Git-Url: http://git.kaiwu.me/%22data:,/static/$%7BGITURL%7D/1?a=commitdiff_plain;h=69caa535300fce261dbab2d7fc3b841b882ae757;p=haproxy.git BUG/MINOR: stream: Fix custom timeouts initialization when setting backend 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) --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 5ff19f926..4e269c488 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -16679,7 +16679,11 @@ set-timeout { client | connect | queue | server | tarpit | tunnel } { 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 diff --git a/src/stream.c b/src/stream.c index 2f8dacd1c..24cdb7230 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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.