diff --git a/veilid-core/src/routing_table/bucket_entry.rs b/veilid-core/src/routing_table/bucket_entry.rs index 8f3d0155..39f7e9f4 100644 --- a/veilid-core/src/routing_table/bucket_entry.rs +++ b/veilid-core/src/routing_table/bucket_entry.rs @@ -247,7 +247,6 @@ impl BucketEntryInner { *opt_current_sni = None; } - // Retuns true if the node info changed pub fn update_signed_node_info( &mut self, routing_domain: RoutingDomain, @@ -289,6 +288,13 @@ impl BucketEntryInner { self.set_envelope_support(envelope_support); self.updated_since_last_network_change = true; self.touch_last_seen(get_aligned_timestamp()); + + // If we're updating an entry's node info, purge all + // but the last connection in our last connections list + // because the dial info could have changed and its safer to just reconnect. + // The latest connection would have been the once we got the new node info + // over so that connection is still valid. + self.clear_last_connections_except_latest(); } pub fn has_node_info(&self, routing_domain_set: RoutingDomainSet) -> bool { @@ -410,6 +416,35 @@ impl BucketEntryInner { self.last_connections.clear(); } + // Clears the table of last connections except the most recent one + pub fn clear_last_connections_except_latest(&mut self) { + if self.last_connections.len() == 0 { + // No last_connections + return; + } + let mut dead_keys = Vec::with_capacity(self.last_connections.len()-1); + let mut most_recent_connection = None; + let mut most_recent_connection_time = 0u64; + for (k, v) in &self.last_connections { + let lct = v.1.as_u64(); + if lct > most_recent_connection_time { + most_recent_connection = Some(k); + most_recent_connection_time = lct; + } + } + let Some(most_recent_connection) = most_recent_connection else { + return; + }; + for (k, _) in &self.last_connections { + if k != most_recent_connection { + dead_keys.push(k.clone()); + } + } + for dk in dead_keys { + self.last_connections.remove(&dk); + } + } + // Gets all the 'last connections' that match a particular filter, and their accompanying timestamps of last use pub(super) fn last_connections( &self, diff --git a/veilid-core/src/routing_table/tasks/ping_validator.rs b/veilid-core/src/routing_table/tasks/ping_validator.rs index 54f84dae..7f47fbc0 100644 --- a/veilid-core/src/routing_table/tasks/ping_validator.rs +++ b/veilid-core/src/routing_table/tasks/ping_validator.rs @@ -71,8 +71,8 @@ impl RoutingTable { let relay_nr_filtered = relay_nr.filtered_clone(NodeRefFilter::new().with_dial_info_filter(dif)); - #[cfg(feature = "network-result-extra")] - log_rtab!(debug "--> Keepalive ping to {:?}", relay_nr_filtered); + //#[cfg(feature = "network-result-extra")] + log_rtab!("--> Keepalive ping to {:?}", relay_nr_filtered); unord.push( async move { @@ -111,6 +111,7 @@ impl RoutingTable { // Just do a single ping with the best protocol for all the other nodes to check for liveness for nr in node_refs { let rpc = rpc.clone(); + log_rtab!("--> Validator ping to {:?}", nr); unord.push( async move { rpc.rpc_call_status(Destination::direct(nr)).await } .instrument(Span::current()) diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 01f02043..ebe633d5 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -526,6 +526,37 @@ impl VeilidAPI { Ok(routing_table.debug_info_entry(node_ref)) } + async fn debug_relay(&self, args: String) -> VeilidAPIResult { + let args: Vec = args.split_whitespace().map(|s| s.to_owned()).collect(); + let routing_table = self.network_manager()?.routing_table(); + + let relay_node = get_debug_argument_at( + &args, + 0, + "debug_relay", + "node_id", + get_node_ref(routing_table), + )?; + + let routing_domain = get_debug_argument_at( + &args, + 0, + "debug_relay", + "routing_domain", + get_routing_domain, + ) + .ok() + .unwrap_or(RoutingDomain::PublicInternet); + + // Dump routing table entry + let routing_table = self.network_manager()?.routing_table(); + routing_table + .edit_routing_domain(routing_domain) + .set_relay_node(relay_node) + .commit(); + Ok("Relay changed".to_owned()) + } + async fn debug_nodeinfo(&self, _args: String) -> VeilidAPIResult { // Dump routing table entry let routing_table = self.network_manager()?.routing_table(); @@ -1306,6 +1337,7 @@ detach restart network contact [] ping +relay [public|local] route allocate [ord|*ord] [rel] [] [in|out] release publish [full] @@ -1374,6 +1406,8 @@ record list self.debug_entries(rest).await } else if arg == "entry" { self.debug_entry(rest).await + } else if arg == "relay" { + self.debug_relay(rest).await } else if arg == "ping" { self.debug_ping(rest).await } else if arg == "contact" {