BUG/MINOR: filters: Always set FLT_END analyser when CF_FLT_ANALYZE flag is set
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 13 Aug 2021 12:00:46 +0000 (14:00 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 20 Sep 2021 14:39:58 +0000 (16:39 +0200)
CF_FLT_ANALYZE flags may be set before the FLT_END analyser. Thus if an error is
triggered in the mean time, this may block the stream and prevent it to be
released. It is indeed a problem only for the response channel because the
response analysers may be skipped on early errors.

So, to prevent any issue, depending on the code path, the FLT_END analyser is
systematically set when the CF_FLT_ANALYZE flag is set.

This patch must be backported in all stable branches.

(cherry picked from commit 26eb5ea352c2ba8b25f014222773fb6946004bef)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit feca2a4534092158319d43c65dd23ffd61889a5a)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

src/filters.c

index b5e83ae..ca7c2df 100644 (file)
@@ -473,8 +473,10 @@ flt_stream_start(struct stream *s)
                if (FLT_OPS(filter)->stream_start && FLT_OPS(filter)->stream_start(s, filter) < 0)
                        return -1;
        }
-       if (strm_li(s) && (strm_li(s)->analysers & AN_REQ_FLT_START_FE))
+       if (strm_li(s) && (strm_li(s)->analysers & AN_REQ_FLT_START_FE)) {
                s->req.flags |= CF_FLT_ANALYZE;
+               s->req.analysers |= AN_RES_FLT_END;
+       }
        return 0;
 }
 
@@ -533,10 +535,14 @@ flt_set_stream_backend(struct stream *s, struct proxy *be)
                    FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
                        return -1;
        }
-       if (be->be_req_ana & AN_REQ_FLT_START_BE)
+       if (be->be_req_ana & AN_REQ_FLT_START_BE) {
                s->req.flags |= CF_FLT_ANALYZE;
-       if ((strm_fe(s)->fe_rsp_ana | be->be_rsp_ana) & (AN_RES_FLT_START_FE|AN_RES_FLT_START_BE))
+               s->req.analysers |= AN_RES_FLT_END;
+       }
+       if ((strm_fe(s)->fe_rsp_ana | be->be_rsp_ana) & (AN_RES_FLT_START_FE|AN_RES_FLT_START_BE)) {
                s->res.flags |= CF_FLT_ANALYZE;
+               s->res.analysers |= AN_RES_FLT_END;
+       }
 
        return 0;
 }
@@ -706,6 +712,7 @@ flt_start_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
 
        /* Set flag on channel to tell that the channel is filtered */
        chn->flags |= CF_FLT_ANALYZE;
+       chn->analysers |= AN_RES_FLT_END;
 
        RESUME_FILTER_LOOP(s, chn) {
                if (!(chn->flags & CF_ISRESP)) {