From 714eca1411ae8ba45d83d90a25330db262bd3f4d Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 12 Jul 2023 19:38:35 -0400 Subject: [PATCH] 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