summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-09-09 16:58:18 +0200
committerDavid Lönnhager <david.l@mullvad.net>2025-09-18 17:20:42 +0200
commit656871c71b5b5b957e6deacfef9cdd2856165408 (patch)
tree24adb47eb80af32360f488103102ed87f8c7b9f5
parent38302bd84da48c51a183ab3cbe23e429bd541a13 (diff)
downloadmullvadvpn-656871c71b5b5b957e6deacfef9cdd2856165408.tar.xz
mullvadvpn-656871c71b5b5b957e6deacfef9cdd2856165408.zip
Specify any number of relay endpoints in WinFw
-rw-r--r--talpid-core/src/firewall/windows/winfw/mod.rs2
-rw-r--r--talpid-core/src/firewall/windows/winfw/sys.rs6
-rw-r--r--windows/winfw/src/winfw/fwcontext.cpp22
-rw-r--r--windows/winfw/src/winfw/fwcontext.h4
-rw-r--r--windows/winfw/src/winfw/winfw.cpp64
-rw-r--r--windows/winfw/src/winfw/winfw.h10
6 files changed, 77 insertions, 31 deletions
diff --git a/talpid-core/src/firewall/windows/winfw/mod.rs b/talpid-core/src/firewall/windows/winfw/mod.rs
index 9a2d5a7c8a..adfff4e748 100644
--- a/talpid-core/src/firewall/windows/winfw/mod.rs
+++ b/talpid-core/src/firewall/windows/winfw/mod.rs
@@ -175,6 +175,7 @@ pub(super) fn apply_policy_connecting(
let res = unsafe {
WinFw_ApplyPolicyConnecting(
winfw_settings,
+ 1,
&winfw_relay,
exit_endpoint_ip_ptr,
relay_client_wstr_ptrs.as_ptr(),
@@ -255,6 +256,7 @@ pub(super) fn apply_policy_connected(
let result = unsafe {
WinFw_ApplyPolicyConnected(
winfw_settings,
+ 1,
&winfw_relay,
exit_endpoint_ip_ptr,
relay_client_wstr_ptrs.as_ptr(),
diff --git a/talpid-core/src/firewall/windows/winfw/sys.rs b/talpid-core/src/firewall/windows/winfw/sys.rs
index 40bb61599c..ca36823a10 100644
--- a/talpid-core/src/firewall/windows/winfw/sys.rs
+++ b/talpid-core/src/firewall/windows/winfw/sys.rs
@@ -131,7 +131,8 @@ unsafe extern "system" {
#[link_name = "WinFw_ApplyPolicyConnecting"]
pub fn WinFw_ApplyPolicyConnecting(
settings: &WinFwSettings,
- relay: &WinFwEndpoint,
+ numRelays: usize,
+ relays: &WinFwEndpoint,
exitEndpointIp: *const libc::wchar_t,
relayClient: *const *const libc::wchar_t,
relayClientLen: usize,
@@ -143,7 +144,8 @@ unsafe extern "system" {
#[link_name = "WinFw_ApplyPolicyConnected"]
pub fn WinFw_ApplyPolicyConnected(
settings: &WinFwSettings,
- relay: &WinFwEndpoint,
+ numRelays: usize,
+ relays: &WinFwEndpoint,
exitEndpointIp: *const libc::wchar_t,
relayClient: *const *const libc::wchar_t,
relayClientLen: usize,
diff --git a/windows/winfw/src/winfw/fwcontext.cpp b/windows/winfw/src/winfw/fwcontext.cpp
index dc0a38b304..69a79537cd 100644
--- a/windows/winfw/src/winfw/fwcontext.cpp
+++ b/windows/winfw/src/winfw/fwcontext.cpp
@@ -191,7 +191,7 @@ FwContext::FwContext
bool FwContext::applyPolicyConnecting
(
const WinFwSettings &settings,
- const WinFwEndpoint &relay,
+ const std::vector<WinFwEndpoint> &relays,
const std::optional<wfp::IpAddress> &exitEndpointIp,
const std::vector<std::wstring> &relayClients,
const std::optional<std::wstring> &tunnelInterfaceAlias,
@@ -203,7 +203,11 @@ bool FwContext::applyPolicyConnecting
AppendNetBlockedRules(ruleset);
AppendSettingsRules(ruleset, settings);
- AppendRelayRules(ruleset, relay, relayClients);
+
+ for (const auto &relay : relays)
+ {
+ AppendRelayRules(ruleset, relay, relayClients);
+ }
if (allowedEndpoint.has_value())
{
@@ -299,9 +303,9 @@ bool FwContext::applyPolicyConnecting
bool FwContext::applyPolicyConnected
(
const WinFwSettings &settings,
- const WinFwEndpoint &relay,
+ const std::vector<WinFwEndpoint> &relays,
const std::optional<wfp::IpAddress> &exitEndpointIp,
- const std::vector<std::wstring> &relayClient,
+ const std::vector<std::wstring> &relayClients,
const std::wstring &tunnelInterfaceAlias,
const std::vector<wfp::IpAddress> &tunnelDnsServers,
const std::vector<wfp::IpAddress> &nonTunnelDnsServers
@@ -311,7 +315,11 @@ bool FwContext::applyPolicyConnected
AppendNetBlockedRules(ruleset);
AppendSettingsRules(ruleset, settings);
- AppendRelayRules(ruleset, relay, relayClient);
+
+ for (const auto &relay : relays)
+ {
+ AppendRelayRules(ruleset, relay, relayClients);
+ }
if (!tunnelDnsServers.empty())
{
@@ -327,14 +335,14 @@ bool FwContext::applyPolicyConnected
}
ruleset.emplace_back(std::make_unique<baseline::PermitVpnTunnel>(
- relayClient,
+ relayClients,
tunnelInterfaceAlias,
std::nullopt,
exitEndpointIp
));
ruleset.emplace_back(std::make_unique<baseline::PermitVpnTunnelService>(
- relayClient,
+ relayClients,
tunnelInterfaceAlias,
std::nullopt,
exitEndpointIp
diff --git a/windows/winfw/src/winfw/fwcontext.h b/windows/winfw/src/winfw/fwcontext.h
index 8a4e4f0301..c8f3c2b4e5 100644
--- a/windows/winfw/src/winfw/fwcontext.h
+++ b/windows/winfw/src/winfw/fwcontext.h
@@ -27,7 +27,7 @@ public:
bool applyPolicyConnecting
(
const WinFwSettings &settings,
- const WinFwEndpoint &relay,
+ const std::vector<WinFwEndpoint> &relays,
const std::optional<wfp::IpAddress> &exitEndpointIp,
const std::vector<std::wstring> &relayClients,
const std::optional<std::wstring> &tunnelInterfaceAlias,
@@ -38,7 +38,7 @@ public:
bool applyPolicyConnected
(
const WinFwSettings &settings,
- const WinFwEndpoint &relay,
+ const std::vector<WinFwEndpoint> &relays,
const std::optional<wfp::IpAddress> &exitEndpointIp,
const std::vector<std::wstring> &relayClients,
const std::wstring &tunnelInterfaceAlias,
diff --git a/windows/winfw/src/winfw/winfw.cpp b/windows/winfw/src/winfw/winfw.cpp
index 064532235c..6d79bf8356 100644
--- a/windows/winfw/src/winfw/winfw.cpp
+++ b/windows/winfw/src/winfw/winfw.cpp
@@ -328,7 +328,8 @@ WINFW_POLICY_STATUS
WINFW_API
WinFw_ApplyPolicyConnecting(
const WinFwSettings *settings,
- const WinFwEndpoint *relay,
+ size_t numRelays,
+ const WinFwEndpoint *relays,
const wchar_t *exitEndpointIp,
const wchar_t **relayClients,
size_t relayClientsLen,
@@ -349,9 +350,14 @@ WinFw_ApplyPolicyConnecting(
THROW_ERROR("Invalid argument: settings");
}
- if (nullptr == relay)
+ if (nullptr == relays)
{
- THROW_ERROR("Invalid argument: relay");
+ THROW_ERROR("Invalid argument: relays");
+ }
+
+ if (0 == numRelays)
+ {
+ THROW_ERROR("Invalid argument: numRelays");
}
if (nullptr == allowedTunnelTraffic)
@@ -359,23 +365,33 @@ WinFw_ApplyPolicyConnecting(
THROW_ERROR("Invalid argument: allowedTunnelTraffic");
}
+ std::vector<WinFwEndpoint> relayEndpoints;
+ relayEndpoints.reserve(numRelays);
+ for (size_t i = 0; i < numRelays; i++)
+ {
+ relayEndpoints.push_back(relays[i]);
+ }
+
const auto exitIpAddr = (exitEndpointIp != nullptr) ? std::make_optional(wfp::IpAddress(exitEndpointIp)) : std::nullopt;
- const auto entryIpAddr = wfp::IpAddress(relay->ip);
- if (entryIpAddr == exitIpAddr)
+ for (const auto &entryEndpoint : relayEndpoints)
{
- THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp");
+ const auto ipAddr = wfp::IpAddress(entryEndpoint.ip);
+ if (ipAddr == exitIpAddr)
+ {
+ THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp");
+ }
}
std::vector<std::wstring> relayClientWstrings;
relayClientWstrings.reserve(relayClientsLen);
- for(int i = 0; i < relayClientsLen; i++) {
+ for (size_t i = 0; i < relayClientsLen; i++) {
relayClientWstrings.push_back(relayClients[i]);
}
return g_fwContext->applyPolicyConnecting(
*settings,
- *relay,
+ relayEndpoints,
exitIpAddr,
relayClientWstrings,
tunnelInterfaceAlias != nullptr ? std::make_optional(tunnelInterfaceAlias) : std::nullopt,
@@ -407,7 +423,8 @@ WINFW_POLICY_STATUS
WINFW_API
WinFw_ApplyPolicyConnected(
const WinFwSettings *settings,
- const WinFwEndpoint *relay,
+ size_t numRelays,
+ const WinFwEndpoint *relays,
const wchar_t *exitEndpointIp,
const wchar_t **relayClients,
size_t relayClientsLen,
@@ -430,9 +447,14 @@ WinFw_ApplyPolicyConnected(
THROW_ERROR("Invalid argument: settings");
}
- if (nullptr == relay)
+ if (nullptr == relays)
{
- THROW_ERROR("Invalid argument: relay");
+ THROW_ERROR("Invalid argument: relays");
+ }
+
+ if (0 == numRelays)
+ {
+ THROW_ERROR("Invalid argument: numRelays");
}
if (nullptr == tunnelInterfaceAlias)
@@ -450,12 +472,22 @@ WinFw_ApplyPolicyConnected(
THROW_ERROR("Invalid argument: nonTunnelDnsServers");
}
+ std::vector<WinFwEndpoint> relayEndpoints;
+ relayEndpoints.reserve(numRelays);
+ for (size_t i = 0; i < numRelays; i++)
+ {
+ relayEndpoints.push_back(relays[i]);
+ }
+
const auto exitIpAddr = (exitEndpointIp != nullptr) ? std::make_optional(wfp::IpAddress(exitEndpointIp)) : std::nullopt;
- const auto entryIpAddr = wfp::IpAddress(relay->ip);
- if (entryIpAddr == exitIpAddr)
+ for (const auto &entryEndpoint : relayEndpoints)
{
- THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp");
+ const auto ipAddr = wfp::IpAddress(entryEndpoint.ip);
+ if (ipAddr == exitIpAddr)
+ {
+ THROW_ERROR("Invalid argument: relay IP must not equal exitEndpointIp");
+ }
}
std::vector<wfp::IpAddress> convertedTunnelDnsServers;
@@ -499,13 +531,13 @@ WinFw_ApplyPolicyConnected(
std::vector<std::wstring> relayClientWstrings;
relayClientWstrings.reserve(relayClientsLen);
- for(int i = 0; i < relayClientsLen; i++) {
+ for (size_t i = 0; i < relayClientsLen; i++) {
relayClientWstrings.push_back(relayClients[i]);
}
return g_fwContext->applyPolicyConnected(
*settings,
- *relay,
+ relayEndpoints,
exitIpAddr,
relayClientWstrings,
tunnelInterfaceAlias,
diff --git a/windows/winfw/src/winfw/winfw.h b/windows/winfw/src/winfw/winfw.h
index f3e26ea4aa..f4cd3b4bca 100644
--- a/windows/winfw/src/winfw/winfw.h
+++ b/windows/winfw/src/winfw/winfw.h
@@ -159,7 +159,7 @@ enum WINFW_POLICY_STATUS
//
// Apply restrictions in the firewall that block all traffic, except:
// - What is specified by settings
-// - Communication with the relay server
+// - Communication with the relay server(s)
// - Specified in-tunnel traffic, except DNS.
//
// Parameters:
@@ -174,7 +174,8 @@ WINFW_POLICY_STATUS
WINFW_API
WinFw_ApplyPolicyConnecting(
const WinFwSettings *settings,
- const WinFwEndpoint *relay,
+ size_t numRelays,
+ const WinFwEndpoint *relays,
const wchar_t *exitEndpointIp,
const wchar_t **relayClient,
size_t relayClientLen,
@@ -188,7 +189,7 @@ WinFw_ApplyPolicyConnecting(
//
// Apply restrictions in the firewall that block all traffic, except:
// - What is specified by settings
-// - Communication with the relay server
+// - Communication with the relay server(s)
// - Non-DNS traffic inside the VPN tunnel
// - DNS requests inside the VPN tunnel to any server in 'tunnelDnsServers'
// - DNS requests outside the VPN tunnel to any server in 'nonTunnelDnsServers'
@@ -208,7 +209,8 @@ WINFW_POLICY_STATUS
WINFW_API
WinFw_ApplyPolicyConnected(
const WinFwSettings *settings,
- const WinFwEndpoint *relay,
+ size_t numRelays,
+ const WinFwEndpoint *relays,
const wchar_t *exitEndpointIp,
const wchar_t **relayClient,
size_t relayClientLen,