Merge branch 'network-testing' into 'main'

Fix Network Issues

See merge request veilid/veilid!61
This commit is contained in:
Christien Rioux 2023-07-13 00:43:23 +00:00
commit 0894a9d6ec
7 changed files with 64 additions and 27 deletions

View File

@ -119,6 +119,7 @@ impl DiscoveryContext {
let c = config.get(); let c = config.get();
c.network.dht.max_find_node_count as usize c.network.dht.max_find_node_count as usize
}; };
let routing_domain = RoutingDomain::PublicInternet;
// Build an filter that matches our protocol and address type // Build an filter that matches our protocol and address type
// and excludes relayed nodes so we can get an accurate external address // and excludes relayed nodes so we can get an accurate external address
@ -126,14 +127,14 @@ impl DiscoveryContext {
.with_protocol_type(protocol_type) .with_protocol_type(protocol_type)
.with_address_type(address_type); .with_address_type(address_type);
let inbound_dial_info_entry_filter = RoutingTable::make_inbound_dial_info_entry_filter( let inbound_dial_info_entry_filter = RoutingTable::make_inbound_dial_info_entry_filter(
RoutingDomain::PublicInternet, routing_domain,
dial_info_filter.clone(), dial_info_filter.clone(),
); );
let disallow_relays_filter = Box::new( let disallow_relays_filter = Box::new(
move |rti: &RoutingTableInner, v: Option<Arc<BucketEntry>>| { move |rti: &RoutingTableInner, v: Option<Arc<BucketEntry>>| {
let v = v.unwrap(); let v = v.unwrap();
v.with(rti, |_rti, e| { 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() n.relay_ids().is_empty()
} else { } else {
false false
@ -141,7 +142,34 @@ impl DiscoveryContext {
}) })
}, },
) as RoutingTableEntryFilter; ) 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<Arc<BucketEntry>>| {
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_fully_direct_inbound()
})
.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<Arc<BucketEntry>>| {
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 // Find public nodes matching this filter
let peers = self let peers = self
@ -156,16 +184,11 @@ impl DiscoveryContext {
return None; 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 { 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( peer.set_filter(Some(
NodeRefFilter::new() NodeRefFilter::new()
.with_routing_domain(RoutingDomain::PublicInternet) .with_routing_domain(routing_domain)
.with_dial_info_filter(dial_info_filter.clone()), .with_dial_info_filter(dial_info_filter.clone()),
)); ));
if let Some(sa) = self.request_public_address(peer.clone()).await { if let Some(sa) = self.request_public_address(peer.clone()).await {

View File

@ -114,6 +114,13 @@ impl RoutingTable {
let mut out = String::new(); let mut out = String::new();
out += &format!("Entries: {}\n", inner.bucket_entry_count()); 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 { for ck in &VALID_CRYPTO_KINDS {
let mut b = 0; let mut b = 0;
let blen = inner.buckets[ck].len(); let blen = inner.buckets[ck].len();

View File

@ -369,8 +369,8 @@ impl RouteSpecStore {
} }
let opt_relay = match node.locked_mut(rti).relay(RoutingDomain::PublicInternet) { let opt_relay = match node.locked_mut(rti).relay(RoutingDomain::PublicInternet) {
Ok(r) => r, Ok(r) => r,
Err(e) => { Err(_) => {
log_rtab!(error "failed to get relay for route node: {}", e); // Not selecting a relay through ourselves
return None; return None;
} }
}; };

View File

@ -15,6 +15,7 @@ impl RoutingTable {
}; };
let own_node_info = own_peer_info.signed_node_info().node_info(); let own_node_info = own_peer_info.signed_node_info().node_info();
let network_class = own_node_info.network_class(); let network_class = own_node_info.network_class();
let relay_node_filter = self.make_public_internet_relay_node_filter();
// Get routing domain editor // Get routing domain editor
let mut editor = self.edit_routing_domain(RoutingDomain::PublicInternet); let mut editor = self.edit_routing_domain(RoutingDomain::PublicInternet);
@ -28,7 +29,18 @@ impl RoutingTable {
info!("Relay node died, dropping relay {}", relay_node); info!("Relay node died, dropping relay {}", relay_node);
editor.clear_relay_node(); editor.clear_relay_node();
false 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!( info!(
"Relay node no longer required, dropping relay {}", "Relay node no longer required, dropping relay {}",
relay_node relay_node
@ -100,8 +112,8 @@ impl RoutingTable {
let can_serve_as_relay = e let can_serve_as_relay = e
.node_info(RoutingDomain::PublicInternet) .node_info(RoutingDomain::PublicInternet)
.map(|n| { .map(|n| {
if !(n.has_capability(CAP_RELAY) && n.is_signal_capable()) { if !(n.has_capability(CAP_RELAY) && n.is_fully_direct_inbound()) {
// Needs to be able to signal and relay // Needs to be able to accept packets to relay directly
return false; return false;
} }

View File

@ -211,15 +211,8 @@ impl NodeInfo {
true true
} }
/// Can this node assist with signalling? Yes but only if it doesn't require signalling, itself. /// Can direct connections be made
/// Also used to determine if nodes are capable of validation of dial info, as that operation pub fn is_fully_direct_inbound(&self) -> bool {
/// 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;
}
// Must be inbound capable // Must be inbound capable
if !matches!(self.network_class, NetworkClass::InboundCapable) { if !matches!(self.network_class, NetworkClass::InboundCapable) {
return false; return false;

View File

@ -41,7 +41,8 @@ impl RPCProcessor {
let routing_table = self.routing_table(); let routing_table = self.routing_table();
{ {
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { 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( return Ok(NetworkResult::service_unavailable(
"signal is not available", "signal is not available",
)); ));

View File

@ -72,7 +72,7 @@ impl RPCProcessor {
{ {
if let Some(opi) = routing_table.get_own_peer_info(detail.routing_domain) { if let Some(opi) = routing_table.get_own_peer_info(detail.routing_domain) {
let ni = opi.signed_node_info().node_info(); 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( return Ok(NetworkResult::service_unavailable(
"validate dial info is not available", "validate dial info is not available",
)); ));
@ -118,7 +118,8 @@ impl RPCProcessor {
entry.with(rti, move |_rti, e| { entry.with(rti, move |_rti, e| {
e.node_info(routing_domain) e.node_info(routing_domain)
.map(|ni| { .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) .unwrap_or(false)
}) })