From 87694f5f4a7e0b9da1c535b4be62d8071705c0a1 Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 12 Jul 2023 00:04:44 -0400 Subject: [PATCH 1/3] more entries detail --- veilid-core/src/routing_table/debug.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/veilid-core/src/routing_table/debug.rs b/veilid-core/src/routing_table/debug.rs index f329a4b4..32c9d366 100644 --- a/veilid-core/src/routing_table/debug.rs +++ b/veilid-core/src/routing_table/debug.rs @@ -114,6 +114,13 @@ impl RoutingTable { let mut out = String::new(); out += &format!("Entries: {}\n", inner.bucket_entry_count()); + out += &format!(" Live:\n"); + for ec in inner.cached_entry_counts() { + let routing_domain = ec.0 .0; + let crypto_kind = ec.0 .1; + let count = ec.1; + out += &format!(" {:?}:{}: {}\n", routing_domain, crypto_kind, count); + } for ck in &VALID_CRYPTO_KINDS { let mut b = 0; let blen = inner.buckets[ck].len(); From 714eca1411ae8ba45d83d90a25330db262bd3f4d Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 12 Jul 2023 19:38:35 -0400 Subject: [PATCH 2/3] relay fixes --- .../native/network_class_discovery.rs | 42 ++++++++++++++----- .../route_spec_store/route_spec_store.rs | 4 +- .../routing_table/tasks/relay_management.rs | 14 ++++++- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/veilid-core/src/network_manager/native/network_class_discovery.rs b/veilid-core/src/network_manager/native/network_class_discovery.rs index 02905bf9..c6a4ae8a 100644 --- a/veilid-core/src/network_manager/native/network_class_discovery.rs +++ b/veilid-core/src/network_manager/native/network_class_discovery.rs @@ -119,6 +119,7 @@ impl DiscoveryContext { let c = config.get(); c.network.dht.max_find_node_count as usize }; + let routing_domain = RoutingDomain::PublicInternet; // Build an filter that matches our protocol and address type // and excludes relayed nodes so we can get an accurate external address @@ -126,14 +127,14 @@ impl DiscoveryContext { .with_protocol_type(protocol_type) .with_address_type(address_type); let inbound_dial_info_entry_filter = RoutingTable::make_inbound_dial_info_entry_filter( - RoutingDomain::PublicInternet, + routing_domain, dial_info_filter.clone(), ); let disallow_relays_filter = Box::new( move |rti: &RoutingTableInner, v: Option>| { let v = v.unwrap(); v.with(rti, |_rti, e| { - if let Some(n) = e.signed_node_info(RoutingDomain::PublicInternet) { + if let Some(n) = e.signed_node_info(routing_domain) { n.relay_ids().is_empty() } else { false @@ -141,7 +142,33 @@ impl DiscoveryContext { }) }, ) as RoutingTableEntryFilter; - let filters = VecDeque::from([inbound_dial_info_entry_filter, disallow_relays_filter]); + let will_validate_dial_info_filter = Box::new( + move |rti: &RoutingTableInner, v: Option>| { + let entry = v.unwrap(); + entry.with(rti, move |_rti, e| { + e.node_info(routing_domain) + .map(|ni| { + ni.has_capability(CAP_VALIDATE_DIAL_INFO) && ni.is_signal_capable() + }) + .unwrap_or(false) + }) + }, + ) as RoutingTableEntryFilter; + + let mut filters = VecDeque::from([ + inbound_dial_info_entry_filter, + disallow_relays_filter, + will_validate_dial_info_filter, + ]); + if let Some(ignore_node_ids) = ignore_node_ids { + let ignore_nodes_filter = Box::new( + move |rti: &RoutingTableInner, v: Option>| { + let v = v.unwrap(); + v.with(rti, |_rti, e| !e.node_ids().contains_any(&ignore_node_ids)) + }, + ) as RoutingTableEntryFilter; + filters.push_back(ignore_nodes_filter); + } // Find public nodes matching this filter let peers = self @@ -156,16 +183,11 @@ impl DiscoveryContext { return None; } - // For each peer, if it's not our ignore-node, ask them for our public address, filtering on desired dial info + // For each peer, ask them for our public address, filtering on desired dial info for mut peer in peers { - if let Some(ignore_node_ids) = &ignore_node_ids { - if peer.node_ids().contains_any(ignore_node_ids) { - continue; - } - } peer.set_filter(Some( NodeRefFilter::new() - .with_routing_domain(RoutingDomain::PublicInternet) + .with_routing_domain(routing_domain) .with_dial_info_filter(dial_info_filter.clone()), )); if let Some(sa) = self.request_public_address(peer.clone()).await { diff --git a/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs b/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs index f1ae27c4..b1a2aef1 100644 --- a/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs +++ b/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs @@ -369,8 +369,8 @@ impl RouteSpecStore { } let opt_relay = match node.locked_mut(rti).relay(RoutingDomain::PublicInternet) { Ok(r) => r, - Err(e) => { - log_rtab!(error "failed to get relay for route node: {}", e); + Err(_) => { + // Not selecting a relay through ourselves return None; } }; diff --git a/veilid-core/src/routing_table/tasks/relay_management.rs b/veilid-core/src/routing_table/tasks/relay_management.rs index 960c5bc9..4b0f36ce 100644 --- a/veilid-core/src/routing_table/tasks/relay_management.rs +++ b/veilid-core/src/routing_table/tasks/relay_management.rs @@ -15,6 +15,7 @@ impl RoutingTable { }; let own_node_info = own_peer_info.signed_node_info().node_info(); let network_class = own_node_info.network_class(); + let relay_node_filter = self.make_public_internet_relay_node_filter(); // Get routing domain editor let mut editor = self.edit_routing_domain(RoutingDomain::PublicInternet); @@ -28,7 +29,18 @@ impl RoutingTable { info!("Relay node died, dropping relay {}", relay_node); editor.clear_relay_node(); false - } else if !own_node_info.requires_relay() { + } + // Relay node no longer can relay + else if relay_node.operate(|_rti, e| !relay_node_filter(e)) { + info!( + "Relay node can no longer relay, dropping relay {}", + relay_node + ); + editor.clear_relay_node(); + false + } + // Relay node is no longer required + else if !own_node_info.requires_relay() { info!( "Relay node no longer required, dropping relay {}", relay_node From 0a16938f9bdd9c37326ecaad8a77392dcc246564 Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 12 Jul 2023 20:12:45 -0400 Subject: [PATCH 3/3] fix signal --- .../network_manager/native/network_class_discovery.rs | 3 ++- .../src/routing_table/tasks/relay_management.rs | 4 ++-- veilid-core/src/routing_table/types/node_info.rs | 11 ++--------- veilid-core/src/rpc_processor/rpc_signal.rs | 3 ++- .../src/rpc_processor/rpc_validate_dial_info.rs | 5 +++-- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/veilid-core/src/network_manager/native/network_class_discovery.rs b/veilid-core/src/network_manager/native/network_class_discovery.rs index c6a4ae8a..3de494e1 100644 --- a/veilid-core/src/network_manager/native/network_class_discovery.rs +++ b/veilid-core/src/network_manager/native/network_class_discovery.rs @@ -148,7 +148,8 @@ impl DiscoveryContext { entry.with(rti, move |_rti, e| { e.node_info(routing_domain) .map(|ni| { - ni.has_capability(CAP_VALIDATE_DIAL_INFO) && ni.is_signal_capable() + ni.has_capability(CAP_VALIDATE_DIAL_INFO) + && ni.is_fully_direct_inbound() }) .unwrap_or(false) }) diff --git a/veilid-core/src/routing_table/tasks/relay_management.rs b/veilid-core/src/routing_table/tasks/relay_management.rs index 4b0f36ce..95612f8a 100644 --- a/veilid-core/src/routing_table/tasks/relay_management.rs +++ b/veilid-core/src/routing_table/tasks/relay_management.rs @@ -112,8 +112,8 @@ impl RoutingTable { let can_serve_as_relay = e .node_info(RoutingDomain::PublicInternet) .map(|n| { - if !(n.has_capability(CAP_RELAY) && n.is_signal_capable()) { - // Needs to be able to signal and relay + if !(n.has_capability(CAP_RELAY) && n.is_fully_direct_inbound()) { + // Needs to be able to accept packets to relay directly return false; } diff --git a/veilid-core/src/routing_table/types/node_info.rs b/veilid-core/src/routing_table/types/node_info.rs index 96c40637..4bbf31da 100644 --- a/veilid-core/src/routing_table/types/node_info.rs +++ b/veilid-core/src/routing_table/types/node_info.rs @@ -211,15 +211,8 @@ impl NodeInfo { true } - /// Can this node assist with signalling? Yes but only if it doesn't require signalling, itself. - /// Also used to determine if nodes are capable of validation of dial info, as that operation - /// has the same requirements, inbound capability and a dial info that requires no assistance - pub fn is_signal_capable(&self) -> bool { - // Has capability? - if !self.has_capability(CAP_SIGNAL) { - return false; - } - + /// Can direct connections be made + pub fn is_fully_direct_inbound(&self) -> bool { // Must be inbound capable if !matches!(self.network_class, NetworkClass::InboundCapable) { return false; diff --git a/veilid-core/src/rpc_processor/rpc_signal.rs b/veilid-core/src/rpc_processor/rpc_signal.rs index 4e32952a..4b325d73 100644 --- a/veilid-core/src/rpc_processor/rpc_signal.rs +++ b/veilid-core/src/rpc_processor/rpc_signal.rs @@ -41,7 +41,8 @@ impl RPCProcessor { let routing_table = self.routing_table(); { if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().is_signal_capable() { + let ni = opi.signed_node_info().node_info(); + if !ni.has_capability(CAP_SIGNAL) { return Ok(NetworkResult::service_unavailable( "signal is not available", )); diff --git a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs index 16598b31..37eaef96 100644 --- a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs +++ b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs @@ -72,7 +72,7 @@ impl RPCProcessor { { if let Some(opi) = routing_table.get_own_peer_info(detail.routing_domain) { let ni = opi.signed_node_info().node_info(); - if !ni.has_capability(CAP_VALIDATE_DIAL_INFO) || !ni.is_signal_capable() { + if !ni.has_capability(CAP_VALIDATE_DIAL_INFO) || !ni.is_fully_direct_inbound() { return Ok(NetworkResult::service_unavailable( "validate dial info is not available", )); @@ -118,7 +118,8 @@ impl RPCProcessor { entry.with(rti, move |_rti, e| { e.node_info(routing_domain) .map(|ni| { - ni.has_capability(CAP_VALIDATE_DIAL_INFO) && ni.is_signal_capable() + ni.has_capability(CAP_VALIDATE_DIAL_INFO) + && ni.is_fully_direct_inbound() }) .unwrap_or(false) })