Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set tunnel name to wg0-mullvad for wireguard-go #6713

Merged
merged 2 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions talpid-tunnel/src/tun_provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,

Expand Down Expand Up @@ -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),
Expand Down
157 changes: 78 additions & 79 deletions talpid-tunnel/src/tun_provider/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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))
}
Expand All @@ -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>;
/// A tunnel device builder.
///
/// Call [`Self::create`] to create [`TunnelDevice`] from the config.
pub struct TunnelDeviceBuilder {
config: Configuration,
}

/// Set host IPs for interface
fn set_ip(&mut self, ip: IpAddr) -> Result<(), NetworkInterfaceError>;
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(())
}

/// Get name of interface
fn get_name(&self) -> &str;
}
let dev = platform::create(&self.config).map_err(Error::CreateDevice)?;
apply_async_flags(dev.as_raw_fd()).map_err(Error::SetDeviceAsync)?;
Ok(TunnelDevice { dev })
}

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(())
}
/// 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
}

/// A tunnel device
pub struct TunnelDevice {
dev: platform::Device,
/// 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);
});
self
}
}

impl TunnelDevice {
/// Creates a new Tunnel device
#[allow(unused_mut)]
pub fn new() -> Result<Self, NetworkInterfaceError> {
let mut config = Configuration::default();

#[cfg(target_os = "linux")]
config.platform(|config| {
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 })
impl Default for TunnelDeviceBuilder {
fn default() -> Self {
let config = Configuration::default();
Self { config }
}
}

Expand All @@ -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")]
{
Expand All @@ -173,7 +174,7 @@ impl NetworkInterface for TunnelDevice {
)
.run()
.map(|_| ())
.map_err(NetworkInterfaceError::SetIpv6)
.map_err(Error::SetIpv6)
}
#[cfg(target_os = "macos")]
{
Expand All @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions talpid-wireguard/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions talpid-wireguard/src/wireguard_go/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions talpid-wireguard/src/wireguard_kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 3 additions & 1 deletion talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down
Loading