From 86dee2b6ed98f8f067082d8567d2bd0a4d59742d Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 6 Oct 2023 16:41:25 -0400 Subject: [PATCH 01/10] xfer --- Cargo.lock | 1 + .../src/intf/native/protected_store.rs | 15 ++++++++-- veilid-flutter/lib/veilid.dart | 2 +- veilid-flutter/rust/Cargo.toml | 1 + veilid-flutter/rust/src/dart_ffi.rs | 29 ++++++++++++++----- veilid-tools/src/log_thru.rs | 8 +++++ 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fcaf2e1..d2fbe3f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5380,6 +5380,7 @@ dependencies = [ "opentelemetry", "opentelemetry-otlp", "opentelemetry-semantic-conventions", + "paranoid-android", "parking_lot 0.12.1", "serde", "serde_json", diff --git a/veilid-core/src/intf/native/protected_store.rs b/veilid-core/src/intf/native/protected_store.rs index 7faa0f49..accae460 100644 --- a/veilid-core/src/intf/native/protected_store.rs +++ b/veilid-core/src/intf/native/protected_store.rs @@ -41,6 +41,8 @@ impl ProtectedStore { #[instrument(level = "debug", skip(self), err)] pub async fn init(&self) -> EyreResult<()> { + log_pstore!(error "ASDFASDFASDF"); + let delete = { let c = self.config.get(); let mut inner = self.inner.lock(); @@ -48,11 +50,19 @@ impl ProtectedStore { // Attempt to open the secure keyring cfg_if! { if #[cfg(target_os = "android")] { - inner.keyring_manager = KeyringManager::new_secure(&c.program_name, crate::intf::android::get_android_globals()).ok(); + let maybe_km = KeyringManager::new_secure(&c.program_name, crate::intf::android::get_android_globals()); } else { - inner.keyring_manager = KeyringManager::new_secure(&c.program_name).ok(); + let maybe_km = KeyringManager::new_secure(&c.program_name); } } + + inner.keyring_manager = match maybe_km { + Ok(v) => Some(v), + Err(e) => { + log_pstore!(error "Failed to create secure keyring manager: {}", e); + None + } + }; } if (c.protected_store.always_use_insecure_storage || c.protected_store.allow_insecure_fallback) @@ -78,6 +88,7 @@ impl ProtectedStore { ); } if inner.keyring_manager.is_none() { + log_pstore!(error "QWERQWER"); bail!("Could not initialize the protected store."); } c.protected_store.delete diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index 84709a11..e17ec7e9 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -2,8 +2,8 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:equatable/equatable.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:fixnum/fixnum.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; ////////////////////////////////////////////////////////// diff --git a/veilid-flutter/rust/Cargo.toml b/veilid-flutter/rust/Cargo.toml index 11fb0f05..4b45d99e 100644 --- a/veilid-flutter/rust/Cargo.toml +++ b/veilid-flutter/rust/Cargo.toml @@ -63,3 +63,4 @@ hostname = "^0" # Dependencies for Android builds only [target.'cfg(target_os = "android")'.dependencies] jni = "^0" +paranoid-android = "0.2.1" diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index 812f8ab9..00388f67 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -166,14 +166,26 @@ pub extern "C" fn initialize_veilid_core(platform_config: FfiStr) { // Terminal logger if platform_config.logging.terminal.enabled { - let filter = - veilid_core::VeilidLayerFilter::new(platform_config.logging.terminal.level, None); - let layer = tracing_subscriber::fmt::Layer::new() - .compact() - .with_writer(std::io::stdout) - .with_filter(filter.clone()); - filters.insert("terminal", filter); - layers.push(layer.boxed()); + cfg_if! { + if #[cfg(target_os = "android")] { + let filter = + veilid_core::VeilidLayerFilter::new(platform_config.logging.terminal.level, None); + let layer = paranoid_android::layer("veilid-flutter") + .with_ansi(false) + .with_filter(filter.clone()); + filters.insert("terminal", filter); + layers.push(layer.boxed()); + } else { + let filter = + veilid_core::VeilidLayerFilter::new(platform_config.logging.terminal.level, None); + let layer = tracing_subscriber::fmt::Layer::new() + .compact() + .with_writer(std::io::stdout) + .with_filter(filter.clone()); + filters.insert("terminal", filter); + layers.push(layer.boxed()); + } + } }; // OpenTelemetry logger @@ -237,6 +249,7 @@ pub extern "C" fn initialize_veilid_core(platform_config: FfiStr) { .try_init() .map_err(|e| format!("failed to initialize logging: {}", e)) .expect("failed to initalize ffi platform"); + } #[no_mangle] diff --git a/veilid-tools/src/log_thru.rs b/veilid-tools/src/log_thru.rs index 89ef8233..9988e7d5 100644 --- a/veilid-tools/src/log_thru.rs +++ b/veilid-tools/src/log_thru.rs @@ -177,6 +177,14 @@ macro_rules! log_pstore { (warn $fmt:literal, $($arg:expr),+) => { warn!(target:"pstore", $fmt, $($arg),+); }; + (debug $text:expr) => { debug!( + target: "pstore", + "{}", + $text, + )}; + (debug $fmt:literal, $($arg:expr),+) => { + debug!(target:"pstore", $fmt, $($arg),+); + }; ($text:expr) => {trace!( target: "pstore", "{}", From c80a473fdb7d981fccb11b47db376c577762a5d4 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 8 Oct 2023 12:40:17 -0400 Subject: [PATCH 02/10] missing symbols on x86_64 android emulator --- Cargo.lock | 1 + veilid-core/Cargo.toml | 1 + veilid-core/build.rs | 27 ++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d2fbe3f9..d633533a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5290,6 +5290,7 @@ dependencies = [ "flume", "futures-util", "getrandom", + "glob", "hex", "ifstructs", "jni", diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 783d4ead..0a82ca4e 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -279,6 +279,7 @@ wasm-logger = "0.2.0" [build-dependencies] capnpc = "0.18.0" +glob = "0.3.1" [package.metadata.wasm-pack.profile.release] wasm-opt = ["-O", "--enable-mutable-globals"] diff --git a/veilid-core/build.rs b/veilid-core/build.rs index 745f3e52..5f38c28e 100644 --- a/veilid-core/build.rs +++ b/veilid-core/build.rs @@ -1,4 +1,8 @@ -use std::process::{Command, Stdio}; +use glob::glob; +use std::{ + env, + process::{Command, Stdio}, +}; const CAPNP_VERSION: &str = "1.0.1"; // Keep in sync with scripts/install_capnp.sh const PROTOC_VERSION: &str = "24.3"; // Keep in sync with scripts/install_protoc.sh @@ -111,4 +115,25 @@ fn main() { .run() .expect("compiling schema"); } + + // Fix for missing __extenddftf2 on Android x86_64 Emulator + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + // if target_os == "android" || target_os == "linux" { + // println!("cargo:rustc-link-lib=stdc++"); + // } else { + // println!("cargo:rustc-link-lib=c++"); + // } + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + if target_arch == "x86_64" && target_os == "android" { + let missing_library = "clang_rt.builtins-x86_64-android"; + let android_ndk_home = env::var("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set"); + let lib_path = glob(&format!("{android_ndk_home}/**/lib{missing_library}.a")) + .expect("failed to glob") + .next() + .expect("Need libclang_rt.builtins-x86_64-android.a") + .unwrap(); + let lib_dir = lib_path.parent().unwrap(); + println!("cargo:rustc-link-search={}", lib_dir.display()); + println!("cargo:rustc-link-lib=static={missing_library}"); + } } From 084d4ae98b1997f192826f53ddaa1c83b6ede836 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Tue, 10 Oct 2023 09:56:47 -0400 Subject: [PATCH 03/10] remove crap --- veilid-core/src/intf/native/protected_store.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/veilid-core/src/intf/native/protected_store.rs b/veilid-core/src/intf/native/protected_store.rs index accae460..c952d9c5 100644 --- a/veilid-core/src/intf/native/protected_store.rs +++ b/veilid-core/src/intf/native/protected_store.rs @@ -41,8 +41,6 @@ impl ProtectedStore { #[instrument(level = "debug", skip(self), err)] pub async fn init(&self) -> EyreResult<()> { - log_pstore!(error "ASDFASDFASDF"); - let delete = { let c = self.config.get(); let mut inner = self.inner.lock(); From 54c403ebfb68caa5364ed72271f650ee5dcdc5ff Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Wed, 11 Oct 2023 23:12:54 -0400 Subject: [PATCH 04/10] keep network from going down when external ip addresses haven't changed --- .../native/discovery_context.rs | 43 +++++++++++++++++++ veilid-core/src/network_manager/native/mod.rs | 3 ++ .../native/network_class_discovery.rs | 41 +++++++++++++++--- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/veilid-core/src/network_manager/native/discovery_context.rs b/veilid-core/src/network_manager/native/discovery_context.rs index 2837ed4c..d7b2376e 100644 --- a/veilid-core/src/network_manager/native/discovery_context.rs +++ b/veilid-core/src/network_manager/native/discovery_context.rs @@ -39,8 +39,11 @@ struct DiscoveryContextInner { struct DiscoveryContextUnlockedInner { routing_table: RoutingTable, net: Network, + clear_network_callback: ClearNetworkCallback, + // per-protocol intf_addrs: Vec, + existing_external_address: Option, protocol_type: ProtocolType, address_type: AddressType, } @@ -51,21 +54,45 @@ pub struct DiscoveryContext { inner: Arc>, } +pub type ClearNetworkCallback = Arc SendPinBoxFuture<()> + Send + Sync>; + impl DiscoveryContext { pub fn new( routing_table: RoutingTable, net: Network, protocol_type: ProtocolType, address_type: AddressType, + clear_network_callback: ClearNetworkCallback, ) -> Self { let intf_addrs = Self::get_local_addresses(routing_table.clone(), protocol_type, address_type); + // Get the existing external address to check to see if it has changed + let existing_dial_info = routing_table.all_filtered_dial_info_details( + RoutingDomain::PublicInternet.into(), + &DialInfoFilter::default() + .with_address_type(address_type) + .with_protocol_type(protocol_type), + ); + let existing_external_address = if existing_dial_info.len() == 1 { + Some( + existing_dial_info + .first() + .unwrap() + .dial_info + .socket_address(), + ) + } else { + None + }; + Self { unlocked_inner: Arc::new(DiscoveryContextUnlockedInner { routing_table, net, + clear_network_callback, intf_addrs, + existing_external_address, protocol_type, address_type, }), @@ -631,6 +658,22 @@ impl DiscoveryContext { return; } + // Did external addresses change from the last time we made dialinfo? + let some_clear_network_callback = { + let inner = self.inner.lock(); + let ext_1 = inner.external_1.as_ref().unwrap().address; + let ext_2 = inner.external_2.as_ref().unwrap().address; + if (ext_1 != ext_2) || Some(ext_1) != self.unlocked_inner.existing_external_address { + // External address was not found, or has changed, go ahead and clear the network so we can do better + Some(self.unlocked_inner.clear_network_callback.clone()) + } else { + None + } + }; + if let Some(clear_network_callback) = some_clear_network_callback { + clear_network_callback().await; + } + // UPNP Automatic Mapping /////////// if enable_upnp { diff --git a/veilid-core/src/network_manager/native/mod.rs b/veilid-core/src/network_manager/native/mod.rs index ead28274..2cca19ea 100644 --- a/veilid-core/src/network_manager/native/mod.rs +++ b/veilid-core/src/network_manager/native/mod.rs @@ -99,6 +99,8 @@ struct NetworkInner { enable_ipv6_local: bool, /// set if we need to calculate our public dial info again needs_public_dial_info_check: bool, + /// set if we have yet to clear the network during public dial info checking + network_already_cleared: bool, /// the punishment closure to enax public_dial_info_check_punishment: Option>, /// udp socket record for bound-first sockets, which are used to guarantee a port is available before @@ -148,6 +150,7 @@ impl Network { network_started: false, network_needs_restart: false, needs_public_dial_info_check: false, + network_already_cleared: false, public_dial_info_check_punishment: None, protocol_config: Default::default(), static_public_dialinfo: ProtocolTypeSet::empty(), diff --git a/veilid-core/src/network_manager/native/network_class_discovery.rs b/veilid-core/src/network_manager/native/network_class_discovery.rs index c0336fdd..44fe04b5 100644 --- a/veilid-core/src/network_manager/native/network_class_discovery.rs +++ b/veilid-core/src/network_manager/native/network_class_discovery.rs @@ -22,7 +22,6 @@ impl Network { editor.clear_dial_info_details(None, None); editor.set_network_class(Some(NetworkClass::OutboundOnly)); - editor.clear_relay_node(); editor.commit(true).await; } } @@ -103,7 +102,7 @@ impl Network { ) -> EyreResult<()> { // Figure out if we can optimize TCP/WS checking since they are often on the same port let (protocol_config, tcp_same_port) = { - let inner = self.inner.lock(); + let mut inner = self.inner.lock(); let protocol_config = inner.protocol_config.clone(); let tcp_same_port = if protocol_config.inbound.contains(ProtocolType::TCP) && protocol_config.inbound.contains(ProtocolType::WS) @@ -112,6 +111,10 @@ impl Network { } else { false }; + // Allow network to be cleared if external addresses change + inner.network_already_cleared = false; + + // (protocol_config, tcp_same_port) }; @@ -125,8 +128,7 @@ impl Network { .into_iter() .collect(); - // Clear public dialinfo and network class in prep for discovery - + // Set most permissive network config let mut editor = self .routing_table() .edit_routing_domain(RoutingDomain::PublicInternet); @@ -136,11 +138,30 @@ impl Network { protocol_config.family_global, protocol_config.public_internet_capabilities.clone(), ); - editor.clear_dial_info_details(None, None); - editor.set_network_class(None); - editor.clear_relay_node(); editor.commit(true).await; + // Create a callback to clear the network if we need to 'start over' + let this = self.clone(); + let clear_network_callback: ClearNetworkCallback = Arc::new(move || { + let this = this.clone(); + Box::pin(async move { + // Ensure we only do this once per network class discovery + { + let mut inner = this.inner.lock(); + if inner.network_already_cleared { + return; + } + inner.network_already_cleared = true; + } + let mut editor = this + .routing_table() + .edit_routing_domain(RoutingDomain::PublicInternet); + editor.clear_dial_info_details(None, None); + editor.set_network_class(None); + editor.commit(true).await; + }) + }); + // Process all protocol and address combinations let mut unord = FuturesUnordered::new(); // Do UDPv4+v6 at the same time as everything else @@ -152,6 +173,7 @@ impl Network { self.clone(), ProtocolType::UDP, AddressType::IPV4, + clear_network_callback.clone(), ); udpv4_context .discover(&mut unord) @@ -166,6 +188,7 @@ impl Network { self.clone(), ProtocolType::UDP, AddressType::IPV6, + clear_network_callback.clone(), ); udpv6_context .discover(&mut unord) @@ -182,6 +205,7 @@ impl Network { self.clone(), ProtocolType::TCP, AddressType::IPV4, + clear_network_callback.clone(), ); tcpv4_context .discover(&mut unord) @@ -195,6 +219,7 @@ impl Network { self.clone(), ProtocolType::WS, AddressType::IPV4, + clear_network_callback.clone(), ); wsv4_context .discover(&mut unord) @@ -211,6 +236,7 @@ impl Network { self.clone(), ProtocolType::TCP, AddressType::IPV6, + clear_network_callback.clone(), ); tcpv6_context .discover(&mut unord) @@ -225,6 +251,7 @@ impl Network { self.clone(), ProtocolType::WS, AddressType::IPV6, + clear_network_callback.clone(), ); wsv6_context .discover(&mut unord) From ebd36d82ef6aa3cf6eddb062ec78cd17c275748b Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 12 Oct 2023 21:17:47 -0400 Subject: [PATCH 05/10] network interface changes cleanup --- .../intf/native/network_interfaces/apple.rs | 59 +++++++++++++------ .../src/intf/native/network_interfaces/mod.rs | 17 ++++-- .../intf/native/network_interfaces/netlink.rs | 10 +--- .../network_interfaces/sockaddr_tools.rs | 16 +---- .../intf/native/network_interfaces/windows.rs | 13 ++-- .../native/discovery_context.rs | 16 +++-- veilid-core/src/network_manager/native/mod.rs | 14 ++--- .../native/network_class_discovery.rs | 8 +-- 8 files changed, 84 insertions(+), 69 deletions(-) diff --git a/veilid-core/src/intf/native/network_interfaces/apple.rs b/veilid-core/src/intf/native/network_interfaces/apple.rs index 88422f60..17e7bb6d 100644 --- a/veilid-core/src/intf/native/network_interfaces/apple.rs +++ b/veilid-core/src/intf/native/network_interfaces/apple.rs @@ -3,9 +3,9 @@ use super::*; use libc::{ close, freeifaddrs, getifaddrs, if_nametoindex, ifaddrs, ioctl, pid_t, sockaddr, sockaddr_in6, - socket, sysctl, time_t, AF_INET6, CTL_NET, IFF_BROADCAST, IFF_LOOPBACK, IFF_RUNNING, IFNAMSIZ, - NET_RT_FLAGS, PF_ROUTE, RTAX_DST, RTAX_GATEWAY, RTAX_MAX, RTA_DST, RTA_GATEWAY, RTF_GATEWAY, - SOCK_DGRAM, + socket, sysctl, time_t, AF_INET6, CTL_NET, IFF_BROADCAST, IFF_LOOPBACK, IFF_POINTOPOINT, + IFF_RUNNING, IFNAMSIZ, NET_RT_FLAGS, PF_ROUTE, RTAX_DST, RTAX_GATEWAY, RTAX_MAX, RTA_DST, + RTA_GATEWAY, RTF_GATEWAY, SOCK_DGRAM, }; use sockaddr_tools::SockAddr; use std::ffi::CStr; @@ -13,12 +13,15 @@ use std::io; use std::os::raw::{c_int, c_uchar, c_ulong, c_ushort, c_void}; const SIOCGIFAFLAG_IN6: c_ulong = 0xC1206949; +const SIOCGIFALIFETIME_IN6: c_ulong = 0xC1206951; const IN6_IFF_TENTATIVE: c_ushort = 0x0002; const IN6_IFF_DUPLICATED: c_ushort = 0x0004; const IN6_IFF_DETACHED: c_ushort = 0x0008; +const IN6_IFF_AUTOCONF: c_ushort = 0x0040; const IN6_IFF_TEMPORARY: c_ushort = 0x0080; const IN6_IFF_DEPRECATED: c_ushort = 0x0010; const IN6_IFF_DYNAMIC: c_ushort = 0x0100; +const IN6_IFF_SECURED: c_ushort = 0x0400; macro_rules! set_name { ($name_field:expr, $name_str:expr) => {{ @@ -198,6 +201,9 @@ impl in6_ifreq { pub fn get_flags6(&self) -> c_ushort { unsafe { self.ifr_ifru.ifru_flags6 as c_ushort } } + pub fn get_ia6t_expire(&self) -> time_t { + unsafe { self.ifr_ifru.ifru_lifetime.ia6t_expire as time_t } + } } pub fn do_broadcast(ifaddr: &ifaddrs) -> Option { @@ -368,37 +374,59 @@ impl PlatformSupportApple { Ok(InterfaceFlags { is_loopback: (flags & IFF_LOOPBACK) != 0, is_running: (flags & IFF_RUNNING) != 0, + is_point_to_point: (flags & IFF_POINTOPOINT) != 0, has_default_route: self.default_route_interfaces.contains(&index), }) } fn get_address_flags(ifname: &str, addr: sockaddr_in6) -> EyreResult { - let mut req = in6_ifreq::from_name(ifname).unwrap(); - req.set_addr(addr); - let sock = unsafe { socket(AF_INET6, SOCK_DGRAM, 0) }; if sock < 0 { bail!("Socket error {:?}", io::Error::last_os_error()); } + let mut req = in6_ifreq::from_name(ifname).unwrap(); + req.set_addr(addr); + let res = unsafe { ioctl(sock, SIOCGIFAFLAG_IN6, &mut req) }; - unsafe { close(sock) }; if res < 0 { + unsafe { close(sock) }; bail!( "SIOCGIFAFLAG_IN6 failed with error on device '{}': {:?}", ifname, io::Error::last_os_error() ); } - let flags = req.get_flags6(); + let mut req = in6_ifreq::from_name(ifname).unwrap(); + req.set_addr(addr); + + let res = unsafe { ioctl(sock, SIOCGIFALIFETIME_IN6, &mut req) }; + unsafe { close(sock) }; + if res < 0 { + bail!( + "SIOCGIFALIFETIME_IN6 failed with error on device '{}': {:?}", + ifname, + io::Error::last_os_error() + ); + } + let expire = req.get_ia6t_expire(); + + let is_auto_generated_random_address = + flags & (IN6_IFF_SECURED | IN6_IFF_AUTOCONF) == (IN6_IFF_SECURED | IN6_IFF_AUTOCONF); + + let is_temporary = + (flags & IN6_IFF_TEMPORARY) != 0 || (expire != 0 && is_auto_generated_random_address); + let is_dynamic = (flags & (IN6_IFF_DYNAMIC | IN6_IFF_AUTOCONF)) != 0; + let is_preferred = (flags + & (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED)) + == 0; + Ok(AddressFlags { - is_temporary: (flags & IN6_IFF_TEMPORARY) != 0, - is_dynamic: (flags & IN6_IFF_DYNAMIC) != 0, - is_preferred: (flags - & (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED)) - == 0, + is_temporary, + is_dynamic, + is_preferred, }) } @@ -408,11 +436,6 @@ impl PlatformSupportApple { ) -> EyreResult<()> { self.refresh_default_route_interfaces().await?; - // If we have no routes, this isn't going to work - if self.default_route_interfaces.is_empty() { - bail!("no routes available for NetworkInterfaces"); - } - // Ask for all the addresses we have let ifaddrs = IfAddrs::new().wrap_err("failed to get interface addresses")?; for ifaddr in ifaddrs.iter() { diff --git a/veilid-core/src/intf/native/network_interfaces/mod.rs b/veilid-core/src/intf/native/network_interfaces/mod.rs index 4c53cab9..5f4581cb 100644 --- a/veilid-core/src/intf/native/network_interfaces/mod.rs +++ b/veilid-core/src/intf/native/network_interfaces/mod.rs @@ -74,6 +74,7 @@ pub struct Ifv6Addr { pub struct InterfaceFlags { pub is_loopback: bool, pub is_running: bool, + pub is_point_to_point: bool, pub has_default_route: bool, } @@ -261,6 +262,10 @@ impl NetworkInterface { self.flags.is_loopback } + pub fn is_point_to_point(&self) -> bool { + self.flags.is_point_to_point + } + pub fn is_running(&self) -> bool { self.flags.is_running } @@ -363,9 +368,9 @@ impl NetworkInterfaces { // See if our best addresses have changed if old_best_addresses != inner.interface_address_cache { - trace!( - "Network interface addresses changed: {:?}", - inner.interface_address_cache + debug!( + "Network interface addresses changed: \nFrom: {:?}\n To: {:?}\n", + old_best_addresses, inner.interface_address_cache ); return Ok(true); } @@ -391,7 +396,11 @@ impl NetworkInterfaces { // Reduce interfaces to their best routable ip addresses let mut intf_addrs = Vec::new(); for intf in inner.interfaces.values() { - if !intf.is_running() || !intf.has_default_route() || intf.is_loopback() { + if !intf.is_running() + || !intf.has_default_route() + || intf.is_loopback() + || intf.is_point_to_point() + { continue; } if let Some(pipv4) = intf.primary_ipv4() { diff --git a/veilid-core/src/intf/native/network_interfaces/netlink.rs b/veilid-core/src/intf/native/network_interfaces/netlink.rs index e1f0c750..eb0eb188 100644 --- a/veilid-core/src/intf/native/network_interfaces/netlink.rs +++ b/veilid-core/src/intf/native/network_interfaces/netlink.rs @@ -4,8 +4,8 @@ use alloc::collections::btree_map::Entry; use futures_util::stream::TryStreamExt; use ifstructs::ifreq; use libc::{ - close, if_indextoname, ioctl, socket, IFF_LOOPBACK, IFF_RUNNING, IF_NAMESIZE, SIOCGIFFLAGS, - SOCK_DGRAM, + close, if_indextoname, ioctl, socket, IFF_LOOPBACK, IFF_POINTOPOINT, IFF_RUNNING, IF_NAMESIZE, + SIOCGIFFLAGS, SOCK_DGRAM, }; use netlink_packet_route::{ nlas::address::Nla, AddressMessage, AF_INET, AF_INET6, IFA_F_DADFAILED, IFA_F_DEPRECATED, @@ -138,6 +138,7 @@ impl PlatformSupportNetlink { Ok(InterfaceFlags { is_loopback: (flags & IFF_LOOPBACK) != 0, is_running: (flags & IFF_RUNNING) != 0, + is_point_to_point: (flags & IFF_POINTOPOINT) != 0, has_default_route: self.default_route_interfaces.contains(&index), }) } @@ -248,11 +249,6 @@ impl PlatformSupportNetlink { // Refresh the routes self.refresh_default_route_interfaces().await?; - // If we have no routes, this isn't going to work - if self.default_route_interfaces.is_empty() { - bail!("no routes available for NetworkInterfaces"); - } - // Ask for all the addresses we have let mut names = BTreeMap::::new(); let mut addresses = self.handle.as_ref().unwrap().address().get().execute(); diff --git a/veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs b/veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs index 605c6c32..91451714 100644 --- a/veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs +++ b/veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs @@ -48,13 +48,7 @@ impl SockAddr { ((sa.sin_addr.s_addr >> 16) & 255) as u8, ((sa.sin_addr.s_addr >> 24) & 255) as u8, ))), - Some(SockAddrIn::In6(sa)) => { - // Ignore all fe80:: addresses as these are link locals - if sa.sin6_addr.s6_addr[0] == 0xfe && sa.sin6_addr.s6_addr[1] == 0x80 { - return None; - } - Some(IpAddr::V6(Ipv6Addr::from(sa.sin6_addr.s6_addr))) - } + Some(SockAddrIn::In6(sa)) => Some(IpAddr::V6(Ipv6Addr::from(sa.sin6_addr.s6_addr))), None => None, } } @@ -64,10 +58,6 @@ impl SockAddr { match self.sockaddr_in() { Some(SockAddrIn::In(sa)) => { let s_addr = unsafe { sa.sin_addr.S_un.S_addr() }; - // Ignore all 169.254.x.x addresses as these are not active interfaces - if s_addr & 65535 == 0xfea9 { - return None; - } Some(IpAddr::V4(Ipv4Addr::new( (s_addr & 255u32) as u8, ((s_addr >> 8) & 255u32) as u8, @@ -77,10 +67,6 @@ impl SockAddr { } Some(SockAddrIn::In6(sa)) => { let s6_addr = unsafe { sa.sin6_addr.u.Byte() }; - // Ignore all fe80:: addresses as these are link locals - if s6_addr[0] == 0xfe && s6_addr[1] == 0x80 { - return None; - } Some(IpAddr::V6(Ipv6Addr::from(*s6_addr))) } None => None, diff --git a/veilid-core/src/intf/native/network_interfaces/windows.rs b/veilid-core/src/intf/native/network_interfaces/windows.rs index 53b74ba2..0e6f20c5 100644 --- a/veilid-core/src/intf/native/network_interfaces/windows.rs +++ b/veilid-core/src/intf/native/network_interfaces/windows.rs @@ -13,7 +13,7 @@ use libc::{self, c_ulong, c_void, size_t}; use std::ffi::CStr; use std::{io, ptr}; use winapi::shared::ifdef::IfOperStatusUp; -use winapi::shared::ipifcons::IF_TYPE_SOFTWARE_LOOPBACK; +use winapi::shared::ipifcons::{IF_TYPE_SOFTWARE_LOOPBACK, IF_TYPE_TUNNEL}; use winapi::shared::nldef::{ IpDadStatePreferred, IpPrefixOriginDhcp, IpSuffixOriginDhcp, IpSuffixOriginRandom, }; @@ -36,6 +36,7 @@ impl PlatformSupportWindows { InterfaceFlags { is_loopback: intf.get_flag_loopback(), is_running: intf.get_flag_running(), + is_point_to_point: intf.get_flag_point_to_point(), has_default_route: intf.get_has_default_route(), } } @@ -55,13 +56,6 @@ impl PlatformSupportWindows { &mut self, interfaces: &mut BTreeMap, ) -> EyreResult<()> { - //self.refresh_default_route_interfaces().await?; - - // If we have no routes, this isn't going to work - // if self.default_route_interfaces.is_empty() { - // return Err("no routes available for NetworkInterfaces".to_owned()); - // } - // Iterate all the interfaces let windows_interfaces = WindowsInterfaces::new().wrap_err("failed to get windows interfaces")?; @@ -224,6 +218,9 @@ impl IpAdapterAddresses { pub fn get_flag_running(&self) -> bool { unsafe { (*self.data).OperStatus == IfOperStatusUp } } + pub fn get_flag_point_to_point(&self) -> bool { + unsafe { (*self.data).IfType == IF_TYPE_TUNNEL } + } pub fn get_has_default_route(&self) -> bool { unsafe { !(*self.data).FirstGatewayAddress.is_null() } } diff --git a/veilid-core/src/network_manager/native/discovery_context.rs b/veilid-core/src/network_manager/native/discovery_context.rs index d7b2376e..e92ef48e 100644 --- a/veilid-core/src/network_manager/native/discovery_context.rs +++ b/veilid-core/src/network_manager/native/discovery_context.rs @@ -658,12 +658,20 @@ impl DiscoveryContext { return; } - // Did external addresses change from the last time we made dialinfo? + // Did external address change from the last time we made dialinfo? + // Disregard port for this because we only need to know if the ip address has changed + // If the port has changed it will change only for this protocol and will be overwritten individually by each protocol discover() let some_clear_network_callback = { let inner = self.inner.lock(); - let ext_1 = inner.external_1.as_ref().unwrap().address; - let ext_2 = inner.external_2.as_ref().unwrap().address; - if (ext_1 != ext_2) || Some(ext_1) != self.unlocked_inner.existing_external_address { + let ext_1 = inner.external_1.as_ref().unwrap().address.address(); + let ext_2 = inner.external_2.as_ref().unwrap().address.address(); + if (ext_1 != ext_2) + || Some(ext_1) + != self + .unlocked_inner + .existing_external_address + .map(|ea| ea.address()) + { // External address was not found, or has changed, go ahead and clear the network so we can do better Some(self.unlocked_inner.clear_network_callback.clone()) } else { diff --git a/veilid-core/src/network_manager/native/mod.rs b/veilid-core/src/network_manager/native/mod.rs index 2cca19ea..618a5b91 100644 --- a/veilid-core/src/network_manager/native/mod.rs +++ b/veilid-core/src/network_manager/native/mod.rs @@ -375,15 +375,14 @@ impl Network { addrs } - // See if our interface addresses have changed, if so we need to punt the network - // and redo all our addresses. This is overkill, but anything more accurate - // would require inspection of routing tables that we dont want to bother with + // See if our interface addresses have changed, if so redo public dial info if necessary async fn check_interface_addresses(&self) -> EyreResult { if !self.unlocked_inner.interfaces.refresh().await? { return Ok(false); } - self.inner.lock().network_needs_restart = true; + self.inner.lock().needs_public_dial_info_check = true; + Ok(true) } @@ -700,7 +699,7 @@ impl Network { self.unlocked_inner .interfaces .with_interfaces(|interfaces| { - trace!("interfaces: {:#?}", interfaces); + debug!("interfaces: {:#?}", interfaces); for intf in interfaces.values() { // Skip networks that we should never encounter @@ -978,9 +977,8 @@ impl Network { _l: u64, _t: u64, ) -> EyreResult<()> { - if self.check_interface_addresses().await? { - info!("interface addresses changed, restarting network"); - } + self.check_interface_addresses().await?; + Ok(()) } diff --git a/veilid-core/src/network_manager/native/network_class_discovery.rs b/veilid-core/src/network_manager/native/network_class_discovery.rs index 44fe04b5..e0bdf9ec 100644 --- a/veilid-core/src/network_manager/native/network_class_discovery.rs +++ b/veilid-core/src/network_manager/native/network_class_discovery.rs @@ -50,13 +50,11 @@ impl Network { let mut add = false; if let Some(edi) = existing_dial_info.get(&(pt, at)) { - if did.class < edi.class { - // Better dial info class was found, clear existing dialinfo for this pt/at pair + if did.class <= edi.class { + // Better or same dial info class was found, clear existing dialinfo for this pt/at pair + // Only keep one dial info per protocol/address type combination clear = true; add = true; - } else if did.class == edi.class { - // Same dial info class, just add dial info - add = true; } // Otherwise, don't upgrade, don't add, this is worse than what we have already } else { From d922bc1f5d18f179dde4a326117bef560197c0c4 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 13 Oct 2023 17:57:38 -0400 Subject: [PATCH 06/10] windows upnp work --- Cargo.lock | 16 ++-- Cargo.toml | 1 + veilid-core/Cargo.toml | 2 +- veilid-core/src/intf/native/mod.rs | 1 - .../src/network_manager/native/igd_manager.rs | 74 +++++++++++-------- veilid-core/src/network_manager/native/mod.rs | 23 +++--- .../network_manager/native/start_protocols.rs | 8 +- veilid-core/src/network_manager/wasm/mod.rs | 4 +- veilid-core/src/tests/common/mod.rs | 1 - veilid-core/src/tests/native/mod.rs | 4 - veilid-tools/Cargo.toml | 7 +- veilid-tools/src/lib.rs | 3 + .../src}/network_interfaces/apple.rs | 11 +-- .../src}/network_interfaces/mod.rs | 46 +++++++----- .../src}/network_interfaces/netlink.rs | 23 +++--- .../src}/network_interfaces/sockaddr_tools.rs | 0 .../src}/network_interfaces/tools.rs | 0 .../src}/network_interfaces/windows.rs | 11 +-- veilid-tools/src/tests/native/mod.rs | 12 +++ .../tests/native/test_network_interfaces.rs | 2 +- 20 files changed, 138 insertions(+), 111 deletions(-) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/apple.rs (98%) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/mod.rs (92%) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/netlink.rs (96%) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/sockaddr_tools.rs (100%) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/tools.rs (100%) rename {veilid-core/src/intf/native => veilid-tools/src}/network_interfaces/windows.rs (98%) rename veilid-core/src/tests/common/test_host_interface.rs => veilid-tools/src/tests/native/test_network_interfaces.rs (94%) diff --git a/Cargo.lock b/Cargo.lock index d633533a..dc9c16a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,14 +499,13 @@ checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" [[package]] name = "attohttpc" -version = "0.16.3" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb8867f378f33f78a811a8eb9bf108ad99430d7aad43315dd9319c827ef6247" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" dependencies = [ "http", "log", "url", - "wildmatch", ] [[package]] @@ -5406,9 +5405,9 @@ dependencies = [ [[package]] name = "veilid-igd" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28428a3f826ed334f995522e554d7c8c1a5a0e0a0248fc795a31022ddf436c9d" +checksum = "ce2b3c073da0025538ff4cf5bea61a7a7a046c1bf060e2d0981c71800747551d" dependencies = [ "attohttpc", "log", @@ -5517,6 +5516,7 @@ dependencies = [ "wasm-bindgen-test", "wasm-logger", "wee_alloc", + "winapi", ] [[package]] @@ -5781,12 +5781,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" -[[package]] -name = "wildmatch" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a" - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 90d036a5..b9b4a26c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ cursive_core = { git = "https://gitlab.com/veilid/cursive.git" } # keyvaluedb-memorydb = { path = "../keyvaluedb/keyvaluedb-memorydb" } # keyvaluedb-sqlite = { path = "../keyvaluedb/keyvaluedb-sqlite" } # keyvaluedb-web = { path = "../keyvaluedb/keyvaluedb-web" } +# igd = { package = "veilid-igd", path = "../rust-igd" } [profile.release] opt-level = "s" diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 0a82ca4e..ac906416 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -170,7 +170,7 @@ keyvaluedb-sqlite = "0.1.1" # Network async-tungstenite = { version = "0.23.0", features = ["async-tls"] } -igd = { package = "veilid-igd", version = "0.1.0" } +igd = { package = "veilid-igd", version = "0.1.1" } async-tls = "0.12.0" webpki = "0.22.1" webpki-roots = "0.25.2" diff --git a/veilid-core/src/intf/native/mod.rs b/veilid-core/src/intf/native/mod.rs index d8cc6811..35c6c602 100644 --- a/veilid-core/src/intf/native/mod.rs +++ b/veilid-core/src/intf/native/mod.rs @@ -12,6 +12,5 @@ pub use system::*; #[cfg(target_os = "android")] pub mod android; -pub mod network_interfaces; use super::*; diff --git a/veilid-core/src/network_manager/native/igd_manager.rs b/veilid-core/src/network_manager/native/igd_manager.rs index 32e3e3f2..302dba33 100644 --- a/veilid-core/src/network_manager/native/igd_manager.rs +++ b/veilid-core/src/network_manager/native/igd_manager.rs @@ -26,7 +26,7 @@ struct PortMapValue { struct IGDManagerInner { local_ip_addrs: BTreeMap, - gateways: BTreeMap>, + gateways: BTreeMap>, port_maps: BTreeMap, } @@ -121,17 +121,21 @@ impl IGDManager { fn find_gateway( inner: &mut IGDManagerInner, - address_type: AddressType, + local_ip: IpAddr, ) -> Option> { - if let Some(gw) = inner.gateways.get(&address_type) { + + if let Some(gw) = inner.gateways.get(&local_ip) { return Some(gw.clone()); } - let gateway = match address_type { - AddressType::IPV4 => { - match igd::search_gateway(SearchOptions::new_v4( + let gateway = match local_ip { + IpAddr::V4(v4) => { + let mut opts = SearchOptions::new_v4( UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64, - )) { + ); + opts.bind_addr = SocketAddr::V4(SocketAddrV4::new(v4, 0)); + + match igd::search_gateway(opts) { Ok(v) => v, Err(e) => { log_net!(debug "couldn't find ipv4 igd: {}", e); @@ -139,11 +143,14 @@ impl IGDManager { } } } - AddressType::IPV6 => { - match igd::search_gateway(SearchOptions::new_v6( + IpAddr::V6(v6) => { + let mut opts = SearchOptions::new_v6( Ipv6SearchScope::LinkLocal, UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64, - )) { + ); + opts.bind_addr = SocketAddr::V6(SocketAddrV6::new(v6, 0, 0, 0)); + + match igd::search_gateway(opts) { Ok(v) => v, Err(e) => { log_net!(debug "couldn't find ipv6 igd: {}", e); @@ -151,17 +158,18 @@ impl IGDManager { } } } + }; let gw = Arc::new(gateway); - inner.gateways.insert(address_type, gw.clone()); + inner.gateways.insert(local_ip, gw.clone()); Some(gw) } fn get_gateway( inner: &mut IGDManagerInner, - address_type: AddressType, + local_ip: IpAddr, ) -> Option> { - if let Some(gw) = inner.gateways.get(&address_type) { + if let Some(gw) = inner.gateways.get(&local_ip) { return Some(gw.clone()); } None @@ -191,8 +199,12 @@ impl IGDManager { let pmk = found?; let _pmv = inner.port_maps.remove(&pmk).expect("key found but remove failed"); + + // Get local ip address + let local_ip = Self::find_local_ip(&mut inner, at)?; + // Find gateway - let gw = Self::find_gateway(&mut inner, at)?; + let gw = Self::find_gateway(&mut inner, local_ip)?; // Unmap port match gw.remove_port(convert_llpt(llpt), mapped_port) { @@ -233,7 +245,7 @@ impl IGDManager { let local_ip = Self::find_local_ip(&mut inner, at)?; // Find gateway - let gw = Self::find_gateway(&mut inner, at)?; + let gw = Self::find_gateway(&mut inner, local_ip)?; // Get external address let ext_ip = match gw.get_external_ip() { @@ -325,14 +337,6 @@ impl IGDManager { // Process full renewals for (k, v) in full_renews { - - // Get gateway for address type - let gw = match Self::get_gateway(&mut inner, k.at) { - Some(gw) => gw, - None => { - return Err(eyre!("gateway missing for address type")); - } - }; // Get local ip for address type let local_ip = match Self::get_local_ip(&mut inner, k.at) { @@ -341,6 +345,14 @@ impl IGDManager { return Err(eyre!("local ip missing for address type")); } }; + + // Get gateway for interface + let gw = match Self::get_gateway(&mut inner, local_ip) { + Some(gw) => gw, + None => { + return Err(eyre!("gateway missing for interface")); + } + }; // Delete the mapping if it exists, ignore any errors here let _ = gw.remove_port(convert_llpt(k.llpt), v.mapped_port); @@ -370,14 +382,6 @@ impl IGDManager { // Process normal renewals for (k, mut v) in renews { - // Get gateway for address type - let gw = match Self::get_gateway(&mut inner, k.at) { - Some(gw) => gw, - None => { - return Err(eyre!("gateway missing for address type")); - } - }; - // Get local ip for address type let local_ip = match Self::get_local_ip(&mut inner, k.at) { Some(ip) => ip, @@ -386,6 +390,14 @@ impl IGDManager { } }; + // Get gateway for interface + let gw = match Self::get_gateway(&mut inner, local_ip) { + Some(gw) => gw, + None => { + return Err(eyre!("gateway missing for address type")); + } + }; + let desc = this.get_description(k.llpt, k.local_port); match gw.add_port(convert_llpt(k.llpt), v.mapped_port, SocketAddr::new(local_ip, k.local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) { Ok(()) => { diff --git a/veilid-core/src/network_manager/native/mod.rs b/veilid-core/src/network_manager/native/mod.rs index 618a5b91..3eab81f8 100644 --- a/veilid-core/src/network_manager/native/mod.rs +++ b/veilid-core/src/network_manager/native/mod.rs @@ -10,7 +10,6 @@ use super::*; use crate::routing_table::*; use connection_manager::*; use discovery_context::*; -use network_interfaces::*; use network_tcp::*; use protocol::tcp::RawTcpProtocolHandler; use protocol::udp::RawUdpProtocolHandler; @@ -316,7 +315,7 @@ impl Network { if !from.ip().is_unspecified() { vec![*from] } else { - let addrs = self.get_usable_interface_addresses(); + let addrs = self.get_stable_interface_addresses(); addrs .iter() .filter_map(|a| { @@ -358,13 +357,13 @@ impl Network { }) } - pub fn is_usable_interface_address(&self, addr: IpAddr) -> bool { - let usable_addrs = self.get_usable_interface_addresses(); - usable_addrs.contains(&addr) + pub fn is_stable_interface_address(&self, addr: IpAddr) -> bool { + let stable_addrs = self.get_stable_interface_addresses(); + stable_addrs.contains(&addr) } - pub fn get_usable_interface_addresses(&self) -> Vec { - let addrs = self.unlocked_inner.interfaces.best_addresses(); + pub fn get_stable_interface_addresses(&self) -> Vec { + let addrs = self.unlocked_inner.interfaces.stable_addresses(); let addrs: Vec = addrs .into_iter() .filter(|addr| { @@ -377,7 +376,13 @@ impl Network { // See if our interface addresses have changed, if so redo public dial info if necessary async fn check_interface_addresses(&self) -> EyreResult { - if !self.unlocked_inner.interfaces.refresh().await? { + if !self + .unlocked_inner + .interfaces + .refresh() + .await + .wrap_err("failed to check network interfaces")? + { return Ok(false); } @@ -723,7 +728,7 @@ impl Network { { let mut inner = self.inner.lock(); inner.enable_ipv4 = false; - for addr in self.get_usable_interface_addresses() { + for addr in self.get_stable_interface_addresses() { if addr.is_ipv4() { log_net!(debug "enable address {:?} as ipv4", addr); inner.enable_ipv4 = true; diff --git a/veilid-core/src/network_manager/native/start_protocols.rs b/veilid-core/src/network_manager/native/start_protocols.rs index c5511563..85575fd5 100644 --- a/veilid-core/src/network_manager/native/start_protocols.rs +++ b/veilid-core/src/network_manager/native/start_protocols.rs @@ -342,7 +342,7 @@ impl Network { // See if this public address is also a local interface address we haven't registered yet let is_interface_address = (|| { - for ip_addr in self.get_usable_interface_addresses() { + for ip_addr in self.get_stable_interface_addresses() { if pdi_addr.ip() == ip_addr { return true; } @@ -438,7 +438,7 @@ impl Network { // See if this public address is also a local interface address if !registered_addresses.contains(&gsa.ip()) - && self.is_usable_interface_address(gsa.ip()) + && self.is_stable_interface_address(gsa.ip()) { editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?; } @@ -552,7 +552,7 @@ impl Network { // See if this public address is also a local interface address if !registered_addresses.contains(&gsa.ip()) - && self.is_usable_interface_address(gsa.ip()) + && self.is_stable_interface_address(gsa.ip()) { editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?; } @@ -653,7 +653,7 @@ impl Network { } // See if this public address is also a local interface address - if self.is_usable_interface_address(pdi_addr.ip()) { + if self.is_stable_interface_address(pdi_addr.ip()) { editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?; } } diff --git a/veilid-core/src/network_manager/wasm/mod.rs b/veilid-core/src/network_manager/wasm/mod.rs index 3de5c95a..78439cb2 100644 --- a/veilid-core/src/network_manager/wasm/mod.rs +++ b/veilid-core/src/network_manager/wasm/mod.rs @@ -425,11 +425,11 @@ impl Network { trace!("network stopped"); } - pub fn is_usable_interface_address(&self, _addr: IpAddr) -> bool { + pub fn is_stable_interface_address(&self, _addr: IpAddr) -> bool { false } - pub fn get_usable_interface_addresses(&self) -> Vec { + pub fn get_stable_interface_addresses(&self) -> Vec { Vec::new() } diff --git a/veilid-core/src/tests/common/mod.rs b/veilid-core/src/tests/common/mod.rs index 13d151cd..2c507282 100644 --- a/veilid-core/src/tests/common/mod.rs +++ b/veilid-core/src/tests/common/mod.rs @@ -1,4 +1,3 @@ -pub mod test_host_interface; pub mod test_protected_store; pub mod test_veilid_config; pub mod test_veilid_core; diff --git a/veilid-core/src/tests/native/mod.rs b/veilid-core/src/tests/native/mod.rs index bcb7d701..558904a5 100644 --- a/veilid-core/src/tests/native/mod.rs +++ b/veilid-core/src/tests/native/mod.rs @@ -13,8 +13,6 @@ use crate::*; #[allow(dead_code)] pub async fn run_all_tests() { // iOS and Android tests also run these. - info!("TEST: test_host_interface"); - test_host_interface::test_all().await; info!("TEST: test_types"); test_types::test_all().await; info!("TEST: test_veilid_core"); @@ -114,8 +112,6 @@ cfg_if! { }); } - run_test!(test_host_interface); - run_test!(test_types); run_test!(test_veilid_core); diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index ea8fd23e..137c0c6b 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -69,7 +69,7 @@ futures-util = { version = "0.3.28", default-features = false, features = [ chrono = "0.4.31" libc = "0.2.148" -nix = { version = "0.27.1", features = [ "user" ] } +nix = { version = "0.27.1", features = ["user"] } # Dependencies for WASM builds only [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -93,9 +93,8 @@ paranoid-android = { version = "0.2.1", optional = true } android_logger = "0.13.3" # Dependencies for Windows -# [target.'cfg(target_os = "windows")'.dependencies] -# windows = { version = "^0", features = [ "Win32_NetworkManagement_Dns", "Win32_Foundation", "alloc" ]} -# windows-permissions = "^0" +[target.'cfg(target_os = "windows")'.dependencies] +winapi = { version = "0.3.9", features = ["iptypes", "iphlpapi"] } # Dependencies for iOS [target.'cfg(target_os = "ios")'.dependencies] diff --git a/veilid-tools/src/lib.rs b/veilid-tools/src/lib.rs index e9cb44b1..8573aedd 100644 --- a/veilid-tools/src/lib.rs +++ b/veilid-tools/src/lib.rs @@ -40,6 +40,7 @@ pub mod log_thru; pub mod must_join_handle; pub mod must_join_single_future; pub mod mutable_future; +pub mod network_interfaces; pub mod network_result; pub mod random; pub mod single_shot_eventual; @@ -182,6 +183,8 @@ pub use must_join_single_future::*; #[doc(inline)] pub use mutable_future::*; #[doc(inline)] +pub use network_interfaces::*; +#[doc(inline)] pub use network_result::*; #[doc(inline)] pub use random::*; diff --git a/veilid-core/src/intf/native/network_interfaces/apple.rs b/veilid-tools/src/network_interfaces/apple.rs similarity index 98% rename from veilid-core/src/intf/native/network_interfaces/apple.rs rename to veilid-tools/src/network_interfaces/apple.rs index 17e7bb6d..63fd92ba 100644 --- a/veilid-core/src/intf/native/network_interfaces/apple.rs +++ b/veilid-tools/src/network_interfaces/apple.rs @@ -1,3 +1,4 @@ +#![cfg(any(target_os = "macos", target_os = "ios"))] #![allow(non_camel_case_types)] use super::*; @@ -273,10 +274,10 @@ pub struct PlatformSupportApple { } impl PlatformSupportApple { - pub fn new() -> EyreResult { - Ok(PlatformSupportApple { + pub fn new() -> Self { + PlatformSupportApple { default_route_interfaces: BTreeSet::new(), - }) + } } async fn refresh_default_route_interfaces(&mut self) -> EyreResult<()> { @@ -433,11 +434,11 @@ impl PlatformSupportApple { pub async fn get_interfaces( &mut self, interfaces: &mut BTreeMap, - ) -> EyreResult<()> { + ) -> io::Result<()> { self.refresh_default_route_interfaces().await?; // Ask for all the addresses we have - let ifaddrs = IfAddrs::new().wrap_err("failed to get interface addresses")?; + let ifaddrs = IfAddrs::new()?; for ifaddr in ifaddrs.iter() { // Get the interface name let ifname = unsafe { CStr::from_ptr(ifaddr.ifa_name) } diff --git a/veilid-core/src/intf/native/network_interfaces/mod.rs b/veilid-tools/src/network_interfaces/mod.rs similarity index 92% rename from veilid-core/src/intf/native/network_interfaces/mod.rs rename to veilid-tools/src/network_interfaces/mod.rs index 5f4581cb..7ca44f47 100644 --- a/veilid-core/src/intf/native/network_interfaces/mod.rs +++ b/veilid-tools/src/network_interfaces/mod.rs @@ -1,18 +1,17 @@ +mod apple; +mod netlink; +mod sockaddr_tools; mod tools; +mod windows; use crate::*; cfg_if::cfg_if! { if #[cfg(any(target_os = "linux", target_os = "android"))] { - mod netlink; use self::netlink::PlatformSupportNetlink as PlatformSupport; } else if #[cfg(target_os = "windows")] { - mod windows; - mod sockaddr_tools; use self::windows::PlatformSupportWindows as PlatformSupport; } else if #[cfg(any(target_os = "macos", target_os = "ios"))] { - mod apple; - mod sockaddr_tools; use self::apple::PlatformSupportApple as PlatformSupport; } else { compile_error!("No network interfaces support for this platform!"); @@ -315,13 +314,22 @@ impl fmt::Debug for NetworkInterfaces { .finish()?; if f.alternate() { writeln!(f)?; - writeln!(f, "// best_addresses: {:?}", inner.interface_address_cache)?; + writeln!( + f, + "// stable_addresses: {:?}", + inner.interface_address_cache + )?; } Ok(()) } } -#[allow(dead_code)] +impl Default for NetworkInterfaces { + fn default() -> Self { + Self::new() + } +} + impl NetworkInterfaces { pub fn new() -> Self { Self { @@ -344,14 +352,14 @@ impl NetworkInterfaces { inner.interface_address_cache.clear(); inner.valid = false; } - // returns Ok(false) if refresh had no changes, Ok(true) if changes were present - pub async fn refresh(&self) -> EyreResult { + // returns false if refresh had no changes, true if changes were present + pub async fn refresh(&self) -> std::io::Result { let mut last_interfaces = { let mut last_interfaces = BTreeMap::::new(); - let mut platform_support = PlatformSupport::new()?; - if let Err(e) = platform_support.get_interfaces(&mut last_interfaces).await { - debug!("no network interfaces are enabled: {}", e); - } + let mut platform_support = PlatformSupport::new(); + platform_support + .get_interfaces(&mut last_interfaces) + .await?; last_interfaces }; @@ -361,16 +369,16 @@ impl NetworkInterfaces { if last_interfaces != inner.interfaces { // get last address cache - let old_best_addresses = inner.interface_address_cache.clone(); + let old_stable_addresses = inner.interface_address_cache.clone(); // redo the address cache - Self::cache_best_addresses(&mut inner); + Self::cache_stable_addresses(&mut inner); // See if our best addresses have changed - if old_best_addresses != inner.interface_address_cache { + if old_stable_addresses != inner.interface_address_cache { debug!( "Network interface addresses changed: \nFrom: {:?}\n To: {:?}\n", - old_best_addresses, inner.interface_address_cache + old_stable_addresses, inner.interface_address_cache ); return Ok(true); } @@ -385,14 +393,14 @@ impl NetworkInterfaces { f(&inner.interfaces) } - pub fn best_addresses(&self) -> Vec { + pub fn stable_addresses(&self) -> Vec { let inner = self.inner.lock(); inner.interface_address_cache.clone() } ///////////////////////////////////////////// - fn cache_best_addresses(inner: &mut NetworkInterfacesInner) { + fn cache_stable_addresses(inner: &mut NetworkInterfacesInner) { // Reduce interfaces to their best routable ip addresses let mut intf_addrs = Vec::new(); for intf in inner.interfaces.values() { diff --git a/veilid-core/src/intf/native/network_interfaces/netlink.rs b/veilid-tools/src/network_interfaces/netlink.rs similarity index 96% rename from veilid-core/src/intf/native/network_interfaces/netlink.rs rename to veilid-tools/src/network_interfaces/netlink.rs index eb0eb188..00e083c3 100644 --- a/veilid-core/src/intf/native/network_interfaces/netlink.rs +++ b/veilid-tools/src/network_interfaces/netlink.rs @@ -1,3 +1,5 @@ +#![cfg(any(target_os = "linux", target_os = "android"))] + use super::*; use alloc::collections::btree_map::Entry; @@ -27,7 +29,7 @@ use std::io; use std::os::raw::c_int; use tools::*; -fn get_interface_name(index: u32) -> EyreResult { +fn get_interface_name(index: u32) -> io::Result { let mut ifnamebuf = [0u8; (IF_NAMESIZE + 1)]; cfg_if! { if #[cfg(all(any(target_os = "android", target_os="linux"), any(target_arch = "arm", target_arch = "aarch64")))] { @@ -69,12 +71,12 @@ pub struct PlatformSupportNetlink { } impl PlatformSupportNetlink { - pub fn new() -> EyreResult { - Ok(PlatformSupportNetlink { + pub fn new() -> Self { + PlatformSupportNetlink { connection_jh: None, handle: None, default_route_interfaces: BTreeSet::new(), - }) + } } // Figure out which interfaces have default routes @@ -245,18 +247,14 @@ impl PlatformSupportNetlink { async fn get_interfaces_internal( &mut self, interfaces: &mut BTreeMap, - ) -> EyreResult<()> { + ) -> io::Result<()> { // Refresh the routes self.refresh_default_route_interfaces().await?; // Ask for all the addresses we have let mut names = BTreeMap::::new(); let mut addresses = self.handle.as_ref().unwrap().address().get().execute(); - while let Some(msg) = addresses - .try_next() - .await - .wrap_err("failed to iterate interface addresses")? - { + while let Some(msg) = addresses.try_next().await? { // Have we seen this interface index yet? // Get the name from the index, cached, if we can let ifname = match names.entry(msg.header.index) { @@ -314,10 +312,9 @@ impl PlatformSupportNetlink { pub async fn get_interfaces( &mut self, interfaces: &mut BTreeMap, - ) -> EyreResult<()> { + ) -> io::Result<()> { // Get the netlink connection - let (connection, handle, _) = new_connection_with_socket::() - .wrap_err("failed to create rtnetlink socket")?; + let (connection, handle, _) = new_connection_with_socket::()?; // Spawn a connection handler let connection_jh = spawn(connection); diff --git a/veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs b/veilid-tools/src/network_interfaces/sockaddr_tools.rs similarity index 100% rename from veilid-core/src/intf/native/network_interfaces/sockaddr_tools.rs rename to veilid-tools/src/network_interfaces/sockaddr_tools.rs diff --git a/veilid-core/src/intf/native/network_interfaces/tools.rs b/veilid-tools/src/network_interfaces/tools.rs similarity index 100% rename from veilid-core/src/intf/native/network_interfaces/tools.rs rename to veilid-tools/src/network_interfaces/tools.rs diff --git a/veilid-core/src/intf/native/network_interfaces/windows.rs b/veilid-tools/src/network_interfaces/windows.rs similarity index 98% rename from veilid-core/src/intf/native/network_interfaces/windows.rs rename to veilid-tools/src/network_interfaces/windows.rs index 0e6f20c5..661f8d69 100644 --- a/veilid-core/src/intf/native/network_interfaces/windows.rs +++ b/veilid-tools/src/network_interfaces/windows.rs @@ -1,3 +1,5 @@ +#![cfg(target_os = "windows")] + // Copyright 2018 MaidSafe.net limited. // // This SAFE Network Software is licensed to you under the MIT license EyreResult { - Ok(PlatformSupportWindows {}) + pub fn new() -> Self { + PlatformSupportWindows {} } fn get_interface_flags(intf: &IpAdapterAddresses) -> InterfaceFlags { @@ -55,10 +57,9 @@ impl PlatformSupportWindows { pub async fn get_interfaces( &mut self, interfaces: &mut BTreeMap, - ) -> EyreResult<()> { + ) -> io::Result<()> { // Iterate all the interfaces - let windows_interfaces = - WindowsInterfaces::new().wrap_err("failed to get windows interfaces")?; + let windows_interfaces = WindowsInterfaces::new()?; for windows_interface in windows_interfaces.iter() { // Get name let intf_name = windows_interface.name(); diff --git a/veilid-tools/src/tests/native/mod.rs b/veilid-tools/src/tests/native/mod.rs index 65da6ca5..7fcf2e9e 100644 --- a/veilid-tools/src/tests/native/mod.rs +++ b/veilid-tools/src/tests/native/mod.rs @@ -3,6 +3,7 @@ mod test_assembly_buffer; mod test_async_peek_stream; +mod test_network_interfaces; use super::*; @@ -13,6 +14,8 @@ use super::*; pub async fn run_all_tests() { info!("TEST: exec_test_host_interface"); test_host_interface::test_all().await; + info!("TEST: exec_test_network_interfaces"); + test_network_interfaces::test_all().await; info!("TEST: exec_test_async_peek_stream"); test_async_peek_stream::test_all().await; info!("TEST: exec_test_async_tag_lock"); @@ -82,6 +85,15 @@ cfg_if! { }); } + #[test] + #[serial] + fn run_test_network_interfaces() { + setup(); + block_on(async { + test_network_interfaces::test_all().await; + }); + } + #[test] #[serial] fn run_test_async_peek_stream() { diff --git a/veilid-core/src/tests/common/test_host_interface.rs b/veilid-tools/src/tests/native/test_network_interfaces.rs similarity index 94% rename from veilid-core/src/tests/common/test_host_interface.rs rename to veilid-tools/src/tests/native/test_network_interfaces.rs index d1a52cdc..4ba1844b 100644 --- a/veilid-core/src/tests/common/test_host_interface.rs +++ b/veilid-tools/src/tests/native/test_network_interfaces.rs @@ -2,7 +2,7 @@ use crate::*; cfg_if! { if #[cfg(not(target_arch = "wasm32"))] { - use intf::network_interfaces::NetworkInterfaces; + use network_interfaces::NetworkInterfaces; pub async fn test_network_interfaces() { info!("testing network interfaces"); From cf6a1399280f3375e97406676abd69e43c5b4666 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 13 Oct 2023 18:17:10 -0400 Subject: [PATCH 07/10] linux fixes --- Cargo.lock | 8 +++--- veilid-core/Cargo.toml | 12 --------- veilid-tools/Cargo.toml | 13 ++++++++- .../src/network_interfaces/netlink.rs | 27 +++++++++---------- .../src/network_interfaces/sockaddr_tools.rs | 1 + 5 files changed, 30 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc9c16a6..db727ae8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5291,7 +5291,6 @@ dependencies = [ "getrandom", "glob", "hex", - "ifstructs", "jni", "jni-sys", "js-sys", @@ -5306,8 +5305,6 @@ dependencies = [ "lz4_flex", "ndk", "ndk-glue", - "netlink-packet-route", - "netlink-sys", "nix 0.27.1", "num-traits", "once_cell", @@ -5316,7 +5313,6 @@ dependencies = [ "parking_lot 0.12.1", "paste", "range-set-blaze", - "rtnetlink", "rustls", "rustls-pemfile", "schemars", @@ -5483,6 +5479,7 @@ dependencies = [ "fn_name", "futures-util", "getrandom", + "ifstructs", "jni", "jni-sys", "js-sys", @@ -5491,6 +5488,8 @@ dependencies = [ "log", "ndk", "ndk-glue", + "netlink-packet-route", + "netlink-sys", "nix 0.27.1", "once_cell", "oslog", @@ -5499,6 +5498,7 @@ dependencies = [ "rand", "rand_core", "range-set-blaze", + "rtnetlink", "send_wrapper 0.6.0", "serial_test", "simplelog", diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index ac906416..aaf053b9 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -25,7 +25,6 @@ rt-async-std = [ "async-std-resolver", "trust-dns-resolver", "async_executors/async_std", - "rtnetlink/smol_socket", "veilid-tools/rt-async-std", ] rt-tokio = [ @@ -36,7 +35,6 @@ rt-tokio = [ "async_executors/tokio_tp", "async_executors/tokio_io", "async_executors/tokio_timer", - "rtnetlink/tokio_socket", "veilid-tools/rt-tokio", ] @@ -238,16 +236,6 @@ ndk = { version = "0.7.0" } ndk-glue = { version = "0.7.0", features = ["logger"] } paranoid-android = { version = "0.2.1", optional = true } -# Dependenices for all Unix (Linux, Android, MacOS, iOS) -[target.'cfg(unix)'.dependencies] -ifstructs = "0.1.1" - -# Dependencies for Linux or Android -[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies] -rtnetlink = { version = "=0.13.1", default-features = false } -netlink-sys = { version = "=0.8.5" } -netlink-packet-route = { version = "=0.17.1" } - # Dependencies for Windows [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3.9", features = ["iptypes", "iphlpapi"] } diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index 137c0c6b..234d6d1e 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -14,10 +14,11 @@ crate-type = ["cdylib", "staticlib", "rlib"] [features] default = ["rt-tokio"] -rt-async-std = ["async-std", "async_executors/async_std"] +rt-async-std = ["async-std", "async_executors/async_std", "rtnetlink/smol_socket"] rt-tokio = [ "tokio", "tokio-util", + "rtnetlink/tokio_socket", "async_executors/tokio_tp", "async_executors/tokio_io", "async_executors/tokio_timer", @@ -82,6 +83,12 @@ getrandom = { version = "0.2", features = ["js"] } async-lock = "2.8.0" send_wrapper = { version = "0.6.0", features = ["futures"] } +# Dependencies for Linux or Android +[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies] +rtnetlink = { version = "=0.13.1", default-features = false } +netlink-sys = { version = "=0.8.5" } +netlink-packet-route = { version = "=0.17.1" } + # Dependencies for Android [target.'cfg(target_os = "android")'.dependencies] jni = "0.21.1" @@ -101,6 +108,10 @@ winapi = { version = "0.3.9", features = ["iptypes", "iphlpapi"] } oslog = { version = "0.2.0", optional = true } tracing-oslog = { version = "0.1.2", optional = true } +# Dependenices for all Unix (Linux, Android, MacOS, iOS) +[target.'cfg(unix)'.dependencies] +ifstructs = "0.1.1" + ### DEV DEPENDENCIES [dev-dependencies] diff --git a/veilid-tools/src/network_interfaces/netlink.rs b/veilid-tools/src/network_interfaces/netlink.rs index 00e083c3..8354a775 100644 --- a/veilid-tools/src/network_interfaces/netlink.rs +++ b/veilid-tools/src/network_interfaces/netlink.rs @@ -2,7 +2,6 @@ use super::*; -use alloc::collections::btree_map::Entry; use futures_util::stream::TryStreamExt; use ifstructs::ifreq; use libc::{ @@ -14,6 +13,7 @@ use netlink_packet_route::{ IFA_F_OPTIMISTIC, IFA_F_PERMANENT, IFA_F_TEMPORARY, IFA_F_TENTATIVE, }; use rtnetlink::{new_connection_with_socket, Handle, IpVersion}; +use std::collections::btree_map::Entry; cfg_if! { if #[cfg(feature="rt-async-std")] { use netlink_sys::{SmolSocket as RTNetLinkSocket}; @@ -34,11 +34,11 @@ fn get_interface_name(index: u32) -> io::Result { cfg_if! { if #[cfg(all(any(target_os = "android", target_os="linux"), any(target_arch = "arm", target_arch = "aarch64")))] { if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr()) }.is_null() { - bail!("if_indextoname returned null"); + bail_io_error_other!("if_indextoname returned null"); } } else { if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr() as *mut i8) }.is_null() { - bail!("if_indextoname returned null"); + bail_io_error_other!("if_indextoname returned null"); } } } @@ -46,11 +46,11 @@ fn get_interface_name(index: u32) -> io::Result { let ifnamebuflen = ifnamebuf .iter() .position(|c| *c == 0u8) - .ok_or_else(|| eyre!("null not found in interface name"))?; + .ok_or_else(|| io_error_other!("null not found in interface name"))?; let ifname_str = CStr::from_bytes_with_nul(&ifnamebuf[0..=ifnamebuflen]) - .wrap_err("failed to convert interface name")? + .map_err(|e| io_error_other!(e))? .to_str() - .wrap_err("invalid characters in interface name")?; + .map_err(|e| io_error_other!(e))?; Ok(ifname_str.to_owned()) } @@ -80,7 +80,7 @@ impl PlatformSupportNetlink { } // Figure out which interfaces have default routes - async fn refresh_default_route_interfaces(&mut self) -> EyreResult<()> { + async fn refresh_default_route_interfaces(&mut self) { self.default_route_interfaces.clear(); let mut routesv4 = self .handle @@ -112,15 +112,14 @@ impl PlatformSupportNetlink { } } } - Ok(()) } - fn get_interface_flags(&self, index: u32, ifname: &str) -> EyreResult { - let mut req = ifreq::from_name(ifname).wrap_err("failed to convert interface name")?; + fn get_interface_flags(&self, index: u32, ifname: &str) -> io::Result { + let mut req = ifreq::from_name(ifname)?; let sock = unsafe { socket(AF_INET as i32, SOCK_DGRAM, 0) }; if sock < 0 { - return Err(io::Error::last_os_error()).wrap_err("failed to create socket"); + return Err(io::Error::last_os_error()); } cfg_if! { @@ -132,7 +131,7 @@ impl PlatformSupportNetlink { } unsafe { close(sock) }; if res < 0 { - return Err(io::Error::last_os_error()).wrap_err("failed to close socket"); + return Err(io::Error::last_os_error()); } let flags = req.get_flags() as c_int; @@ -249,12 +248,12 @@ impl PlatformSupportNetlink { interfaces: &mut BTreeMap, ) -> io::Result<()> { // Refresh the routes - self.refresh_default_route_interfaces().await?; + self.refresh_default_route_interfaces().await; // Ask for all the addresses we have let mut names = BTreeMap::::new(); let mut addresses = self.handle.as_ref().unwrap().address().get().execute(); - while let Some(msg) = addresses.try_next().await? { + while let Some(msg) = addresses.try_next().await.map_err(|e| io_error_other!(e))? { // Have we seen this interface index yet? // Get the name from the index, cached, if we can let ifname = match names.entry(msg.header.index) { diff --git a/veilid-tools/src/network_interfaces/sockaddr_tools.rs b/veilid-tools/src/network_interfaces/sockaddr_tools.rs index 91451714..3b61a985 100644 --- a/veilid-tools/src/network_interfaces/sockaddr_tools.rs +++ b/veilid-tools/src/network_interfaces/sockaddr_tools.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] // Copyright 2018 MaidSafe.net limited. // // This SAFE Network Software is licensed to you under the MIT license Date: Fri, 13 Oct 2023 18:41:11 -0400 Subject: [PATCH 08/10] fix apple --- veilid-tools/src/network_interfaces/apple.rs | 36 ++++++++------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/veilid-tools/src/network_interfaces/apple.rs b/veilid-tools/src/network_interfaces/apple.rs index 63fd92ba..1a7d5a75 100644 --- a/veilid-tools/src/network_interfaces/apple.rs +++ b/veilid-tools/src/network_interfaces/apple.rs @@ -280,7 +280,7 @@ impl PlatformSupportApple { } } - async fn refresh_default_route_interfaces(&mut self) -> EyreResult<()> { + async fn refresh_default_route_interfaces(&mut self) { self.default_route_interfaces.clear(); let mut mib = [CTL_NET, PF_ROUTE, 0, 0, NET_RT_FLAGS, RTF_GATEWAY]; @@ -300,7 +300,8 @@ impl PlatformSupportApple { ) } < 0 { - bail!("Unable to get memory size for routing table"); + error!("Unable to get memory size for routing table"); + return; } // Allocate a buffer @@ -318,7 +319,8 @@ impl PlatformSupportApple { ) } < 0 { - bail!("Unable to get memory size for routing table"); + error!("Unable to get memory size for routing table"); + return; } // Process each routing message @@ -367,23 +369,21 @@ impl PlatformSupportApple { mib_ptr = unsafe { mib_ptr.add((*rt).rtm_msglen.into()) }; } - - Ok(()) } - fn get_interface_flags(&self, index: u32, flags: c_int) -> EyreResult { - Ok(InterfaceFlags { + fn get_interface_flags(&self, index: u32, flags: c_int) -> InterfaceFlags { + InterfaceFlags { is_loopback: (flags & IFF_LOOPBACK) != 0, is_running: (flags & IFF_RUNNING) != 0, is_point_to_point: (flags & IFF_POINTOPOINT) != 0, has_default_route: self.default_route_interfaces.contains(&index), - }) + } } - fn get_address_flags(ifname: &str, addr: sockaddr_in6) -> EyreResult { + fn get_address_flags(ifname: &str, addr: sockaddr_in6) -> io::Result { let sock = unsafe { socket(AF_INET6, SOCK_DGRAM, 0) }; if sock < 0 { - bail!("Socket error {:?}", io::Error::last_os_error()); + return Err(io::Error::last_os_error()); } let mut req = in6_ifreq::from_name(ifname).unwrap(); @@ -392,11 +392,7 @@ impl PlatformSupportApple { let res = unsafe { ioctl(sock, SIOCGIFAFLAG_IN6, &mut req) }; if res < 0 { unsafe { close(sock) }; - bail!( - "SIOCGIFAFLAG_IN6 failed with error on device '{}': {:?}", - ifname, - io::Error::last_os_error() - ); + return Err(io::Error::last_os_error()); } let flags = req.get_flags6(); @@ -406,11 +402,7 @@ impl PlatformSupportApple { let res = unsafe { ioctl(sock, SIOCGIFALIFETIME_IN6, &mut req) }; unsafe { close(sock) }; if res < 0 { - bail!( - "SIOCGIFALIFETIME_IN6 failed with error on device '{}': {:?}", - ifname, - io::Error::last_os_error() - ); + return Err(io::Error::last_os_error()); } let expire = req.get_ia6t_expire(); @@ -435,7 +427,7 @@ impl PlatformSupportApple { &mut self, interfaces: &mut BTreeMap, ) -> io::Result<()> { - self.refresh_default_route_interfaces().await?; + self.refresh_default_route_interfaces().await; // Ask for all the addresses we have let ifaddrs = IfAddrs::new()?; @@ -451,7 +443,7 @@ impl PlatformSupportApple { // Map the name to a NetworkInterface if !interfaces.contains_key(&ifname) { // If we have no NetworkInterface yet, make one - let flags = self.get_interface_flags(ifindex, ifaddr.ifa_flags as c_int)?; + let flags = self.get_interface_flags(ifindex, ifaddr.ifa_flags as c_int); interfaces.insert(ifname.clone(), NetworkInterface::new(ifname.clone(), flags)); } let intf = interfaces.get_mut(&ifname).unwrap(); From f456f418d2455fe972170d1059bede258ac47623 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 13 Oct 2023 19:45:03 -0400 Subject: [PATCH 09/10] testing cleanup --- veilid-tools/Cargo.toml | 8 ++++++-- veilid-tools/src/tests/ios/mod.rs | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index 234d6d1e..5f32a588 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -14,7 +14,11 @@ crate-type = ["cdylib", "staticlib", "rlib"] [features] default = ["rt-tokio"] -rt-async-std = ["async-std", "async_executors/async_std", "rtnetlink/smol_socket"] +rt-async-std = [ + "async-std", + "async_executors/async_std", + "rtnetlink/smol_socket", +] rt-tokio = [ "tokio", "tokio-util", @@ -26,7 +30,7 @@ rt-tokio = [ rt-wasm-bindgen = ["async_executors/bindgen", "async_executors/timer"] veilid_tools_android_tests = ["dep:paranoid-android"] -veilid_tools_ios_tests = ["dep:oslog", "dep:tracing-oslog"] +veilid_tools_ios_tests = ["dep:tracing", "dep:oslog", "dep:tracing-oslog"] tracing = ["dep:tracing", "dep:tracing-subscriber"] network-result-extra = [] network-result-info = [] diff --git a/veilid-tools/src/tests/ios/mod.rs b/veilid-tools/src/tests/ios/mod.rs index 77534395..ce4780df 100644 --- a/veilid-tools/src/tests/ios/mod.rs +++ b/veilid-tools/src/tests/ios/mod.rs @@ -15,20 +15,23 @@ pub extern "C" fn run_veilid_tools_tests() { pub fn veilid_tools_setup_ios_tests() { cfg_if! { if #[cfg(feature = "tracing")] { + use tracing::level_filters::LevelFilter; use tracing_oslog::OsLogger; use tracing_subscriber::prelude::*; + use tracing_subscriber::filter::Targets; - let mut filters = filter::Targets::new(); + let mut filters = Targets::new(); for ig in DEFAULT_LOG_IGNORE_LIST { - filters = filters.with_target(ig, filter::LevelFilter::OFF); + filters = filters.with_target(ig, LevelFilter::OFF); } tracing_subscriber::registry() + .with(OsLogger::new("com.veilid.veilidtools-tests", "default")) + .with(LevelFilter::TRACE) .with(filters) - .with(filter::LevelFilter::TRACE) - .with(OsLogger::new("com.veilid.veilidtools-tests", "")) .init(); } else { use oslog::OsLogger; + use log::LevelFilter; OsLogger::new("com.veilid.veilidtools-tests") .level_filter(LevelFilter::Trace) From 2fc4247be623409c4c869cb8ba909351ffaed2f0 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 14 Oct 2023 13:50:34 -0400 Subject: [PATCH 10/10] try different dialinfo for bootstrap --- .../src/routing_table/tasks/bootstrap.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/veilid-core/src/routing_table/tasks/bootstrap.rs b/veilid-core/src/routing_table/tasks/bootstrap.rs index e69a0524..329d40a0 100644 --- a/veilid-core/src/routing_table/tasks/bootstrap.rs +++ b/veilid-core/src/routing_table/tasks/bootstrap.rs @@ -384,6 +384,22 @@ impl RoutingTable { let routing_table = self.clone(); unord.push( async move { + // Get what contact method would be used for contacting the bootstrap + let bsdi = match routing_table + .network_manager() + .get_node_contact_method(nr.clone()) + { + Ok(NodeContactMethod::Direct(v)) => v, + Ok(v) => { + log_rtab!(warn "invalid contact method for bootstrap: {:?}", v); + return; + } + Err(e) => { + log_rtab!(warn "unable to bootstrap: {}", e); + return; + } + }; + // Need VALID signed peer info, so ask bootstrap to find_node of itself // which will ensure it has the bootstrap's signed peer info as part of the response let _ = routing_table.find_target(crypto_kind, nr.clone()).await; @@ -391,7 +407,10 @@ impl RoutingTable { // Ensure we got the signed peer info if !nr.signed_node_info_has_valid_signature(RoutingDomain::PublicInternet) { log_rtab!(warn "bootstrap server is not responding"); - log_rtab!(debug "bootstrap server is not responding: {}", nr); + log_rtab!(debug "bootstrap server is not responding for dialinfo: {}", bsdi); + + // Try a different dialinfo next time + routing_table.network_manager().address_filter().set_dial_info_failed(bsdi); } else { // otherwise this bootstrap is valid, lets ask it to find ourselves now routing_table.reverse_find_node(crypto_kind, nr, true).await