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-Tag: v3.5-dev8~171 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=3a8bc71e460bd40c8cb260c553ff04e0294d4dda;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 42b10b0f5..655716300 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 58a714a1e..bf643e49c 100644 --- a/include/haproxy/htx.h +++ b/include/haproxy/htx.h @@ -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" : "")); } } diff --git a/src/htx.c b/src/htx.c index dc6854dc6..5e2052a3e 100644 --- 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); }