]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: peers: Fix update message parsing during a full resync
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 7 Nov 2025 11:47:31 +0000 (12:47 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 7 Nov 2025 11:47:34 +0000 (12:47 +0100)
The commit 590c5ff2e ("MEDIUM: peers: No longer ack updates during a full
resync") introduced a regression. During a full resync, the ID of an update
message is not parsed at all. Thus, the parsing of the whole message in
desynchronized.

On full resync the update id itself is ignored, to not be acked, but it must
be parsed. It is now fixed.

It is a 3.3-specific bug, no backport needed.

src/peers.c

index bbb72352c1f715481ee9a2ed60c14c7046a071e3..9a97ebb6bd599c9dd04dfa90c44f45c8e33b5313 100644 (file)
@@ -1811,21 +1811,20 @@ int peer_treat_updatemsg(struct appctx *appctx, struct peer *p, int updt, int ex
 
        expire = MS_TO_TICKS(table->expire);
 
-       if (p->learnstate != PEER_LR_ST_PROCESSING) {
-               if (updt) {
-                       if (msg_len < sizeof(update)) {
-                               TRACE_ERROR("malformed update message: message too small", PEERS_EV_SESS_IO|PEERS_EV_RX_MSG|PEERS_EV_PROTO_ERR, appctx, p, st);
-                               goto malformed_exit;
-                       }
-
-                       memcpy(&update, *msg_cur, sizeof(update));
-                       *msg_cur += sizeof(update);
-                       st->last_get = htonl(update);
-               }
-               else {
-                       st->last_get++;
+       if (updt) {
+               if (msg_len < sizeof(update)) {
+                       TRACE_ERROR("malformed update message: message too small", PEERS_EV_SESS_IO|PEERS_EV_RX_MSG|PEERS_EV_PROTO_ERR, appctx, p, st);
+                       goto malformed_exit;
                }
+
+               memcpy(&update, *msg_cur, sizeof(update));
+               *msg_cur += sizeof(update);
        }
+       else
+               update = st->last_get + 1;
+
+       if (p->learnstate != PEER_LR_ST_PROCESSING)
+               st->last_get = htonl(update);
 
        if (exp) {
                size_t expire_sz = sizeof expire;