]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-h1/mux-h2/mux-fcgi/h3: Disable 0-copy for buffers of different size
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 3 Feb 2026 06:55:31 +0000 (07:55 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 18 Feb 2026 12:26:21 +0000 (13:26 +0100)
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
src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c

index 849bba2a6fbdd8910e2d04ccd91746b7e9d6fec3..bc479ce406489c9ca669e612c7e85afa5abc9e17 100644 (file)
--- 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;
index 45b546f011a67c900a2f2a585260b3a4a58a16b2..33153fffadbf3aa24b34f513992aafa48ba9be4f 100644 (file)
@@ -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);
 
index 045fd603a31d3771249caf01ade59afffe17aee7..bdb461237f3f3cb11ccbb23937a8b7d69a2c85b2 100644 (file)
@@ -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;
index 41fbbc26dd8b4b282e65fa009073446ff894d058..c2fb15efc34eabac2e52bc5c12302926259c9374 100644 (file)
@@ -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;