diff --git a/include/haproxy/stconn-t.h b/include/haproxy/stconn-t.h index f418e95b5..c3468478e 100644 --- a/include/haproxy/stconn-t.h +++ b/include/haproxy/stconn-t.h @@ -39,6 +39,7 @@ enum iobuf_flags { * .done_fastfwd() on consumer side must take care of this flag */ IOBUF_FL_EOI = 0x00000010, /* A EOI was encountered on producer side */ + IOBUF_FL_FF_WANT_ROOM = 0x00000020, /* Producer need more room in the IOBUF to forward data */ }; /* Flags used */ diff --git a/include/haproxy/stconn.h b/include/haproxy/stconn.h index f60eaa88d..e6548a622 100644 --- a/include/haproxy/stconn.h +++ b/include/haproxy/stconn.h @@ -474,7 +474,7 @@ static inline size_t se_nego_ff(struct sedesc *se, struct buffer *input, size_t if (se_fl_test(se, SE_FL_T_MUX)) { const struct mux_ops *mux = se->conn->mux; - se->iobuf.flags &= ~IOBUF_FL_FF_BLOCKED; + se->iobuf.flags &= ~(IOBUF_FL_FF_BLOCKED|IOBUF_FL_FF_WANT_ROOM); if (mux->nego_fastfwd && mux->done_fastfwd) { /* Disable zero-copy forwarding if EOS or an error was reported. */ if (se_fl_test(se, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING)) { diff --git a/src/applet.c b/src/applet.c index 2ad931611..2bc3eb5ee 100644 --- a/src/applet.c +++ b/src/applet.c @@ -694,7 +694,7 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags) if (se_fl_test(appctx->sedesc, SE_FL_WANT_ROOM)) { /* The applet request more room, report the info at the iobuf level */ - sdo->iobuf.flags |= IOBUF_FL_FF_BLOCKED; + sdo->iobuf.flags |= (IOBUF_FL_FF_BLOCKED|IOBUF_FL_FF_WANT_ROOM); TRACE_STATE("waiting for more room", APPLET_EV_RECV|APPLET_EV_BLK, appctx); } @@ -716,7 +716,7 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags) /* else */ /* applet_have_more_data(appctx); */ - if (se_done_ff(sdo) != 0 || !(sdo->iobuf.flags & IOBUF_FL_FF_BLOCKED)) { + if (se_done_ff(sdo) != 0 || !(sdo->iobuf.flags & (IOBUF_FL_FF_BLOCKED|IOBUF_FL_FF_WANT_ROOM))) { /* Something was forwarding or the consumer states it is not * blocked anyore, don't reclaim more room */ se_fl_clr(appctx->sedesc, SE_FL_WANT_ROOM); diff --git a/src/mux_quic.c b/src/mux_quic.c index 64b8ac0a3..8272b93da 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -3049,11 +3049,12 @@ static size_t qmux_strm_done_ff(struct stconn *sc) if (!(qcs->flags & QC_SF_FIN_STREAM) && !sd->iobuf.data) { TRACE_STATE("no data sent", QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); - /* There is nothing to forward and the SD is blocked. Try to - * release the TXBUF to retry. + /* There is nothing to forward and the SD was blocked after a + * successful nego by the producer. We can try to release the + * TXBUF to retry. In this case, the TX buf MUST exist. */ - if ((qcs->sd->iobuf.flags & IOBUF_FL_FF_BLOCKED) && !qcc_release_stream_txbuf(qcs)) - qcs->sd->iobuf.flags &= ~IOBUF_FL_FF_BLOCKED; + if ((qcs->sd->iobuf.flags & IOBUF_FL_FF_WANT_ROOM) && !qcc_release_stream_txbuf(qcs)) + qcs->sd->iobuf.flags &= ~(IOBUF_FL_FF_BLOCKED|IOBUF_FL_FF_WANT_ROOM); goto end; }