From 91fb928c6e9e7e61c9c8f569057e0a71b591c25b Mon Sep 17 00:00:00 2001 From: Luc Busquin <133058544+Cybis320@users.noreply.github.com> Date: Mon, 6 Jul 2026 19:14:03 -0700 Subject: [PATCH] Fix i32 overflow: peers offline 24.9-49.7 days wrongly reported online (#676) `Duration::as_millis()` returns u128; casting it `as i32` in the online-status and punch-hole checks keeps only the low 32 bits as a signed integer. Once a peer has not registered for more than 2^31 ms (~24.855 days), the value wraps negative and passes the `elapsed < REG_TIMEOUT` test, so a long-offline peer is reported online and connection attempts are relayed to its stale socket_addr. The in-memory peer map is never evicted, so last_reg_time stays frozen until hbbs restarts, making the false-online window 24.86-49.71 days (and it repeats every ~49.71 days). Widen REG_TIMEOUT and the two elapsed casts from i32 to i64 so the comparison no longer overflows. Co-authored-by: Claude Opus 4.8 (1M context) --- src/rendezvous_server.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rendezvous_server.rs b/src/rendezvous_server.rs index d8d9be8..dff45eb 100644 --- a/src/rendezvous_server.rs +++ b/src/rendezvous_server.rs @@ -47,7 +47,7 @@ enum Data { RelayServers(RelayServers), } -const REG_TIMEOUT: i32 = 30_000; +const REG_TIMEOUT: i64 = 30_000; type TcpStreamSink = SplitSink, Bytes>; type WsSink = SplitSink, tungstenite::Message>; enum Sink { @@ -697,7 +697,7 @@ impl RendezvousServer { if let Some(peer) = self.pm.get(&id).await { let (elapsed, peer_addr) = { let r = peer.read().await; - (r.last_reg_time.elapsed().as_millis() as i32, r.socket_addr) + (r.last_reg_time.elapsed().as_millis() as i64, r.socket_addr) }; if elapsed >= REG_TIMEOUT { let mut msg_out = RendezvousMessage::new(); @@ -790,7 +790,7 @@ impl RendezvousServer { let mut states = BytesMut::zeroed((peers.len() + 7) / 8); for (i, peer_id) in peers.iter().enumerate() { if let Some(peer) = self.pm.get_in_memory(peer_id).await { - let elapsed = peer.read().await.last_reg_time.elapsed().as_millis() as i32; + let elapsed = peer.read().await.last_reg_time.elapsed().as_millis() as i64; // bytes index from left to right let states_idx = i / 8; let bit_idx = 7 - i % 8;