diff --git a/veilid-core/src/intf/native/network/mod.rs b/veilid-core/src/intf/native/network/mod.rs index 03f30575..eccac9e4 100644 --- a/veilid-core/src/intf/native/network/mod.rs +++ b/veilid-core/src/intf/native/network/mod.rs @@ -64,9 +64,7 @@ struct NetworkInner { struct NetworkUnlockedInner { // Background processes - update_udpv4_dialinfo_task: TickTask, - update_tcpv4_dialinfo_task: TickTask, - update_wsv4_dialinfo_task: TickTask, + update_public_dialinfo_task: TickTask, } #[derive(Clone)] @@ -106,9 +104,7 @@ impl Network { fn new_unlocked_inner() -> NetworkUnlockedInner { NetworkUnlockedInner { - update_udpv4_dialinfo_task: TickTask::new(1), - update_tcpv4_dialinfo_task: TickTask::new(1), - update_wsv4_dialinfo_task: TickTask::new(1), + update_public_dialinfo_task: TickTask::new(1), } } @@ -119,31 +115,13 @@ impl Network { unlocked_inner: Arc::new(Self::new_unlocked_inner()), }; - // Set udp dialinfo tick task + // Set public dialinfo tick task { let this2 = this.clone(); this.unlocked_inner - .update_udpv4_dialinfo_task + .update_public_dialinfo_task .set_routine(move |l, t| { - Box::pin(this2.clone().update_udpv4_dialinfo_task_routine(l, t)) - }); - } - // Set tcp dialinfo tick task - { - let this2 = this.clone(); - this.unlocked_inner - .update_tcpv4_dialinfo_task - .set_routine(move |l, t| { - Box::pin(this2.clone().update_tcpv4_dialinfo_task_routine(l, t)) - }); - } - // Set ws dialinfo tick task - { - let this2 = this.clone(); - this.unlocked_inner - .update_wsv4_dialinfo_task - .set_routine(move |l, t| { - Box::pin(this2.clone().update_wsv4_dialinfo_task_routine(l, t)) + Box::pin(this2.clone().update_public_dialinfo_task_routine(l, t)) }); } @@ -521,24 +499,22 @@ impl Network { // If we can have public dialinfo, or we haven't figured out our network class yet, // and we're active for UDP, we should attempt to get our public dialinfo sorted out // and assess our network class if we haven't already - if protocol_config.inbound.udp - && !udp_static_public_dialinfo - && (network_class.inbound_capable() || network_class == NetworkClass::Invalid) + if (network_class.inbound_capable() || network_class == NetworkClass::Invalid) + && { - let filter = DialInfoFilter::all() - .with_protocol_type(ProtocolType::UDP) + let filter = DialInfoFilter::global() + .with_protocol_type(ProtocolType::TCP) .with_address_type(AddressType::IPV4); - let need_udpv4_dialinfo = routing_table + let need_tcpv4_dialinfo = routing_table .first_public_filtered_dial_info_detail(&filter) .is_none(); - if need_udpv4_dialinfo { - // If we have no public UDPv4 dialinfo, then we need to run a NAT check - // ensure the singlefuture is running for this - self.unlocked_inner - .update_udpv4_dialinfo_task - .tick() - .await?; + if need_tcpv4_dialinfo { } + + self.unlocked_inner + .update_public_dialinfo_task + .tick() + .await?; } // Same but for TCPv4 diff --git a/veilid-core/src/routing_table/bucket.rs b/veilid-core/src/routing_table/bucket.rs index ae6cec19..69581526 100644 --- a/veilid-core/src/routing_table/bucket.rs +++ b/veilid-core/src/routing_table/bucket.rs @@ -38,7 +38,7 @@ impl Bucket { // Get a node ref to return let entry_ref = self.entries.get_mut(&node_id).unwrap(); - NodeRef::new(self.routing_table.clone(), node_id, entry_ref) + NodeRef::new(self.routing_table.clone(), node_id, entry_ref, None) } pub(super) fn remove_entry(&mut self, node_id: &DHTKey) { diff --git a/veilid-core/src/routing_table/find_nodes.rs b/veilid-core/src/routing_table/find_nodes.rs index 6340ae34..dc7c29d7 100644 --- a/veilid-core/src/routing_table/find_nodes.rs +++ b/veilid-core/src/routing_table/find_nodes.rs @@ -34,7 +34,14 @@ impl RoutingTable { }, )), // transform - |e| NodeRef::new(self.clone(), *e.0, e.1.as_mut().unwrap()), + |e| { + NodeRef::new( + self.clone(), + *e.0, + e.1.as_mut().unwrap(), + Some(dial_info_filter.clone()), + ) + }, ) } diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index fe0b1675..e96276bc 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -490,7 +490,7 @@ impl RoutingTable { let bucket = &mut inner.buckets[idx]; bucket .entry_mut(&node_id) - .map(|e| NodeRef::new(self.clone(), node_id, e)) + .map(|e| NodeRef::new(self.clone(), node_id, e, None)) } // Shortcut function to add a node to our routing table if it doesn't exist @@ -546,19 +546,24 @@ impl RoutingTable { for (k, entry) in b.entries_mut() { // Ensure it's not dead if !matches!(entry.state(cur_ts), BucketEntryState::Dead) { - // Ensure we have a node info - if let Some(node_status) = &entry.peer_stats().status { - // Ensure the node will relay - if node_status.will_relay { - if let Some(best_inbound_relay) = best_inbound_relay.as_mut() { - if best_inbound_relay.operate(|best| { - BucketEntry::cmp_fastest_reliable(cur_ts, best, entry) - }) == std::cmp::Ordering::Greater - { - *best_inbound_relay = NodeRef::new(self.clone(), *k, entry); + // Ensure this node is not on our local network + if !entry.local_node_info().has_dial_info() { + // Ensure we have the node's status + if let Some(node_status) = &entry.peer_stats().status { + // Ensure the node will relay + if node_status.will_relay { + if let Some(best_inbound_relay) = best_inbound_relay.as_mut() { + if best_inbound_relay.operate(|best| { + BucketEntry::cmp_fastest_reliable(cur_ts, best, entry) + }) == std::cmp::Ordering::Greater + { + *best_inbound_relay = + NodeRef::new(self.clone(), *k, entry, None); + } + } else { + best_inbound_relay = + Some(NodeRef::new(self.clone(), *k, entry, None)); } - } else { - best_inbound_relay = Some(NodeRef::new(self.clone(), *k, entry)); } } } @@ -709,7 +714,7 @@ impl RoutingTable { let mut noderefs = Vec::::with_capacity(inner.bucket_entry_count); for b in &mut inner.buckets { for (k, entry) in b.entries_mut() { - noderefs.push(NodeRef::new(self.clone(), *k, entry)) + noderefs.push(NodeRef::new(self.clone(), *k, entry, None)) } } noderefs @@ -736,7 +741,7 @@ impl RoutingTable { for b in &mut inner.buckets { for (k, entry) in b.entries_mut() { if entry.needs_ping(self.clone(), k, cur_ts) { - let nr = NodeRef::new(self.clone(), *k, entry); + let nr = NodeRef::new(self.clone(), *k, entry, None); log_rtab!( " --- ping validating: {:?} ({})", nr, diff --git a/veilid-core/src/routing_table/node_ref.rs b/veilid-core/src/routing_table/node_ref.rs index 6d8c96c9..35344762 100644 --- a/veilid-core/src/routing_table/node_ref.rs +++ b/veilid-core/src/routing_table/node_ref.rs @@ -9,14 +9,21 @@ const CONNECTIONLESS_TIMEOUT_SECS: u32 = 29; pub struct NodeRef { routing_table: RoutingTable, node_id: DHTKey, + filter: Option, } impl NodeRef { - pub fn new(routing_table: RoutingTable, key: DHTKey, entry: &mut BucketEntry) -> Self { + pub fn new( + routing_table: RoutingTable, + key: DHTKey, + entry: &mut BucketEntry, + filter: Option, + ) -> Self { entry.ref_count += 1; Self { routing_table, node_id: key, + filter, } } @@ -34,18 +41,79 @@ impl NodeRef { pub fn peer_info(&self) -> PeerInfo { self.operate(|e| e.peer_info(self.node_id())) } - pub fn node_info(&self) -> NodeInfo { - self.operate(|e| e.node_info().clone()) - } - pub fn local_node_info(&self) -> LocalNodeInfo { - self.operate(|e| e.local_node_info().clone()) - } pub fn has_seen_our_node_info(&self) -> bool { self.operate(|e| e.has_seen_our_node_info()) } pub fn set_seen_our_node_info(&self) { self.operate(|e| e.set_seen_our_node_info(true)); } + + pub fn first_filtered_dial_info(&self) -> Option { + self.operate(|e| { + if matches!( + self.filter.map(|f| f.peer_scope).unwrap_or(PeerScope::All), + PeerScope::All | PeerScope::Global + ) { + e.node_info().first_filtered_dial_info(|di| { + if let Some(filter) = self.filter { + di.matches_filter(&filter) + } else { + true + } + }) + } else { + None + } + .or_else(|| { + if matches!( + self.filter.map(|f| f.peer_scope).unwrap_or(PeerScope::All), + PeerScope::All | PeerScope::Local + ) { + e.local_node_info().first_filtered_dial_info(|di| { + if let Some(filter) = self.filter { + di.matches_filter(&filter) + } else { + true + } + }) + } else { + None + } + }) + }) + } + + pub fn all_filtered_dial_info(&self) -> Vec { + let mut out = Vec::new(); + self.operate(|e| { + if matches!( + self.filter.map(|f| f.peer_scope).unwrap_or(PeerScope::All), + PeerScope::All | PeerScope::Global + ) { + out.append(&mut e.node_info().all_filtered_dial_info(|di| { + if let Some(filter) = self.filter { + di.matches_filter(&filter) + } else { + true + } + })) + } + if matches!( + self.filter.map(|f| f.peer_scope).unwrap_or(PeerScope::All), + PeerScope::All | PeerScope::Local + ) { + out.append(&mut e.local_node_info().all_filtered_dial_info(|di| { + if let Some(filter) = self.filter { + di.matches_filter(&filter) + } else { + true + } + })) + } + }); + out + } + pub async fn last_connection(&self) -> Option { // Get the last connection and the last time we saw anything with this connection let (last_connection, last_seen) = self.operate(|e| { @@ -88,6 +156,7 @@ impl Clone for NodeRef { Self { routing_table: self.routing_table.clone(), node_id: self.node_id, + filter: self.filter.clone(), } } }