From 70a0346cc38d2ad99eb51899a151fd51b5676aef Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 13 Jul 2023 18:52:03 -0400 Subject: [PATCH] fix some more network issues --- veilid-core/src/intf/native/system.rs | 20 ++++++++++++++--- .../network_manager/native/protocol/udp.rs | 6 ++++- veilid-core/src/network_manager/send_data.rs | 18 +++++++-------- veilid-core/src/network_manager/tasks/mod.rs | 6 +++++ .../route_spec_store/route_spec_store.rs | 3 ++- .../src/routing_table/tasks/bootstrap.rs | 22 ++++++++++++++----- .../tasks/private_route_management.rs | 8 +++++++ veilid-flutter/setup_flutter.sh | 4 ++++ veilid-tools/src/assembly_buffer.rs | 2 -- 9 files changed, 68 insertions(+), 21 deletions(-) diff --git a/veilid-core/src/intf/native/system.rs b/veilid-core/src/intf/native/system.rs index 9855c256..3d98a668 100644 --- a/veilid-core/src/intf/native/system.rs +++ b/veilid-core/src/intf/native/system.rs @@ -19,7 +19,7 @@ cfg_if! { if #[cfg(feature="rt-async-std")] { use async_std_resolver::{config, resolver, resolver_from_system_conf, AsyncStdResolver as AsyncResolver}; } else if #[cfg(feature="rt-tokio")] { - use trust_dns_resolver::{config, TokioAsyncResolver as AsyncResolver, error::ResolveError}; + use trust_dns_resolver::{config, TokioAsyncResolver as AsyncResolver, error::ResolveError, error::ResolveErrorKind}; pub async fn resolver( config: config::ResolverConfig, @@ -66,6 +66,12 @@ cfg_if! { Ok(resolver) } } + + async fn reset_resolver() { + let mut resolver_lock = RESOLVER.lock().await; + *resolver_lock = None; + } + } } @@ -107,9 +113,17 @@ pub async fn txt_lookup>(host: S) -> EyreResult> { } else { let resolver = get_resolver().await?; - let txt_result = resolver + let txt_result = match resolver .txt_lookup(host.as_ref()) - .await?; + .await { + Ok(v) => v, + Err(e) => { + if matches!(e.kind(), ResolveErrorKind::NoConnections) { + reset_resolver().await; + } + bail!("txt_lookup error: {}", e); + } + }; let mut out = Vec::new(); for x in txt_result.iter() { for s in x.txt_data() { diff --git a/veilid-core/src/network_manager/native/protocol/udp.rs b/veilid-core/src/network_manager/native/protocol/udp.rs index 824c0532..da129a75 100644 --- a/veilid-core/src/network_manager/native/protocol/udp.rs +++ b/veilid-core/src/network_manager/native/protocol/udp.rs @@ -39,8 +39,8 @@ impl RawUdpProtocolHandler { NetworkResult::Value(None) => { continue; } + #[cfg(feature = "network-result-extra")] nres => { - #[cfg(feature = "network-result-extra")] log_network_result!( "UDP::recv_message insert_frame failed: {:?} <= size={} remote_addr={}", nres, @@ -49,6 +49,10 @@ impl RawUdpProtocolHandler { ); continue; } + #[cfg(not(feature = "network-result-extra"))] + _ => { + continue; + } }; // Check length of reassembled message (same for all protocols) diff --git a/veilid-core/src/network_manager/send_data.rs b/veilid-core/src/network_manager/send_data.rs index 0d8b336e..9a8ea1e1 100644 --- a/veilid-core/src/network_manager/send_data.rs +++ b/veilid-core/src/network_manager/send_data.rs @@ -12,29 +12,29 @@ impl NetworkManager { /// Sending to a node requires determining a NetworkClass compatible mechanism pub fn send_data( &self, - target_node_ref: NodeRef, + destination_node_ref: NodeRef, data: Vec, ) -> SendPinBoxFuture>> { let this = self.clone(); Box::pin( async move { // Get the best way to contact this node - let contact_method = this.get_node_contact_method(target_node_ref.clone())?; + let contact_method = this.get_node_contact_method(destination_node_ref.clone())?; // If we need to relay, do it - let (contact_method, node_ref, relayed) = match contact_method { + let (contact_method, target_node_ref, relayed) = match contact_method { NodeContactMethod::OutboundRelay(relay_nr) | NodeContactMethod::InboundRelay(relay_nr) => { let cm = this.get_node_contact_method(relay_nr.clone())?; (cm, relay_nr, true) } - cm => (cm, target_node_ref.clone(), false), + cm => (cm, destination_node_ref.clone(), false), }; - + #[cfg(feature = "verbose-tracing")] debug!( "ContactMethod: {:?} for {:?}", - contact_method, target_node_ref + contact_method, destination_node_ref ); // Try the contact method @@ -43,15 +43,15 @@ impl NetworkManager { | NodeContactMethod::InboundRelay(relay_nr) => { // Relay loop or multiple relays bail!( - "Relay loop or multiple relays detected: {} -> {} -> {}", + "Relay loop or multiple relays detected: destination {} resolved to target {} via extraneous relay {}", + destination_node_ref, target_node_ref, - node_ref, relay_nr ); } NodeContactMethod::Direct(dial_info) => { network_result_try!( - this.send_data_ncm_direct(node_ref, dial_info, data).await? + this.send_data_ncm_direct(target_node_ref, dial_info, data).await? ) } NodeContactMethod::SignalReverse(relay_nr, target_node_ref) => { diff --git a/veilid-core/src/network_manager/tasks/mod.rs b/veilid-core/src/network_manager/tasks/mod.rs index 06bec578..d7ff6fb0 100644 --- a/veilid-core/src/network_manager/tasks/mod.rs +++ b/veilid-core/src/network_manager/tasks/mod.rs @@ -86,5 +86,11 @@ impl NetworkManager { if let Err(e) = self.unlocked_inner.rolling_transfers_task.stop().await { warn!("rolling_transfers_task not stopped: {}", e); } + + debug!("stopping routing table tasks"); + let routing_table = self.routing_table(); + routing_table.cancel_tasks().await; + + // other tasks will get cancelled via the 'shutdown' mechanism } } 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 b1a2aef1..ef1f4762 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 @@ -188,7 +188,8 @@ impl RouteSpecStore { } let Some(our_peer_info) = rti.get_own_peer_info(RoutingDomain::PublicInternet) else { - bail!("Can't allocate route until we have our own peer info"); + log_rtab!(debug "unable to allocate route until we have our own peer info"); + return Ok(None); }; // Get relay node if we have one diff --git a/veilid-core/src/routing_table/tasks/bootstrap.rs b/veilid-core/src/routing_table/tasks/bootstrap.rs index 1913e5be..f48a6011 100644 --- a/veilid-core/src/routing_table/tasks/bootstrap.rs +++ b/veilid-core/src/routing_table/tasks/bootstrap.rs @@ -124,7 +124,16 @@ impl RoutingTable { let mut bsnames = Vec::::new(); for bh in bootstrap { // Get TXT record for bootstrap (bootstrap.veilid.net, or similar) - let records = intf::txt_lookup(&bh).await?; + let records = match intf::txt_lookup(&bh).await { + Ok(v) => v, + Err(e) => { + warn!( + "Network may be down. No bootstrap resolution for '{}': {}", + bh, e + ); + continue; + } + }; for record in records { // Split the bootstrap name record by commas for rec in record.split(',') { @@ -152,7 +161,10 @@ impl RoutingTable { // look up boostrap node txt records let bsnirecords = match intf::txt_lookup(&bsname).await { Err(e) => { - warn!("bootstrap node txt lookup failed for {}: {}", bsname, e); + warn!( + "Network may be down. Bootstrap node txt lookup failed for {}: {}", + bsname, e + ); return None; } Ok(v) => v, @@ -171,7 +183,7 @@ impl RoutingTable { let txt_version: u8 = match records[0].parse::() { Ok(v) => v, Err(e) => { - warn!( + log_rtab!(warn "invalid txt_version specified in bootstrap node txt record: {}", e ); @@ -182,7 +194,7 @@ impl RoutingTable { BOOTSTRAP_TXT_VERSION_0 => { match self.process_bootstrap_records_v0(records).await { Err(e) => { - warn!( + log_rtab!(error "couldn't process v0 bootstrap records from {}: {}", bsname, e ); @@ -196,7 +208,7 @@ impl RoutingTable { } } _ => { - warn!("unsupported bootstrap txt record version"); + log_rtab!(warn "unsupported bootstrap txt record version"); continue; } }; diff --git a/veilid-core/src/routing_table/tasks/private_route_management.rs b/veilid-core/src/routing_table/tasks/private_route_management.rs index 715c25aa..7e522377 100644 --- a/veilid-core/src/routing_table/tasks/private_route_management.rs +++ b/veilid-core/src/routing_table/tasks/private_route_management.rs @@ -179,6 +179,14 @@ impl RoutingTable { return Ok(()); } + // If we don't have our own peer info then don't do this yet + if self + .get_own_peer_info(RoutingDomain::PublicInternet) + .is_none() + { + return Ok(()); + }; + // Test locally allocated routes first // This may remove dead routes let routes_needing_testing = self.get_allocated_routes_to_test(cur_ts); diff --git a/veilid-flutter/setup_flutter.sh b/veilid-flutter/setup_flutter.sh index 664d28fa..83145471 100755 --- a/veilid-flutter/setup_flutter.sh +++ b/veilid-flutter/setup_flutter.sh @@ -80,6 +80,10 @@ elif [ "$OS" == "macos" ]; then # sudo arch -x86_64 gem install ffi sudo arch -x86_64 gem install cocoapods + if [ "$(uname -p)" == "arm" ]; then + sudo softwareupdate --install-rosetta --agree-to-license + fi + # ensure platforms are enabled in flutter flutter config --enable-macos-desktop --enable-ios --enable-android fi diff --git a/veilid-tools/src/assembly_buffer.rs b/veilid-tools/src/assembly_buffer.rs index 3f3bd948..d2bdf077 100644 --- a/veilid-tools/src/assembly_buffer.rs +++ b/veilid-tools/src/assembly_buffer.rs @@ -61,7 +61,6 @@ impl PeerMessages { if assembly.data.len() != len as usize { // Drop the assembly and just go with the new fragment as starting a new assembly let seq = assembly.seq; - drop(assembly); self.remove_assembly(ass); self.new_assembly(timestamp, seq, off, len, chunk); return false; @@ -74,7 +73,6 @@ impl PeerMessages { // if fragments overlap, drop the old assembly and go with a new one if !assembly.parts.is_disjoint(&part) { let seq = assembly.seq; - drop(assembly); self.remove_assembly(ass); self.new_assembly(timestamp, seq, off, len, chunk); return false;