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)
This commit is contained in:
Christopher Faulet 2026-07-07 09:03:46 +02:00
parent e9a4746f58
commit 69caa53530
2 changed files with 19 additions and 7 deletions

View 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

View 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.