]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: sink: retry attempt for sft server may never occur
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 2 Oct 2025 19:40:57 +0000 (21:40 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Fri, 3 Oct 2025 12:31:05 +0000 (14:31 +0200)
Since 9561b9fb6 ("BUG/MINOR: sink: add tempo between 2 connection
attempts for sft servers"), there is a possibility that the tempo we use
to schedule the task expiry may point to TICK_ETERNITY as we add ticks to
tempo with a simple addition that doesn't take care of potential wrapping.

When this happens (although relatively rare, since now_ms only wraps every
49.7 days, but a forced wrap occurs 20 seconds after haproxy is started
so it is more likely to happen there), the process_sink_forward() task
expiry being set to TICK_ETERNITY, it may never be called again, this
is especially true if the ring section only contains a single server.

To fix the issue, we must use tick_add() helper function to set the tempo
value and this way we ensure that the value will never be TICK_ETERNITY.

It must be backported everywhere 9561b9fb6 was backported (up to 2.6
it seems).

src/sink.c

index 7a31d38273a04d374f9e94d141419ac541bc9406..03f57abd8b327ec6181ca3d6278483dcd3cf8cff 100644 (file)
@@ -701,7 +701,7 @@ static struct task *process_sink_forward(struct task * task, void *context, unsi
                         * establishment attempt per second.
                         */
                        if (!sft->appctx) {
-                               uint tempo = sft->last_conn + MS_TO_TICKS(1000);
+                               int tempo = tick_add(sft->last_conn, MS_TO_TICKS(1000));
 
                                if (sft->last_conn == TICK_ETERNITY || tick_is_expired(tempo, now_ms))
                                        sft->appctx = sink_forward_session_create(sink, sft);