public address detection work
This commit is contained in:
@@ -1,33 +1,36 @@
|
||||
use super::*;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
// Reliable pings are done with increased spacing between pings
|
||||
// - Start secs is the number of seconds between the first two pings
|
||||
// - Max secs is the maximum number of seconds between consecutive pings
|
||||
// - Multiplier changes the number of seconds between pings over time
|
||||
// making it longer as the node becomes more reliable
|
||||
/// Reliable pings are done with increased spacing between pings
|
||||
|
||||
/// - Start secs is the number of seconds between the first two pings
|
||||
const RELIABLE_PING_INTERVAL_START_SECS: u32 = 10;
|
||||
/// - Max secs is the maximum number of seconds between consecutive pings
|
||||
const RELIABLE_PING_INTERVAL_MAX_SECS: u32 = 10 * 60;
|
||||
/// - Multiplier changes the number of seconds between pings over time
|
||||
/// making it longer as the node becomes more reliable
|
||||
const RELIABLE_PING_INTERVAL_MULTIPLIER: f64 = 2.0;
|
||||
|
||||
// Unreliable pings are done for a fixed amount of time while the
|
||||
// node is given a chance to come back online before it is made dead
|
||||
// If a node misses a single ping, it is marked unreliable and must
|
||||
// return reliable pings for the duration of the span before being
|
||||
// marked reliable again
|
||||
// - Span is the number of seconds total to attempt to validate the node
|
||||
// - Interval is the number of seconds between each ping
|
||||
/// Unreliable pings are done for a fixed amount of time while the
|
||||
/// node is given a chance to come back online before it is made dead
|
||||
/// If a node misses a single ping, it is marked unreliable and must
|
||||
/// return reliable pings for the duration of the span before being
|
||||
/// marked reliable again
|
||||
///
|
||||
/// - Span is the number of seconds total to attempt to validate the node
|
||||
const UNRELIABLE_PING_SPAN_SECS: u32 = 60;
|
||||
/// - Interval is the number of seconds between each ping
|
||||
const UNRELIABLE_PING_INTERVAL_SECS: u32 = 5;
|
||||
|
||||
// Keepalive pings are done occasionally to ensure holepunched public dialinfo
|
||||
// remains valid, as well as to make sure we remain in any relay node's routing table
|
||||
/// Keepalive pings are done occasionally to ensure holepunched public dialinfo
|
||||
/// remains valid, as well as to make sure we remain in any relay node's routing table
|
||||
const KEEPALIVE_PING_INTERVAL_SECS: u32 = 10;
|
||||
|
||||
// How many times do we try to ping a never-reached node before we call it dead
|
||||
/// How many times do we try to ping a never-reached node before we call it dead
|
||||
const NEVER_REACHED_PING_COUNT: u32 = 3;
|
||||
|
||||
// Do not change order here, it will mess up other sorts
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum BucketEntryState {
|
||||
Dead,
|
||||
@@ -42,6 +45,7 @@ struct LastConnectionKey(PeerScope, ProtocolType, AddressType);
|
||||
pub struct BucketEntryInner {
|
||||
min_max_version: Option<(u8, u8)>,
|
||||
seen_our_node_info: bool,
|
||||
updated_since_last_network_change: bool,
|
||||
last_connections: BTreeMap<LastConnectionKey, (ConnectionDescriptor, u64)>,
|
||||
opt_signed_node_info: Option<SignedNodeInfo>,
|
||||
opt_local_node_info: Option<LocalNodeInfo>,
|
||||
@@ -112,22 +116,44 @@ impl BucketEntryInner {
|
||||
}
|
||||
|
||||
// Retuns true if the node info changed
|
||||
pub fn update_node_info(&mut self, signed_node_info: SignedNodeInfo) -> bool {
|
||||
// Don't update with older node info, or something less valid
|
||||
pub fn update_signed_node_info(
|
||||
&mut self,
|
||||
signed_node_info: SignedNodeInfo,
|
||||
allow_invalid_signature: bool,
|
||||
) -> bool {
|
||||
// Don't allow invalid signatures unless we are explicitly allowing it
|
||||
if !allow_invalid_signature && !signed_node_info.signature.valid {
|
||||
return false;
|
||||
}
|
||||
|
||||
// See if we have an existing signed_node_info to update or not
|
||||
if let Some(current_sni) = &self.opt_signed_node_info {
|
||||
if current_sni.signature.valid && !signed_node_info.signature.valid {
|
||||
return false;
|
||||
}
|
||||
if signed_node_info.timestamp < current_sni.timestamp {
|
||||
// If the timestamp hasn't changed or is less, ignore this update
|
||||
if signed_node_info.timestamp <= current_sni.timestamp {
|
||||
// If we received a node update with the same timestamp
|
||||
// we can try again, but only if our network hasn't changed
|
||||
if !self.updated_since_last_network_change
|
||||
&& signed_node_info.timestamp == current_sni.timestamp
|
||||
{
|
||||
// No need to update the signednodeinfo though since the timestamp is the same
|
||||
// Just return true so we can make the node not dead
|
||||
self.updated_since_last_network_change = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the protocol min/max version we have
|
||||
self.min_max_version = Some((
|
||||
signed_node_info.node_info.min_version,
|
||||
signed_node_info.node_info.max_version,
|
||||
));
|
||||
|
||||
// Update the signed node info
|
||||
self.opt_signed_node_info = Some(signed_node_info);
|
||||
|
||||
self.updated_since_last_network_change = true;
|
||||
true
|
||||
}
|
||||
pub fn update_local_node_info(&mut self, local_node_info: LocalNodeInfo) {
|
||||
@@ -238,6 +264,14 @@ impl BucketEntryInner {
|
||||
self.seen_our_node_info
|
||||
}
|
||||
|
||||
pub fn set_updated_since_last_network_change(&mut self, updated: bool) {
|
||||
self.updated_since_last_network_change = updated;
|
||||
}
|
||||
|
||||
pub fn has_updated_since_last_network_change(&self) -> bool {
|
||||
self.updated_since_last_network_change
|
||||
}
|
||||
|
||||
///// stats methods
|
||||
// called every ROLLING_TRANSFERS_INTERVAL_SECS seconds
|
||||
pub(super) fn roll_transfers(&mut self, last_ts: u64, cur_ts: u64) {
|
||||
@@ -461,6 +495,7 @@ impl BucketEntry {
|
||||
inner: RwLock::new(BucketEntryInner {
|
||||
min_max_version: None,
|
||||
seen_our_node_info: false,
|
||||
updated_since_last_network_change: false,
|
||||
last_connections: BTreeMap::new(),
|
||||
opt_signed_node_info: None,
|
||||
opt_local_node_info: None,
|
||||
|
@@ -533,9 +533,11 @@ impl RoutingTable {
|
||||
}
|
||||
|
||||
// register the node if it's new
|
||||
if let Some(nr) =
|
||||
self.register_node_with_signed_node_info(p.node_id.key, p.signed_node_info.clone())
|
||||
{
|
||||
if let Some(nr) = self.register_node_with_signed_node_info(
|
||||
p.node_id.key,
|
||||
p.signed_node_info.clone(),
|
||||
false,
|
||||
) {
|
||||
out.push(nr);
|
||||
}
|
||||
}
|
||||
|
@@ -290,6 +290,7 @@ impl RoutingTable {
|
||||
// Public dial info changed, go through all nodes and reset their 'seen our node info' bit
|
||||
if matches!(domain, RoutingDomain::PublicInternet) {
|
||||
Self::reset_all_seen_our_node_info(&*inner);
|
||||
Self::reset_all_updated_since_last_network_change(&*inner);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -303,6 +304,14 @@ impl RoutingTable {
|
||||
});
|
||||
}
|
||||
|
||||
fn reset_all_updated_since_last_network_change(inner: &RoutingTableInner) {
|
||||
let cur_ts = intf::get_timestamp();
|
||||
Self::with_entries(&*inner, cur_ts, BucketEntryState::Dead, |_, v| {
|
||||
v.with_mut(|e| e.set_updated_since_last_network_change(false));
|
||||
Option::<()>::None
|
||||
});
|
||||
}
|
||||
|
||||
pub fn clear_dial_info_details(&self, domain: RoutingDomain) {
|
||||
trace!("clearing dial info domain: {:?}", domain);
|
||||
|
||||
@@ -587,6 +596,7 @@ impl RoutingTable {
|
||||
&self,
|
||||
node_id: DHTKey,
|
||||
signed_node_info: SignedNodeInfo,
|
||||
allow_invalid_signature: bool,
|
||||
) -> Option<NodeRef> {
|
||||
// validate signed node info is not something malicious
|
||||
if node_id == self.node_id() {
|
||||
@@ -601,7 +611,7 @@ impl RoutingTable {
|
||||
}
|
||||
|
||||
self.create_node_ref(node_id, |e| {
|
||||
if e.update_node_info(signed_node_info) {
|
||||
if e.update_signed_node_info(signed_node_info, allow_invalid_signature) {
|
||||
// at least someone thought this node was live and its node info changed so lets try to contact it
|
||||
e.touch_last_seen(intf::get_timestamp());
|
||||
}
|
||||
|
@@ -108,6 +108,12 @@ impl NodeRef {
|
||||
pub fn set_seen_our_node_info(&self) {
|
||||
self.operate_mut(|e| e.set_seen_our_node_info(true));
|
||||
}
|
||||
pub fn has_updated_since_last_network_change(&self) -> bool {
|
||||
self.operate(|e| e.has_updated_since_last_network_change())
|
||||
}
|
||||
pub fn set_updated_since_last_network_change(&self) {
|
||||
self.operate_mut(|e| e.set_updated_since_last_network_change(true));
|
||||
}
|
||||
pub fn network_class(&self) -> Option<NetworkClass> {
|
||||
self.operate(|e| e.node_info().map(|n| n.network_class))
|
||||
}
|
||||
@@ -139,7 +145,7 @@ impl NodeRef {
|
||||
|
||||
// Register relay node and return noderef
|
||||
self.routing_table
|
||||
.register_node_with_signed_node_info(t.node_id.key, t.signed_node_info)
|
||||
.register_node_with_signed_node_info(t.node_id.key, t.signed_node_info, false)
|
||||
.map(|mut nr| {
|
||||
nr.set_filter(self.filter_ref().cloned());
|
||||
nr
|
||||
|
Reference in New Issue
Block a user