diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-26 15:29:22 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-26 15:29:22 +0100 |
| commit | 34e99d33d6d6f9eaf53eec302ba94c16ba24f958 (patch) | |
| tree | d8f7ea6a3a3c2a5151ed5781c37c6a739121d6a2 | |
| parent | 70e9b630ac16391ba4db5a707d76395060671a17 (diff) | |
| parent | cca7e8e120f3592a28500d61d7d2d37719f43931 (diff) | |
| download | mullvadvpn-34e99d33d6d6f9eaf53eec302ba94c16ba24f958.tar.xz mullvadvpn-34e99d33d6d6f9eaf53eec302ba94c16ba24f958.zip | |
Merge branch 'add-wintun-logger'
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 26 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/windows.rs | 66 |
2 files changed, 89 insertions, 3 deletions
diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs index 6210b61d8b..1236efde5a 100644 --- a/talpid-core/src/tunnel/openvpn/mod.rs +++ b/talpid-core/src/tunnel/openvpn/mod.rs @@ -270,6 +270,8 @@ pub struct OpenVpnMonitor<C: OpenVpnBuilder = OpenVpnCommand> { #[cfg(windows)] wintun_adapter: Option<windows::TemporaryWintunAdapter>, + #[cfg(windows)] + _wintun_logger: Option<windows::WintunLoggerHandle>, } @@ -364,9 +366,12 @@ impl OpenVpnMonitor<OpenVpnCommand> { let proxy_monitor = Self::start_proxy(¶ms.proxy, &proxy_resources)?; #[cfg(windows)] - let wintun_adapter = { - let dll = get_wintun_dll(resource_dir)?; + let dll = get_wintun_dll(resource_dir)?; + #[cfg(windows)] + let wintun_logger = dll.activate_logging(); + #[cfg(windows)] + let wintun_adapter = { { if let Ok(adapter) = windows::WintunAdapter::open(dll.clone(), &*ADAPTER_ALIAS, &*ADAPTER_POOL) @@ -465,6 +470,8 @@ impl OpenVpnMonitor<OpenVpnCommand> { proxy_monitor, #[cfg(windows)] Some(wintun_adapter), + #[cfg(windows)] + Some(wintun_logger), ) } } @@ -518,6 +525,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> { proxy_auth_file: Option<mktemp::TempFile>, proxy_monitor: Option<Box<dyn ProxyMonitor>>, #[cfg(windows)] wintun_adapter: Option<windows::TemporaryWintunAdapter>, + #[cfg(windows)] wintun_logger: Option<windows::WintunLoggerHandle>, ) -> Result<OpenVpnMonitor<C>> where L: Fn(openvpn_plugin::EventType, HashMap<String, String>) + Send + Sync + 'static, @@ -574,6 +582,8 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> { #[cfg(windows)] wintun_adapter, + #[cfg(windows)] + _wintun_logger: wintun_logger, }) } @@ -1191,6 +1201,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ); assert_eq!( Some(PathBuf::from("./my_test_plugin")), @@ -1211,6 +1223,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ); assert_eq!( Some(PathBuf::from("./my_test_log_file")), @@ -1232,6 +1246,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ) .unwrap(); assert!(testee.wait().is_ok()); @@ -1251,6 +1267,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ) .unwrap(); assert!(testee.wait().is_err()); @@ -1270,6 +1288,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ) .unwrap(); testee.close_handle().close().unwrap(); @@ -1289,6 +1309,8 @@ mod tests { None, #[cfg(windows)] None, + #[cfg(windows)] + None, ) .unwrap_err(); match error { diff --git a/talpid-core/src/tunnel/openvpn/windows.rs b/talpid-core/src/tunnel/openvpn/windows.rs index a97b923f92..c1aa80a631 100644 --- a/talpid-core/src/tunnel/openvpn/windows.rs +++ b/talpid-core/src/tunnel/openvpn/windows.rs @@ -52,6 +52,18 @@ type WintunGetAdapterNameFn = type WintunGetAdapterLuidFn = unsafe extern "stdcall" fn(adapter: RawHandle, luid: *mut NET_LUID); +type WintunLoggerCbFn = extern "stdcall" fn(WintunLoggerLevel, *const u16); + +type WintunSetLoggerFn = unsafe extern "stdcall" fn(Option<WintunLoggerCbFn>); + +#[repr(C)] +#[allow(dead_code)] +enum WintunLoggerLevel { + Info, + Warn, + Err, +} + pub struct WintunDll { handle: HINSTANCE, @@ -61,6 +73,7 @@ pub struct WintunDll { func_delete: WintunDeleteAdapterFn, func_get_adapter_name: WintunGetAdapterNameFn, func_get_adapter_luid: WintunGetAdapterLuidFn, + func_set_logger: WintunSetLoggerFn, } unsafe impl Send for WintunDll {} @@ -190,7 +203,6 @@ impl WintunDll { if handle == ptr::null_mut() { return Err(io::Error::last_os_error()); } - Self::new_inner(handle, Self::get_proc_address) } @@ -236,6 +248,12 @@ impl WintunDll { CStr::from_bytes_with_nul(b"WintunGetAdapterLUID\0").unwrap(), )?) }, + func_set_logger: unsafe { + std::mem::transmute(get_proc_fn( + handle, + CStr::from_bytes_with_nul(b"WintunSetLogger\0").unwrap(), + )?) + }, }) } @@ -308,6 +326,14 @@ impl WintunDll { (self.func_get_adapter_luid)(adapter, luid.as_mut_ptr()); luid.assume_init() } + + pub fn activate_logging(self: &Arc<Self>) -> WintunLoggerHandle { + WintunLoggerHandle::from_handle(self.clone()) + } + + fn set_logger(&self, logger: Option<WintunLoggerCbFn>) { + unsafe { (self.func_set_logger)(logger) }; + } } impl Drop for WintunDll { @@ -316,6 +342,44 @@ impl Drop for WintunDll { } } +pub struct WintunLoggerHandle { + dll_handle: Arc<WintunDll>, +} + +impl WintunLoggerHandle { + fn from_handle(dll_handle: Arc<WintunDll>) -> Self { + dll_handle.set_logger(Some(Self::callback)); + Self { dll_handle } + } + + extern "stdcall" fn callback(level: WintunLoggerLevel, message: *const u16) { + if message.is_null() { + return; + } + let message = unsafe { U16CStr::from_ptr_str(message) }; + + use WintunLoggerLevel::*; + + match level { + Info => log::info!("[Wintun] {}", message.to_string_lossy()), + Warn => log::warn!("[Wintun] {}", message.to_string_lossy()), + Err => log::error!("[Wintun] {}", message.to_string_lossy()), + } + } +} + +impl fmt::Debug for WintunLoggerHandle { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("WintunLogger").finish() + } +} + +impl Drop for WintunLoggerHandle { + fn drop(&mut self) { + self.dll_handle.set_logger(None); + } +} + /// Obtain a string representation for a GUID object. pub fn string_from_guid(guid: &GUID) -> String { use std::{ffi::OsString, os::windows::ffi::OsStringExt}; |
