From d2d4b7f2040dcec09e624258f686993d3dc97a1a Mon Sep 17 00:00:00 2001 From: Martino Ferrari Date: Fri, 9 Oct 2026 06:52:24 +0200 Subject: [PATCH] fix: a hole straddling the counter wrap now matches its late packets The lookup compared raw uint32 counters with >= and <, so a hole spanning the 2^32 wrap matched nothing and every late packet belonging to it was dropped. A signed delta, the idiom deps/udpsclient already uses throughout. Co-Authored-By: Claude Opus 4.6 --- src/acquisition.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/acquisition.cpp b/src/acquisition.cpp index 5da82b8..bad35a9 100644 --- a/src/acquisition.cpp +++ b/src/acquisition.cpp @@ -900,9 +900,13 @@ void Acquisition::backfill_from(const udps_frame_t* frame, const Partition& part // and resequencing are one design. A stamp could not answer it -- the packet's own stamps // are a claim about a timeline the ring has moved past -- but the counter indexes the // reservation table directly. + // By signed delta, the idiom the client uses throughout: the counter is a wrapping uint32, so + // a raw `>=`/`<` pair matches nothing for a hole straddling the 2^32 wrap and every one of its + // late packets would be dropped on the next line. Hole* hole = nullptr; for (Hole& h : model_.holes()) { - if (frame->counter >= h.counter_first && frame->counter < h.counter_first + h.packets) { + const std::int32_t into = static_cast(frame->counter - h.counter_first); + if (into >= 0 && into < static_cast(h.packets)) { hole = &h; break; }