diff --git a/Cargo.toml b/Cargo.toml index fc643afc..9a4173d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,8 +27,9 @@ webpki = "~0.21.3" features = [ "serde" ] [dependencies.igd] - version = "~0.12.0" + version = "~0.11.1" features = [ "aio" ] + optional = true [dependencies.quinn] version = "~0.6.1" @@ -54,3 +55,7 @@ rand = "~0.7.3" [target."cfg(any(all(unix, not(any(target_os = \"android\", target_os = \"androideabi\", target_os = \"ios\"))), windows))".dependencies] dirs-next = "2.0.0" + +[features] +default = [ "igd" ] +no-igd = [] diff --git a/src/api.rs b/src/api.rs index 651918d5..436f2ada 100644 --- a/src/api.rs +++ b/src/api.rs @@ -15,9 +15,11 @@ use super::{ peer_config::{self, DEFAULT_IDLE_TIMEOUT_MSEC, DEFAULT_KEEP_ALIVE_INTERVAL_MSEC}, }; use futures::{future, TryFutureExt}; -use log::{debug, error, info, trace, warn}; +#[cfg(not(feature = "no-igd"))] +use log::warn; +use log::{debug, error, info, trace}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}; -use std::path::PathBuf; +use std::{collections::HashSet, path::PathBuf}; /// In the absence of a port supplied by the user via the config we will first try using this /// before using a random port. @@ -315,25 +317,40 @@ fn bind( fn unwrap_config_or_default(cfg: Option) -> Result { let mut cfg = cfg.map_or(Config::read_or_construct_default(None)?, |cfg| cfg); + if cfg.local_ip.is_none() { - cfg.local_ip = match crate::igd::get_local_ip() { - Ok(addr) => Some(addr), - Err(err) => { - warn!("Error realizing local IP using IGD gateway: {}", err); - let socket = UdpSocket::bind("0.0.0.0:0")?; - let mut local_ip = None; - for addr in cfg.hard_coded_contacts.iter() { - if let Ok(Ok(local_addr)) = socket.connect(addr).map(|()| socket.local_addr()) { - local_ip = Some(local_addr.ip()); - break; - } + #[cfg(feature = "no-igd")] + { + cfg.local_ip = realize_ip_from_contacts(&cfg.hard_coded_contacts)?; + } + + #[cfg(not(feature = "no-igd"))] + { + cfg.local_ip = match crate::igd::get_local_ip() { + Ok(addr) => Some(addr), + Err(err) => { + warn!("Error realizing local IP using IGD gateway: {}", err); + realize_ip_from_contacts(&cfg.hard_coded_contacts)? } - local_ip } } - }; + } + if cfg.clean { Config::clear_config_from_disk(None)?; } + Ok(cfg) } + +fn realize_ip_from_contacts(contacts: &HashSet) -> Result> { + debug!("Realizing local IP by connecting to contacts"); + let socket = UdpSocket::bind("0.0.0.0:0")?; + for addr in contacts.iter() { + if let Ok(Ok(local_addr)) = socket.connect(addr).map(|()| socket.local_addr()) { + return Ok(Some(local_addr.ip())); + } + } + + Ok(None) +} diff --git a/src/endpoint.rs b/src/endpoint.rs index 01188ee9..9da6e220 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -8,10 +8,10 @@ // Software. use super::error::Error; -use super::igd::forward_port; use super::wire_msg::WireMsg; +#[cfg(not(feature = "no-igd"))] +use super::{api::DEFAULT_UPNP_LEASE_DURATION_SEC, igd::forward_port}; use super::{ - api::DEFAULT_UPNP_LEASE_DURATION_SEC, connection_deduplicator::ConnectionDeduplicator, connection_pool::ConnectionPool, connections::{ @@ -32,6 +32,7 @@ use tokio::time::timeout; const CERT_SERVER_NAME: &str = "MaidSAFE.net"; // Number of seconds before timing out the IGD request to forward a port. +#[cfg(not(feature = "no-igd"))] const PORT_FORWARD_TIMEOUT: u64 = 30; /// Channel on which incoming messages can be listened to @@ -210,6 +211,12 @@ impl Endpoint { let mut addr = None; + #[cfg(feature = "no-igd")] + if self.qp2p_config.forward_port { + warn!("Ignoring 'forward_port' flag from config since IGD has been disabled (feature 'no-igd' has been set)"); + } + + #[cfg(not(feature = "no-igd"))] if self.qp2p_config.forward_port { // Attempt to use IGD for port forwarding match timeout( diff --git a/src/lib.rs b/src/lib.rs index c98080e6..cc8072ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,7 @@ mod connection_pool; mod connections; mod endpoint; mod error; +#[cfg(not(feature = "no-igd"))] mod igd; mod peer_config; #[cfg(test)]