summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--talpid-tunnel-config-client/src/lib.rs36
-rw-r--r--talpid-wireguard/Cargo.toml2
-rw-r--r--talpid-wireguard/build.rs7
-rw-r--r--talpid-wireguard/src/ephemeral.rs9
-rw-r--r--talpid-wireguard/src/lib.rs28
-rw-r--r--talpid-wireguard/src/wireguard_go/mod.rs68
-rw-r--r--talpid-wireguard/src/wireguard_nt/mod.rs2
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!(
"{}",