]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: htx: Add support for flags on HTX blocks
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 8 Jul 2026 13:23:11 +0000 (15:23 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 24 Jul 2026 09:58:25 +0000 (11:58 +0200)
In the commit 32b51cdf3 ("BUG/MINOR: config: reject configs using HTTP with
bufsize >= 256 MB"), the maximum possible size for buffers is limited to 256
MB. So, on HTX side, it means a bloc cannot have a relative address higher
than this value. So on the 32-bits integer used to store the relative block
address, only 28 bits can be used, and 4 bits remains unused.

So these 4 bits were reused to store flags on block themselves. In this
patch, the support for these flags is introduced and the HTX API was adapted
to deal with it.

include/haproxy/htx-t.h
include/haproxy/htx.h
src/htx.c

index 2e2b1b58d87f9e5312c0c8118f58946b8a2667bc..db3d3edff988336901cd448eb9bc5df97d365a35 100644 (file)
@@ -214,9 +214,12 @@ enum htx_blk_type {
        HTX_BLK_UNUSED = 15, /* unused/removed block */
 };
 
+#define HTX_BLK_FL_NONE 0x00 /* For init purpose */
+
 /* One HTX block descriptor */
 struct htx_blk {
-       uint32_t addr; /* relative storage address of the block's payload */
+       uint32_t flags:4;
+       uint32_t addr:28; /* relative storage address of the block's payload */
        uint32_t info; /* information about the block (type, length) */
 };
 
index 8e237c03238eba085b6e1b3763ee189d9402878e..c68e695e8d9505ff987168a19165c9e48f9ed3c4 100644 (file)
@@ -539,7 +539,8 @@ static inline struct htx_blk *htx_add_header(struct htx *htx, const struct ist n
             prevblk && htx_get_blk_type(prevblk) > HTX_BLK_HDR;
             prevblk = htx_get_prev_blk(htx, blk)) {
 
-               /* Swap .addr and .info fields */
+               /* Swap .flags, .addr and .info fields */
+               blk->flags ^= prevblk->flags; prevblk->flags ^= blk->flags; blk->flags ^= prevblk->flags;
                blk->addr ^= prevblk->addr; prevblk->addr ^= blk->addr; blk->addr ^= prevblk->addr;
                blk->info ^= prevblk->info; prevblk->info ^= blk->info; blk->info ^= prevblk->info;
                blk = prevblk;
@@ -575,7 +576,8 @@ static inline struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist
             prevblk && htx_get_blk_type(prevblk) > HTX_BLK_TLR;
             prevblk = htx_get_prev_blk(htx, blk)) {
 
-               /* Swap .addr and .info fields */
+               /* Swap .flags, .addr and .info fields */
+               blk->flags ^= prevblk->flags; prevblk->flags ^= blk->flags; blk->flags ^= prevblk->flags;
                blk->addr ^= prevblk->addr; prevblk->addr ^= blk->addr; blk->addr ^= prevblk->addr;
                blk->info ^= prevblk->info; prevblk->info ^= blk->info; blk->info ^= prevblk->info;
                blk = prevblk;
@@ -934,20 +936,20 @@ static inline void htx_dump(struct buffer *chunk, const struct htx *htx, int ful
 
                if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL) {
                        sl = htx_get_blk_ptr(htx, blk);
-                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s %.*s %.*s\n",
-                                     pos, htx_blk_type_str(type), sz, blk->addr,
+                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - flags=0x%04x - size=%-6u - addr=%-6u\t%.*s %.*s %.*s\n",
+                                     pos, htx_blk_type_str(type), blk->flags, sz, blk->addr,
                                      HTX_SL_P1_LEN(sl), HTX_SL_P1_PTR(sl),
                                      HTX_SL_P2_LEN(sl), HTX_SL_P2_PTR(sl),
                                      HTX_SL_P3_LEN(sl), HTX_SL_P3_PTR(sl));
                }
                else if (type == HTX_BLK_HDR || type == HTX_BLK_TLR)
-                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s: %.*s\n",
-                                     pos, htx_blk_type_str(type), sz, blk->addr,
+                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - flags=0x%04x - size=%-6u - addr=%-6u\t%.*s: %.*s\n",
+                                     pos, htx_blk_type_str(type), blk->flags, sz, blk->addr,
                                      (int)MIN(n.len, 32), n.ptr,
                                      (int)MIN(v.len, 64), v.ptr);
                else
-                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u%s\n",
-                                     pos, htx_blk_type_str(type), sz, blk->addr,
+                       chunk_appendf(chunk, "\t\t[%u] type=%-17s - flags=0x%04x - size=%-6u - addr=%-6u%s\n",
+                                     pos, htx_blk_type_str(type), blk->flags, sz, blk->addr,
                                      (!v.len ? "\t<empty>" : ""));
        }
 }
