From: Christopher Faulet Date: Wed, 8 Jul 2026 13:23:11 +0000 (+0200) Subject: MINOR: htx: Add support for flags on HTX blocks X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=298f6b9355b992bf67f98ff03b93de28e7969481;p=haproxy.git MINOR: htx: Add support for flags on HTX blocks 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. --- diff --git a/include/haproxy/htx-t.h b/include/haproxy/htx-t.h index 2e2b1b58d..db3d3edff 100644 --- a/include/haproxy/htx-t.h +++ b/include/haproxy/htx-t.h @@ -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) */ }; diff --git a/include/haproxy/htx.h b/include/haproxy/htx.h index 8e237c032..c68e695e8 100644 --- a/include/haproxy/htx.h +++ b/include/haproxy/htx.h @@ -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" : "")); } } diff --git a/src/htx.c b/src/htx.c index f6bb60e41..3cd5a44cd 100644 --- 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); }