fix(firmware/lib): wrap-safe millis() comparison in net_guard reconnect timer

net_guard_tick() compared absolute uint32_t millis() values:
  if (millis() < s_next_retry_ms) return;
This is broken across the ~49.7-day millis() wrap: depending on which
side of the wrap each value lands, retries either tight-loop or stall
indefinitely. The device is designed for multi-month uptime, so this
is a real production case, not a theoretical one.

Replace with the standard wrap-safe pattern using a signed difference.

Found via adversarial review (run 2026-05-01-202910, gpt-5.5 reviewer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 15:36:06 -07:00
parent ef00afb14e
commit 8342904488

View File

@@ -126,7 +126,11 @@ extern "C" void net_guard_tick() {
}
if (s_up || s_cfg == nullptr) return;
if (millis() < s_next_retry_ms) return;
// Wrap-safe: signed difference handles the ~49.7-day millis() wrap. The
// device is meant to run for months between reboots, so absolute compare
// (millis() < s_next_retry_ms) would either tight-loop retries across the
// wrap or stall them until millis() climbed back past an old high mark.
if ((int32_t)(millis() - s_next_retry_ms) < 0) return;
if (s_up) return; // re-check after the timing gate — closes GOT_IP-vs-tick race
s_attempts++;
// WiFi.begin() alone re-associates cleanly; a prior WiFi.disconnect() call