reimplement node_ref filtering

This commit is contained in:
John Smith 2022-04-19 11:23:44 -04:00
parent 1d30073360
commit 0440391189
5 changed files with 121 additions and 64 deletions

View File

@ -64,9 +64,7 @@ struct NetworkInner {
struct NetworkUnlockedInner { struct NetworkUnlockedInner {
// Background processes // Background processes
update_udpv4_dialinfo_task: TickTask, update_public_dialinfo_task: TickTask,
update_tcpv4_dialinfo_task: TickTask,
update_wsv4_dialinfo_task: TickTask,
} }
#[derive(Clone)] #[derive(Clone)]
@ -106,9 +104,7 @@ impl Network {
fn new_unlocked_inner() -> NetworkUnlockedInner { fn new_unlocked_inner() -> NetworkUnlockedInner {
NetworkUnlockedInner { NetworkUnlockedInner {
update_udpv4_dialinfo_task: TickTask::new(1), update_public_dialinfo_task: TickTask::new(1),
update_tcpv4_dialinfo_task: TickTask::new(1),
update_wsv4_dialinfo_task: TickTask::new(1),
} }
} }
@ -119,31 +115,13 @@ impl Network {
unlocked_inner: Arc::new(Self::new_unlocked_inner()), unlocked_inner: Arc::new(Self::new_unlocked_inner()),
}; };
// Set udp dialinfo tick task // Set public dialinfo tick task
{ {
let this2 = this.clone(); let this2 = this.clone();
this.unlocked_inner this.unlocked_inner
.update_udpv4_dialinfo_task .update_public_dialinfo_task
.set_routine(move |l, t| { .set_routine(move |l, t| {
Box::pin(this2.clone().update_udpv4_dialinfo_task_routine(l, t)) Box::pin(this2.clone().update_public_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))
}); });
} }
@ -521,24 +499,22 @@ impl Network {
// If we can have public dialinfo, or we haven't figured out our network class yet, // 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 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 // and assess our network class if we haven't already
if protocol_config.inbound.udp if (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
&& !udp_static_public_dialinfo &&
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
{ {
let filter = DialInfoFilter::all() let filter = DialInfoFilter::global()
.with_protocol_type(ProtocolType::UDP) .with_protocol_type(ProtocolType::TCP)
.with_address_type(AddressType::IPV4); .with_address_type(AddressType::IPV4);
let need_udpv4_dialinfo = routing_table let need_tcpv4_dialinfo = routing_table
.first_public_filtered_dial_info_detail(&filter) .first_public_filtered_dial_info_detail(&filter)
.is_none(); .is_none();
if need_udpv4_dialinfo { if need_tcpv4_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?;
} }
self.unlocked_inner
.update_public_dialinfo_task
.tick()
.await?;
} }
// Same but for TCPv4 // Same but for TCPv4

View File

@ -38,7 +38,7 @@ impl Bucket {
// Get a node ref to return // Get a node ref to return
let entry_ref = self.entries.get_mut(&node_id).unwrap(); 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) { pub(super) fn remove_entry(&mut self, node_id: &DHTKey) {

View File

@ -34,7 +34,14 @@ impl RoutingTable {
}, },
)), )),
// transform // 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()),
)
},
) )
} }

View File

@ -490,7 +490,7 @@ impl RoutingTable {
let bucket = &mut inner.buckets[idx]; let bucket = &mut inner.buckets[idx];
bucket bucket
.entry_mut(&node_id) .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 // 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() { for (k, entry) in b.entries_mut() {
// Ensure it's not dead // Ensure it's not dead
if !matches!(entry.state(cur_ts), BucketEntryState::Dead) { if !matches!(entry.state(cur_ts), BucketEntryState::Dead) {
// Ensure we have a node info // Ensure this node is not on our local network
if let Some(node_status) = &entry.peer_stats().status { if !entry.local_node_info().has_dial_info() {
// Ensure the node will relay // Ensure we have the node's status
if node_status.will_relay { if let Some(node_status) = &entry.peer_stats().status {
if let Some(best_inbound_relay) = best_inbound_relay.as_mut() { // Ensure the node will relay
if best_inbound_relay.operate(|best| { if node_status.will_relay {
BucketEntry::cmp_fastest_reliable(cur_ts, best, entry) if let Some(best_inbound_relay) = best_inbound_relay.as_mut() {
}) == std::cmp::Ordering::Greater if best_inbound_relay.operate(|best| {
{ BucketEntry::cmp_fastest_reliable(cur_ts, best, entry)
*best_inbound_relay = NodeRef::new(self.clone(), *k, 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); let mut noderefs = Vec::<NodeRef>::with_capacity(inner.bucket_entry_count);
for b in &mut inner.buckets { for b in &mut inner.buckets {
for (k, entry) in b.entries_mut() { 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 noderefs
@ -736,7 +741,7 @@ impl RoutingTable {
for b in &mut inner.buckets { for b in &mut inner.buckets {
for (k, entry) in b.entries_mut() { for (k, entry) in b.entries_mut() {
if entry.needs_ping(self.clone(), k, cur_ts) { 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!( log_rtab!(
" --- ping validating: {:?} ({})", " --- ping validating: {:?} ({})",
nr, nr,

View File

@ -9,14 +9,21 @@ const CONNECTIONLESS_TIMEOUT_SECS: u32 = 29;
pub struct NodeRef { pub struct NodeRef {
routing_table: RoutingTable, routing_table: RoutingTable,
node_id: DHTKey, node_id: DHTKey,
filter: Option<DialInfoFilter>,
} }
impl NodeRef { 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; entry.ref_count += 1;
Self { Self {
routing_table, routing_table,
node_id: key, node_id: key,
filter,
} }
} }
@ -34,18 +41,79 @@ impl NodeRef {
pub fn peer_info(&self) -> PeerInfo { pub fn peer_info(&self) -> PeerInfo {
self.operate(|e| e.peer_info(self.node_id())) 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 { pub fn has_seen_our_node_info(&self) -> bool {
self.operate(|e| e.has_seen_our_node_info()) self.operate(|e| e.has_seen_our_node_info())
} }
pub fn set_seen_our_node_info(&self) { pub fn set_seen_our_node_info(&self) {
self.operate(|e| e.set_seen_our_node_info(true)); 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> { pub async fn last_connection(&self) -> Option<ConnectionDescriptor> {
// Get the last connection and the last time we saw anything with this connection // Get the last connection and the last time we saw anything with this connection
let (last_connection, last_seen) = self.operate(|e| { let (last_connection, last_seen) = self.operate(|e| {
@ -88,6 +156,7 @@ impl Clone for NodeRef {
Self { Self {
routing_table: self.routing_table.clone(), routing_table: self.routing_table.clone(),
node_id: self.node_id, node_id: self.node_id,
filter: self.filter.clone(),
} }
} }
} }