summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-04-23 18:37:06 +0200
committerDavid Lönnhager <david.l@mullvad.net>2020-04-24 16:51:47 +0200
commit2eaa3845ef8e64208f30784575356f4137412133 (patch)
treefa491fe7e5cc57e89694df884a4695f65dc69d8b /talpid-core/src
parent2dfa1d08eb6a3c9d422bfbd84854073fa932182c (diff)
downloadmullvadvpn-2eaa3845ef8e64208f30784575356f4137412133.tar.xz
mullvadvpn-2eaa3845ef8e64208f30784575356f4137412133.zip
Enable IPv6 for WireGuard interface
Diffstat (limited to 'talpid-core/src')
-rw-r--r--talpid-core/src/tunnel/mod.rs22
-rw-r--r--talpid-core/src/winnet.rs44
2 files changed, 57 insertions, 9 deletions
diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs
index 0f8a902406..afee640829 100644
--- a/talpid-core/src/tunnel/mod.rs
+++ b/talpid-core/src/tunnel/mod.rs
@@ -3,7 +3,6 @@ use crate::logging;
#[cfg(not(target_os = "android"))]
use std::collections::HashMap;
use std::{
- ffi::OsString,
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
path::{Path, PathBuf},
@@ -348,14 +347,27 @@ fn try_enabling_ipv6(tunnel_parameters: &TunnelParameters) -> Result<()> {
return Err(Error::EnableIpv6Error);
}
- let alias = match tunnel_parameters {
+ let guid_string: String;
+
+ let guid = match tunnel_parameters {
TunnelParameters::OpenVpn(..) => {
- crate::winnet::get_tap_interface_alias().map_err(Error::WinnetError)?
+ // TODO: This status check can be removed if it is certain
+ // that `enable_ipv6_for_adapter` is reliable.
+ let status =
+ crate::winnet::get_tap_interface_ipv6_status().map_err(Error::WinnetError)?;
+ if status {
+ return Ok(());
+ }
+
+ let alias = crate::winnet::get_tap_interface_alias().map_err(Error::WinnetError)?;
+ guid_string =
+ crate::winnet::interface_alias_to_guid(&alias).map_err(Error::WinnetError)?;
+ &guid_string
}
- TunnelParameters::Wireguard(..) => OsString::from("wg-mullvad"),
+ TunnelParameters::Wireguard(..) => "{AFE43773-E1F8-4EBB-8536-576AB86AFE9A}",
};
- crate::winnet::enable_ipv6_for_adapter(&alias).map_err(Error::WinnetError)
+ crate::winnet::enable_ipv6_for_adapter(&guid).map_err(Error::WinnetError)
}
#[cfg(target_os = "windows")]
diff --git a/talpid-core/src/winnet.rs b/talpid-core/src/winnet.rs
index 3e7a52bf75..534dab5228 100644
--- a/talpid-core/src/winnet.rs
+++ b/talpid-core/src/winnet.rs
@@ -25,6 +25,10 @@ pub enum Error {
#[error(display = "Failed to enable IPv6 on the network interface")]
EnableIpv6,
+ /// Failed to enable IPv6 on the network interface.
+ #[error(display = "Failed to obtain GUID for the network interface")]
+ GetInterfaceGuid,
+
/// Failed to read IPv6 status on the TAP network interface.
#[error(display = "Failed to read IPv6 status on the TAP network interface")]
GetIpv6Status,
@@ -71,13 +75,13 @@ pub fn ensure_best_metric_for_interface(interface_alias: &str) -> Result<bool, E
}
/// Enables IPv6 for a given interface.
-pub fn enable_ipv6_for_adapter(interface_alias: &OsStr) -> Result<(), Error> {
- let interface_alias_ws =
- WideCString::from_os_str(interface_alias).map_err(Error::InvalidInterfaceAlias)?;
+pub fn enable_ipv6_for_adapter(interface_guid: &str) -> Result<(), Error> {
+ let interface_guid_ws =
+ WideCString::from_str(interface_guid).map_err(Error::InvalidInterfaceAlias)?;
let result = unsafe {
WinNet_EnableIpv6ForAdapter(
- interface_alias_ws.as_ptr(),
+ interface_guid_ws.as_ptr(),
Some(log_sink),
logging_context(),
)
@@ -133,6 +137,30 @@ pub fn get_tap_interface_alias() -> Result<OsString, Error> {
Ok(alias.to_os_string())
}
+/// Determines the interface guid for a given adapter alias.
+pub fn interface_alias_to_guid(interface_alias: &OsStr) -> Result<String, Error> {
+ let interface_alias =
+ WideCString::from_os_str(interface_alias).map_err(Error::InvalidInterfaceAlias)?;
+ let mut guid_ptr: *mut wchar_t = ptr::null_mut();
+ let status = unsafe {
+ WinNet_InterfaceAliasToGuid(
+ interface_alias.as_ptr(),
+ &mut guid_ptr as *mut _,
+ Some(log_sink),
+ logging_context(),
+ )
+ };
+
+ if !status {
+ return Err(Error::GetInterfaceGuid);
+ }
+
+ let guid = unsafe { WideCString::from_ptr_str(guid_ptr) };
+ unsafe { WinNet_ReleaseString(guid_ptr) };
+
+ Ok(guid.to_string_lossy())
+}
+
#[allow(dead_code)]
#[repr(u32)]
pub enum WinNetAddrFamily {
@@ -428,6 +456,14 @@ mod api {
sink_context: *const u8,
) -> bool;
+ #[link_name = "WinNet_InterfaceAliasToGuid"]
+ pub fn WinNet_InterfaceAliasToGuid(
+ interface_alias: *const wchar_t,
+ interface_guid: *mut *mut wchar_t,
+ sink: Option<LogSink>,
+ sink_context: *const u8,
+ ) -> bool;
+
#[link_name = "WinNet_ReleaseString"]
pub fn WinNet_ReleaseString(string: *mut wchar_t);