From 36282ae348a70230d7b22a2fa714590cb9090106 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 3 Feb 2026 07:55:31 +0100 Subject: [PATCH] MEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size Today, it is useless to check the buffers size before performing a 0-copy in muxes when data are sent, but it will be mandatory when the large buffers support on channels will be added. Indeed, muxes will still rely on normal buffers, so we must take care to never swap buffers of different size. --- src/h3.c | 2 +- src/mux_fcgi.c | 3 ++- src/mux_h1.c | 6 ++++-- src/mux_h2.c | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/h3.c b/src/h3.c index 849bba2a6..bc479ce40 100644 --- a/src/h3.c +++ b/src/h3.c @@ -2678,7 +2678,7 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx, * buffer to perform zero-copy. This is only achievable if MUX buffer * is currently empty. */ - if (unlikely(fsize == count && + if (unlikely(fsize == count && b_size(res) == b_size(buf) && !b_data(res) && htx_nbblks(htx) == 1 && type == HTX_BLK_DATA)) { void *old_area = res->area; diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 45b546f01..33153fffa 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -2151,7 +2151,8 @@ static size_t fcgi_strm_send_stdin(struct fcgi_conn *fconn, struct fcgi_strm *fs goto end; type = htx_get_blk_type(blk); size = htx_get_blksz(blk); - if (unlikely(size == count && htx_nbblks(htx) == 1 && type == HTX_BLK_DATA)) { + if (unlikely(size == count && b_size(mbuf) == b_size(buf) && + htx_nbblks(htx) == 1 && type == HTX_BLK_DATA)) { void *old_area = mbuf->area; int eom = (htx->flags & HTX_FL_EOM); diff --git a/src/mux_h1.c b/src/mux_h1.c index 045fd603a..bdb461237 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -3058,7 +3058,8 @@ static size_t h1_make_data(struct h1s *h1s, struct h1m *h1m, struct buffer *buf, (!(h1m->flags & H1_MF_CHNK) || ((h1m->flags & H1_MF_CHNK) && (!h1m->curr_len || count == h1m->curr_len))) && htx_nbblks(htx) == 1 && htx_get_blk_type(blk) == HTX_BLK_DATA && - htx_get_blk_value(htx, blk).len == count) { + htx_get_blk_value(htx, blk).len == count && + b_size(&h1c->obuf) == b_size(buf)) { void *old_area; int eom = (htx->flags & HTX_FL_EOM); @@ -3344,7 +3345,8 @@ static size_t h1_make_tunnel(struct h1s *h1s, struct h1m *h1m, struct buffer *bu if (!b_data(&h1c->obuf) && htx_nbblks(htx) == 1 && htx_get_blk_type(blk) == HTX_BLK_DATA && - htx_get_blksz(blk) == count) { + htx_get_blksz(blk) == count && + b_size(&h1c->obuf) == b_size(buf)) { void *old_area; old_area = h1c->obuf.area; diff --git a/src/mux_h2.c b/src/mux_h2.c index 41fbbc26d..c2fb15efc 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -7234,7 +7234,7 @@ static size_t h2s_make_data(struct h2s *h2s, struct buffer *buf, size_t count) * the time. This goes for headers, data blocks and any data extracted * from the HTX blocks. */ - if (unlikely(fsize == count && + if (unlikely(fsize == count && b_size(mbuf) == b_size(buf) && htx_nbblks(htx) == 1 && type == HTX_BLK_DATA && fsize <= h2s_mws(h2s) && fsize <= h2c->mws && fsize <= h2c->mfs)) { void *old_area = mbuf->area;