summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-08-11 13:36:04 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-08-15 11:32:37 +0200
commitdca9e98c0e83bf6b800b8223d07430a538f273be (patch)
treec9173f76dab0ca952e260997c33945f5291abb83
parent41a962e7d0cd4cde45a193dbc93e6bd65bbd20e3 (diff)
downloadmullvadvpn-dca9e98c0e83bf6b800b8223d07430a538f273be.tar.xz
mullvadvpn-dca9e98c0e83bf6b800b8223d07430a538f273be.zip
Update wintun module for Wintun 0.14
-rw-r--r--talpid-core/src/tunnel/openvpn/mod.rs28
-rw-r--r--talpid-core/src/tunnel/openvpn/wintun.rs192
2 files changed, 37 insertions, 183 deletions
diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs
index 9c09c935f8..15d9013610 100644
--- a/talpid-core/src/tunnel/openvpn/mod.rs
+++ b/talpid-core/src/tunnel/openvpn/mod.rs
@@ -43,7 +43,7 @@ mod wintun;
#[cfg(windows)]
lazy_static! {
static ref ADAPTER_ALIAS: U16CString = U16CString::from_str("Mullvad").unwrap();
- static ref ADAPTER_POOL: U16CString = U16CString::from_str("Mullvad").unwrap();
+ static ref ADAPTER_TUNNEL_TYPE: U16CString = U16CString::from_str("Mullvad").unwrap();
}
#[cfg(windows)]
@@ -87,11 +87,6 @@ pub enum Error {
#[error(display = "Failed to create Wintun adapter")]
WintunCreateAdapterError(#[error(source)] io::Error),
- /// cannot determine adapter name
- #[cfg(windows)]
- #[error(display = "Failed to determine alias of Wintun adapter")]
- WintunFindAlias(#[error(source)] io::Error),
-
/// OpenVPN process died unexpectedly
#[error(display = "OpenVPN process died unexpectedly")]
ChildProcessDied,
@@ -215,7 +210,7 @@ impl std::fmt::Debug for dyn WintunContext {
#[cfg(windows)]
#[derive(Debug)]
struct WintunContextImpl {
- adapter: wintun::TemporaryWintunAdapter,
+ adapter: wintun::WintunAdapter,
wait_v6_interface: bool,
_logger: wintun::WintunLoggerHandle,
}
@@ -224,7 +219,7 @@ struct WintunContextImpl {
#[async_trait::async_trait]
impl WintunContext for WintunContextImpl {
fn luid(&self) -> NET_LUID {
- self.adapter.adapter().luid()
+ self.adapter.luid()
}
fn ipv6(&self) -> bool {
@@ -232,22 +227,19 @@ impl WintunContext for WintunContextImpl {
}
async fn wait_for_interfaces(&self) -> io::Result<()> {
- let luid = self.adapter.adapter().luid();
+ let luid = self.adapter.luid();
crate::windows::wait_for_interfaces(luid, true, self.wait_v6_interface).await
}
fn prepare_interface(&self) {
- self.adapter.adapter().prepare_interface();
+ self.adapter.prepare_interface();
}
}
#[cfg(windows)]
impl WintunContextImpl {
- fn alias(&self) -> Result<U16CString> {
- self.adapter
- .adapter()
- .name()
- .map_err(Error::WintunFindAlias)
+ fn alias(&self) -> U16CString {
+ self.adapter.name()
}
}
@@ -300,7 +292,7 @@ impl OpenVpnMonitor<OpenVpnCommand> {
resource_dir,
&proxy_monitor,
#[cfg(windows)]
- wintun.alias()?.to_os_string(),
+ wintun.alias().to_os_string(),
)?;
let plugin_path = Self::get_plugin_path(resource_dir)?;
@@ -347,10 +339,10 @@ impl OpenVpnMonitor<OpenVpnCommand> {
let dll = wintun::WintunDll::instance(resource_dir).map_err(Error::WintunDllError)?;
let wintun_logger = dll.activate_logging();
- let (wintun_adapter, _reboot_required) = wintun::TemporaryWintunAdapter::create(
+ let wintun_adapter = wintun::WintunAdapter::create(
dll.clone(),
&*ADAPTER_ALIAS,
- &*ADAPTER_POOL,
+ &*ADAPTER_TUNNEL_TYPE,
Some(ADAPTER_GUID.clone()),
)
.map_err(Error::WintunCreateAdapterError)?;
diff --git a/talpid-core/src/tunnel/openvpn/wintun.rs b/talpid-core/src/tunnel/openvpn/wintun.rs
index 813d0de2e7..9d9996aefc 100644
--- a/talpid-core/src/tunnel/openvpn/wintun.rs
+++ b/talpid-core/src/tunnel/openvpn/wintun.rs
@@ -14,7 +14,7 @@ use winapi::{
shared::{
guiddef::GUID,
ifdef::NET_LUID,
- minwindef::{BOOL, FARPROC, HINSTANCE, HMODULE},
+ minwindef::{FARPROC, HINSTANCE, HMODULE},
netioapi::ConvertInterfaceLuidToGuid,
winerror::NO_ERROR,
},
@@ -35,33 +35,17 @@ lazy_static! {
static ref WINTUN_DLL: Mutex<Option<Arc<WintunDll>>> = Mutex::new(None);
}
-/// Longest possible adapter name (in characters), including null terminator
-const MAX_ADAPTER_NAME: usize = 128;
-
-type WintunOpenAdapterFn =
- unsafe extern "stdcall" fn(pool: *const u16, name: *const u16) -> RawHandle;
-
type WintunCreateAdapterFn = unsafe extern "stdcall" fn(
- pool: *const u16,
name: *const u16,
+ tunnel_type: *const u16,
requested_guid: *const GUID,
- reboot_required: *mut BOOL,
) -> RawHandle;
-type WintunFreeAdapterFn = unsafe extern "stdcall" fn(adapter: RawHandle);
-
-type WintunDeleteAdapterFn = unsafe extern "stdcall" fn(
- adapter: RawHandle,
- force_close_sessions: BOOL,
- reboot_required: *mut BOOL,
-) -> BOOL;
-
-type WintunGetAdapterNameFn =
- unsafe extern "stdcall" fn(adapter: RawHandle, name: *mut u16) -> BOOL;
+type WintunCloseAdapterFn = unsafe extern "stdcall" fn(adapter: RawHandle);
type WintunGetAdapterLuidFn = unsafe extern "stdcall" fn(adapter: RawHandle, luid: *mut NET_LUID);
-type WintunLoggerCbFn = extern "stdcall" fn(WintunLoggerLevel, *const u16);
+type WintunLoggerCbFn = extern "stdcall" fn(WintunLoggerLevel, u64, *const u16);
type WintunSetLoggerFn = unsafe extern "stdcall" fn(Option<WintunLoggerCbFn>);
@@ -75,11 +59,8 @@ enum WintunLoggerLevel {
pub struct WintunDll {
handle: HINSTANCE,
- func_open: WintunOpenAdapterFn,
func_create: WintunCreateAdapterFn,
- func_free: WintunFreeAdapterFn,
- func_delete: WintunDeleteAdapterFn,
- func_get_adapter_name: WintunGetAdapterNameFn,
+ func_close: WintunCloseAdapterFn,
func_get_adapter_luid: WintunGetAdapterLuidFn,
func_set_logger: WintunSetLoggerFn,
}
@@ -87,50 +68,11 @@ pub struct WintunDll {
unsafe impl Send for WintunDll {}
unsafe impl Sync for WintunDll {}
-type RebootRequired = bool;
-
-/// A new Wintun adapter that is destroyed when dropped.
-#[derive(Debug)]
-pub struct TemporaryWintunAdapter {
- pub adapter: WintunAdapter,
-}
-
-impl TemporaryWintunAdapter {
- pub fn create(
- dll_handle: Arc<WintunDll>,
- pool: &U16CStr,
- name: &U16CStr,
- requested_guid: Option<GUID>,
- ) -> io::Result<(Self, RebootRequired)> {
- let (adapter, reboot_required) =
- WintunAdapter::create(dll_handle, pool, name, requested_guid)?;
- Ok((TemporaryWintunAdapter { adapter }, reboot_required))
- }
-
- pub fn adapter(&self) -> &WintunAdapter {
- &self.adapter
- }
-}
-
-impl Drop for TemporaryWintunAdapter {
- fn drop(&mut self) {
- if let Err(error) = unsafe {
- self.adapter
- .dll_handle
- .delete_adapter(self.adapter.handle, true)
- } {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to delete Wintun adapter")
- );
- }
- }
-}
-
/// Represents a Wintun adapter.
pub struct WintunAdapter {
dll_handle: Arc<WintunDll>,
handle: RawHandle,
+ name: U16CString,
}
impl fmt::Debug for WintunAdapter {
@@ -145,41 +87,20 @@ unsafe impl Send for WintunAdapter {}
unsafe impl Sync for WintunAdapter {}
impl WintunAdapter {
- pub fn open(dll_handle: Arc<WintunDll>, pool: &U16CStr, name: &U16CStr) -> io::Result<Self> {
- Ok(Self {
- handle: dll_handle.open_adapter(pool, name)?,
- dll_handle,
- })
- }
-
pub fn create(
dll_handle: Arc<WintunDll>,
- pool: &U16CStr,
name: &U16CStr,
+ tunnel_type: &U16CStr,
requested_guid: Option<GUID>,
- ) -> io::Result<(Self, RebootRequired)> {
- {
- if let Ok(adapter) = Self::open(dll_handle.clone(), name, pool) {
- // Delete existing adapter in case it has residual config
- adapter.delete(false).map_err(|error| {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to delete existing Wintun adapter")
- );
- error
- })?;
- }
- }
-
- let (handle, restart_required) = dll_handle.create_adapter(pool, name, requested_guid)?;
-
- if restart_required {
- log::warn!("You may need to restart Windows to complete the install of Wintun");
- }
-
- let adapter = Self { dll_handle, handle };
+ ) -> io::Result<Self> {
+ let handle = dll_handle.create_adapter(name, tunnel_type, requested_guid)?;
+ let adapter = Self {
+ dll_handle,
+ handle,
+ name: name.to_owned(),
+ };
adapter.restore_missing_component_id();
- Ok((adapter, restart_required))
+ Ok(adapter)
}
pub fn prepare_interface(&self) {
@@ -191,15 +112,8 @@ impl WintunAdapter {
}
}
- pub fn delete(self, force_close_sessions: bool) -> io::Result<RebootRequired> {
- unsafe {
- self.dll_handle
- .delete_adapter(self.handle, force_close_sessions)
- }
- }
-
- pub fn name(&self) -> io::Result<U16CString> {
- unsafe { self.dll_handle.get_adapter_name(self.handle) }
+ pub fn name(&self) -> U16CString {
+ self.name.to_owned()
}
pub fn luid(&self) -> NET_LUID {
@@ -262,7 +176,7 @@ impl WintunAdapter {
impl Drop for WintunAdapter {
fn drop(&mut self) {
- unsafe { self.dll_handle.free_adapter(self.handle) };
+ unsafe { self.dll_handle.close_adapter(self.handle) };
}
}
@@ -301,34 +215,16 @@ impl WintunDll {
) -> io::Result<Self> {
Ok(WintunDll {
handle,
- func_open: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WintunOpenAdapter\0").unwrap(),
- )?) as *const _ as *const _)
- },
func_create: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WintunCreateAdapter\0").unwrap(),
)?) as *const _ as *const _)
},
- func_delete: unsafe {
+ func_close: unsafe {
*((&get_proc_fn(
handle,
- CStr::from_bytes_with_nul(b"WintunDeleteAdapter\0").unwrap(),
- )?) as *const _ as *const _)
- },
- func_free: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WintunFreeAdapter\0").unwrap(),
- )?) as *const _ as *const _)
- },
- func_get_adapter_name: unsafe {
- *((&get_proc_fn(
- handle,
- CStr::from_bytes_with_nul(b"WintunGetAdapterName\0").unwrap(),
+ CStr::from_bytes_with_nul(b"WintunCloseAdapter\0").unwrap(),
)?) as *const _ as *const _)
},
func_get_adapter_luid: unsafe {
@@ -354,59 +250,25 @@ impl WintunDll {
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,
- force_close_sessions: bool,
- ) -> io::Result<RebootRequired> {
- let mut reboot_required = 0;
- let force_close_sessions = if force_close_sessions { 1 } else { 0 };
- let result = (self.func_delete)(adapter, force_close_sessions, &mut reboot_required);
- if result == 0 {
- return Err(io::Error::last_os_error());
- }
- Ok(reboot_required != 0)
- }
-
- pub unsafe fn free_adapter(&self, adapter: RawHandle) {
- (self.func_free)(adapter);
+ Ok(handle)
}
- 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 {
@@ -440,7 +302,7 @@ impl WintunLoggerHandle {
Self { dll_handle }
}
- extern "stdcall" fn callback(level: WintunLoggerLevel, message: *const u16) {
+ extern "stdcall" fn callback(level: WintunLoggerLevel, _timestamp: u64, message: *const u16) {
if message.is_null() {
return;
}