windows upnp work
This commit is contained in:
parent
ebd36d82ef
commit
d922bc1f5d
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -12,6 +12,5 @@ pub use system::*;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod android;
|
||||
pub mod network_interfaces;
|
||||
|
||||
use super::*;
|
||||
|
@ -26,7 +26,7 @@ struct PortMapValue {
|
||||
|
||||
struct IGDManagerInner {
|
||||
local_ip_addrs: BTreeMap<AddressType, IpAddr>,
|
||||
gateways: BTreeMap<AddressType, Arc<Gateway>>,
|
||||
gateways: BTreeMap<IpAddr, Arc<Gateway>>,
|
||||
port_maps: BTreeMap<PortMapKey, PortMapValue>,
|
||||
}
|
||||
|
||||
@ -121,17 +121,21 @@ impl IGDManager {
|
||||
|
||||
fn find_gateway(
|
||||
inner: &mut IGDManagerInner,
|
||||
address_type: AddressType,
|
||||
local_ip: IpAddr,
|
||||
) -> Option<Arc<Gateway>> {
|
||||
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<Arc<Gateway>> {
|
||||
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(()) => {
|
||||
|
@ -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<IpAddr> {
|
||||
let addrs = self.unlocked_inner.interfaces.best_addresses();
|
||||
pub fn get_stable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
let addrs = self.unlocked_inner.interfaces.stable_addresses();
|
||||
let addrs: Vec<IpAddr> = 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<bool> {
|
||||
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;
|
||||
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
@ -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<IpAddr> {
|
||||
pub fn get_stable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
pub mod test_host_interface;
|
||||
pub mod test_protected_store;
|
||||
pub mod test_veilid_config;
|
||||
pub mod test_veilid_core;
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
|
@ -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::*;
|
||||
|
@ -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<Self> {
|
||||
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<String, NetworkInterface>,
|
||||
) -> 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) }
|
@ -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<bool> {
|
||||
// returns false if refresh had no changes, true if changes were present
|
||||
pub async fn refresh(&self) -> std::io::Result<bool> {
|
||||
let mut last_interfaces = {
|
||||
let mut last_interfaces = BTreeMap::<String, NetworkInterface>::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<IpAddr> {
|
||||
pub fn stable_addresses(&self) -> Vec<IpAddr> {
|
||||
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() {
|
@ -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<String> {
|
||||
fn get_interface_name(index: u32) -> io::Result<String> {
|
||||
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<Self> {
|
||||
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<String, NetworkInterface>,
|
||||
) -> EyreResult<()> {
|
||||
) -> io::Result<()> {
|
||||
// Refresh the routes
|
||||
self.refresh_default_route_interfaces().await?;
|
||||
|
||||
// Ask for all the addresses we have
|
||||
let mut names = BTreeMap::<u32, String>::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<String, NetworkInterface>,
|
||||
) -> EyreResult<()> {
|
||||
) -> io::Result<()> {
|
||||
// Get the netlink connection
|
||||
let (connection, handle, _) = new_connection_with_socket::<RTNetLinkSocket>()
|
||||
.wrap_err("failed to create rtnetlink socket")?;
|
||||
let (connection, handle, _) = new_connection_with_socket::<RTNetLinkSocket>()?;
|
||||
|
||||
// Spawn a connection handler
|
||||
let connection_jh = spawn(connection);
|
@ -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 <LICENSE-MIT
|
||||
@ -28,8 +30,8 @@ use winapi::um::iptypes::{
|
||||
pub struct PlatformSupportWindows {}
|
||||
|
||||
impl PlatformSupportWindows {
|
||||
pub fn new() -> EyreResult<Self> {
|
||||
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<String, NetworkInterface>,
|
||||
) -> 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();
|
@ -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() {
|
||||
|
@ -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");
|
Loading…
Reference in New Issue
Block a user