From e040ea5ec78571c4fe15cb812213c9fdfcece3c8 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Sat, 27 Aug 2022 14:46:22 +0200 Subject: [PATCH] node: Don't allow timestamps with too much delta Signed-off-by: Alexis Sellier --- node/src/protocol.rs | 12 ++++++++---- node/src/test/tests.rs | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/node/src/protocol.rs b/node/src/protocol.rs index c425d0e0..852d542c 100644 --- a/node/src/protocol.rs +++ b/node/src/protocol.rs @@ -37,6 +37,7 @@ pub const ANNOUNCE_INTERVAL: LocalDuration = LocalDuration::from_secs(30); pub const SYNC_INTERVAL: LocalDuration = LocalDuration::from_secs(60); pub const PRUNE_INTERVAL: LocalDuration = LocalDuration::from_mins(30); pub const MAX_CONNECTION_ATTEMPTS: usize = 3; +pub const MAX_TIME_DELTA: LocalDuration = LocalDuration::from_mins(60); /// Commands sent to the protocol by the operator. #[derive(Debug)] @@ -878,20 +879,23 @@ impl Peer { let inventory = Message::inventory(ctx).unwrap(); ctx.write(self.addr, inventory); } - Message::Inventory { timestamp: 0, .. } => { - return Err(PeerError::InvalidTimestamp(0)); - } Message::Inventory { timestamp, inv, origin, } => { + let now = ctx.clock.local_time(); let last = ctx .timestamps .entry(self.id()) .or_insert_with(Timestamp::default); - // Discard inventory messages from timestamps in the past. + // Don't allow messages from too far in the past or future. + if timestamp.abs_diff(now.as_secs()) > MAX_TIME_DELTA.as_secs() { + return Err(PeerError::InvalidTimestamp(timestamp)); + } + // Discard inventory messages we've already seen, otherwise update + // out last seen time. if timestamp > *last { *last = timestamp; } else { diff --git a/node/src/test/tests.rs b/node/src/test/tests.rs index 25f95fa2..92d6786f 100644 --- a/node/src/test/tests.rs +++ b/node/src/test/tests.rs @@ -122,12 +122,14 @@ fn test_inventory_fetch() { fn test_inventory_relay_bad_timestamp() { let mut alice = Peer::new("alice", [7, 7, 7, 7], MockStorage::empty()); let bob = Peer::new("bob", [8, 8, 8, 8], MockStorage::empty()); + let two_hours = 3600 * 2; + let timestamp = alice.local_time.as_secs() - two_hours; alice.connect_to(&bob.addr()); alice.receive( &bob.addr(), Message::Inventory { - timestamp: 0, + timestamp, inv: vec![], origin: None, }, @@ -135,7 +137,7 @@ fn test_inventory_relay_bad_timestamp() { assert_matches!( alice.outbox().next(), Some(Io::Disconnect(addr, DisconnectReason::Error(PeerError::InvalidTimestamp(t)))) - if addr == bob.addr() && t == 0 + if addr == bob.addr() && t == timestamp ); }