summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian Holmin <sebastian.holmin@mullvad.net>2025-01-24 16:26:57 +0100
committerSebastian Holmin <sebastian.holmin@mullvad.net>2025-01-27 20:03:18 +0100
commit50338aa1cfea1209a50fd120782eb12ca4f21903 (patch)
tree25706c9e131de16b1c7621782bfa75547f7614d9
parent52b36a35070bbf493b3ce180d0b8d9b91e7e753e (diff)
downloadmullvadvpn-50338aa1cfea1209a50fd120782eb12ca4f21903.tar.xz
mullvadvpn-50338aa1cfea1209a50fd120782eb12ca4f21903.zip
Refactor wireguard implementation picker
-rw-r--r--talpid-wireguard/src/lib.rs149
1 files changed, 87 insertions, 62 deletions
diff --git a/talpid-wireguard/src/lib.rs b/talpid-wireguard/src/lib.rs
index 330a2c76cf..78a977aff3 100644
--- a/talpid-wireguard/src/lib.rs
+++ b/talpid-wireguard/src/lib.rs
@@ -643,9 +643,11 @@ impl WireguardMonitor {
log::debug!("Tunnel MTU: {}", config.mtu);
#[cfg(target_os = "linux")]
- if !*FORCE_USERSPACE_WIREGUARD {
- // If DAITA is enabled, wireguard-go has to be used.
- if config.daita {
+ {
+ let userspace_wireguard = *FORCE_USERSPACE_WIREGUARD || config.daita;
+ if userspace_wireguard {
+ log::debug!("Using userspace WireGuard implementation");
+
let tunnel = runtime
.block_on(Self::open_wireguard_go_tunnel(
config,
@@ -653,69 +655,65 @@ impl WireguardMonitor {
tun_provider,
))
.map(Box::new)?;
- return Ok(tunnel);
- }
-
- if will_nm_manage_dns() {
- match wireguard_kernel::NetworkManagerTunnel::new(runtime.clone(), config) {
- Ok(tunnel) => {
- log::debug!("Using NetworkManager to use kernel WireGuard implementation");
- return Ok(Box::new(tunnel));
- }
- Err(err) => {
- log::error!(
- "{}",
- err.display_chain_with_msg(
- "Failed to initialize WireGuard tunnel via NetworkManager"
- )
- );
- }
- };
+ Ok(tunnel)
} else {
- match wireguard_kernel::NetlinkTunnel::new(runtime.clone(), config) {
- Ok(tunnel) => {
- log::debug!("Using kernel WireGuard implementation");
- return Ok(Box::new(tunnel));
- }
- Err(error) => {
- log::error!(
- "{}",
- error.display_chain_with_msg(
- "Failed to setup kernel WireGuard device, falling back to the userspace implementation"
- )
- );
- }
- };
- }
- }
+ log::debug!("Using kernel WireGuard implementation");
+ {
+ let res: Option<TunnelType> = if will_nm_manage_dns() {
+ match wireguard_kernel::NetworkManagerTunnel::new(runtime.clone(), config) {
+ Ok(tunnel) => {
+ log::debug!(
+ "Using NetworkManager to use kernel WireGuard implementation"
+ );
+ Some(Box::new(tunnel))
+ }
+ Err(err) => {
+ log::error!(
+ "{}",
+ err.display_chain_with_msg(
+ "Failed to initialize WireGuard tunnel via NetworkManager"
+ )
+ );
+ None
+ }
+ }
+ } else {
+ match wireguard_kernel::NetlinkTunnel::new(runtime.clone(), config) {
+ Ok(tunnel) => {
+ log::debug!("Using kernel WireGuard implementation");
+ Some(Box::new(tunnel))
+ }
+ Err(error) => {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to setup kernel WireGuard device, falling back to the userspace implementation"
+ )
+ );
+ None
+ }
+ }
+ };
- #[cfg(target_os = "windows")]
- {
- #[cfg(wireguard_go)]
- {
- let use_userspace_wg = config.daita || *FORCE_USERSPACE_WIREGUARD;
- if use_userspace_wg {
- log::debug!("Using userspace WireGuard implementation");
- let tunnel = runtime
- .block_on(Self::open_wireguard_go_tunnel(
- config,
- log_path,
- setup_done_tx,
- route_manager,
- ))
- .map(Box::new)?;
- return Ok(tunnel);
+ match res {
+ Some(tunnel) => Ok(tunnel),
+ None => {
+ log::warn!("Falling back to userspace WireGuard implementation");
+ let tunnel = runtime
+ .block_on(Self::open_wireguard_go_tunnel(
+ config,
+ log_path,
+ tun_provider,
+ ))
+ .map(Box::new)?;
+ Ok(tunnel)
+ }
+ }
}
}
-
- wireguard_nt::WgNtTunnel::start_tunnel(config, log_path, resource_dir, setup_done_tx)
- .map(|tun| Box::new(tun) as Box<dyn Tunnel + 'static>)
- .map_err(Error::TunnelError)
}
-
- #[cfg(all(wireguard_go, not(target_os = "windows")))]
+ #[cfg(target_os = "macos")]
{
- #[cfg(target_os = "linux")]
log::debug!("Using userspace WireGuard implementation");
let tunnel = runtime
@@ -723,12 +721,39 @@ impl WireguardMonitor {
config,
log_path,
tun_provider,
- #[cfg(target_os = "android")]
- gateway_only,
))
.map(Box::new)?;
Ok(tunnel)
}
+ #[cfg(target_os = "windows")]
+ {
+ let userspace_wireguard = *FORCE_USERSPACE_WIREGUARD || config.daita;
+
+ if userspace_wireguard {
+ log::debug!("Using userspace WireGuard implementation");
+
+ let tunnel = runtime
+ .block_on(Self::open_wireguard_go_tunnel(
+ config,
+ log_path,
+ setup_done_tx,
+ route_manager,
+ ))
+ .map(Box::new)?;
+ Ok(tunnel)
+ } else {
+ log::debug!("Using kernel WireGuard implementation");
+
+ wireguard_nt::WgNtTunnel::start_tunnel(
+ config,
+ log_path,
+ resource_dir,
+ setup_done_tx,
+ )
+ .map(|tun| Box::new(tun) as Box<dyn Tunnel + 'static>)
+ .map_err(Error::TunnelError)
+ }
+ }
}
/// Configure and start a Wireguard-go tunnel.