]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: spoe: Don't rely on stream's expiration to detect processing timeout
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 14 Mar 2024 09:21:56 +0000 (10:21 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 15 Mar 2024 08:09:22 +0000 (09:09 +0100)
On stream side, the SPOE filter relied on the stream's expiration date to be
woken up and be able to detect processing timeout. However, the stream
expiration date must not be updated this way. Mainly because it may be
overwritten at the end of process_stream(). In the worst case, it is set to
TICK_ETERNITY for any reason. In this case, it is impossible to detect the
SPOE filter must time out and abort the processing.

The right way to do is to set an analysis expiration date on the
corresponding channel, depending on the direction. This expiration date will
be used to compute the stream's expiration date at the end of
process_stream().

This patch may be related to issue #2478. It must be backported to all
stable versions.

src/flt_spoe.c

index d83eff9bf8d1d451c58c43e12bb00e82c375af02..cd65c0e49e6cd8bceec843e28a57d22ef4951b0b 100644 (file)
@@ -2625,6 +2625,8 @@ spoe_stop_processing(struct spoe_agent *agent, struct spoe_context *ctx)
 
        /* Reset processing timer */
        ctx->process_exp = TICK_ETERNITY;
+       ctx->strm->req.analyse_exp = TICK_ETERNITY;
+       ctx->strm->res.analyse_exp = TICK_ETERNITY;
 
        spoe_release_buffer(&ctx->buffer, &ctx->buffer_wait);
 
@@ -2683,8 +2685,10 @@ spoe_process_messages(struct stream *s, struct spoe_context *ctx,
 
                if (!tick_isset(ctx->process_exp)) {
                        ctx->process_exp = tick_add_ifset(now_ms, agent->timeout.processing);
-                       s->task->expire  = tick_first((tick_is_expired(s->task->expire, now_ms) ? 0 : s->task->expire),
-                                                     ctx->process_exp);
+                       if (dir == SMP_OPT_DIR_REQ)
+                               s->req.analyse_exp = ctx->process_exp;
+                       else
+                               s->res.analyse_exp = ctx->process_exp;
                }
                ret = spoe_start_processing(agent, ctx, dir);
                if (!ret)