summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-12-07 14:40:22 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-12-07 14:40:22 +0100
commit5fa6d87ef42bc3452d13e8149b11fd26386b6a83 (patch)
treecd50e7a85952cde802dbc018958305c3e506fb40
parentf646fcd1607129e3823acd2ff104f5c8dc001772 (diff)
parent1491c9d0462da46caa7250a50c5451bf50659d84 (diff)
downloadmullvadvpn-5fa6d87ef42bc3452d13e8149b11fd26386b6a83.tar.xz
mullvadvpn-5fa6d87ef42bc3452d13e8149b11fd26386b6a83.zip
Merge branch 'wg-nt-update'
-rw-r--r--CHANGELOG.md4
m---------dist-assets/binaries0
-rw-r--r--dist-assets/windows/installer.nsh5
-rw-r--r--gui/tasks/distribution.js2
-rw-r--r--talpid-core/src/tunnel/wireguard/wireguard_nt.rs182
-rw-r--r--talpid-core/src/windows.rs26
-rw-r--r--windows/driverlogic/src/driverlogic.cpp16
-rw-r--r--windows/driverlogic/src/wireguard.h6
8 files changed, 70 insertions, 171 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 305c0107f4..595d472ba3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,9 @@ Line wrap the file at 100 chars. Th
* Android Background Execution Limits.
* The System Settings way of killing apps ("Force Stop").
+#### Windows
+- Update wireguard-nt to 0.10.1.
+
### Fixed
- Always kill `sslocal` if the tunnel monitor fails to start when using bridges.
- Show relay location constraint correctly in the CLI when it is set to `any`.
@@ -46,6 +49,7 @@ Line wrap the file at 100 chars. Th
- Fix app size after changing display scale.
- Fix daemon not starting if all excluded app paths reside on non-existent/unmounted volumes.
- Remove tray icon of current running app version when upgrading.
+- Allow Mullvad wireguard-nt tunnels to work simultaneously with other wg-nt tunnels.
#### Android
- Fix Quick Settings tile showing wrong state in certain scenarios.
diff --git a/dist-assets/binaries b/dist-assets/binaries
-Subproject 19a97997b188855d0ba5aedb7419683df45d93b
+Subproject 0ce1cdd413319fbbf0756d339113d36391d535c
diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh
index 402802e1dc..1f8d8823cd 100644
--- a/dist-assets/windows/installer.nsh
+++ b/dist-assets/windows/installer.nsh
@@ -13,7 +13,6 @@
#
!define WINTUN_POOL "Mullvad"
-!define WG_NT_POOL "Mullvad"
# "sc" exit code
!define SERVICE_STARTED 0
@@ -68,7 +67,7 @@
SetOutPath "$TEMP"
File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\wintun\wintun.dll"
- File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\wireguard-nt\wireguard.dll"
+ File "${BUILD_RESOURCES_DIR}\binaries\x86_64-pc-windows-msvc\wireguard-nt\mullvad-wireguard.dll"
File "${BUILD_RESOURCES_DIR}\..\windows\driverlogic\bin\x64-Release\driverlogic.exe"
!macroend
@@ -234,7 +233,7 @@
log::Log "RemoveWireGuardNt()"
- nsExec::ExecToStack '"$TEMP\driverlogic.exe" wg-nt-cleanup ${WG_NT_POOL}'
+ nsExec::ExecToStack '"$TEMP\driverlogic.exe" wg-nt-cleanup'
Pop $0
Pop $1
diff --git a/gui/tasks/distribution.js b/gui/tasks/distribution.js
index 6f74d65eda..f677cc799b 100644
--- a/gui/tasks/distribution.js
+++ b/gui/tasks/distribution.js
@@ -114,7 +114,7 @@ const config = {
{ from: distAssets('binaries/x86_64-pc-windows-msvc/sslocal.exe'), to: '.' },
{ from: root('build/lib/x86_64-pc-windows-msvc/libwg.dll'), to: '.' },
{ from: distAssets('binaries/x86_64-pc-windows-msvc/wintun/wintun.dll'), to: '.' },
- { from: distAssets('binaries/x86_64-pc-windows-msvc/wireguard-nt/wireguard.dll'), to: '.' },
+ { from: distAssets('binaries/x86_64-pc-windows-msvc/wireguard-nt/mullvad-wireguard.dll'), to: '.' },
],
},
diff --git a/talpid-core/src/tunnel/wireguard/wireguard_nt.rs b/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
index 66b9c086fc..dde1a991fd 100644
--- a/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
+++ b/talpid-core/src/tunnel/wireguard/wireguard_nt.rs
@@ -40,7 +40,7 @@ use winapi::{
lazy_static! {
static ref WG_NT_DLL: Mutex<Option<Arc<WgNtDll>>> = Mutex::new(None);
- static ref ADAPTER_POOL: U16CString = U16CString::from_str("Mullvad").unwrap();
+ static ref ADAPTER_TYPE: U16CString = U16CString::from_str("Mullvad").unwrap();
static ref ADAPTER_ALIAS: U16CString = U16CString::from_str("Mullvad").unwrap();
}
@@ -51,24 +51,14 @@ const ADAPTER_GUID: GUID = GUID {
Data4: [0x8b, 0x05, 0x31, 0xda, 0x25, 0xa0, 0x44, 0xa9],
};
-/// Longest possible adapter name (in characters), including null terminator
-const MAX_ADAPTER_NAME: usize = 128;
-
-type WireGuardOpenAdapterFn =
- unsafe extern "stdcall" fn(pool: *const u16, name: *const u16) -> RawHandle;
type WireGuardCreateAdapterFn = unsafe extern "stdcall" fn(
- pool: *const u16,
name: *const u16,
+ tunnel_type: *const u16,
requested_guid: *const GUID,
- reboot_required: *mut BOOL,
) -> RawHandle;
-type WireGuardFreeAdapterFn = unsafe extern "stdcall" fn(adapter: RawHandle);
-type WireGuardDeleteAdapterFn =
- unsafe extern "stdcall" fn(adapter: RawHandle, reboot_required: *mut BOOL) -> BOOL;
+type WireGuardCloseAdapterFn = unsafe extern "stdcall" fn(adapter: RawHandle);
type WireGuardGetAdapterLuidFn =
unsafe extern "stdcall" fn(adapter: RawHandle, luid: *mut NET_LUID);
-type WireGuardGetAdapterNameFn =
- unsafe extern "stdcall" fn(adapter: RawHandle, name: *mut u16) -> BOOL;
type WireGuardSetConfigurationFn = unsafe extern "stdcall" fn(
adapter: RawHandle,
config: *const MaybeUninit<u8>,
@@ -116,29 +106,19 @@ enum WireGuardAdapterLogState {
type WireGuardSetAdapterLoggingFn =
unsafe extern "stdcall" fn(adapter: RawHandle, state: WireGuardAdapterLogState) -> BOOL;
-type RebootRequired = bool;
-
pub type Result<T> = std::result::Result<T, Error>;
#[derive(err_derive::Error, Debug)]
#[error(no_from)]
pub enum Error {
/// Failed to load WireGuardNT
- #[error(display = "Failed to load wireguard.dll")]
+ #[error(display = "Failed to load mullvad-wireguard.dll")]
DllError(#[error(source)] io::Error),
- /// Failed to remove tunnel interface
- #[error(display = "Failed to remove residual tunnel device")]
- DeleteExistingTunnelError(#[error(source)] io::Error),
-
/// Failed to create tunnel interface
#[error(display = "Failed to create WireGuard device")]
CreateTunnelDeviceError(#[error(source)] io::Error),
- /// Failed to delete tunnel interface
- #[error(display = "Failed to delete WireGuard device")]
- DeleteTunnelDeviceError(#[error(source)] io::Error),
-
/// Failed to obtain tunnel interface alias
#[error(display = "Failed to obtain interface name")]
ObtainAliasError(#[error(source)] io::Error),
@@ -432,40 +412,20 @@ impl WgNtTunnel {
resource_dir: &Path,
) -> Result<Self> {
let dll = load_wg_nt_dll(resource_dir)?;
-
let logger_handle = LoggerHandle::new(dll.clone(), log_path)?;
-
- {
- if let Ok(device) = WgNtAdapter::open(dll.clone(), &*ADAPTER_POOL, &*ADAPTER_ALIAS) {
- device.delete().map_err(Error::DeleteExistingTunnelError)?;
- }
- }
-
- let (device, reboot_required) = WgNtAdapter::create(
+ let device = WgNtAdapter::create(
dll.clone(),
- &*ADAPTER_POOL,
&*ADAPTER_ALIAS,
+ &*ADAPTER_TYPE,
Some(ADAPTER_GUID.clone()),
)
.map_err(Error::CreateTunnelDeviceError)?;
- if reboot_required {
- log::warn!("You may need to reboot to finish installing WireGuardNT");
- }
-
let interface_luid = device.luid();
- let interface_name = match device.name() {
- Ok(name) => name.to_string_lossy(),
- Err(error) => {
- if let Err(error) = device.delete() {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to delete tunnel device")
- );
- }
- return Err(Error::ObtainAliasError(error));
- }
- };
+ let interface_name = device
+ .name()
+ .map_err(Error::ObtainAliasError)?
+ .to_string_lossy();
let tunnel = WgNtTunnel {
device: Some(device),
@@ -477,13 +437,8 @@ impl WgNtTunnel {
Ok(tunnel)
}
- fn stop_tunnel(&mut self) -> Result<()> {
- if let Some(device) = self.device.take() {
- if let Err(error) = device.delete() {
- return Err(Error::DeleteTunnelDeviceError(error));
- }
- }
- Ok(())
+ fn stop_tunnel(&mut self) {
+ let _ = self.device.take();
}
fn configure(&self, config: &Config) -> Result<()> {
@@ -510,12 +465,7 @@ impl WgNtTunnel {
impl Drop for WgNtTunnel {
fn drop(&mut self) {
- if let Err(error) = self.stop_tunnel() {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to stop WireGuardNT tunnel")
- );
- }
+ self.stop_tunnel();
}
}
@@ -580,27 +530,21 @@ unsafe impl Send for WgNtAdapter {}
unsafe impl Sync for WgNtAdapter {}
impl WgNtAdapter {
- fn open(dll_handle: Arc<WgNtDll>, pool: &U16CStr, name: &U16CStr) -> io::Result<Self> {
- let handle = dll_handle.open_adapter(pool, name)?;
- Ok(Self { dll_handle, handle })
- }
-
fn create(
dll_handle: Arc<WgNtDll>,
- pool: &U16CStr,
name: &U16CStr,
+ tunnel_type: &U16CStr,
requested_guid: Option<GUID>,
- ) -> io::Result<(Self, RebootRequired)> {
- let (handle, restart_required) = dll_handle.create_adapter(pool, name, requested_guid)?;
- Ok((Self { dll_handle, handle }, restart_required))
- }
-
- fn delete(self) -> io::Result<RebootRequired> {
- unsafe { self.dll_handle.delete_adapter(self.handle) }
+ ) -> io::Result<Self> {
+ let handle = dll_handle.create_adapter(name, tunnel_type, requested_guid)?;
+ Ok(Self { dll_handle, handle })
}
fn name(&self) -> io::Result<U16CString> {
- unsafe { self.dll_handle.get_adapter_name(self.handle) }
+ windows::alias_from_luid(&self.luid()).and_then(|alias| {
+ U16CString::from_os_str(alias)
+ .map_err(|_| io::Error::new(io::ErrorKind::Other, "unexpected null char"))
+ })
}
fn luid(&self) -> NET_LUID {
@@ -638,18 +582,15 @@ impl WgNtAdapter {
impl Drop for WgNtAdapter {
fn drop(&mut self) {
- unsafe { self.dll_handle.free_adapter(self.handle) };
+ unsafe { self.dll_handle.close_adapter(self.handle) };
}
}
struct WgNtDll {
handle: HINSTANCE,
- func_open: WireGuardOpenAdapterFn,
func_create: WireGuardCreateAdapterFn,
- func_delete: WireGuardDeleteAdapterFn,
- func_free: WireGuardFreeAdapterFn,
+ func_close: WireGuardCloseAdapterFn,
func_get_adapter_luid: WireGuardGetAdapterLuidFn,
- func_get_adapter_name: WireGuardGetAdapterNameFn,
func_set_configuration: WireGuardSetConfigurationFn,
func_get_configuration: WireGuardGetConfigurationFn,
func_set_adapter_state: WireGuardSetStateFn,
@@ -662,7 +603,8 @@ unsafe impl Sync for WgNtDll {}
impl WgNtDll {
pub fn new(resource_dir: &Path) -> io::Result<Self> {
- let wg_nt_dll = U16CString::from_os_str_truncate(resource_dir.join("wireguard.dll"));
+ let wg_nt_dll =
+ U16CString::from_os_str_truncate(resource_dir.join("mullvad-wireguard.dll"));
let handle = unsafe {
LoadLibraryExW(
@@ -683,28 +625,16 @@ impl WgNtDll {
) -> io::Result<Self> {
Ok(WgNtDll {
handle,
- func_open: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WireGuardOpenAdapter\0").unwrap(),
- )?) as *const _ as *const _)
- },
func_create: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WireGuardCreateAdapter\0").unwrap(),
)?) as *const _ as *const _)
},
- func_delete: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WireGuardDeleteAdapter\0").unwrap(),
- )?) as *const _ as *const _)
- },
- func_free: unsafe {
+ func_close: unsafe {
*((&get_proc_fn(
handle,
- CStr::from_bytes_with_nul(b"WireGuardFreeAdapter\0").unwrap(),
+ CStr::from_bytes_with_nul(b"WireGuardCloseAdapter\0").unwrap(),
)?) as *const _ as *const _)
},
func_get_adapter_luid: unsafe {
@@ -713,12 +643,6 @@ impl WgNtDll {
CStr::from_bytes_with_nul(b"WireGuardGetAdapterLUID\0").unwrap(),
)?) as *const _ as *const _)
},
- func_get_adapter_name: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WireGuardGetAdapterName\0").unwrap(),
- )?) as *const _ as *const _)
- },
func_set_configuration: unsafe {
*((&get_proc_fn(
handle,
@@ -760,54 +684,25 @@ impl WgNtDll {
Ok(handle)
}
- pub fn open_adapter(&self, pool: &U16CStr, name: &U16CStr) -> io::Result<RawHandle> {
- let handle = unsafe { (self.func_open)(pool.as_ptr(), name.as_ptr()) };
- if handle == ptr::null_mut() {
- return Err(io::Error::last_os_error());
- }
- Ok(handle)
- }
-
pub fn create_adapter(
&self,
- pool: &U16CStr,
name: &U16CStr,
+ tunnel_type: &U16CStr,
requested_guid: Option<GUID>,
- ) -> io::Result<(RawHandle, RebootRequired)> {
+ ) -> io::Result<RawHandle> {
let guid_ptr = match requested_guid.as_ref() {
Some(guid) => guid as *const _,
None => ptr::null_mut(),
};
- let mut reboot_required = 0;
- let handle = unsafe {
- (self.func_create)(pool.as_ptr(), name.as_ptr(), guid_ptr, &mut reboot_required)
- };
+ let handle = unsafe { (self.func_create)(name.as_ptr(), tunnel_type.as_ptr(), guid_ptr) };
if handle == ptr::null_mut() {
return Err(io::Error::last_os_error());
}
- Ok((handle, reboot_required != 0))
- }
-
- pub unsafe fn delete_adapter(&self, adapter: RawHandle) -> io::Result<RebootRequired> {
- let mut reboot_required = 0;
- let result = (self.func_delete)(adapter, &mut reboot_required);
- if result == 0 {
- return Err(io::Error::last_os_error());
- }
- Ok(reboot_required != 0)
+ Ok(handle)
}
- pub unsafe fn free_adapter(&self, adapter: RawHandle) {
- (self.func_free)(adapter);
- }
-
- pub unsafe fn get_adapter_name(&self, adapter: RawHandle) -> io::Result<U16CString> {
- let mut alias_buffer = vec![0u16; MAX_ADAPTER_NAME];
- let result = (self.func_get_adapter_name)(adapter, alias_buffer.as_mut_ptr());
- if result == 0 {
- return Err(io::Error::last_os_error());
- }
- Ok(U16CString::from_vec_truncate(alias_buffer))
+ pub unsafe fn close_adapter(&self, adapter: RawHandle) {
+ (self.func_close)(adapter);
}
pub unsafe fn get_adapter_luid(&self, adapter: RawHandle) -> NET_LUID {
@@ -1051,15 +946,8 @@ impl Tunnel for WgNtTunnel {
}
fn stop(mut self: Box<Self>) -> std::result::Result<(), super::TunnelError> {
- if let Err(error) = self.stop_tunnel() {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to stop WireGuardNT tunnel")
- );
- Err(super::TunnelError::StopWireguardError { status: 0 })
- } else {
- Ok(())
- }
+ self.stop_tunnel();
+ Ok(())
}
}
diff --git a/talpid-core/src/windows.rs b/talpid-core/src/windows.rs
index 7648441a91..1febc5bc21 100644
--- a/talpid-core/src/windows.rs
+++ b/talpid-core/src/windows.rs
@@ -1,9 +1,12 @@
use socket2::SockAddr;
use std::{
- ffi::OsStr,
+ ffi::{OsStr, OsString},
fmt, io, mem,
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
- os::windows::{ffi::OsStrExt, io::RawHandle},
+ os::windows::{
+ ffi::{OsStrExt, OsStringExt},
+ io::RawHandle,
+ },
sync::Mutex,
time::{Duration, Instant},
};
@@ -12,12 +15,13 @@ use winapi::shared::{
in6addr::IN6_ADDR,
inaddr::IN_ADDR,
netioapi::{
- CancelMibChangeNotify2, ConvertInterfaceAliasToLuid, FreeMibTable, GetIpInterfaceEntry,
- GetUnicastIpAddressEntry, GetUnicastIpAddressTable, MibAddInstance,
- NotifyIpInterfaceChange, SetIpInterfaceEntry, MIB_IPINTERFACE_ROW,
+ CancelMibChangeNotify2, ConvertInterfaceAliasToLuid, ConvertInterfaceLuidToAlias,
+ FreeMibTable, GetIpInterfaceEntry, GetUnicastIpAddressEntry, GetUnicastIpAddressTable,
+ MibAddInstance, NotifyIpInterfaceChange, SetIpInterfaceEntry, MIB_IPINTERFACE_ROW,
MIB_UNICASTIPADDRESS_ROW, MIB_UNICASTIPADDRESS_TABLE,
},
nldef::{IpDadStatePreferred, IpDadStateTentative, NL_DAD_STATE},
+ ntddndis::NDIS_IF_MAX_STRING_SIZE,
ntdef::FALSE,
winerror::{ERROR_NOT_FOUND, NO_ERROR},
ws2def::{
@@ -359,6 +363,18 @@ pub fn luid_from_alias<T: AsRef<OsStr>>(alias: T) -> io::Result<NET_LUID> {
Ok(luid)
}
+/// Returns the alias of an interface given its LUID.
+pub fn alias_from_luid(luid: &NET_LUID) -> io::Result<OsString> {
+ let mut buffer = [0u16; NDIS_IF_MAX_STRING_SIZE + 1];
+ let status =
+ unsafe { ConvertInterfaceLuidToAlias(luid, &mut buffer[0] as *mut _, buffer.len()) };
+ if status != NO_ERROR {
+ return Err(io::Error::from_raw_os_error(status as i32));
+ }
+ let nul = buffer.iter().position(|&c| c == 0u16).unwrap();
+ Ok(OsString::from_wide(&buffer[0..nul]))
+}
+
fn af_family_from_family(family: Option<AddressFamily>) -> u16 {
family
.map(|family| family as u16)
diff --git a/windows/driverlogic/src/driverlogic.cpp b/windows/driverlogic/src/driverlogic.cpp
index 3cb1739e21..aba746d3e3 100644
--- a/windows/driverlogic/src/driverlogic.cpp
+++ b/windows/driverlogic/src/driverlogic.cpp
@@ -283,24 +283,16 @@ ReturnCode CommandWireGuardNtCleanup(const std::vector<std::wstring> &args)
{
ArgumentContext argsContext(args);
- argsContext.ensureExactArgumentCount(1);
-
- const auto poolName = argsContext.next();
+ argsContext.ensureExactArgumentCount(0);
WireGuardNtDll wgNt;
- BOOL rebootRequired;
-
- if (FALSE == wgNt.deletePoolDriver(poolName.c_str(), &rebootRequired))
+ if (FALSE == wgNt.deleteDriver())
{
- throw std::runtime_error("Failed to delete WireGuardNT pool");
+ throw std::runtime_error("Failed to delete WireGuardNT driver");
}
- std::wstringstream ss;
-
- ss << L"Successfully deleted WireGuardNT pool. Reboot required: " << rebootRequired;
-
- Log(ss.str());
+ Log(L"Successfully deleted WireGuardNT driver");
return ReturnCode::GENERAL_SUCCESS;
}
diff --git a/windows/driverlogic/src/wireguard.h b/windows/driverlogic/src/wireguard.h
index 5892b248f1..e99da56c05 100644
--- a/windows/driverlogic/src/wireguard.h
+++ b/windows/driverlogic/src/wireguard.h
@@ -10,7 +10,7 @@ public:
WireGuardNtDll() : dllHandle(nullptr)
{
- auto path = GetProcessModulePath().replace_filename(L"wireguard.dll");
+ auto path = GetProcessModulePath().replace_filename(L"mullvad-wireguard.dll");
dllHandle = LoadLibraryExW(path.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
if (nullptr == dllHandle)
@@ -20,7 +20,7 @@ public:
try
{
- deletePoolDriver = getProcAddressOrThrow<WIREGUARD_DELETE_POOL_DRIVER_FUNC*>("WireGuardDeletePoolDriver");
+ deleteDriver = getProcAddressOrThrow<WIREGUARD_DELETE_DRIVER_FUNC*>("WireGuardDeleteDriver");
}
catch (...)
{
@@ -37,7 +37,7 @@ public:
}
}
- WIREGUARD_DELETE_POOL_DRIVER_FUNC *deletePoolDriver;
+ WIREGUARD_DELETE_DRIVER_FUNC *deleteDriver;
private: