node: Don't allow timestamps with too much delta
Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
parent
9ca982ee28
commit
e040ea5ec7
|
|
@ -37,6 +37,7 @@ pub const ANNOUNCE_INTERVAL: LocalDuration = LocalDuration::from_secs(30);
|
||||||
pub const SYNC_INTERVAL: LocalDuration = LocalDuration::from_secs(60);
|
pub const SYNC_INTERVAL: LocalDuration = LocalDuration::from_secs(60);
|
||||||
pub const PRUNE_INTERVAL: LocalDuration = LocalDuration::from_mins(30);
|
pub const PRUNE_INTERVAL: LocalDuration = LocalDuration::from_mins(30);
|
||||||
pub const MAX_CONNECTION_ATTEMPTS: usize = 3;
|
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.
|
/// Commands sent to the protocol by the operator.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -878,20 +879,23 @@ impl Peer {
|
||||||
let inventory = Message::inventory(ctx).unwrap();
|
let inventory = Message::inventory(ctx).unwrap();
|
||||||
ctx.write(self.addr, inventory);
|
ctx.write(self.addr, inventory);
|
||||||
}
|
}
|
||||||
Message::Inventory { timestamp: 0, .. } => {
|
|
||||||
return Err(PeerError::InvalidTimestamp(0));
|
|
||||||
}
|
|
||||||
Message::Inventory {
|
Message::Inventory {
|
||||||
timestamp,
|
timestamp,
|
||||||
inv,
|
inv,
|
||||||
origin,
|
origin,
|
||||||
} => {
|
} => {
|
||||||
|
let now = ctx.clock.local_time();
|
||||||
let last = ctx
|
let last = ctx
|
||||||
.timestamps
|
.timestamps
|
||||||
.entry(self.id())
|
.entry(self.id())
|
||||||
.or_insert_with(Timestamp::default);
|
.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 {
|
if timestamp > *last {
|
||||||
*last = timestamp;
|
*last = timestamp;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,14 @@ fn test_inventory_fetch() {
|
||||||
fn test_inventory_relay_bad_timestamp() {
|
fn test_inventory_relay_bad_timestamp() {
|
||||||
let mut alice = Peer::new("alice", [7, 7, 7, 7], MockStorage::empty());
|
let mut alice = Peer::new("alice", [7, 7, 7, 7], MockStorage::empty());
|
||||||
let bob = Peer::new("bob", [8, 8, 8, 8], 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.connect_to(&bob.addr());
|
||||||
alice.receive(
|
alice.receive(
|
||||||
&bob.addr(),
|
&bob.addr(),
|
||||||
Message::Inventory {
|
Message::Inventory {
|
||||||
timestamp: 0,
|
timestamp,
|
||||||
inv: vec![],
|
inv: vec![],
|
||||||
origin: None,
|
origin: None,
|
||||||
},
|
},
|
||||||
|
|
@ -135,7 +137,7 @@ fn test_inventory_relay_bad_timestamp() {
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
alice.outbox().next(),
|
alice.outbox().next(),
|
||||||
Some(Io::Disconnect(addr, DisconnectReason::Error(PeerError::InvalidTimestamp(t))))
|
Some(Io::Disconnect(addr, DisconnectReason::Error(PeerError::InvalidTimestamp(t))))
|
||||||
if addr == bob.addr() && t == 0
|
if addr == bob.addr() && t == timestamp
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue