summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-09-02 15:09:55 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-09-02 15:09:55 +0200
commitd0040f934b9120e25399a71f60f6365303986937 (patch)
tree33a9582934d0c2d65593a63870c145613a7271da
parentce2b4ff61e87b70fa48c7f296a8e782c4b3fcd7b (diff)
parent6df61153bc7385587b209c67699bdaa1cd61a9b0 (diff)
downloadmullvadvpn-d0040f934b9120e25399a71f60f6365303986937.tar.xz
mullvadvpn-d0040f934b9120e25399a71f60f6365303986937.zip
Merge branch 'set-wggo-tun-name'
-rw-r--r--CHANGELOG.md3
-rw-r--r--talpid-tunnel/src/tun_provider/mod.rs4
-rw-r--r--talpid-tunnel/src/tun_provider/unix.rs157
-rw-r--r--talpid-wireguard/src/config.rs4
-rw-r--r--talpid-wireguard/src/wireguard_go/mod.rs6
-rw-r--r--talpid-wireguard/src/wireguard_kernel/mod.rs2
-rw-r--r--talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs4
-rw-r--r--talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs4
8 files changed, 101 insertions, 83 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38c2bcc5b9..e4bac530c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,9 @@ Line wrap the file at 100 chars. Th
### Fixed
- macOS and Linux: Fix potential crash when disconnecting with DAITA enabled.
+#### Linux
+- Set tunnel name to `wg0-mullvad` for userspace WireGuard.
+
#### macOS
- Exclude programs when executed using a relative path from a shell.
- Reduce packet loss when using split tunneling.
diff --git a/talpid-tunnel/src/tun_provider/mod.rs b/talpid-tunnel/src/tun_provider/mod.rs
index da7baf9889..94a82735d1 100644
--- a/talpid-tunnel/src/tun_provider/mod.rs
+++ b/talpid-tunnel/src/tun_provider/mod.rs
@@ -34,6 +34,9 @@ cfg_if! {
/// Configuration for creating a tunnel device.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TunConfig {
+ /// Interface name to use.
+ pub name: Option<String>,
+
/// IP addresses for the tunnel interface.
pub addresses: Vec<IpAddr>,
@@ -77,6 +80,7 @@ impl TunConfig {
/// Android to route all traffic inside the tunnel.
pub fn blocking_config() -> TunConfig {
TunConfig {
+ name: None,
addresses: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))],
mtu: 1380,
ipv4_gateway: Ipv4Addr::new(10, 64, 0, 1),
diff --git a/talpid-tunnel/src/tun_provider/unix.rs b/talpid-tunnel/src/tun_provider/unix.rs
index 640af527b3..1081b3ce44 100644
--- a/talpid-tunnel/src/tun_provider/unix.rs
+++ b/talpid-tunnel/src/tun_provider/unix.rs
@@ -11,17 +11,25 @@ use tun::{platform, Configuration, Device};
/// Errors that can occur while setting up a tunnel device.
#[derive(Debug, thiserror::Error)]
pub enum Error {
- /// Failure to create a tunnel device.
- #[error("Failed to create a tunnel device")]
- CreateTunnelDevice(#[source] NetworkInterfaceError),
+ /// Failed to set IP address
+ #[error("Failed to set IPv4 address")]
+ SetIpv4(#[source] tun::Error),
+
+ /// Failed to set IP address
+ #[error("Failed to set IPv6 address")]
+ SetIpv6(#[source] io::Error),
- /// Failure to set a tunnel device IP address.
- #[error("Failed to set tunnel IP address: {0}")]
- SetIpAddr(IpAddr, #[source] NetworkInterfaceError),
+ /// Unable to open a tunnel device
+ #[error("Unable to open a tunnel device")]
+ CreateDevice(#[source] tun::Error),
+
+ /// Failed to apply async flags to tunnel device
+ #[error("Failed to apply async flags to tunnel device")]
+ SetDeviceAsync(#[source] nix::Error),
- /// Failure to set the tunnel device as up.
- #[error("Failed to set the tunnel device as up")]
- SetUp(#[source] NetworkInterfaceError),
+ /// Failed to enable/disable link device
+ #[error("Failed to enable/disable link device")]
+ ToggleDevice(#[source] tun::Error),
}
/// Factory of tunnel devices on Unix systems.
@@ -42,15 +50,23 @@ impl UnixTunProvider {
/// Open a tunnel using the current tunnel config.
pub fn open_tun(&mut self) -> Result<UnixTun, Error> {
- let mut tunnel_device = TunnelDevice::new().map_err(Error::CreateTunnelDevice)?;
+ let mut tunnel_device = {
+ #[allow(unused_mut)]
+ let mut builder = TunnelDeviceBuilder::default();
+ #[cfg(target_os = "linux")]
+ builder.enable_packet_information();
+ #[cfg(target_os = "linux")]
+ if let Some(ref name) = self.config.name {
+ builder.name(name);
+ }
+ builder.create()?
+ };
for ip in self.config.addresses.iter() {
- tunnel_device
- .set_ip(*ip)
- .map_err(|cause| Error::SetIpAddr(*ip, cause))?;
+ tunnel_device.set_ip(*ip)?;
}
- tunnel_device.set_up(true).map_err(Error::SetUp)?;
+ tunnel_device.set_up(true)?;
Ok(UnixTun(tunnel_device))
}
@@ -76,67 +92,55 @@ impl Deref for UnixTun {
}
}
-/// Errors that can happen when working with *nix tunnel interfaces.
-#[derive(thiserror::Error, Debug)]
-pub enum NetworkInterfaceError {
- /// Failed to set IP address
- #[error("Failed to set IPv4 address")]
- SetIpv4(#[source] tun::Error),
-
- /// Failed to set IP address
- #[error("Failed to set IPv6 address")]
- SetIpv6(#[source] io::Error),
-
- /// Unable to open a tunnel device
- #[error("Unable to open a tunnel device")]
- CreateDevice(#[source] tun::Error),
-
- /// Failed to apply async flags to tunnel device
- #[error("Failed to apply async flags to tunnel device")]
- SetDeviceAsync(#[source] nix::Error),
-
- /// Failed to enable/disable link device
- #[error("Failed to enable/disable link device")]
- ToggleDevice(#[source] tun::Error),
+/// A tunnel device
+pub struct TunnelDevice {
+ dev: platform::Device,
}
-/// A trait for managing link devices
-pub trait NetworkInterface: Sized {
- /// Bring a given interface up or down
- fn set_up(&mut self, up: bool) -> Result<(), NetworkInterfaceError>;
-
- /// Set host IPs for interface
- fn set_ip(&mut self, ip: IpAddr) -> Result<(), NetworkInterfaceError>;
-
- /// Get name of interface
- fn get_name(&self) -> &str;
+/// A tunnel device builder.
+///
+/// Call [`Self::create`] to create [`TunnelDevice`] from the config.
+pub struct TunnelDeviceBuilder {
+ config: Configuration,
}
-fn apply_async_flags(fd: RawFd) -> Result<(), nix::Error> {
- fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFL)?;
- let arg = fcntl::FcntlArg::F_SETFL(fcntl::OFlag::O_RDWR | fcntl::OFlag::O_NONBLOCK);
- fcntl::fcntl(fd, arg)?;
- Ok(())
-}
+impl TunnelDeviceBuilder {
+ /// Create a [`TunnelDevice`] from this builder.
+ pub fn create(self) -> Result<TunnelDevice, Error> {
+ fn apply_async_flags(fd: RawFd) -> Result<(), nix::Error> {
+ fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFL)?;
+ let arg = fcntl::FcntlArg::F_SETFL(fcntl::OFlag::O_RDWR | fcntl::OFlag::O_NONBLOCK);
+ fcntl::fcntl(fd, arg)?;
+ Ok(())
+ }
-/// A tunnel device
-pub struct TunnelDevice {
- dev: platform::Device,
-}
+ let dev = platform::create(&self.config).map_err(Error::CreateDevice)?;
+ apply_async_flags(dev.as_raw_fd()).map_err(Error::SetDeviceAsync)?;
+ Ok(TunnelDevice { dev })
+ }
-impl TunnelDevice {
- /// Creates a new Tunnel device
- #[allow(unused_mut)]
- pub fn new() -> Result<Self, NetworkInterfaceError> {
- let mut config = Configuration::default();
+ /// Set a custom name for this tunnel device.
+ #[cfg(target_os = "linux")]
+ pub fn name(&mut self, name: &str) -> &mut Self {
+ self.config.name(name);
+ self
+ }
- #[cfg(target_os = "linux")]
- config.platform(|config| {
- config.packet_information(true);
+ /// Enable packet information.
+ /// When enabled the first 4 bytes of each packet is a header with flags and protocol type.
+ #[cfg(target_os = "linux")]
+ pub fn enable_packet_information(&mut self) -> &mut Self {
+ self.config.platform(|platform_config| {
+ platform_config.packet_information(true);
});
- let mut dev = platform::create(&config).map_err(NetworkInterfaceError::CreateDevice)?;
- apply_async_flags(dev.as_raw_fd()).map_err(NetworkInterfaceError::SetDeviceAsync)?;
- Ok(Self { dev })
+ self
+ }
+}
+
+impl Default for TunnelDeviceBuilder {
+ fn default() -> Self {
+ let config = Configuration::default();
+ Self { config }
}
}
@@ -152,13 +156,10 @@ impl IntoRawFd for TunnelDevice {
}
}
-impl NetworkInterface for TunnelDevice {
- fn set_ip(&mut self, ip: IpAddr) -> Result<(), NetworkInterfaceError> {
+impl TunnelDevice {
+ fn set_ip(&mut self, ip: IpAddr) -> Result<(), Error> {
match ip {
- IpAddr::V4(ipv4) => self
- .dev
- .set_address(ipv4)
- .map_err(NetworkInterfaceError::SetIpv4),
+ IpAddr::V4(ipv4) => self.dev.set_address(ipv4).map_err(Error::SetIpv4),
IpAddr::V6(ipv6) => {
#[cfg(target_os = "linux")]
{
@@ -173,7 +174,7 @@ impl NetworkInterface for TunnelDevice {
)
.run()
.map(|_| ())
- .map_err(NetworkInterfaceError::SetIpv6)
+ .map_err(Error::SetIpv6)
}
#[cfg(target_os = "macos")]
{
@@ -186,16 +187,14 @@ impl NetworkInterface for TunnelDevice {
)
.run()
.map(|_| ())
- .map_err(NetworkInterfaceError::SetIpv6)
+ .map_err(Error::SetIpv6)
}
}
}
}
- fn set_up(&mut self, up: bool) -> Result<(), NetworkInterfaceError> {
- self.dev
- .enabled(up)
- .map_err(NetworkInterfaceError::ToggleDevice)
+ fn set_up(&mut self, up: bool) -> Result<(), Error> {
+ self.dev.enabled(up).map_err(Error::ToggleDevice)
}
fn get_name(&self) -> &str {
diff --git a/talpid-wireguard/src/config.rs b/talpid-wireguard/src/config.rs
index 924446e8eb..c599d34483 100644
--- a/talpid-wireguard/src/config.rs
+++ b/talpid-wireguard/src/config.rs
@@ -5,6 +5,10 @@ use std::{
};
use talpid_types::net::{obfuscation::ObfuscatorConfig, wireguard, GenericTunnelOptions};
+/// Name to use for the tunnel device
+#[cfg(target_os = "linux")]
+pub(crate) const MULLVAD_INTERFACE_NAME: &str = "wg0-mullvad";
+
/// Config required to set up a single WireGuard tunnel
#[derive(Debug, Clone)]
pub struct Config {
diff --git a/talpid-wireguard/src/wireguard_go/mod.rs b/talpid-wireguard/src/wireguard_go/mod.rs
index 14f2d82cc6..678412bb1e 100644
--- a/talpid-wireguard/src/wireguard_go/mod.rs
+++ b/talpid-wireguard/src/wireguard_go/mod.rs
@@ -19,6 +19,8 @@ use super::{
stats::{Stats, StatsMap},
Config, Tunnel, TunnelError,
};
+#[cfg(target_os = "linux")]
+use crate::config::MULLVAD_INTERFACE_NAME;
use crate::logging::{clean_up_logging, initialize_logging};
const MAX_PREPARE_TUN_ATTEMPTS: usize = 4;
@@ -130,6 +132,10 @@ impl WgGoTunnel {
let mut tun_provider = tun_provider.lock().unwrap();
let tun_config = tun_provider.config_mut();
+ #[cfg(target_os = "linux")]
+ {
+ tun_config.name = Some(MULLVAD_INTERFACE_NAME.to_string());
+ }
tun_config.addresses = config.tunnel.addresses.clone();
tun_config.ipv4_gateway = config.ipv4_gateway;
tun_config.ipv6_gateway = config.ipv6_gateway;
diff --git a/talpid-wireguard/src/wireguard_kernel/mod.rs b/talpid-wireguard/src/wireguard_kernel/mod.rs
index a3c053acfc..db00557ffa 100644
--- a/talpid-wireguard/src/wireguard_kernel/mod.rs
+++ b/talpid-wireguard/src/wireguard_kernel/mod.rs
@@ -84,8 +84,6 @@ pub enum Error {
NetworkManager(#[source] nm_tunnel::Error),
}
-pub(crate) const MULLVAD_INTERFACE_NAME: &str = "wg0-mullvad";
-
#[derive(Debug)]
pub struct Handle {
pub wg_handle: WireguardConnection,
diff --git a/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs b/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
index 0c6bec8823..52d8616c02 100644
--- a/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
+++ b/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
@@ -2,10 +2,12 @@ use std::pin::Pin;
use futures::Future;
+use crate::config::MULLVAD_INTERFACE_NAME;
+
use super::{
super::stats::{Stats, StatsMap},
wg_message::DeviceNla,
- Config, Error, Handle, Tunnel, TunnelError, MULLVAD_INTERFACE_NAME,
+ Config, Error, Handle, Tunnel, TunnelError,
};
pub struct NetlinkTunnel {
diff --git a/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs b/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
index 12f37f3e45..76cfbcaddd 100644
--- a/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
+++ b/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
@@ -1,6 +1,8 @@
+use crate::config::MULLVAD_INTERFACE_NAME;
+
use super::{
super::stats::{Stats, StatsMap},
- Config, Error as WgKernelError, Handle, Tunnel, TunnelError, MULLVAD_INTERFACE_NAME,
+ Config, Error as WgKernelError, Handle, Tunnel, TunnelError,
};
use futures::Future;
use std::{collections::HashMap, pin::Pin};