From 1b9a0493282d29212e0d5e135f3fb292ee631e09 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 16 Sep 2023 11:26:07 -0400 Subject: [PATCH] resolve work --- veilid-core/src/routing_table/bucket_entry.rs | 13 +++--- veilid-core/src/rpc_processor/mod.rs | 26 ++++++++---- veilid-core/src/veilid_api/debug.rs | 41 +++++++++++++++++++ 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/veilid-core/src/routing_table/bucket_entry.rs b/veilid-core/src/routing_table/bucket_entry.rs index 6d2ae45b..0d6fd71b 100644 --- a/veilid-core/src/routing_table/bucket_entry.rs +++ b/veilid-core/src/routing_table/bucket_entry.rs @@ -649,9 +649,10 @@ impl BucketEntryInner { return false; } - // if we have seen the node consistently for longer that UNRELIABLE_PING_SPAN_SECS match self.peer_stats.rpc_stats.first_consecutive_seen_ts { + // If we have not seen seen a node consecutively, it can't be reliable None => false, + // If we have seen the node consistently for longer than UNRELIABLE_PING_SPAN_SECS then it is reliable Some(ts) => { cur_ts.saturating_sub(ts) >= TimestampDuration::new(UNRELIABLE_PING_SPAN_SECS as u64 * 1000000u64) } @@ -662,11 +663,13 @@ impl BucketEntryInner { if self.peer_stats.rpc_stats.failed_to_send >= NEVER_REACHED_PING_COUNT { return true; } - // if we have not heard from the node at all for the duration of the unreliable ping span - // a node is not dead if we haven't heard from it yet, - // but we give it NEVER_REACHED_PING_COUNT chances to ping before we say it's dead + match self.peer_stats.rpc_stats.last_seen_ts { - None => self.peer_stats.rpc_stats.recent_lost_answers < NEVER_REACHED_PING_COUNT, + // a node is not dead if we haven't heard from it yet, + // but we give it NEVER_REACHED_PING_COUNT chances to ping before we say it's dead + None => self.peer_stats.rpc_stats.recent_lost_answers >= NEVER_REACHED_PING_COUNT, + + // return dead if we have not heard from the node at all for the duration of the unreliable ping span Some(ts) => { cur_ts.saturating_sub(ts) >= TimestampDuration::new(UNRELIABLE_PING_SPAN_SECS as u64 * 1000000u64) } diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 38a38ed8..63510ab0 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -453,7 +453,7 @@ impl RPCProcessor { ////////////////////////////////////////////////////////////////////// - /// Search the DHT for a single node closest to a key and add it to the routing table and return the node reference + /// Search the DHT for a single node and add it to the routing table and return the node reference /// If no node was found in the timeout, this returns None async fn search_dht_single_key( &self, @@ -491,14 +491,20 @@ impl RPCProcessor { }; // Routine to call to check if we're done at each step - let check_done = |closest_nodes: &[NodeRef]| { - // If the node we want to locate is one of the closest nodes, return it immediately - if let Some(out) = closest_nodes - .iter() - .find(|x| x.node_ids().contains(&node_id)) - { - return Some(out.clone()); + let check_done = |_:&[NodeRef]| { + let Ok(Some(nr)) = routing_table + .lookup_node_ref(node_id) else { + return None; + }; + + // ensure we have some dial info for the entry already, + // and that the node is still alive + // if not, we should keep looking for better info + if !matches!(nr.state(get_aligned_timestamp()),BucketEntryState::Dead) && + nr.has_any_dial_info() { + return Some(nr); } + None }; @@ -534,8 +540,10 @@ impl RPCProcessor { .map_err(RPCError::internal)? { // ensure we have some dial info for the entry already, + // and that the node is still alive // if not, we should do the find_node anyway - if nr.has_any_dial_info() { + if !matches!(nr.state(get_aligned_timestamp()),BucketEntryState::Dead) && + nr.has_any_dial_info() { return Ok(Some(nr)); } } diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 2ef953de..e0d05661 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -871,6 +871,47 @@ impl VeilidAPI { Ok(format!("{:#?}", cm)) } + async fn debug_resolve(&self, args: String) -> VeilidAPIResult { + let netman = self.network_manager()?; + let routing_table = netman.routing_table(); + + let args: Vec = args.split_whitespace().map(|s| s.to_owned()).collect(); + + let dest = async_get_debug_argument_at( + &args, + 0, + "debug_resolve", + "destination", + get_destination(routing_table.clone()), + ) + .await?; + + match &dest { + Destination::Direct { + target, + safety_selection: _, + } => Ok(format!( + "Destination: {:#?}\nTarget Entry:\n{}\n", + &dest, + routing_table.debug_info_entry(target.clone()) + )), + Destination::Relay { + relay, + target, + safety_selection: _, + } => Ok(format!( + "Destination: {:#?}\nTarget Entry:\n{}\nRelay Entry:\n{}\n", + &dest, + routing_table.clone().debug_info_entry(target.clone()), + routing_table.debug_info_entry(relay.clone()) + )), + Destination::PrivateRoute { + private_route: _, + safety_selection: _, + } => Ok(format!("Destination: {:#?}", &dest)), + } + } + async fn debug_ping(&self, args: String) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table();