Skip to content

Commit

Permalink
Add fallback when failing to create wintun adapter
Browse files Browse the repository at this point in the history
Co-authored-by: Markus Pettersson <markus.pettersson@mullvad.net>
  • Loading branch information
Serock3 and MarkusPettersson98 committed Sep 24, 2024
1 parent 7807b09 commit 5a11fac
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions talpid-openvpn/src/wintun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ type WintunCreateAdapterFn = unsafe extern "stdcall" fn(
requested_guid: *const GUID,
) -> RawHandle;

type WintunOpenAdapterFn = unsafe extern "stdcall" fn(name: *const u16) -> RawHandle;

type WintunCloseAdapterFn = unsafe extern "stdcall" fn(adapter: RawHandle);

type WintunGetAdapterLuidFn =
Expand All @@ -48,6 +50,7 @@ enum WintunLoggerLevel {
pub struct WintunDll {
handle: HMODULE,
func_create: WintunCreateAdapterFn,
func_open: WintunOpenAdapterFn,
func_close: WintunCloseAdapterFn,
func_get_adapter_luid: WintunGetAdapterLuidFn,
func_set_logger: WintunSetLoggerFn,
Expand Down Expand Up @@ -190,28 +193,19 @@ impl WintunDll {
Ok(WintunDll {
handle,
func_create: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WintunCreateAdapter\0").unwrap(),
)?) as *const _ as *const _)
*((&get_proc_fn(handle, c"WintunCreateAdapter")?) as *const _ as *const _)
},
func_open: unsafe {
*((&get_proc_fn(handle, c"WintunOpenAdapter")?) as *const _ as *const _)
},
func_close: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WintunCloseAdapter\0").unwrap(),
)?) as *const _ as *const _)
*((&get_proc_fn(handle, c"WintunCloseAdapter")?) as *const _ as *const _)
},
func_get_adapter_luid: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WintunGetAdapterLUID\0").unwrap(),
)?) as *const _ as *const _)
*((&get_proc_fn(handle, c"WintunGetAdapterLUID")?) as *const _ as *const _)
},
func_set_logger: unsafe {
*((&get_proc_fn(
handle,
CStr::from_bytes_with_nul(b"WintunSetLogger\0").unwrap(),
)?) as *const _ as *const _)
*((&get_proc_fn(handle, c"WintunSetLogger")?) as *const _ as *const _)
},
})
}
Expand All @@ -236,7 +230,23 @@ impl WintunDll {
};
let handle = unsafe { (self.func_create)(name.as_ptr(), tunnel_type.as_ptr(), guid_ptr) };
if handle.is_null() {
return Err(io::Error::last_os_error());
log::error!(
"Failed to create Wintun adapter: {}",
io::Error::last_os_error()
);
// This is an attempt to fix the elusive "Failed to create Wintun adapter" error.
// we cannot reproduce the issue on our end, but if it is caused by an existing adapter
// that hasn't been cleaned up properly, it may help to open the adapter and return it.
log::info!(
"Attempting to open existing adapter with name: '{}'",
name.to_string_lossy()
);
let handle = unsafe { (self.func_open)(name.as_ptr()) };
if handle.is_null() {
return Err(io::Error::last_os_error());
} else {
return Ok(handle);
}
}
Ok(handle)
}
Expand Down

0 comments on commit 5a11fac

Please sign in to comment.