summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2022-03-28 14:38:46 +0100
committerEmīls <emils@mullvad.net>2022-03-28 14:38:46 +0100
commit2d3494f3ee886f4c2ec13025833e05e05bd1feac (patch)
tree3200f43bf81e63745c283e03e4a17e303d634643
parent077a1f91b738195ec15731bb5cb8ec9608b66db2 (diff)
parent8d156280895239741fc506f93c7eb4c0f65ecf78 (diff)
downloadmullvadvpn-2d3494f3ee886f4c2ec13025833e05e05bd1feac.tar.xz
mullvadvpn-2d3494f3ee886f4c2ec13025833e05e05bd1feac.zip
Merge branch 'use-icmp-on-macos'
-rw-r--r--talpid-core/Cargo.toml8
-rw-r--r--talpid-core/src/ping_monitor/android.rs (renamed from talpid-core/src/ping_monitor/unix.rs)32
-rw-r--r--talpid-core/src/ping_monitor/icmp.rs30
-rw-r--r--talpid-core/src/ping_monitor/mod.rs10
-rw-r--r--talpid-core/src/tunnel/wireguard/connectivity_check.rs4
-rw-r--r--talpid-core/src/tunnel/wireguard/mod.rs2
6 files changed, 44 insertions, 42 deletions
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index d0cf685753..7ff3b8721f 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -32,9 +32,11 @@ tokio = { version = "1.8", features = ["process", "rt-multi-thread", "fs"] }
tokio-stream = { version = "0.1", features = ["io-util"] }
rand = "0.7"
tunnel-obfuscation = { path = "../tunnel-obfuscation" }
-socket2 = { version = "0.4.2", features = ["all"] }
[target.'cfg(not(target_os="android"))'.dependencies]
+byteorder = "1"
+internet-checksum = "0.2"
+socket2 = { version = "0.4.2", features = ["all"] }
parity-tokio-ipc = "0.9"
triggered = "0.1.1"
tonic = "0.5"
@@ -57,13 +59,11 @@ netlink-packet-utils = "0.4"
netlink-packet-route = "0.8"
netlink-proto = "0.7"
netlink-sys = "0.7"
-byteorder = "1"
nftnl = { version = "0.6.2", features = ["nftnl-1-1-0"] }
mnl = { version = "0.2.2", features = ["mnl-1-0-4"] }
which = { version = "4.0", default-features = false }
tun = "0.5.1"
talpid-dbus = { path = "../talpid-dbus" }
-internet-checksum = "0.2"
[target.'cfg(target_os = "macos")'.dependencies]
@@ -75,8 +75,6 @@ subslice = "0.2"
[target.'cfg(windows)'.dependencies]
-byteorder = "1"
-internet-checksum = "0.2"
widestring = "0.5"
winreg = { version = "0.7", features = ["transactions"] }
winapi = { version = "0.3.6", features = ["combaseapi", "handleapi", "ifdef", "libloaderapi", "netioapi", "psapi", "stringapiset", "synchapi", "tlhelp32", "winbase", "winioctl", "winuser", "dbt"] }
diff --git a/talpid-core/src/ping_monitor/unix.rs b/talpid-core/src/ping_monitor/android.rs
index b93678a22b..9263dbac79 100644
--- a/talpid-core/src/ping_monitor/unix.rs
+++ b/talpid-core/src/ping_monitor/android.rs
@@ -15,17 +15,15 @@ pub enum Error {
/// A pinger that sends ICMP requests without waiting for responses
pub struct Pinger {
addr: Ipv4Addr,
- interface_name: String,
processes: Vec<duct::Handle>,
}
impl Pinger {
/// Creates a new pinger that will send ICMP requests only through the specified interface
- pub fn new(addr: Ipv4Addr, interface_name: String) -> Result<Self, Error> {
+ pub fn new(addr: Ipv4Addr) -> Result<Self, Error> {
Ok(Self {
processes: vec![],
addr,
- interface_name,
})
}
@@ -45,7 +43,7 @@ impl super::Pinger for Pinger {
fn send_icmp(&mut self) -> Result<(), Error> {
self.try_deplete_process_list();
- let cmd = ping_cmd(self.addr, 1, &self.interface_name);
+ let cmd = ping_cmd(self.addr, 1);
let handle = cmd.start().map_err(Error::PingError)?;
self.processes.push(handle);
Ok(())
@@ -77,32 +75,10 @@ impl Drop for Pinger {
}
}
-fn ping_cmd(ip: Ipv4Addr, timeout_secs: u16, interface: &str) -> duct::Expression {
- let mut args = vec!["-n", "-i", "1"];
-
- let timeout_flag = if cfg!(target_os = "linux") || cfg!(target_os = "android") {
- "-w"
- } else {
- "-t"
- };
+fn ping_cmd(ip: Ipv4Addr, timeout_secs: u16) -> duct::Expression {
let timeout_secs = timeout_secs.to_string();
-
- args.extend_from_slice(&[timeout_flag, &timeout_secs]);
-
- let interface_flag = if cfg!(target_os = "linux") {
- Some("-I")
- } else if cfg!(target_os = "macos") {
- Some("-b")
- } else {
- None
- };
-
- if let Some(interface_flag) = interface_flag {
- args.extend_from_slice(&[interface_flag, interface]);
- }
-
let ip = ip.to_string();
- args.push(&ip);
+ let args = ["-n", "-i", "1", "-w", &timeout_secs, &ip];
duct::cmd("ping", args)
.stdin_null()
diff --git a/talpid-core/src/ping_monitor/icmp.rs b/talpid-core/src/ping_monitor/icmp.rs
index a25a31e1b2..67f5b70cb5 100644
--- a/talpid-core/src/ping_monitor/icmp.rs
+++ b/talpid-core/src/ping_monitor/icmp.rs
@@ -30,6 +30,16 @@ pub enum Error {
#[error(display = "Failed to write to socket")]
WriteError(#[error(source)] io::Error),
+ /// Failed to get device index
+ #[cfg(target_os = "macos")]
+ #[error(display = "Failed to obtain device index")]
+ DeviceIdxError(nix::errno::Errno),
+
+ /// Failed to bind socket to device by index
+ #[cfg(target_os = "macos")]
+ #[error(display = "Failed to bind socket to device by index")]
+ BindSocketByDeviceError(io::Error),
+
/// ICMP buffer too small
#[error(display = "ICMP message buffer too small")]
BufferTooSmall,
@@ -49,7 +59,10 @@ pub struct Pinger {
}
impl Pinger {
- pub fn new(addr: Ipv4Addr, #[cfg(target_os = "linux")] interface_name: String) -> Result<Self> {
+ pub fn new(
+ addr: Ipv4Addr,
+ #[cfg(not(target_os = "windows"))] interface_name: String,
+ ) -> Result<Self> {
let addr = SocketAddr::new(addr.into(), 0);
let sock = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::ICMPV4))
.map_err(Error::OpenError)?;
@@ -59,6 +72,9 @@ impl Pinger {
sock.bind_device(Some(interface_name.as_bytes()))
.map_err(Error::SocketOptError)?;
+ #[cfg(target_os = "macos")]
+ Self::set_device_index(&sock, &interface_name)?;
+
Ok(Self {
sock,
addr,
@@ -67,6 +83,18 @@ impl Pinger {
})
}
+ #[cfg(target_os = "macos")]
+ fn set_device_index(socket: &Socket, interface_name: &str) -> Result<()> {
+ let index = nix::net::if_::if_nametoindex(interface_name).map_err(Error::DeviceIdxError)?;
+ // Asserting that `index` is non-zero since otherwise `if_nametoindex` would have return
+ // an error
+ socket
+ .bind_device_by_index(std::num::NonZeroU32::new(index))
+ .map_err(Error::BindSocketByDeviceError)?;
+
+ Ok(())
+ }
+
fn send_ping_request(&mut self, message: &[u8], destination: SocketAddr) -> Result<()> {
let mut tries = 0;
let mut result = Ok(());
diff --git a/talpid-core/src/ping_monitor/mod.rs b/talpid-core/src/ping_monitor/mod.rs
index e978bd38b2..9b105a50dc 100644
--- a/talpid-core/src/ping_monitor/mod.rs
+++ b/talpid-core/src/ping_monitor/mod.rs
@@ -1,8 +1,8 @@
-#[cfg(any(target_os = "android", target_os = "macos"))]
-#[path = "unix.rs"]
+#[cfg(any(target_os = "android"))]
+#[path = "android.rs"]
mod imp;
-#[cfg(any(target_os = "windows", target_os = "linux"))]
+#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
#[path = "icmp.rs"]
mod imp;
@@ -19,11 +19,11 @@ pub trait Pinger: Send {
/// Create a new pinger
pub fn new_pinger(
addr: std::net::Ipv4Addr,
- #[cfg(not(target_os = "windows"))] interface_name: String,
+ #[cfg(any(target_os = "linux", target_os = "macos"))] interface_name: String,
) -> Result<Box<dyn Pinger>, Error> {
Ok(Box::new(imp::Pinger::new(
addr,
- #[cfg(not(target_os = "windows"))]
+ #[cfg(any(target_os = "linux", target_os = "macos"))]
interface_name,
)?))
}
diff --git a/talpid-core/src/tunnel/wireguard/connectivity_check.rs b/talpid-core/src/tunnel/wireguard/connectivity_check.rs
index 162fb248a3..d6bb61a5fc 100644
--- a/talpid-core/src/tunnel/wireguard/connectivity_check.rs
+++ b/talpid-core/src/tunnel/wireguard/connectivity_check.rs
@@ -81,13 +81,13 @@ pub struct ConnectivityMonitor {
impl ConnectivityMonitor {
pub(super) fn new(
addr: Ipv4Addr,
- #[cfg(not(target_os = "windows"))] interface: String,
+ #[cfg(any(target_os = "macos", target_os = "linux"))] interface: String,
tunnel_handle: Weak<Mutex<Option<Box<dyn Tunnel>>>>,
close_receiver: mpsc::Receiver<()>,
) -> Result<Self, Error> {
let pinger = new_pinger(
addr,
- #[cfg(not(target_os = "windows"))]
+ #[cfg(any(target_os = "macos", target_os = "linux"))]
interface,
)
.map_err(Error::PingError)?;
diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs
index 817ad74eea..80c8e2ae8e 100644
--- a/talpid-core/src/tunnel/wireguard/mod.rs
+++ b/talpid-core/src/tunnel/wireguard/mod.rs
@@ -229,7 +229,7 @@ impl WireguardMonitor {
let gateway = config.ipv4_gateway;
let mut connectivity_monitor = connectivity_check::ConnectivityMonitor::new(
gateway,
- #[cfg(not(target_os = "windows"))]
+ #[cfg(any(target_os = "macos", target_os = "linux"))]
iface_name.clone(),
Arc::downgrade(&monitor.tunnel),
pinger_rx,