diff options
| -rw-r--r-- | talpid-tunnel-config-client/src/lib.rs | 36 | ||||
| -rw-r--r-- | talpid-wireguard/Cargo.toml | 2 | ||||
| -rw-r--r-- | talpid-wireguard/build.rs | 7 | ||||
| -rw-r--r-- | talpid-wireguard/src/ephemeral.rs | 9 | ||||
| -rw-r--r-- | talpid-wireguard/src/lib.rs | 28 | ||||
| -rw-r--r-- | talpid-wireguard/src/wireguard_go/mod.rs | 68 | ||||
| -rw-r--r-- | talpid-wireguard/src/wireguard_nt/mod.rs | 2 |
7 files changed, 93 insertions, 59 deletions
diff --git a/talpid-tunnel-config-client/src/lib.rs b/talpid-tunnel-config-client/src/lib.rs index 381bc65a53..0be9567259 100644 --- a/talpid-tunnel-config-client/src/lib.rs +++ b/talpid-tunnel-config-client/src/lib.rs @@ -22,7 +22,6 @@ mod proto { tonic::include_proto!("ephemeralpeer"); } -#[cfg(unix)] const DAITA_VERSION: u32 = 2; #[derive(Debug)] @@ -88,7 +87,6 @@ pub const CONFIG_SERVICE_PORT: u16 = 1337; pub struct EphemeralPeer { pub psk: Option<PresharedKey>, - #[cfg(unix)] pub daita: Option<DaitaSettings>, } @@ -141,15 +139,7 @@ pub async fn request_ephemeral_peer_with( wg_parent_pubkey: parent_pubkey.as_bytes().to_vec(), wg_ephemeral_peer_pubkey: ephemeral_pubkey.as_bytes().to_vec(), post_quantum: pq_request, - #[cfg(windows)] - daita: Some(proto::DaitaRequestV1 { - activate_daita: enable_daita, - }), - #[cfg(windows)] - daita_v2: None, - #[cfg(unix)] daita: None, - #[cfg(unix)] daita_v2: enable_daita.then(|| proto::DaitaRequestV2 { level: i32::from(proto::DaitaLevel::LevelDefault), platform: i32::from(get_platform()), @@ -204,29 +194,21 @@ pub async fn request_ephemeral_peer_with( None }; - #[cfg(unix)] - { - let daita = response.daita.map(|daita| DaitaSettings { - client_machines: daita.client_machines, - max_padding_frac: daita.max_padding_frac, - max_blocking_frac: daita.max_blocking_frac, - }); - if daita.is_none() && enable_daita { - return Err(Error::MissingDaitaResponse); - } - Ok(EphemeralPeer { psk, daita }) - } - - #[cfg(windows)] - { - Ok(EphemeralPeer { psk }) + let daita = response.daita.map(|daita| DaitaSettings { + client_machines: daita.client_machines, + max_padding_frac: daita.max_padding_frac, + max_blocking_frac: daita.max_blocking_frac, + }); + if daita.is_none() && enable_daita { + return Err(Error::MissingDaitaResponse); } + Ok(EphemeralPeer { psk, daita }) } -#[cfg(unix)] const fn get_platform() -> proto::DaitaPlatform { use proto::DaitaPlatform; const PLATFORM: DaitaPlatform = if cfg!(target_os = "windows") { + // FIXME: wggo DaitaPlatform::WindowsNative } else if cfg!(target_os = "linux") { DaitaPlatform::LinuxWgGo diff --git a/talpid-wireguard/Cargo.toml b/talpid-wireguard/Cargo.toml index 3a19f5a70a..6341c02bac 100644 --- a/talpid-wireguard/Cargo.toml +++ b/talpid-wireguard/Cargo.toml @@ -30,8 +30,6 @@ tunnel-obfuscation = { path = "../tunnel-obfuscation" } rand = "0.8.5" surge-ping = "0.8.0" rand_chacha = "0.3.1" - -[target.'cfg(not(windows))'.dependencies] wireguard-go-rs = { path = "../wireguard-go-rs"} [target.'cfg(target_os="android")'.dependencies] diff --git a/talpid-wireguard/build.rs b/talpid-wireguard/build.rs index ab3500330c..23c2f3bb67 100644 --- a/talpid-wireguard/build.rs +++ b/talpid-wireguard/build.rs @@ -6,11 +6,10 @@ fn main() { if target_os == "windows" { declare_libs_dir("../dist-assets/binaries"); } - // Wireguard-Go can be used on all platforms except Windows + // Wireguard-Go can be used on all platforms println!("cargo::rustc-check-cfg=cfg(wireguard_go)"); - if matches!(target_os.as_str(), "linux" | "macos" | "android") { - println!("cargo::rustc-cfg=wireguard_go"); - } + println!("cargo::rustc-cfg=wireguard_go"); + // Enable DAITA by default on desktop and android println!("cargo::rustc-check-cfg=cfg(daita)"); println!("cargo::rustc-cfg=daita"); diff --git a/talpid-wireguard/src/ephemeral.rs b/talpid-wireguard/src/ephemeral.rs index 1a61148487..04f24d5fbb 100644 --- a/talpid-wireguard/src/ephemeral.rs +++ b/talpid-wireguard/src/ephemeral.rs @@ -110,7 +110,6 @@ async fn config_ephemeral_peers_inner( ) .await?; - #[cfg(not(target_os = "windows"))] let mut daita = exit_ephemeral_peer.daita; log::debug!("Retrieved ephemeral peer"); @@ -169,7 +168,6 @@ async fn config_ephemeral_peers_inner( #[cfg(daita)] if config.daita { - #[cfg(not(target_os = "windows"))] let Some(daita) = daita else { unreachable!("missing DAITA settings"); @@ -178,17 +176,10 @@ async fn config_ephemeral_peers_inner( // Start local DAITA machines let mut tunnel = tunnel.lock().await; if let Some(tunnel) = tunnel.as_mut() { - #[cfg(not(target_os = "windows"))] tunnel .start_daita(daita) .map_err(Error::TunnelError) .map_err(CloseMsg::SetupError)?; - - #[cfg(target_os = "windows")] - tunnel - .start_daita() - .map_err(Error::TunnelError) - .map_err(CloseMsg::SetupError)?; } } diff --git a/talpid-wireguard/src/lib.rs b/talpid-wireguard/src/lib.rs index 205e150eee..6eecefbbb6 100644 --- a/talpid-wireguard/src/lib.rs +++ b/talpid-wireguard/src/lib.rs @@ -28,7 +28,7 @@ use talpid_tunnel::{ tun_provider::TunProvider, EventHook, TunnelArgs, TunnelEvent, TunnelMetadata, }; -#[cfg(not(target_os = "windows"))] +#[cfg(daita)] use talpid_tunnel_config_client::DaitaSettings; use talpid_types::{ net::{wireguard::TunnelParameters, AllowedTunnelTraffic, Endpoint, TransportProtocol}, @@ -714,7 +714,7 @@ impl WireguardMonitor { .map_err(Error::TunnelError) } - #[cfg(wireguard_go)] + #[cfg(all(wireguard_go, not(target_os = "windows")))] { #[cfg(target_os = "linux")] log::debug!("Using userspace WireGuard implementation"); @@ -738,23 +738,23 @@ impl WireguardMonitor { async fn open_wireguard_go_tunnel( config: &Config, log_path: Option<&Path>, - tun_provider: Arc<Mutex<TunProvider>>, + #[cfg(unix)] tun_provider: Arc<Mutex<TunProvider>>, + #[cfg(windows)] setup_done_tx: mpsc::Sender<std::result::Result<(), BoxedError>>, #[cfg(target_os = "android")] gateway_only: bool, #[cfg(target_os = "android")] cancel_receiver: connectivity::CancelReceiver, ) -> Result<WgGoTunnel> { + #[cfg(unix)] let routes = config .get_tunnel_destinations() .flat_map(Self::replace_default_prefixes); - #[cfg(not(target_os = "android"))] - let tunnel = WgGoTunnel::start_tunnel( - #[allow(clippy::needless_borrow)] - &config, - log_path, - tun_provider, - routes, - ) - .map_err(Error::TunnelError)?; + #[cfg(all(unix, not(target_os = "android")))] + let tunnel = WgGoTunnel::start_tunnel(config, log_path, tun_provider, routes) + .map_err(Error::TunnelError)?; + + #[cfg(target_os = "windows")] + let tunnel = WgGoTunnel::start_tunnel(config, log_path, setup_done_tx) + .map_err(Error::TunnelError)?; // Android uses multihop implemented in Mullvad's wireguard-go fork. When negotiating // with an ephemeral peer, this multihop strategy require us to restart the tunnel @@ -1035,10 +1035,8 @@ pub(crate) trait Tunnel: Send + Sync { ) -> Pin<Box<dyn Future<Output = std::result::Result<(), TunnelError>> + Send + 'a>>; #[cfg(daita)] /// A [`Tunnel`] capable of using DAITA. - #[cfg(not(target_os = "windows"))] + #[cfg(daita)] fn start_daita(&mut self, settings: DaitaSettings) -> std::result::Result<(), TunnelError>; - #[cfg(target_os = "windows")] - fn start_daita(&mut self) -> std::result::Result<(), TunnelError>; } /// Errors to be returned from WireGuard implementations, namely implementers of the Tunnel trait diff --git a/talpid-wireguard/src/wireguard_go/mod.rs b/talpid-wireguard/src/wireguard_go/mod.rs index 4698616d05..86646c1d0c 100644 --- a/talpid-wireguard/src/wireguard_go/mod.rs +++ b/talpid-wireguard/src/wireguard_go/mod.rs @@ -24,7 +24,9 @@ use std::{ }; #[cfg(target_os = "android")] use talpid_tunnel::tun_provider::Error as TunProviderError; +#[cfg(not(target_os = "windows"))] use talpid_tunnel::tun_provider::{Tun, TunProvider}; +#[cfg(daita)] use talpid_tunnel_config_client::DaitaSettings; #[cfg(target_os = "android")] use talpid_types::net::wireguard::PeerConfig; @@ -165,6 +167,7 @@ pub(crate) struct WgGoTunnelState { tunnel_handle: wireguard_go_rs::Tunnel, // holding on to the tunnel device and the log file ensures that the associated file handles // live long enough and get closed when the tunnel is stopped + #[cfg(unix)] _tunnel_device: Tun, // context that maps to fs::File instance and stores the file path, used with logging callback _logging_context: LoggingContext, @@ -214,7 +217,7 @@ impl WgGoTunnelState { } impl WgGoTunnel { - #[cfg(not(target_os = "android"))] + #[cfg(all(not(target_os = "android"), unix))] pub fn start_tunnel( config: &Config, log_path: Option<&Path>, @@ -252,6 +255,69 @@ impl WgGoTunnel { })) } + #[cfg(target_os = "windows")] + pub fn start_tunnel( + config: &Config, + log_path: Option<&Path>, + mut setup_done_tx: futures::channel::mpsc::Sender<std::result::Result<(), BoxedError>>, + ) -> Result<Self> { + use futures::SinkExt; + use talpid_types::ErrorExt; + + let wg_config_str = config.to_userspace_format(); + let logging_context = initialize_logging(log_path) + .map(|ordinal| LoggingContext::new(ordinal, log_path.map(Path::to_owned))) + .map_err(TunnelError::LoggingError)?; + + // TODO: default route clalback + + let handle = wireguard_go_rs::Tunnel::turn_on( + c"Mullvad", + config.mtu, + &wg_config_str, + Some(logging::wg_go_logging_callback), + logging_context.ordinal, + ) + .map_err(|e| TunnelError::FatalStartWireguardError(Box::new(e)))?; + + let has_ipv6 = config.ipv6_gateway.is_some(); + + let luid = handle.luid().to_owned(); + + let setup_task = async move { + log::debug!("Waiting for tunnel IP interfaces to arrive"); + talpid_windows::net::wait_for_interfaces(luid, true, has_ipv6) + .await + .map_err(|e| BoxedError::new(TunnelError::SetupIpInterfaces(e)))?; + log::debug!("Waiting for tunnel IP interfaces: Done"); + + if let Err(error) = talpid_tunnel::network_interface::initialize_interfaces(luid, None) + { + log::error!( + "{}", + error.display_chain_with_msg("Failed to set tunnel interface metric"), + ); + } + + Ok(()) + }; + + tokio::spawn(async move { + let _ = setup_done_tx.send(setup_task.await).await; + }); + + let interface_name = handle.name(); + + Ok(WgGoTunnel(WgGoTunnelState { + interface_name: interface_name.to_owned(), + tunnel_handle: handle, + _logging_context: logging_context, + #[cfg(daita)] + config: config.clone(), + })) + } + + #[cfg(unix)] fn get_tunnel( tun_provider: Arc<Mutex<TunProvider>>, config: &Config, diff --git a/talpid-wireguard/src/wireguard_nt/mod.rs b/talpid-wireguard/src/wireguard_nt/mod.rs index 9243425cde..e5f0aa7c63 100644 --- a/talpid-wireguard/src/wireguard_nt/mod.rs +++ b/talpid-wireguard/src/wireguard_nt/mod.rs @@ -1104,7 +1104,7 @@ impl Tunnel for WgNtTunnel { } #[cfg(daita)] - fn start_daita(&mut self) -> std::result::Result<(), crate::TunnelError> { + fn start_daita(&mut self, _: talpid_tunnel_config_client::DaitaSettings) -> std::result::Result<(), crate::TunnelError> { self.spawn_machinist().map_err(|error| { log::error!( "{}", |
