From: Frederic Lecaille Date: Tue, 20 Oct 2026 14:12:36 +0000 (+0200) Subject: BUG/MEDIUM: peers: fix byte order of last_get on updates without identifier X-Git-Tag: v3.5-dev10~50 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=aec8f99a2558a13e6abe2a6eaf16fa6e5c1953a5;p=haproxy.git BUG/MEDIUM: peers: fix byte order of last_get on updates without identifier Since commit f12252c7a ("BUG/MEDIUM: peers: Fix update message parsing during a full resync"), peer_treat_updatemsg() computes the update ID in a local variable whose byte order depends on the message type. Explicit identifiers are read in network byte order, while implicit identifiers are computed in host byte order as st->last_get + 1. Outside full resynchronization, htonl() is then applied to this variable in both cases before storing it in st->last_get. This correctly converts explicit identifiers, since htonl() and ntohl() perform the same transformation, but incorrectly byte-swaps implicit identifiers on little-endian machines. The incorrect identifier is sent in ACK messages and stored by the sender as st->update. This value initializes the transmission cursors after a reconnection, so its corruption may cause updates to be skipped or unnecessarily resent. A subsequent update carrying an explicit identifier restores the correct last_get value, which can hide the issue when inspecting the final state after a burst of updates. This can be reproduced by completing the initial resynchronization, then sending an UPDATE with identifier 199 followed by an INCUPDATE. On a little-endian receiver, last_get and the acknowledged identifier become 3355443200 (0xc8000000) instead of 200. A regression test exercising this sequence fails without the fix and passes with it. Convert explicit identifiers to host byte order immediately after reading them, then store the resulting identifier without conversion. Leave the full-resynchronization guard unchanged. This must be backported as far as 3.3. --- diff --git a/src/peers.c b/src/peers.c index 37dae2771..c09e58553 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1840,12 +1840,13 @@ int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt, int ex memcpy(&update, *msg_cur, sizeof(update)); *msg_cur += sizeof(update); + update = ntohl(update); } else update = st->last_get + 1; if (p->learnstate != PEER_LR_ST_PROCESSING) - st->last_get = htonl(update); + st->last_get = update; if (exp) { size_t expire_sz = sizeof expire;