reimplement node_ref filtering
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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()),
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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::<NodeRef>::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,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,14 +9,21 @@ const CONNECTIONLESS_TIMEOUT_SECS: u32 = 29;
 | 
			
		||||
pub struct NodeRef {
 | 
			
		||||
    routing_table: RoutingTable,
 | 
			
		||||
    node_id: DHTKey,
 | 
			
		||||
    filter: Option<DialInfoFilter>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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<DialInfoFilter>,
 | 
			
		||||
    ) -> 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<DialInfo> {
 | 
			
		||||
        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<F>(&self) -> Vec<DialInfo> {
 | 
			
		||||
        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<ConnectionDescriptor> {
 | 
			
		||||
        // 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(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user