index f6bb60e41ab48011e9f3762ae03027fa65ebeb92..3cd5a44cd4e5e4c3efd9a17a2324acb1897c3313 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -91,6 +91,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk, uint32_t blkinf
                                htx_memcpy(htx_get_blk_ptr(tmp, newblk), htx_get_blk_ptr(htx, oldblk), blksz);
                                break;
                };
+               newblk->flags |= oldblk->flags;
 
                /* update the start-line position */
                if (htx->first == old)
@@ -142,6 +143,7 @@ static void htx_defrag_blks(struct htx *htx)
                newblk = htx_get_blk(htx, new++);
                newblk->info = posblk->info;
                newblk->addr = posblk->addr;
+               newblk->flags = posblk->flags;
        }
        BUG_ON(!new);
        htx->head = 0;
@@ -167,6 +169,7 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
                htx->head = htx->tail = htx->first = 0;
                blk = htx_get_blk(htx, htx->tail);
                blk->addr = 0;
+               blk->flags = HTX_BLK_FL_NONE;
                htx->data = blksz;
                htx->tail_addr = blksz;
                return blk;
@@ -356,6 +359,7 @@ struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t bl
                return NULL;
        BUG_ON(blk->addr > htx->size);
 
+       blk->flags = HTX_BLK_FL_NONE;
        blk->info = (type << 28);
        if (type < HTX_BLK_EOH)
                htx->hdrs_data += blksz;
@@ -806,6 +810,7 @@ size_t htx_xfer(struct htx *dst, struct htx *src, size_t count, unsigned int fla
                                dst_full = 1;
                                goto stop;
                        }
+                       last_dstblk->flags = blk->flags;
                        break;
 
                default:
@@ -819,6 +824,7 @@ size_t htx_xfer(struct htx *dst, struct htx *src, size_t count, unsigned int fla
                                dst_full = 1;
                                goto stop;
                        }
+                       last_dstblk->flags = blk->flags;
                        last_dstblk->info = blk->info;
                        htx_memcpy(htx_get_blk_ptr(dst, last_dstblk), htx_get_blk_ptr(src, blk), sz);
                        last_dstblk_sz = sz;
@@ -1191,6 +1197,7 @@ struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data)
                        break;
 
                /* Swap .addr and .info fields */
+               blk->flags ^= pblk->flags; pblk->flags ^= blk->flags; blk->flags ^= pblk->flags;
                blk->addr ^= pblk->addr; pblk->addr ^= blk->addr; blk->addr ^= pblk->addr;
                blk->info ^= pblk->info; pblk->info ^= blk->info; blk->info ^= pblk->info;
 
@@ -1213,7 +1220,8 @@ void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk *
        for (pblk = htx_get_prev_blk(htx, cblk); pblk; pblk = htx_get_prev_blk(htx, pblk)) {
                htx->flags |= HTX_FL_UNORDERED;
 
-               /* Swap .addr and .info fields */
+               /* Swap .flags, .addr and .info fields */
+               cblk->flags ^= pblk->flags; pblk->flags ^= cblk->flags; cblk->flags ^= pblk->flags;
                cblk->addr ^= pblk->addr; pblk->addr ^= cblk->addr; cblk->addr ^= pblk->addr;
                cblk->info ^= pblk->info; pblk->info ^= cblk->info; cblk->info ^= pblk->info;
 
@@ -1243,6 +1251,7 @@ int htx_append_msg(struct htx *dst, const struct htx *src)
                newblk = htx_add_blk(dst, type, blksz);
                if (!newblk)
                        goto error;
+               newblk->flags = blk->flags;
                newblk->info = blk->info;
                htx_memcpy(htx_get_blk_ptr(dst, newblk), htx_get_blk_ptr(src, blk), blksz);
        }