From: Christopher Faulet Date: Mon, 11 Dec 2023 12:56:15 +0000 (+0100) Subject: BUG/MEDIUM: stconn: Block zero-copy forwarding if EOS/ERROR on consumer side X-Git-Tag: v3.0-dev1~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2421c6fa7d;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: stconn: Block zero-copy forwarding if EOS/ERROR on consumer side When the producer side (h1 for now) negociates with the consumer side to perform a zero-copy forwarding, we now consider the consumer side as blocked if it is closed and this was reported to the SE via a end-of-stream or a (pending) error. It is performed before calling ->nego_ff callback function, in se_nego_ff(). This way, all consumer are concerned automatically. The aim of this patch is to fix an issue with the QUIC mux. Indeed, it is unexpected to send a frame on an closed stream. This triggers a BUG_ON(). Other muxes are not affected but it remains useless to try to send data if the stream is closed. This patch should fix the issue #2372. It must be backported to 2.9. --- diff --git a/include/haproxy/stconn.h b/include/haproxy/stconn.h index 8bddae4193..9b5502a7df 100644 --- a/include/haproxy/stconn.h +++ b/include/haproxy/stconn.h @@ -511,6 +511,16 @@ static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t se->iobuf.flags &= ~IOBUF_FL_FF_BLOCKED; if (mux->nego_fastfwd && mux->done_fastfwd) { + /* Declare SE as blocked if EOS or an error was reported. + * This may happen if fast-forward was scheduled before the I/O processing on . + * Wake up in this case. + */ + if (se_fl_test(se, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING)) { + se->iobuf.flags |= IOBUF_FL_FF_BLOCKED; + tasklet_wakeup(se->sc->wait_event.tasklet); + goto end; + } + ret = mux->nego_fastfwd(se->sc, input, count, may_splice); if ((se->iobuf.flags & IOBUF_FL_FF_BLOCKED) && !(se->sc->wait_event.events & SUB_RETRY_SEND)) { /* The SC must be subs for send to be notify when some