summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rwxr-xr-xbuild_windows_modules.sh6
-rw-r--r--dist-assets/windows/installer.nsh74
-rwxr-xr-xgui/electron-builder.yml2
-rw-r--r--talpid-core/build.rs6
-rw-r--r--talpid-core/src/lib.rs1
-rw-r--r--talpid-core/src/tunnel/mod.rs8
-rw-r--r--talpid-core/src/tunnel/openvpn.rs14
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs14
-rw-r--r--talpid-core/src/winnet.rs103
-rw-r--r--windows/nsis-plugins/src/driverlogic/context.cpp37
m---------windows/windows-libraries0
-rw-r--r--windows/winnet/extras.sln (renamed from windows/winroute/extras.sln)2
-rw-r--r--windows/winnet/src/extras/loader/loader.cpp27
-rw-r--r--windows/winnet/src/extras/loader/loader.vcxproj (renamed from windows/winroute/src/extras/loader/loader.vcxproj)12
-rw-r--r--windows/winnet/src/extras/loader/loader.vcxproj.filters (renamed from windows/winroute/src/extras/loader/loader.vcxproj.filters)0
-rw-r--r--windows/winnet/src/extras/loader/stdafx.cpp (renamed from windows/winroute/src/extras/loader/stdafx.cpp)0
-rw-r--r--windows/winnet/src/extras/loader/stdafx.h (renamed from windows/winroute/src/extras/loader/stdafx.h)0
-rw-r--r--windows/winnet/src/extras/loader/targetver.h (renamed from windows/winroute/src/extras/loader/targetver.h)0
-rw-r--r--windows/winnet/src/winnet/InterfacePair.cpp (renamed from windows/winroute/src/winroute/InterfacePair.cpp)0
-rw-r--r--windows/winnet/src/winnet/InterfacePair.h (renamed from windows/winroute/src/winroute/InterfacePair.h)0
-rw-r--r--windows/winnet/src/winnet/NetworkInterfaces.cpp (renamed from windows/winroute/src/winroute/NetworkInterfaces.cpp)0
-rw-r--r--windows/winnet/src/winnet/NetworkInterfaces.h (renamed from windows/winroute/src/winroute/NetworkInterfaces.h)0
-rw-r--r--windows/winnet/src/winnet/dllmain.cpp (renamed from windows/winroute/src/winroute/dllmain.cpp)0
-rw-r--r--windows/winnet/src/winnet/interfaceutils.cpp127
-rw-r--r--windows/winnet/src/winnet/interfaceutils.h42
-rw-r--r--windows/winnet/src/winnet/stdafx.cpp (renamed from windows/winroute/src/winroute/stdafx.cpp)0
-rw-r--r--windows/winnet/src/winnet/stdafx.h (renamed from windows/winroute/src/winroute/stdafx.h)3
-rw-r--r--windows/winnet/src/winnet/targetver.h (renamed from windows/winroute/src/winroute/targetver.h)0
-rw-r--r--windows/winnet/src/winnet/winnet.cpp136
-rw-r--r--windows/winnet/src/winnet/winnet.def6
-rw-r--r--windows/winnet/src/winnet/winnet.h73
-rw-r--r--windows/winnet/src/winnet/winnet.rc (renamed from windows/winroute/src/winroute/winroute.rc)0
-rw-r--r--windows/winnet/src/winnet/winnet.vcxproj (renamed from windows/winroute/src/winroute/winroute.vcxproj)28
-rw-r--r--windows/winnet/src/winnet/winnet.vcxproj.filters (renamed from windows/winroute/src/winroute/winroute.vcxproj.filters)10
-rw-r--r--windows/winnet/winnet.sln (renamed from windows/winroute/winroute.sln)2
-rw-r--r--windows/winroute/src/extras/loader/loader.cpp10
-rw-r--r--windows/winroute/src/winroute/winroute.cpp82
-rw-r--r--windows/winroute/src/winroute/winroute.def4
-rw-r--r--windows/winroute/src/winroute/winroute.h50
40 files changed, 650 insertions, 230 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 069e956e9a..6d5e7511e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,6 +34,7 @@ Line wrap the file at 100 chars. Th
#### Windows
- Make the firewall rules permanent until reboot, or until the daemon removes them.
- Increase timeout when updating DNS settings.
+- Use dynamic naming of TAP adapter to avoid collisions with existing adapters.
## [2019.3] - 2019-04-02
### Fixed
diff --git a/build_windows_modules.sh b/build_windows_modules.sh
index 9bfb8c70b7..d533973f6c 100755
--- a/build_windows_modules.sh
+++ b/build_windows_modules.sh
@@ -163,15 +163,15 @@ function main
{
local winfw_root_path=${CPP_ROOT_PATH:-"./windows/winfw"}
local windns_root_path=${CPP_ROOT_PATH:-"./windows/windns"}
- local winroute_root_path=${CPP_ROOT_PATH:-"./windows/winroute"}
+ local winnet_root_path=${CPP_ROOT_PATH:-"./windows/winnet"}
build_solution "$winfw_root_path" "winfw.sln"
build_solution "$windns_root_path" "windns.sln"
- build_solution "$winroute_root_path" "winroute.sln"
+ build_solution "$winnet_root_path" "winnet.sln"
copy_outputs $winfw_root_path "winfw.dll"
copy_outputs $windns_root_path "windns.dll"
- copy_outputs $winroute_root_path "winroute.dll"
+ copy_outputs $winnet_root_path "winnet.dll"
build_nsis_plugins
}
diff --git a/dist-assets/windows/installer.nsh b/dist-assets/windows/installer.nsh
index 5b37f99a8d..0021606a36 100644
--- a/dist-assets/windows/installer.nsh
+++ b/dist-assets/windows/installer.nsh
@@ -76,6 +76,66 @@
!define ExtractDriver '!insertmacro "ExtractDriver"'
#
+# ForceRenameAdapter
+#
+# For when there's a broken TAP adapter present, such that the adapter name
+# we're trying to use is already taken.
+#
+# This function will iteratively find a name that is not taken.
+# Names tried follow the pattern "NewAdapterBaseName-1", "NewAdapterBaseName-2", etc.
+#
+# Returns: 0 in $R0 on success, otherwise an error message in $R0
+#
+!macro ForceRenameAdapter CurrentAdapterName NewAdapterBaseName
+
+ Var /GLOBAL ForceRenameAdapter_Counter
+
+ log::Log "ForceRenameAdapter()"
+
+ Push $0
+ Push $1
+
+ Push 0
+ Pop $ForceRenameAdapter_Counter
+
+ ForceRenameAdapter_retry:
+
+ ${If} $ForceRenameAdapter_Counter == 10
+ StrCpy $R0 "Exhausted namespace when forcing adapter rename"
+ log::Log $R0
+ Goto ForceRenameAdapter_return
+ ${EndIf}
+
+ IntOp $ForceRenameAdapter_Counter $ForceRenameAdapter_Counter + 1
+ StrCpy $0 "${NewAdapterBaseName}-$ForceRenameAdapter_Counter"
+ log::Log "Renaming adapter to $\"$0$\""
+
+ nsExec::ExecToStack '"$SYSDIR\netsh.exe" interface set interface name = "${CurrentAdapterName}" newname = "$0"'
+
+ Pop $0
+ Pop $1
+
+ ${If} $0 != 0
+ StrCpy $R0 "Failed to rename virtual adapter: error $0"
+ log::LogWithDetails $R0 $1
+ Goto ForceRenameAdapter_retry
+ ${EndIf}
+
+ log::Log "ForceRenameAdapter() completed successfully"
+
+ Push 0
+ Pop $R0
+
+ ForceRenameAdapter_return:
+
+ Pop $1
+ Pop $0
+
+!macroend
+
+!define ForceRenameAdapter '!insertmacro "ForceRenameAdapter"'
+
+#
# InstallDriver
#
# Install tunnel driver or update it if already present on the system
@@ -85,6 +145,7 @@
!macro InstallDriver
Var /GLOBAL InstallDriver_BaselineStatus
+ Var /GLOBAL InstallDriver_TapName
log::Log "InstallDriver()"
@@ -136,7 +197,7 @@
${EndIf}
${If} $InstallDriver_BaselineStatus == ${EB_MULLVAD_ADAPTER_PRESENT}
- log::Log "Virtual adapter named $\"Mullvad$\" already present on system"
+ log::Log "Virtual adapter with custom name already present on system"
Goto InstallDriver_return_success
${EndIf}
@@ -170,9 +231,11 @@
Goto InstallDriver_return
${EndIf}
- log::Log "New virtual adapter is named $\"$1$\""
+ StrCpy $InstallDriver_TapName $1
+ log::Log "New virtual adapter is named $\"$1$\""
log::Log "Renaming adapter to $\"Mullvad$\""
+
nsExec::ExecToStack '"$SYSDIR\netsh.exe" interface set interface name = "$1" newname = "Mullvad"'
Pop $0
@@ -181,7 +244,12 @@
${If} $0 != 0
StrCpy $R0 "Failed to rename virtual adapter: error $0"
log::LogWithDetails $R0 $1
- Goto InstallDriver_return
+
+ ${ForceRenameAdapter} $InstallDriver_TapName "Mullvad"
+
+ ${If} $R0 != 0
+ Goto InstallDriver_return
+ ${EndIf}
${EndIf}
InstallDriver_return_success:
diff --git a/gui/electron-builder.yml b/gui/electron-builder.yml
index 44f197a0c4..c3010e6764 100755
--- a/gui/electron-builder.yml
+++ b/gui/electron-builder.yml
@@ -90,7 +90,7 @@ win:
to: .
- from: ../windows/windns/bin/x64-Release/windns.dll
to: .
- - from: ../windows/winroute/bin/x64-Release/winroute.dll
+ - from: ../windows/winnet/bin/x64-Release/winnet.dll
to: .
- from: ../dist-assets/binaries/windows/openvpn.exe
to: .
diff --git a/talpid-core/build.rs b/talpid-core/build.rs
index a733cfccbc..4741a440d0 100644
--- a/talpid-core/build.rs
+++ b/talpid-core/build.rs
@@ -7,7 +7,7 @@ mod win {
pub static WINFW_BUILD_DIR: &'static str = "..\\windows\\winfw\\bin";
pub static WINDNS_BUILD_DIR: &'static str = "..\\windows\\windns\\bin";
- pub static WINROUTE_BUILD_DIR: &'static str = "..\\windows\\winroute\\bin";
+ pub static WINNET_BUILD_DIR: &'static str = "..\\windows\\winnet\\bin";
pub fn default_windows_build_artifact_dir(build_dir: &str) -> PathBuf {
manifest_dir().join(build_dir).join(&target_platform_dir())
@@ -49,10 +49,10 @@ fn main() {
const WINFW_DIR_VAR: &str = "WINFW_LIB_DIR";
const WINDNS_DIR_VAR: &str = "WINDNS_LIB_DIR";
- const WINROUTE_DIR_VAR: &str = "WINROUTE_LIB_DIR";
+ const WINNET_DIR_VAR: &str = "WINNET_LIB_DIR";
declare_library(WINFW_DIR_VAR, WINFW_BUILD_DIR, "winfw");
declare_library(WINDNS_DIR_VAR, WINDNS_BUILD_DIR, "windns");
- declare_library(WINROUTE_DIR_VAR, WINROUTE_BUILD_DIR, "winroute");
+ declare_library(WINNET_DIR_VAR, WINNET_BUILD_DIR, "winnet");
}
#[cfg(not(windows))]
diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs
index 3b2bac9529..fa19f10d98 100644
--- a/talpid-core/src/lib.rs
+++ b/talpid-core/src/lib.rs
@@ -16,6 +16,7 @@
#[macro_use]
mod ffi;
+/// Misc networking functions for Windows.
#[cfg(windows)]
mod winnet;
diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs
index 987f80c872..baa5a906ba 100644
--- a/talpid-core/src/tunnel/mod.rs
+++ b/talpid-core/src/tunnel/mod.rs
@@ -1,7 +1,6 @@
use crate::logging;
use std::{
collections::HashMap,
- ffi::OsString,
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
path::{Path, PathBuf},
@@ -132,7 +131,6 @@ impl TunnelMonitor {
/// on tunnel state changes.
pub fn start<L>(
tunnel_parameters: &TunnelParameters,
- tunnel_alias: Option<OsString>,
log_dir: &Option<PathBuf>,
resource_dir: &Path,
on_event: L,
@@ -145,7 +143,7 @@ impl TunnelMonitor {
match tunnel_parameters {
TunnelParameters::OpenVpn(config) => {
- Self::start_openvpn_tunnel(&config, tunnel_alias, log_file, resource_dir, on_event)
+ Self::start_openvpn_tunnel(&config, log_file, resource_dir, on_event)
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
TunnelParameters::Wireguard(config) => {
@@ -178,7 +176,6 @@ impl TunnelMonitor {
fn start_openvpn_tunnel<L>(
config: &openvpn_types::TunnelParameters,
- tunnel_alias: Option<OsString>,
log: Option<PathBuf>,
resource_dir: &Path,
on_event: L,
@@ -186,8 +183,7 @@ impl TunnelMonitor {
where
L: Fn(TunnelEvent) + Send + Sync + 'static,
{
- let monitor =
- openvpn::OpenVpnMonitor::start(on_event, config, tunnel_alias, log, resource_dir)?;
+ let monitor = openvpn::OpenVpnMonitor::start(on_event, config, log, resource_dir)?;
Ok(TunnelMonitor {
monitor: InternalTunnelMonitor::OpenVpn(monitor),
})
diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs
index ff2094b34e..8186ab9683 100644
--- a/talpid-core/src/tunnel/openvpn.rs
+++ b/talpid-core/src/tunnel/openvpn.rs
@@ -11,7 +11,6 @@ use crate::{
use failure::ResultExt as FailureResultExt;
use std::{
collections::HashMap,
- ffi::OsString,
fs,
io::{self, Write},
path::{Path, PathBuf},
@@ -92,6 +91,11 @@ pub enum Error {
_0
)]
ProxyExited(String),
+
+ /// Failure in Windows syscall.
+ #[cfg(windows)]
+ #[error(display = "Failure in Windows syscall")]
+ WinnetError(#[error(cause)] crate::winnet::Error),
}
@@ -133,7 +137,6 @@ impl OpenVpnMonitor<OpenVpnCommand> {
pub fn start<L>(
on_event: L,
params: &openvpn::TunnelParameters,
- tunnel_alias: Option<OsString>,
log_path: Option<PathBuf>,
resource_dir: &Path,
) -> Result<Self>
@@ -185,7 +188,6 @@ impl OpenVpnMonitor<OpenVpnCommand> {
let cmd = Self::create_openvpn_cmd(
params,
- tunnel_alias,
user_pass_file.as_ref(),
match proxy_auth_file {
Some(ref file) => Some(file.as_ref()),
@@ -437,7 +439,6 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
fn create_openvpn_cmd(
params: &openvpn::TunnelParameters,
- tunnel_alias: Option<OsString>,
user_pass_file: &Path,
proxy_auth_file: Option<&Path>,
resource_dir: &Path,
@@ -457,8 +458,11 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
.user_pass(user_pass_file)
.tunnel_options(&params.options)
.enable_ipv6(params.generic_options.enable_ipv6)
- .tunnel_alias(tunnel_alias)
.ca(resource_dir.join("ca.crt"));
+ #[cfg(windows)]
+ cmd.tunnel_alias(Some(
+ crate::winnet::get_tap_interface_alias().map_err(Error::WinnetError)?,
+ ));
if let Some(proxy_auth_file) = proxy_auth_file {
cmd.proxy_auth(proxy_auth_file);
}
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index f044c61df1..8b9e6bbb63 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -13,7 +13,6 @@ use futures::{
};
use log::{debug, error, info, trace, warn};
use std::{
- ffi::OsString,
net::IpAddr,
path::{Path, PathBuf},
thread,
@@ -28,11 +27,6 @@ use talpid_types::{
const MIN_TUNNEL_ALIVE_TIME: Duration = Duration::from_millis(1000);
-#[cfg(windows)]
-const TUNNEL_INTERFACE_ALIAS: Option<&str> = Some("Mullvad");
-#[cfg(not(windows))]
-const TUNNEL_INTERFACE_ALIAS: Option<&str> = None;
-
/// The tunnel has been started, but it is not established/functional.
pub struct ConnectingState {
tunnel_events: mpsc::UnboundedReceiver<TunnelEvent>,
@@ -73,13 +67,7 @@ impl ConnectingState {
let on_tunnel_event = move |event| {
let _ = event_tx.unbounded_send(event);
};
- let monitor = TunnelMonitor::start(
- &parameters,
- TUNNEL_INTERFACE_ALIAS.to_owned().map(OsString::from),
- log_dir,
- resource_dir,
- on_tunnel_event,
- )?;
+ let monitor = TunnelMonitor::start(&parameters, log_dir, resource_dir, on_tunnel_event)?;
let close_handle = monitor.close_handle();
let tunnel_close_event = Self::spawn_tunnel_monitor_wait_thread(monitor);
diff --git a/talpid-core/src/winnet.rs b/talpid-core/src/winnet.rs
index 1211cd7545..d659534e1f 100644
--- a/talpid-core/src/winnet.rs
+++ b/talpid-core/src/winnet.rs
@@ -1,23 +1,30 @@
-use std::ptr;
-
+pub use self::api::ErrorSink;
+use self::api::*;
use libc::{c_char, c_void, wchar_t};
+use std::{ffi::OsString, ptr};
use widestring::WideCString;
+/// Errors that this module may produce.
#[derive(err_derive::Error, Debug)]
pub enum Error {
- /// Failure to set metrics of network interfaces
+ /// Failed to set the metrics for a network interface.
#[error(display = "Failed to set the metrics for a network interface")]
MetricApplication,
+ /// Supplied interface alias is invalid.
#[error(display = "Supplied interface alias is invalid")]
InvalidInterfaceAlias(#[error(cause)] widestring::NulError<u16>),
+ /// Failed to read IPv6 status on the TAP network interface.
#[error(display = "Failed to read IPv6 status on the TAP network interface")]
GetIpv6Status,
-}
-pub type ErrorSink = extern "system" fn(msg: *const c_char, ctx: *mut c_void);
+ /// Failed to determine alias of TAP adapter.
+ #[error(display = "Failed to determine alias of TAP adapter")]
+ GetTapAlias,
+}
+/// Error callback used with `winnet.dll`.
pub extern "system" fn error_sink(msg: *const c_char, _ctx: *mut c_void) {
use std::ffi::CStr;
if msg.is_null() {
@@ -33,7 +40,7 @@ pub fn ensure_top_metric_for_interface(interface_alias: &str) -> Result<bool, Er
WideCString::from_str(interface_alias).map_err(Error::InvalidInterfaceAlias)?;
let metric_result = unsafe {
- WinRoute_EnsureTopMetric(
+ WinNet_EnsureTopMetric(
interface_alias_ws.as_ptr(),
Some(error_sink),
ptr::null_mut(),
@@ -49,28 +56,16 @@ pub fn ensure_top_metric_for_interface(interface_alias: &str) -> Result<bool, Er
2 => Err(Error::MetricApplication),
// Unexpected value
i => {
- log::error!(
- "Unexpected return code from WinRoute_EnsureTopMetric: {}",
- i
- );
+ log::error!("Unexpected return code from WinNet_EnsureTopMetric: {}", i);
Err(Error::MetricApplication)
}
}
}
-extern "system" {
- #[link_name = "WinRoute_EnsureTopMetric"]
- fn WinRoute_EnsureTopMetric(
- tunnel_interface_alias: *const wchar_t,
- sink: Option<ErrorSink>,
- sink_context: *mut c_void,
- ) -> u32;
-}
-
-
/// Checks if IPv6 is enabled for the TAP interface
pub fn get_tap_interface_ipv6_status() -> Result<bool, Error> {
- let tap_ipv6_status = unsafe { GetTapInterfaceIpv6Status(Some(error_sink), ptr::null_mut()) };
+ let tap_ipv6_status =
+ unsafe { WinNet_GetTapInterfaceIpv6Status(Some(error_sink), ptr::null_mut()) };
match tap_ipv6_status {
// Enabled
@@ -82,7 +77,7 @@ pub fn get_tap_interface_ipv6_status() -> Result<bool, Error> {
// Unexpected value
i => {
log::error!(
- "Unexpected return code from GetTapInterfaceIpv6Status: {}",
+ "Unexpected return code from WinNet_GetTapInterfaceIpv6Status: {}",
i
);
Err(Error::GetIpv6Status)
@@ -90,7 +85,65 @@ pub fn get_tap_interface_ipv6_status() -> Result<bool, Error> {
}
}
-extern "system" {
- #[link_name = "GetTapInterfaceIpv6Status"]
- fn GetTapInterfaceIpv6Status(sink: Option<ErrorSink>, sink_context: *mut c_void) -> u32;
+/// Dynamically determines the alias of the TAP adapter.
+pub fn get_tap_interface_alias() -> Result<OsString, Error> {
+ let mut alias_ptr: *mut wchar_t = ptr::null_mut();
+ let status = unsafe {
+ WinNet_GetTapInterfaceAlias(&mut alias_ptr as *mut _, Some(error_sink), ptr::null_mut())
+ };
+
+ if status != 0 {
+ if status != 1 {
+ log::error!(
+ "Unexpected return code from WinNet_GetTapInterfaceAlias: {}",
+ status
+ );
+ }
+
+ return Err(Error::GetTapAlias);
+ }
+
+ let alias = unsafe { WideCString::from_ptr_str(alias_ptr) };
+ unsafe { WinNet_ReleaseString(alias_ptr) };
+
+ Ok(alias.to_os_string())
+}
+
+#[allow(non_snake_case)]
+mod api {
+ use libc::{c_char, c_void, wchar_t};
+
+ /// Error callback type for use with `winnet.dll`.
+ pub type ErrorSink = extern "system" fn(msg: *const c_char, ctx: *mut c_void);
+
+ extern "system" {
+ #[link_name = "WinNet_EnsureTopMetric"]
+ pub fn WinNet_EnsureTopMetric(
+ tunnel_interface_alias: *const wchar_t,
+ sink: Option<ErrorSink>,
+ sink_context: *mut c_void,
+ ) -> u32;
+ }
+
+ extern "system" {
+ #[link_name = "WinNet_GetTapInterfaceIpv6Status"]
+ pub fn WinNet_GetTapInterfaceIpv6Status(
+ sink: Option<ErrorSink>,
+ sink_context: *mut c_void,
+ ) -> u32;
+ }
+
+ extern "system" {
+ #[link_name = "WinNet_GetTapInterfaceAlias"]
+ pub fn WinNet_GetTapInterfaceAlias(
+ tunnel_interface_alias: *mut *mut wchar_t,
+ sink: Option<ErrorSink>,
+ sink_context: *mut c_void,
+ ) -> u32;
+ }
+
+ extern "system" {
+ #[link_name = "WinNet_ReleaseString"]
+ pub fn WinNet_ReleaseString(string: *mut wchar_t) -> u32;
+ }
}
diff --git a/windows/nsis-plugins/src/driverlogic/context.cpp b/windows/nsis-plugins/src/driverlogic/context.cpp
index d0ad9dfb67..13cb781863 100644
--- a/windows/nsis-plugins/src/driverlogic/context.cpp
+++ b/windows/nsis-plugins/src/driverlogic/context.cpp
@@ -10,6 +10,8 @@
#include <vector>
#include <list>
#include <stdexcept>
+#include <sstream>
+#include <algorithm>
namespace
{
@@ -100,9 +102,40 @@ Context::BaselineStatus Context::establishBaseline()
return BaselineStatus::NO_TAP_ADAPTERS_PRESENT;
}
- for (const auto &adapter : tapAdapters)
+ //
+ // Look for TAP adapter with alias "Mullvad".
+ //
+
+ auto findByAlias = [](const std::set<NetworkAdapter> &adapters, const std::wstring &alias)
{
- if (0 == _wcsicmp(adapter.alias.c_str(), L"mullvad"))
+ const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const NetworkAdapter &candidate)
+ {
+ return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str());
+ });
+
+ return it != adapters.end();
+ };
+
+ static const wchar_t baseAlias[] = L"Mullvad";
+
+ if (findByAlias(tapAdapters, baseAlias))
+ {
+ return BaselineStatus::MULLVAD_ADAPTER_PRESENT;
+ }
+
+ //
+ // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc.
+ //
+
+ for (auto i = 0; i < 10; ++i)
+ {
+ std::wstringstream ss;
+
+ ss << baseAlias << L"-" << i;
+
+ const auto alias = ss.str();
+
+ if (findByAlias(tapAdapters, alias))
{
return BaselineStatus::MULLVAD_ADAPTER_PRESENT;
}
diff --git a/windows/windows-libraries b/windows/windows-libraries
-Subproject d609c6dea5e97f615f18827d4086949b3e857f8
+Subproject d3ba2ac4292f7e5b37e060da1619ed5e07ef63a
diff --git a/windows/winroute/extras.sln b/windows/winnet/extras.sln
index 28d1d51341..a6fec71c96 100644
--- a/windows/winroute/extras.sln
+++ b/windows/winnet/extras.sln
@@ -8,7 +8,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader", "src\extras\loader
{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4} = {89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winroute", "src\winroute\winroute.vcxproj", "{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winnet", "src\winnet\winnet.vcxproj", "{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}"
ProjectSection(ProjectDependencies) = postProject
{B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF}
EndProjectSection
diff --git a/windows/winnet/src/extras/loader/loader.cpp b/windows/winnet/src/extras/loader/loader.cpp
new file mode 100644
index 0000000000..43ec54978c
--- /dev/null
+++ b/windows/winnet/src/extras/loader/loader.cpp
@@ -0,0 +1,27 @@
+#include "stdafx.h"
+#include "../../winnet/winnet.h"
+#include <iostream>
+
+int main()
+{
+ wchar_t *alias = nullptr;
+
+ const auto status = WinNet_GetTapInterfaceAlias(&alias, nullptr, nullptr);
+
+ switch (status)
+ {
+ case WINNET_GTIA_STATUS::FAILURE:
+ {
+ std::wcout << L"Could not determine alias" << std::endl;
+ break;
+ }
+ case WINNET_GTIA_STATUS::SUCCESS:
+ {
+ std::wcout << L"Interface alias: " << alias << std::endl;
+ WinNet_ReleaseString(alias);
+ }
+ };
+
+ return 0;
+}
+
diff --git a/windows/winroute/src/extras/loader/loader.vcxproj b/windows/winnet/src/extras/loader/loader.vcxproj
index bf010c1fd0..325f813778 100644
--- a/windows/winroute/src/extras/loader/loader.vcxproj
+++ b/windows/winnet/src/extras/loader/loader.vcxproj
@@ -106,12 +106,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
- <AdditionalDependencies>winroute.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>winnet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -122,12 +123,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
- <AdditionalDependencies>winroute.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>winnet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -140,6 +142,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -147,7 +150,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
- <AdditionalDependencies>winroute.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>winnet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -160,6 +163,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -167,7 +171,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
- <AdditionalDependencies>winroute.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>winnet.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/windows/winroute/src/extras/loader/loader.vcxproj.filters b/windows/winnet/src/extras/loader/loader.vcxproj.filters
index cd0f4643c7..cd0f4643c7 100644
--- a/windows/winroute/src/extras/loader/loader.vcxproj.filters
+++ b/windows/winnet/src/extras/loader/loader.vcxproj.filters
diff --git a/windows/winroute/src/extras/loader/stdafx.cpp b/windows/winnet/src/extras/loader/stdafx.cpp
index 8d6fa45555..8d6fa45555 100644
--- a/windows/winroute/src/extras/loader/stdafx.cpp
+++ b/windows/winnet/src/extras/loader/stdafx.cpp
diff --git a/windows/winroute/src/extras/loader/stdafx.h b/windows/winnet/src/extras/loader/stdafx.h
index b005a839de..b005a839de 100644
--- a/windows/winroute/src/extras/loader/stdafx.h
+++ b/windows/winnet/src/extras/loader/stdafx.h
diff --git a/windows/winroute/src/extras/loader/targetver.h b/windows/winnet/src/extras/loader/targetver.h
index 87c0086de7..87c0086de7 100644
--- a/windows/winroute/src/extras/loader/targetver.h
+++ b/windows/winnet/src/extras/loader/targetver.h
diff --git a/windows/winroute/src/winroute/InterfacePair.cpp b/windows/winnet/src/winnet/InterfacePair.cpp
index 3c8af26079..3c8af26079 100644
--- a/windows/winroute/src/winroute/InterfacePair.cpp
+++ b/windows/winnet/src/winnet/InterfacePair.cpp
diff --git a/windows/winroute/src/winroute/InterfacePair.h b/windows/winnet/src/winnet/InterfacePair.h
index 9582bac3cd..9582bac3cd 100644
--- a/windows/winroute/src/winroute/InterfacePair.h
+++ b/windows/winnet/src/winnet/InterfacePair.h
diff --git a/windows/winroute/src/winroute/NetworkInterfaces.cpp b/windows/winnet/src/winnet/NetworkInterfaces.cpp
index 2aa352de27..2aa352de27 100644
--- a/windows/winroute/src/winroute/NetworkInterfaces.cpp
+++ b/windows/winnet/src/winnet/NetworkInterfaces.cpp
diff --git a/windows/winroute/src/winroute/NetworkInterfaces.h b/windows/winnet/src/winnet/NetworkInterfaces.h
index bf1d53dddf..bf1d53dddf 100644
--- a/windows/winroute/src/winroute/NetworkInterfaces.h
+++ b/windows/winnet/src/winnet/NetworkInterfaces.h
diff --git a/windows/winroute/src/winroute/dllmain.cpp b/windows/winnet/src/winnet/dllmain.cpp
index e66eb0495d..e66eb0495d 100644
--- a/windows/winroute/src/winroute/dllmain.cpp
+++ b/windows/winnet/src/winnet/dllmain.cpp
diff --git a/windows/winnet/src/winnet/interfaceutils.cpp b/windows/winnet/src/winnet/interfaceutils.cpp
new file mode 100644
index 0000000000..9a406fa6ff
--- /dev/null
+++ b/windows/winnet/src/winnet/interfaceutils.cpp
@@ -0,0 +1,127 @@
+#include "stdafx.h"
+#include "interfaceutils.h"
+#include "libcommon/error.h"
+#include "libcommon/string.h"
+#include "libcommon/synchronization.h"
+#include <vector>
+#include <cstdint>
+#include <algorithm>
+#include <winsock2.h>
+#include <iphlpapi.h>
+#include <windows.h>
+
+//static
+std::wstring InterfaceUtils::m_alias;
+
+//static
+std::mutex InterfaceUtils::m_mutex;
+
+//static
+std::set<InterfaceUtils::NetworkAdapter> InterfaceUtils::GetAllAdapters()
+{
+ ULONG bufferSize = 0;
+
+ const ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
+
+ auto status = GetAdaptersAddresses(AF_INET, flags, nullptr, nullptr, &bufferSize);
+
+ THROW_UNLESS(ERROR_BUFFER_OVERFLOW, status, "Probe for adapter listing buffer size");
+
+ // Memory is cheap, this avoids a looping construct.
+ bufferSize *= 2;
+
+ std::vector<uint8_t> buffer(bufferSize);
+
+ status = GetAdaptersAddresses(AF_INET, flags, nullptr,
+ reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer[0]), &bufferSize);
+
+ THROW_UNLESS(ERROR_SUCCESS, status, "Retrieve adapter listing");
+
+ std::set<NetworkAdapter> adapters;
+
+ for (auto it = (PIP_ADAPTER_ADDRESSES)&buffer[0]; nullptr != it; it = it->Next)
+ {
+ adapters.emplace(NetworkAdapter(common::string::ToWide(it->AdapterName),
+ it->Description, it->FriendlyName));
+ }
+
+ return adapters;
+}
+
+//static
+std::set<InterfaceUtils::NetworkAdapter>
+InterfaceUtils::GetTapAdapters(const std::set<InterfaceUtils::NetworkAdapter> &adapters)
+{
+ std::set<NetworkAdapter> tapAdapters;
+
+ for (const auto &adapter : adapters)
+ {
+ static const wchar_t name[] = L"TAP-Windows Adapter V9";
+
+ //
+ // Compare partial name, because once you start having more TAP adapters
+ // they're named "TAP-Windows Adapter V9 #2" and so on.
+ //
+
+ if (0 == adapter.name.compare(0, _countof(name) - 1, name))
+ {
+ tapAdapters.insert(adapter);
+ }
+ }
+
+ return tapAdapters;
+}
+
+//static
+std::wstring InterfaceUtils::GetTapInterfaceAlias()
+{
+ common::sync::ScopeLock<> cacheLock(m_mutex);
+
+ if (false == m_alias.empty())
+ {
+ return m_alias;
+ }
+
+ //
+ // Look for TAP adapter with alias "Mullvad".
+ //
+
+ auto adapters = GetTapAdapters(GetAllAdapters());
+
+ auto findByAlias = [](const std::set<NetworkAdapter> &adapters, const std::wstring &alias)
+ {
+ const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const NetworkAdapter &candidate)
+ {
+ return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str());
+ });
+
+ return it != adapters.end();
+ };
+
+ static const wchar_t baseAlias[] = L"Mullvad";
+
+ if (findByAlias(adapters, baseAlias))
+ {
+ return m_alias = baseAlias;
+ }
+
+ //
+ // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc.
+ //
+
+ for (auto i = 0; i < 10; ++i)
+ {
+ std::wstringstream ss;
+
+ ss << baseAlias << L"-" << i;
+
+ const auto alias = ss.str();
+
+ if (findByAlias(adapters, alias))
+ {
+ return m_alias = alias;
+ }
+ }
+
+ throw std::runtime_error("Unable to find TAP adapter");
+}
diff --git a/windows/winnet/src/winnet/interfaceutils.h b/windows/winnet/src/winnet/interfaceutils.h
new file mode 100644
index 0000000000..308bfa505b
--- /dev/null
+++ b/windows/winnet/src/winnet/interfaceutils.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <string>
+#include <set>
+#include <mutex>
+
+class InterfaceUtils
+{
+ InterfaceUtils() = delete;
+
+ static std::wstring m_alias;
+ static std::mutex m_mutex;
+
+public:
+
+ struct NetworkAdapter
+ {
+ std::wstring guid;
+ std::wstring name;
+ std::wstring alias;
+
+ NetworkAdapter(std::wstring _guid, std::wstring _name, std::wstring _alias)
+ : guid(_guid)
+ , name(_name)
+ , alias(_alias)
+ {
+ }
+
+ bool operator<(const NetworkAdapter &rhs) const
+ {
+ return _wcsicmp(guid.c_str(), rhs.guid.c_str()) < 0;
+ }
+ };
+
+ static std::set<NetworkAdapter> GetAllAdapters();
+ static std::set<NetworkAdapter> GetTapAdapters(const std::set<NetworkAdapter> &adapters);
+
+ //
+ // Determines alias of primary TAP adapter.
+ //
+ static std::wstring GetTapInterfaceAlias();
+};
diff --git a/windows/winroute/src/winroute/stdafx.cpp b/windows/winnet/src/winnet/stdafx.cpp
index b29c52afc9..b29c52afc9 100644
--- a/windows/winroute/src/winroute/stdafx.cpp
+++ b/windows/winnet/src/winnet/stdafx.cpp
diff --git a/windows/winroute/src/winroute/stdafx.h b/windows/winnet/src/winnet/stdafx.h
index 677e68a9fa..254cb49b0d 100644
--- a/windows/winroute/src/winroute/stdafx.h
+++ b/windows/winnet/src/winnet/stdafx.h
@@ -5,6 +5,9 @@
#pragma once
+// wcscpy
+#define _CRT_SECURE_NO_WARNINGS 1
+
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
diff --git a/windows/winroute/src/winroute/targetver.h b/windows/winnet/src/winnet/targetver.h
index b8b7263c9e..b8b7263c9e 100644
--- a/windows/winroute/src/winroute/targetver.h
+++ b/windows/winnet/src/winnet/targetver.h
diff --git a/windows/winnet/src/winnet/winnet.cpp b/windows/winnet/src/winnet/winnet.cpp
new file mode 100644
index 0000000000..ba14c737da
--- /dev/null
+++ b/windows/winnet/src/winnet/winnet.cpp
@@ -0,0 +1,136 @@
+#include "stdafx.h"
+#include "winnet.h"
+#include "NetworkInterfaces.h"
+#include "interfaceutils.h"
+#include "libcommon/error.h"
+#include <cstdint>
+#include <stdexcept>
+
+extern "C"
+WINNET_LINKAGE
+WINNET_ETM_STATUS
+WINNET_API
+WinNet_EnsureTopMetric(
+ const wchar_t *deviceAlias,
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+)
+{
+ try
+ {
+ NetworkInterfaces interfaces;
+ bool metrics_set = interfaces.SetTopMetricForInterfacesByAlias(deviceAlias);
+ return metrics_set ? WINNET_ETM_STATUS::METRIC_SET : WINNET_ETM_STATUS::METRIC_NO_CHANGE;
+ }
+ catch (std::exception &err)
+ {
+ if (nullptr != errorSink)
+ {
+ errorSink(err.what(), errorSinkContext);
+ }
+
+ return WINNET_ETM_STATUS::FAILURE;
+ }
+ catch (...)
+ {
+ return WINNET_ETM_STATUS::FAILURE;
+ }
+};
+
+extern "C"
+WINNET_LINKAGE
+WINNET_GTII_STATUS
+WINNET_API
+WinNet_GetTapInterfaceIpv6Status(
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+)
+{
+ try
+ {
+ MIB_IPINTERFACE_ROW interface = { 0 };
+
+ interface.InterfaceLuid = NetworkInterfaces::GetInterfaceLuid(InterfaceUtils::GetTapInterfaceAlias());
+ interface.Family = AF_INET6;
+
+ const auto status = GetIpInterfaceEntry(&interface);
+
+ if (NO_ERROR == status)
+ {
+ return WINNET_GTII_STATUS::ENABLED;
+ }
+
+ if (ERROR_NOT_FOUND == status)
+ {
+ return WINNET_GTII_STATUS::DISABLED;
+ }
+
+ common::error::Throw("Resolve TAP IPv6 interface", status);
+ }
+ catch (std::exception &err)
+ {
+ if (nullptr != errorSink)
+ {
+ errorSink(err.what(), errorSinkContext);
+ }
+
+ return WINNET_GTII_STATUS::FAILURE;
+ }
+ catch (...)
+ {
+ return WINNET_GTII_STATUS::FAILURE;
+ }
+}
+
+extern "C"
+WINNET_LINKAGE
+WINNET_GTIA_STATUS
+WINNET_API
+WinNet_GetTapInterfaceAlias(
+ wchar_t **alias,
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+)
+{
+ try
+ {
+ const auto currentAlias = InterfaceUtils::GetTapInterfaceAlias();
+
+ auto stringBuffer = new wchar_t[currentAlias.size() + 1];
+ wcscpy(stringBuffer, currentAlias.c_str());
+
+ *alias = stringBuffer;
+
+ return WINNET_GTIA_STATUS::SUCCESS;
+ }
+ catch (std::exception &err)
+ {
+ if (nullptr != errorSink)
+ {
+ errorSink(err.what(), errorSinkContext);
+ }
+
+ return WINNET_GTIA_STATUS::FAILURE;
+ }
+ catch (...)
+ {
+ return WINNET_GTIA_STATUS::FAILURE;
+ }
+}
+
+extern "C"
+WINNET_LINKAGE
+void
+WINNET_API
+WinNet_ReleaseString(
+ wchar_t *str
+)
+{
+ try
+ {
+ delete[] str;
+ }
+ catch (...)
+ {
+ }
+}
diff --git a/windows/winnet/src/winnet/winnet.def b/windows/winnet/src/winnet/winnet.def
new file mode 100644
index 0000000000..267a797538
--- /dev/null
+++ b/windows/winnet/src/winnet/winnet.def
@@ -0,0 +1,6 @@
+LIBRARY winnet
+EXPORTS
+ WinNet_EnsureTopMetric
+ WinNet_GetTapInterfaceIpv6Status
+ WinNet_GetTapInterfaceAlias
+ WinNet_ReleaseString
diff --git a/windows/winnet/src/winnet/winnet.h b/windows/winnet/src/winnet/winnet.h
new file mode 100644
index 0000000000..b5771f5b5a
--- /dev/null
+++ b/windows/winnet/src/winnet/winnet.h
@@ -0,0 +1,73 @@
+#pragma once
+#include <cstdint>
+
+#ifdef WINNET_EXPORTS
+#define WINNET_LINKAGE __declspec(dllexport)
+#else
+#define WINNET_LINKAGE __declspec(dllimport)
+#endif
+
+#define WINNET_API __stdcall
+
+typedef void (WINNET_API *WinNetErrorSink)(const char *errorMessage, void *context);
+
+enum class WINNET_ETM_STATUS : uint32_t
+{
+ METRIC_NO_CHANGE = 0,
+ METRIC_SET = 1,
+ FAILURE = 2,
+};
+
+extern "C"
+WINNET_LINKAGE
+WINNET_ETM_STATUS
+WINNET_API
+WinNet_EnsureTopMetric(
+ const wchar_t *deviceAlias,
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+);
+
+enum class WINNET_GTII_STATUS : uint32_t
+{
+ ENABLED = 0,
+ DISABLED = 1,
+ FAILURE = 2,
+};
+
+extern "C"
+WINNET_LINKAGE
+WINNET_GTII_STATUS
+WINNET_API
+WinNet_GetTapInterfaceIpv6Status(
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+);
+
+enum class WINNET_GTIA_STATUS : uint32_t
+{
+ SUCCESS = 0,
+ FAILURE = 1,
+};
+
+extern "C"
+WINNET_LINKAGE
+WINNET_GTIA_STATUS
+WINNET_API
+WinNet_GetTapInterfaceAlias(
+ wchar_t **alias,
+ WinNetErrorSink errorSink,
+ void* errorSinkContext
+);
+
+//
+// This is a companion function to the above function.
+// Generically named in case we need other functions here that return strings.
+//
+extern "C"
+WINNET_LINKAGE
+void
+WINNET_API
+WinNet_ReleaseString(
+ wchar_t *str
+);
diff --git a/windows/winroute/src/winroute/winroute.rc b/windows/winnet/src/winnet/winnet.rc
index 2da7924287..2da7924287 100644
--- a/windows/winroute/src/winroute/winroute.rc
+++ b/windows/winnet/src/winnet/winnet.rc
diff --git a/windows/winroute/src/winroute/winroute.vcxproj b/windows/winnet/src/winnet/winnet.vcxproj
index 09efb76938..e43b928d6c 100644
--- a/windows/winroute/src/winroute/winroute.vcxproj
+++ b/windows/winnet/src/winnet/winnet.vcxproj
@@ -21,28 +21,30 @@
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="InterfacePair.cpp" />
+ <ClCompile Include="interfaceutils.cpp" />
<ClCompile Include="NetworkInterfaces.cpp" />
<ClCompile Include="stdafx.cpp" />
- <ClCompile Include="winroute.cpp" />
+ <ClCompile Include="winnet.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="InterfacePair.h" />
+ <ClInclude Include="interfaceutils.h" />
<ClInclude Include="NetworkInterfaces.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
- <ClInclude Include="winroute.h" />
+ <ClInclude Include="winnet.h" />
</ItemGroup>
<ItemGroup>
- <None Include="winroute.def" />
+ <None Include="winnet.def" />
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="winroute.rc" />
+ <ResourceCompile Include="winnet.rc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
- <RootNamespace>winroute</RootNamespace>
+ <RootNamespace>winnet</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -116,7 +118,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>WIN32;_DEBUG;WINROUTE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>WIN32;_DEBUG;WINNET_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
@@ -125,7 +127,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <ModuleDefinitionFile>winroute.def</ModuleDefinitionFile>
+ <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
<AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
@@ -136,7 +138,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;WINROUTE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;WINNET_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
@@ -147,7 +149,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
- <ModuleDefinitionFile>winroute.def</ModuleDefinitionFile>
+ <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -158,7 +160,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>WIN32;NDEBUG;WINROUTE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;WINNET_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
@@ -169,7 +171,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <ModuleDefinitionFile>winroute.def</ModuleDefinitionFile>
+ <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
<AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
@@ -182,7 +184,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;WINROUTE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;WINNET_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
@@ -193,7 +195,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <ModuleDefinitionFile>winroute.def</ModuleDefinitionFile>
+ <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories>
<AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
diff --git a/windows/winroute/src/winroute/winroute.vcxproj.filters b/windows/winnet/src/winnet/winnet.vcxproj.filters
index 216502d069..2d320e7908 100644
--- a/windows/winroute/src/winroute/winroute.vcxproj.filters
+++ b/windows/winnet/src/winnet/winnet.vcxproj.filters
@@ -3,21 +3,23 @@
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="stdafx.cpp" />
- <ClCompile Include="winroute.cpp" />
+ <ClCompile Include="winnet.cpp" />
<ClCompile Include="NetworkInterfaces.cpp" />
<ClCompile Include="InterfacePair.cpp" />
+ <ClCompile Include="interfaceutils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
- <ClInclude Include="winroute.h" />
+ <ClInclude Include="winnet.h" />
<ClInclude Include="NetworkInterfaces.h" />
<ClInclude Include="InterfacePair.h" />
+ <ClInclude Include="interfaceutils.h" />
</ItemGroup>
<ItemGroup>
- <None Include="winroute.def" />
+ <None Include="winnet.def" />
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="winroute.rc" />
+ <ResourceCompile Include="winnet.rc" />
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/windows/winroute/winroute.sln b/windows/winnet/winnet.sln
index 28b21fc2f1..8d95777b4b 100644
--- a/windows/winroute/winroute.sln
+++ b/windows/winnet/winnet.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winroute", "src\winroute\winroute.vcxproj", "{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winnet", "src\winnet\winnet.vcxproj", "{89C5CDE8-04DB-4D9C-A8D8-7F786DAFB6D4}"
ProjectSection(ProjectDependencies) = postProject
{B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF}
EndProjectSection
diff --git a/windows/winroute/src/extras/loader/loader.cpp b/windows/winroute/src/extras/loader/loader.cpp
deleted file mode 100644
index cb775538f9..0000000000
--- a/windows/winroute/src/extras/loader/loader.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "stdafx.h"
-#include "../../winroute/winroute.h"
-
-int main()
-{
- const auto status = GetTapInterfaceIpv6Status(nullptr, nullptr);
-
- return 0;
-}
-
diff --git a/windows/winroute/src/winroute/winroute.cpp b/windows/winroute/src/winroute/winroute.cpp
deleted file mode 100644
index b9f10e3786..0000000000
--- a/windows/winroute/src/winroute/winroute.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "stdafx.h"
-#include "winroute.h"
-#include "NetworkInterfaces.h"
-#include "libcommon/error.h"
-#include <cstdint>
-#include <stdexcept>
-
-
-extern "C"
-WINROUTE_LINKAGE
-WINROUTE_STATUS
-WINROUTE_API
-WinRoute_EnsureTopMetric(
- const wchar_t *deviceAlias,
- WinRouteErrorSink errorSink,
- void* errorSinkContext
-) {
- try
- {
- NetworkInterfaces interfaces;
- bool metrics_set = interfaces.SetTopMetricForInterfacesByAlias(deviceAlias);
- return metrics_set ? WINROUTE_STATUS::METRIC_SET : WINROUTE_STATUS::METRIC_NO_CHANGE;
- }
- catch (std::exception &err)
- {
- if (nullptr != errorSink)
- {
- errorSink(err.what(), errorSinkContext);
- }
- return WINROUTE_STATUS::FAILURE;
-
- }
- catch (...)
- {
- return WINROUTE_STATUS::FAILURE;
- }
-};
-
-extern "C"
-WINROUTE_LINKAGE
-TAP_IPV6_STATUS
-WINROUTE_API
-GetTapInterfaceIpv6Status(
- WinRouteErrorSink errorSink,
- void* errorSinkContext
-)
-{
- try
- {
- MIB_IPINTERFACE_ROW interface = { 0 };
-
- interface.InterfaceLuid = NetworkInterfaces::GetInterfaceLuid(L"Mullvad");
- interface.Family = AF_INET6;
-
- const auto status = GetIpInterfaceEntry(&interface);
-
- if (NO_ERROR == status)
- {
- return TAP_IPV6_STATUS::ENABLED;
- }
-
- if (ERROR_NOT_FOUND == status)
- {
- return TAP_IPV6_STATUS::DISABLED;
- }
-
- common::error::Throw("Resolve TAP IPv6 interface", status);
- }
- catch (std::exception &err)
- {
- if (nullptr != errorSink)
- {
- errorSink(err.what(), errorSinkContext);
- }
-
- return TAP_IPV6_STATUS::FAILURE;
- }
- catch (...)
- {
- return TAP_IPV6_STATUS::FAILURE;
- }
-}
diff --git a/windows/winroute/src/winroute/winroute.def b/windows/winroute/src/winroute/winroute.def
deleted file mode 100644
index 2ea9222482..0000000000
--- a/windows/winroute/src/winroute/winroute.def
+++ /dev/null
@@ -1,4 +0,0 @@
-LIBRARY winroute
-EXPORTS
- WinRoute_EnsureTopMetric
- GetTapInterfaceIpv6Status
diff --git a/windows/winroute/src/winroute/winroute.h b/windows/winroute/src/winroute/winroute.h
deleted file mode 100644
index 6b500cee7e..0000000000
--- a/windows/winroute/src/winroute/winroute.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-#include <cstdint>
-
-#ifdef WINROUTE_EXPORTS
-#define WINROUTE_LINKAGE __declspec(dllexport)
-#else
-#define WINROUTE_LINKAGE __declspec(dllimport)
-#endif
-
-#define WINROUTE_API __stdcall
-
-typedef void (WINROUTE_API *WinRouteErrorSink)(const char *errorMessage, void *context);
-
-enum class WINROUTE_STATUS : uint32_t
-{
- METRIC_NO_CHANGE = 0,
- METRIC_SET = 1,
- FAILURE = 2,
-};
-
-
-extern "C"
-WINROUTE_LINKAGE
-WINROUTE_STATUS
-WINROUTE_API
-WinRoute_EnsureTopMetric(
- const wchar_t *deviceAlias,
- WinRouteErrorSink errorSink,
- void* errorSinkContext
-);
-
-enum class TAP_IPV6_STATUS : uint32_t
-{
- ENABLED = 0,
- DISABLED = 1,
- FAILURE = 2,
-};
-
-//
-// This has nothing to do with routing.
-// We should probably rename this module and use it to gather one-off network functions.
-//
-extern "C"
-WINROUTE_LINKAGE
-TAP_IPV6_STATUS
-WINROUTE_API
-GetTapInterfaceIpv6Status(
- WinRouteErrorSink errorSink,
- void* errorSinkContext
-);