]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stconn: Disable 0-copy forwarding for filters altering the payload
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 May 2025 12:19:52 +0000 (14:19 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 16 May 2025 13:11:37 +0000 (15:11 +0200)
It is especially a problem with Lua filters, but it is important to disable
the 0-copy forwarding if a filter alters the payload, or at least to be able
to disable it. While the filter is registered on the data filtering, it is
not an issue (and it is the common case) because, there is now way to
fast-forward data at all. But it may be an issue if a filter decides to
alter the payload and to unregister from data filtering. In that case, the
0-copy forwarding can be re-enabled in a hardly precdictable state.

To fix the issue, a SC flags was added to do so. The HTTP compression filter
set it and lua filters too if the body length is changed (via
HTTPMessage.set_body_len()).

Note that it is an issue because of a bad design about the HTX. Many info
about the message are stored in the HTX structure itself. It must be
refactored to move several info to the stream-endpoint descriptor. This
should ease modifications at the stream level, from filter or a TCP/HTTP
rules.

This should be backported as far as 3.0. If necessary, it may be backported
on lower versions, as far as 2.6. In that case, it must be reviewed and
adapted.

include/haproxy/stconn-t.h
src/flt_http_comp.c
src/hlua.c
src/stconn.c

index 52fa3e88e90c7bf9b44de84f14931b195a967841..08326df91d86e1d4d6715a10d123e6a996a37773 100644 (file)
@@ -206,6 +206,7 @@ enum sc_flags {
 
        SC_FL_EOS           = 0x00040000,  /* End of stream was reached (from down side to up side) */
        SC_FL_HAVE_BUFF     = 0x00080000,  /* A buffer is ready, flag will be cleared once allocated */
+       SC_FL_NO_FASTFWD    = 0x00100000,  /* disable data fast-forwarding */
 };
 
 /* This function is used to report flags in debugging tools. Please reflect
index 43e32028422a78f0afa34211888f3b1f7bbbf308..265e47280fdfbcda577cdb1b0f311cf1bb240430 100644 (file)
@@ -515,6 +515,7 @@ set_compression_header(struct comp_state *st, struct stream *s, struct http_msg
                        goto error;
        }
 
+       chn_prod(msg->chn)->flags |= SC_FL_NO_FASTFWD;
        return 1;
 
   error:
index 9bb1fe930613b7fe859e946f400cbddce426715a..7ac8fc604644bc23d92a25760698a6a741f940bd 100644 (file)
@@ -7262,6 +7262,7 @@ __LJMP static int hlua_http_msg_set_body_len(lua_State *L)
        }
 
   success:
+       chn_prod(msg->chn)->flags |= SC_FL_NO_FASTFWD;
        lua_pushboolean(L, 1);
        return 1;
 
index ddb56eff88ab728ab7a282392d01e8d255adfcbd..be626447755062ffdb68a77534b58705ce67d208 100644 (file)
@@ -604,6 +604,7 @@ static inline int sc_cond_forward_shut(struct stconn *sc)
 static inline int sc_is_fastfwd_supported(struct stconn *sc)
 {
        return (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD) &&
+               !(sc->flags & SC_FL_NO_FASTFWD) &&
                sc_ep_test(sc, SE_FL_MAY_FASTFWD_PROD) &&
                sc_ep_test(sc_opposite(sc), SE_FL_MAY_FASTFWD_CONS) &&
                sc_ic(sc)->to_forward);