]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: mux-spop: Don't include DALLOC/DFULL flags in SPOP_CF_DEM_BLOCK_ANY
authorAdam Szymanski <adam.88.szymanski@gmail.com>
Wed, 28 Oct 2026 10:19:59 +0000 (11:19 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 28 Oct 2026 14:38:50 +0000 (15:38 +0100)
commitc8a3763548f036b4640d1863e2c284ed22d120e1
tree2647042989cd8c05eddf21eb002bc73e11f043b6
parent8c84ab5621f52112ccd9a704cfd023faf595e469
BUG/MEDIUM: mux-spop: Don't include DALLOC/DFULL flags in SPOP_CF_DEM_BLOCK_ANY

SPOP_CF_DEM_BLOCK_ANY is documented as "aggregate of the demux flags above
except DALLOC/DFULL", like H2_CF_DEM_BLOCK_ANY and FCGI_CF_DEM_BLOCK_ANY, but
its value 0x7E0 also covers SPOP_CF_DEM_DALLOC (0x20) and SPOP_CF_DEM_DFULL
(0x40).

When a single recv() fills the demux buffer, spop_recv() sets
SPOP_CF_DEM_DFULL. spop_process() then skips spop_process_demux() because
the flag is part of SPOP_CF_DEM_BLOCK_ANY, and the only place clearing
SPOP_CF_DEM_DFULL is inside that skipped block. spop_recv_allowed() also
refuses to read. The connection stays stuck with a full dbuf forever: the
peer sees a zero TCP window, ACK frames are never parsed, every stream
attached to the connection times out, and new streams keep being attached
to it because it is still considered available.

This happens with pipelining when enough ACK frames are queued at once to
fill the 16kB demux buffer in one read (e.g. ACKs carrying ~1-3kB
variables), so "no option pipelining" in the spoe-agent section hides it.

The value must be 0x780 (MROOM|SALLOC|SFULL|TOOMANY).

Reproduced on HAProxy 3.4.7 with nbthread 4, pipelining enabled,
50 concurrent HTTP keep-alive clients, and a Go SPOA agent returning
ACK frames carrying approximately 3kB of variables. In three 10-second
test runs, the unpatched version left 3-5 connections stuck with
DEM_DFULL and produced 400-520 SPOE timeouts per run. With the fix,
no stuck connections or SPOE timeouts were observed.

This must be backported as far as 3.1.

Co-authored-by: ITGG <kontakt@itgg.eu>
include/haproxy/mux_spop-t.h