diff --git a/veilid-core/src/network_manager/address_filter.rs b/veilid-core/src/network_manager/address_filter.rs index 2eb104a6..b39dde90 100644 --- a/veilid-core/src/network_manager/address_filter.rs +++ b/veilid-core/src/network_manager/address_filter.rs @@ -272,6 +272,7 @@ impl AddressFilter { let mut inner = self.inner.lock(); inner.punishments_by_ip4.clear(); inner.punishments_by_ip6_prefix.clear(); + self.unlocked_inner.routing_table.clear_punishments(); inner.punishments_by_node_id.clear(); } diff --git a/veilid-core/src/network_manager/mod.rs b/veilid-core/src/network_manager/mod.rs index 3ee0996a..04d95278 100644 --- a/veilid-core/src/network_manager/mod.rs +++ b/veilid-core/src/network_manager/mod.rs @@ -323,6 +323,14 @@ impl NetworkManager { .rpc_processor .clone() } + pub fn opt_rpc_processor(&self) -> Option { + self.unlocked_inner + .components + .read() + .as_ref() + .map(|x| x.rpc_processor.clone()) + } + pub fn connection_manager(&self) -> ConnectionManager { self.unlocked_inner .components diff --git a/veilid-core/src/routing_table/bucket_entry.rs b/veilid-core/src/routing_table/bucket_entry.rs index b85d858e..c5dca3a4 100644 --- a/veilid-core/src/routing_table/bucket_entry.rs +++ b/veilid-core/src/routing_table/bucket_entry.rs @@ -275,9 +275,9 @@ impl BucketEntryInner { && signed_node_info.timestamp() == current_sni.timestamp() { // No need to update the signednodeinfo though since the timestamp is the same - // Touch the node and let it try to live again + // Let the node try to live again but don't mark it as seen yet self.updated_since_last_network_change = true; - self.touch_last_seen(get_aligned_timestamp()); + self.make_not_dead(get_aligned_timestamp()); } return; } @@ -293,10 +293,11 @@ impl BucketEntryInner { let envelope_support = signed_node_info.node_info().envelope_support().to_vec(); // Update the signed node info + // Let the node try to live again but don't mark it as seen yet *opt_current_sni = Some(Box::new(signed_node_info)); self.set_envelope_support(envelope_support); self.updated_since_last_network_change = true; - self.touch_last_seen(get_aligned_timestamp()); + self.make_not_dead(get_aligned_timestamp()); // If we're updating an entry's node info, purge all // but the last connection in our last connections list @@ -760,6 +761,13 @@ impl BucketEntryInner { self.peer_stats.rpc_stats.last_seen_ts = Some(ts); } + pub(super) fn make_not_dead(&mut self, cur_ts: Timestamp) { + self.peer_stats.rpc_stats.last_seen_ts = None; + self.peer_stats.rpc_stats.failed_to_send = 0; + self.peer_stats.rpc_stats.recent_lost_answers = 0; + assert!(!self.check_dead(cur_ts)); + } + pub(super) fn _state_debug_info(&self, cur_ts: Timestamp) -> String { let first_consecutive_seen_ts = if let Some(first_consecutive_seen_ts) = self.peer_stats.rpc_stats.first_consecutive_seen_ts diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index 301fc3df..faf54f4a 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -743,6 +743,16 @@ impl RoutingTable { out } + pub fn clear_punishments(&self) { + let cur_ts = get_aligned_timestamp(); + self.inner + .write() + .with_entries_mut(cur_ts, BucketEntryState::Dead, |rti, e| { + e.with_mut(rti, |_rti, ei| ei.set_punished(false)); + Option::<()>::None + }); + } + ////////////////////////////////////////////////////////////////////// // Find Nodes diff --git a/veilid-core/src/routing_table/routing_table_inner.rs b/veilid-core/src/routing_table/routing_table_inner.rs index 25ea2659..b8f8c829 100644 --- a/veilid-core/src/routing_table/routing_table_inner.rs +++ b/veilid-core/src/routing_table/routing_table_inner.rs @@ -860,7 +860,7 @@ impl RoutingTableInner { timestamp: Timestamp, ) -> EyreResult { let nr = self.create_node_ref(outer_self, &TypedKeyGroup::from(node_id), |_rti, e| { - // this node is live because it literally just connected to us + //e.make_not_dead(timestamp); e.touch_last_seen(timestamp); })?; // set the most recent node address for connection finding and udp replies diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 1909f615..8c7674c5 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -940,6 +940,9 @@ impl VeilidAPI { async fn debug_resolve(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table(); + let Some(_rpc) = netman.opt_rpc_processor() else { + apibail_internal!("Must be attached first"); + }; let args: Vec = args.split_whitespace().map(|s| s.to_owned()).collect(); @@ -981,7 +984,9 @@ impl VeilidAPI { async fn debug_ping(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table(); - let rpc = netman.rpc_processor(); + let Some(rpc) = netman.opt_rpc_processor() else { + apibail_internal!("Must be attached first"); + }; let args: Vec = args.split_whitespace().map(|s| s.to_owned()).collect(); @@ -1012,7 +1017,9 @@ impl VeilidAPI { async fn debug_app_message(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table(); - let rpc = netman.rpc_processor(); + let Some(rpc) = netman.opt_rpc_processor() else { + apibail_internal!("Must be attached first"); + }; let (arg, rest) = args.split_once(' ').unwrap_or((&args, "")); let rest = rest.trim_start().to_owned(); @@ -1046,7 +1053,9 @@ impl VeilidAPI { async fn debug_app_call(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table(); - let rpc = netman.rpc_processor(); + let Some(rpc) = netman.opt_rpc_processor() else { + apibail_internal!("Must be attached first"); + }; let (arg, rest) = args.split_once(' ').unwrap_or((&args, "")); let rest = rest.trim_start().to_owned(); @@ -1083,7 +1092,9 @@ impl VeilidAPI { async fn debug_app_reply(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; - let rpc = netman.rpc_processor(); + let Some(rpc) = netman.opt_rpc_processor() else { + apibail_internal!("Must be attached first"); + }; let (call_id, data) = if let Some(stripped_args) = args.strip_prefix('#') { let (arg, rest) = stripped_args.split_once(' ').unwrap_or((&args, "")); diff --git a/veilid-core/src/veilid_api/types/veilid_state.rs b/veilid-core/src/veilid_api/types/veilid_state.rs index c751d096..6fb5c7bd 100644 --- a/veilid-core/src/veilid_api/types/veilid_state.rs +++ b/veilid-core/src/veilid_api/types/veilid_state.rs @@ -17,6 +17,21 @@ pub enum AttachmentState { OverAttached = 6, Detaching = 7, } +impl AttachmentState { + pub fn is_detached(&self) -> bool { + matches!(self, Self::Detached) + } + pub fn is_attached(&self) -> bool { + matches!( + self, + Self::AttachedWeak + | Self::AttachedGood + | Self::AttachedStrong + | Self::FullyAttached + | Self::OverAttached + ) + } +} impl fmt::Display for AttachmentState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {