aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-31 12:17:13 +0100
committertv <tv@krebsco.de>2026-10-31 12:17:13 +0100
commit6b939f2c73e8909e0a2270e99d934be90181dfd1 (patch)
treeb94b869362f94952dc8806683cb98f4339000b4d /src/transport
parent9ec95a06e109595a7a3408f567970a5ecad99414 (diff)
contradicting clock samples replace stored ones
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/paths.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/transport/paths.rs b/src/transport/paths.rs
index 6512759..2ef3a12 100644
--- a/src/transport/paths.rs
+++ b/src/transport/paths.rs
@@ -107,7 +107,7 @@ const SWITCH_MIN: Duration = Duration::from_millis(5);
/// Paths kept at most: they are of peers this node chose among, but bounded anyway.
const MAX_PATHS: usize = 4096;
/// A path's clock sample with the narrowest bound is kept this long at most; then the
-/// next one takes its place, so a clock that was set anew shows within this time.
+/// next one takes its place. (A clock set anew shows at once: `Table::clock`.)
const CLOCK_KEPT: Duration = Duration::from_secs(300);
/// How far a peer's clock is ahead of ours (behind if negative), from a PING and its
@@ -395,14 +395,18 @@ impl Table {
}
/// A clock sample from a PONG over `address`: kept if its bound is as narrow as the
- /// one kept, or that one is older than `CLOCK_KEPT`. The narrowest bound is the
+ /// one kept, or that one is older than `CLOCK_KEPT`, or the two can't both be right
+ /// (their bounds don't overlap: a clock was set anew). The narrowest bound is the
/// round trip least delayed by queues and relays.
fn clock(&mut self, address: &str, offset: ClockOffset, now: Instant) {
let Some(path) = self.paths.get_mut(address) else {
return;
};
let replaces = path.clock.is_none_or(|(kept, at)| {
- offset.within_ms <= kept.within_ms || now.saturating_duration_since(at) >= CLOCK_KEPT
+ offset.within_ms <= kept.within_ms
+ || now.saturating_duration_since(at) >= CLOCK_KEPT
+ || offset.offset_ms.abs_diff(kept.offset_ms)
+ > offset.within_ms.saturating_add(kept.within_ms)
});
if replaces {
path.clock = Some((offset, now));
@@ -1224,6 +1228,14 @@ mod tests {
table.paths["libp2p:z"].clock.map(|(kept, _)| kept),
Some(wider)
);
+ // A clock set anew: a sample the kept one contradicts takes its place at once,
+ // its bound wider or not.
+ let set_anew = ClockOffset::of(UnixMillis(25_000), heard, rtt * 8);
+ table.clock("libp2p:z", set_anew, now + CLOCK_KEPT);
+ assert_eq!(
+ table.paths["libp2p:z"].clock.map(|(kept, _)| kept),
+ Some(set_anew)
+ );
}
/// A peer's only path is measured too once messages go over it, unless its