]> 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, 18 Sep 2026 15:05:18 +0000 (17:05 +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 42b10b0f5246a894caf7c1e54757150502b7d1fb..65571630085f3707300412f956b77db76793fd18 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 58a714a1e0602da7c2733412d49f75005dfec6cc..bf643e49c7f83555e59e191c32a7b0c425c54e75 100644 (file)
@@ -538,7 +538,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;
@@ -570,7 +571,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;
@@ -932,20 +934,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%02x - 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%02x - 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%02x - size=%-6u - addr=%-6u%s\n",
+                                     pos, htx_blk_type_str(type), blk->flags, sz, blk->addr,
                                      (!v.len ? "\t<empty>" : ""));
        }
 }
index dc6854dc6dc5889f2c66089e9994d526f23e5dc7..5e2052a3e0836fb9e1703e4bc9588e24904db1ae 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -90,6 +90,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)
@@ -139,6 +140,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;
@@ -171,6 +173,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;
@@ -360,6 +363,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;
@@ -405,6 +409,7 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
                if (type < HTX_BLK_EOH)
                        htx->hdrs_data -= sz;
                htx->data -= htx_get_blksz(blk);
+               blk->flags = HTX_BLK_FL_NONE;
                blk->info = ((uint32_t)HTX_BLK_UNUSED << 28);
        }
 
@@ -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;
                        break;
 
                default:
@@ -832,6 +838,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;
@@ -1206,6 +1213,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;
 
@@ -1228,7 +1236,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;
 
@@ -1259,6 +1268,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);
        }