summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--mullvad-cli/src/cmds/tunnel.rs55
-rw-r--r--mullvad-daemon/src/lib.rs34
-rw-r--r--mullvad-daemon/src/management_interface.rs16
-rw-r--r--mullvad-daemon/src/settings.rs14
-rw-r--r--mullvad-management-interface/proto/management_interface.proto3
-rw-r--r--mullvad-management-interface/src/types.rs6
-rw-r--r--talpid-core/src/tunnel/wireguard/config.rs5
-rw-r--r--talpid-core/src/tunnel/wireguard/mod.rs22
-rw-r--r--talpid-core/src/tunnel/wireguard/wireguard_nt.rs1
-rw-r--r--talpid-types/src/net/wireguard.rs4
11 files changed, 149 insertions, 13 deletions
diff --git a/README.md b/README.md
index c562d4cd4a..bf91197235 100644
--- a/README.md
+++ b/README.md
@@ -436,7 +436,7 @@ echo "org.gradle.jvmargs=-Xmx4608M" >> ~/.gradle/gradle.properties
* `"network-manager"`: use `NetworkManager` service through DBus
* `TALPID_FORCE_USERSPACE_WIREGUARD` - Forces the daemon to use the userspace implementation of
- WireGuard on Linux.
+ WireGuard on Linux and Windows.
* `TALPID_DNS_CACHE_POLICY` - On Windows, this changes how DNS is configured:
* `1`: The default. This sets a global list of DNS servers that `dnscache` will use instead of
diff --git a/mullvad-cli/src/cmds/tunnel.rs b/mullvad-cli/src/cmds/tunnel.rs
index 08306b70eb..e01d81a9da 100644
--- a/mullvad-cli/src/cmds/tunnel.rs
+++ b/mullvad-cli/src/cmds/tunnel.rs
@@ -34,11 +34,19 @@ impl Command for Tunnel {
}
fn create_wireguard_subcommand() -> clap::App<'static, 'static> {
- clap::SubCommand::with_name("wireguard")
+ let subcmd = clap::SubCommand::with_name("wireguard")
.about("Manage options for Wireguard tunnels")
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
.subcommand(create_wireguard_mtu_subcommand())
- .subcommand(create_wireguard_keys_subcommand())
+ .subcommand(create_wireguard_keys_subcommand());
+ #[cfg(windows)]
+ {
+ subcmd.subcommand(create_wireguard_use_wg_nt_subcommand())
+ }
+ #[cfg(not(windows))]
+ {
+ subcmd
+ }
}
fn create_wireguard_mtu_subcommand() -> clap::App<'static, 'static> {
@@ -61,6 +69,22 @@ fn create_wireguard_keys_subcommand() -> clap::App<'static, 'static> {
.subcommand(create_wireguard_keys_rotation_interval_subcommand())
}
+#[cfg(windows)]
+fn create_wireguard_use_wg_nt_subcommand() -> clap::App<'static, 'static> {
+ clap::SubCommand::with_name("use-wireguard-nt")
+ .about("Enable or disable wireguard-nt")
+ .setting(clap::AppSettings::SubcommandRequiredElseHelp)
+ .subcommand(clap::SubCommand::with_name("get"))
+ .subcommand(
+ clap::SubCommand::with_name("set").arg(
+ clap::Arg::with_name("policy")
+ .required(true)
+ .takes_value(true)
+ .possible_values(&["on", "off"]),
+ ),
+ )
+}
+
fn create_wireguard_keys_rotation_interval_subcommand() -> clap::App<'static, 'static> {
clap::SubCommand::with_name("rotation-interval")
.about("Manage automatic key rotation (given in hours)")
@@ -147,6 +171,13 @@ impl Tunnel {
_ => unreachable!("unhandled command"),
},
+ #[cfg(windows)]
+ ("use-wireguard-nt", Some(matches)) => match matches.subcommand() {
+ ("get", _) => Self::process_wireguard_use_wg_nt_get().await,
+ ("set", Some(matches)) => Self::process_wireguard_use_wg_nt_set(matches).await,
+ _ => unreachable!("unhandled command"),
+ },
+
_ => unreachable!("unhandled command"),
}
}
@@ -180,6 +211,26 @@ impl Tunnel {
Ok(())
}
+ #[cfg(windows)]
+ async fn process_wireguard_use_wg_nt_get() -> Result<()> {
+ let tunnel_options = Self::get_tunnel_options().await?;
+ if tunnel_options.wireguard.unwrap().use_wireguard_nt {
+ println!("enabled");
+ } else {
+ println!("disabled");
+ }
+ Ok(())
+ }
+
+ #[cfg(windows)]
+ async fn process_wireguard_use_wg_nt_set(matches: &clap::ArgMatches<'_>) -> Result<()> {
+ let new_state = matches.value_of("policy").unwrap() == "on";
+ let mut rpc = new_rpc_client().await?;
+ rpc.set_use_wireguard_nt(new_state).await?;
+ println!("Updated wireguard-nt setting");
+ Ok(())
+ }
+
async fn process_wireguard_key_check() -> Result<()> {
let mut rpc = new_rpc_client().await?;
let key = rpc.get_wireguard_key(()).await;
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 19692d57fa..bde37e85fb 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -281,6 +281,9 @@ pub enum DaemonCommand {
/// Disable split tunnel
#[cfg(windows)]
SetSplitTunnelState(ResponseTx<(), Error>, bool),
+ /// Toggle wireguard-nt on or off
+ #[cfg(target_os = "windows")]
+ UseWireGuardNt(ResponseTx<(), Error>, bool),
/// Makes the daemon exit the main loop and quit.
Shutdown,
/// Saves the target tunnel state and enters a blocking state. The state is restored
@@ -1230,6 +1233,8 @@ where
ClearSplitTunnelApps(tx) => self.on_clear_split_tunnel_apps(tx).await,
#[cfg(windows)]
SetSplitTunnelState(tx, enabled) => self.on_set_split_tunnel_state(tx, enabled).await,
+ #[cfg(target_os = "windows")]
+ UseWireGuardNt(tx, state) => self.on_use_wireguard_nt(tx, state).await,
Shutdown => self.trigger_shutdown_event(),
PrepareRestart => self.on_prepare_restart(),
#[cfg(target_os = "android")]
@@ -1937,6 +1942,35 @@ where
}
}
+ #[cfg(windows)]
+ async fn on_use_wireguard_nt(&mut self, tx: ResponseTx<(), Error>, state: bool) {
+ let save_result = self
+ .settings
+ .set_use_wireguard_nt(state)
+ .await
+ .map_err(Error::SettingsError);
+ match save_result {
+ Ok(settings_changed) => {
+ Self::oneshot_send(tx, Ok(()), "use_wireguard_nt response");
+ if settings_changed {
+ self.event_listener
+ .notify_settings(self.settings.to_settings());
+ if let Some(TunnelType::Wireguard) = self.get_connected_tunnel_type() {
+ info!("Initiating tunnel restart");
+ self.reconnect_tunnel();
+ }
+ }
+ }
+ Err(error) => {
+ error!(
+ "{}",
+ error.display_chain_with_msg("Unable to save settings")
+ );
+ Self::oneshot_send(tx, Err(error), "use_wireguard_nt response");
+ }
+ }
+ }
+
async fn on_update_relay_settings(
&mut self,
tx: ResponseTx<(), settings::Error>,
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 0b2f6b463f..cef8d42f78 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -688,6 +688,22 @@ impl ManagementService for ManagementServiceImpl {
async fn set_split_tunnel_state(&self, _: Request<bool>) -> ServiceResult<()> {
Ok(Response::new(()))
}
+
+ #[cfg(windows)]
+ async fn set_use_wireguard_nt(&self, request: Request<bool>) -> ServiceResult<()> {
+ log::debug!("set_use_wireguard_nt");
+ let state = request.into_inner();
+ let (tx, rx) = oneshot::channel();
+ self.send_command_to_daemon(DaemonCommand::UseWireGuardNt(tx, state))?;
+ self.wait_for_result(rx)
+ .await?
+ .map_err(map_daemon_error)
+ .map(Response::new)
+ }
+ #[cfg(not(windows))]
+ async fn set_use_wireguard_nt(&self, _: Request<bool>) -> ServiceResult<()> {
+ Ok(Response::new(()))
+ }
}
impl ManagementServiceImpl {
diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs
index 02568e3226..e3cfeb8ddc 100644
--- a/mullvad-daemon/src/settings.rs
+++ b/mullvad-daemon/src/settings.rs
@@ -330,6 +330,20 @@ impl SettingsPersister {
self.update(should_save).await
}
+ #[cfg(windows)]
+ pub async fn set_use_wireguard_nt(&mut self, state: bool) -> Result<bool, Error> {
+ let should_save = Self::update_field(
+ &mut self
+ .settings
+ .tunnel_options
+ .wireguard
+ .options
+ .use_wireguard_nt,
+ state,
+ );
+ self.update(should_save).await
+ }
+
fn update_field<T: Eq>(field: &mut T, new_value: T) -> bool {
if *field != new_value {
*field = new_value;
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index 8711ba7b1b..a6d88bb0e0 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -69,6 +69,8 @@ service ManagementService {
rpc RemoveSplitTunnelApp(google.protobuf.StringValue) returns (google.protobuf.Empty) {}
rpc ClearSplitTunnelApps(google.protobuf.Empty) returns (google.protobuf.Empty) {}
rpc SetSplitTunnelState(google.protobuf.BoolValue) returns (google.protobuf.Empty) {}
+
+ rpc SetUseWireguardNt(google.protobuf.BoolValue) returns (google.protobuf.Empty) {}
}
message RelaySettingsUpdate {
@@ -379,6 +381,7 @@ message TunnelOptions {
message WireguardOptions {
uint32 mtu = 1;
google.protobuf.Duration rotation_interval = 2;
+ bool use_wireguard_nt = 3;
}
message GenericOptions {
bool enable_ipv6 = 1;
diff --git a/mullvad-management-interface/src/types.rs b/mullvad-management-interface/src/types.rs
index 81fdbb0e87..4e3a7217eb 100644
--- a/mullvad-management-interface/src/types.rs
+++ b/mullvad-management-interface/src/types.rs
@@ -562,6 +562,10 @@ impl From<&mullvad_types::settings::TunnelOptions> for TunnelOptions {
.wireguard
.rotation_interval
.map(|ivl| Duration::from(std::time::Duration::from(ivl))),
+ #[cfg(windows)]
+ use_wireguard_nt: options.wireguard.options.use_wireguard_nt,
+ #[cfg(not(windows))]
+ use_wireguard_nt: false,
}),
generic: Some(tunnel_options::GenericOptions {
enable_ipv6: options.generic.enable_ipv6,
@@ -1199,6 +1203,8 @@ impl TryFrom<TunnelOptions> for mullvad_types::settings::TunnelOptions {
} else {
None
},
+ #[cfg(windows)]
+ use_wireguard_nt: wireguard_options.use_wireguard_nt,
},
rotation_interval: wireguard_options
.rotation_interval
diff --git a/talpid-core/src/tunnel/wireguard/config.rs b/talpid-core/src/tunnel/wireguard/config.rs
index ae82483c66..252bf8418f 100644
--- a/talpid-core/src/tunnel/wireguard/config.rs
+++ b/talpid-core/src/tunnel/wireguard/config.rs
@@ -23,6 +23,9 @@ pub struct Config {
/// Enable IPv6 routing rules
#[cfg(target_os = "linux")]
pub enable_ipv6: bool,
+ /// Temporary switch for wireguard-nt
+ #[cfg(target_os = "windows")]
+ pub use_wireguard_nt: bool,
}
const DEFAULT_MTU: u16 = 1380;
@@ -109,6 +112,8 @@ impl Config {
fwmark: crate::linux::TUNNEL_FW_MARK,
#[cfg(target_os = "linux")]
enable_ipv6: generic_options.enable_ipv6,
+ #[cfg(target_os = "windows")]
+ use_wireguard_nt: wg_options.use_wireguard_nt,
})
}
diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs
index 8ecec51f4d..a3fa426ca2 100644
--- a/talpid-core/src/tunnel/wireguard/mod.rs
+++ b/talpid-core/src/tunnel/wireguard/mod.rs
@@ -355,16 +355,18 @@ impl WireguardMonitor {
}
#[cfg(target_os = "windows")]
- match wireguard_nt::WgNtTunnel::start_tunnel(config, log_path, resource_dir) {
- Ok(tunnel) => {
- log::debug!("Using WireGuardNT");
- return Ok(Box::new(tunnel));
- }
- Err(error) => {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to setup WireGuardNT tunnel")
- );
+ if config.use_wireguard_nt {
+ match wireguard_nt::WgNtTunnel::start_tunnel(config, log_path, resource_dir) {
+ Ok(tunnel) => {
+ log::debug!("Using WireGuardNT");
+ return Ok(Box::new(tunnel));
+ }
+ Err(error) => {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Failed to setup WireGuardNT tunnel")
+ );
+ }
}
}
diff --git a/talpid-core/src/tunnel/wireguard/wireguard_nt.rs b/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
index 97207eb933..2314ee283f 100644
--- a/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
+++ b/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
@@ -1058,6 +1058,7 @@ mod tests {
ipv4_gateway: "0.0.0.0".parse().unwrap(),
ipv6_gateway: None,
mtu: 0,
+ use_wireguard_nt: true,
}
};
static ref WG_STRUCT_CONFIG: Interface = Interface {
diff --git a/talpid-types/src/net/wireguard.rs b/talpid-types/src/net/wireguard.rs
index c5bde3547e..beced8357d 100644
--- a/talpid-types/src/net/wireguard.rs
+++ b/talpid-types/src/net/wireguard.rs
@@ -86,6 +86,10 @@ pub struct TunnelOptions {
jnix(map = "|maybe_mtu| maybe_mtu.map(|mtu| mtu as i32)")
)]
pub mtu: Option<u16>,
+ /// Temporary switch for wireguard-nt
+ #[cfg(windows)]
+ #[serde(default)]
+ pub use_wireguard_nt: bool,
}
/// Wireguard x25519 private key