diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2025-01-24 16:26:57 +0100 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2025-01-27 20:03:18 +0100 |
| commit | 50338aa1cfea1209a50fd120782eb12ca4f21903 (patch) | |
| tree | 25706c9e131de16b1c7621782bfa75547f7614d9 | |
| parent | 52b36a35070bbf493b3ce180d0b8d9b91e7e753e (diff) | |
| download | mullvadvpn-50338aa1cfea1209a50fd120782eb12ca4f21903.tar.xz mullvadvpn-50338aa1cfea1209a50fd120782eb12ca4f21903.zip | |
Refactor wireguard implementation picker
| -rw-r--r-- | talpid-wireguard/src/lib.rs | 149 |
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. |
