summaryrefslogtreecommitdiffhomepage
path: root/mullvad-daemon
diff options
context:
space:
mode:
authorSebastian Holmin <sebastian.holmin@mullvad.net>2024-08-21 14:06:08 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-08-22 20:24:38 +0200
commitb42d608e4f666c0d3cf020395db2e7b42963e6f2 (patch)
treebb759418736f7a26d54e471fa52d3c5d312a72f9 /mullvad-daemon
parent283d1eb046c1a36d35e1f924ca6a5b3006a9fd1d (diff)
downloadmullvadvpn-b42d608e4f666c0d3cf020395db2e7b42963e6f2.tar.xz
mullvadvpn-b42d608e4f666c0d3cf020395db2e7b42963e6f2.zip
Fix IP-override feature indicator
It was trigger by any overrides existing in the settings, not by the current endpoint being overridden. Add flag to `Relay` to specify if its IPv4 and/or IPv6 has been overridden and use that in combination with the endpoint IP version to derive if the current connection is overridden.
Diffstat (limited to 'mullvad-daemon')
-rw-r--r--mullvad-daemon/src/lib.rs21
-rw-r--r--mullvad-daemon/src/tunnel.rs39
2 files changed, 51 insertions, 9 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index cb1f489f11..926946dc7b 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -958,7 +958,7 @@ impl Daemon {
DeviceMigrationEvent(event) => self.handle_device_migration_event(event),
LocationEvent(location_data) => self.handle_location_event(location_data),
SettingsChanged => {
- self.update_feature_indicators_on_settings_changed();
+ self.update_feature_indicators_on_settings_changed().await;
}
#[cfg(any(windows, target_os = "android", target_os = "macos"))]
ExcludedPathsEvent(update, tx) => self.handle_new_excluded_paths(update, tx).await,
@@ -980,8 +980,11 @@ impl Daemon {
locked_down,
},
TunnelStateTransition::Connecting(endpoint) => {
- let feature_indicators =
- compute_feature_indicators(&self.settings.to_settings(), &endpoint);
+ let feature_indicators = compute_feature_indicators(
+ &self.settings.to_settings(),
+ &endpoint,
+ self.parameters_generator.last_relay_was_overridden().await,
+ );
TunnelState::Connecting {
endpoint,
location: self.parameters_generator.get_last_location().await,
@@ -989,8 +992,11 @@ impl Daemon {
}
}
TunnelStateTransition::Connected(endpoint) => {
- let feature_indicators =
- compute_feature_indicators(&self.settings.to_settings(), &endpoint);
+ let feature_indicators = compute_feature_indicators(
+ &self.settings.to_settings(),
+ &endpoint,
+ self.parameters_generator.last_relay_was_overridden().await,
+ );
TunnelState::Connected {
endpoint,
location: self.parameters_generator.get_last_location().await,
@@ -1129,7 +1135,7 @@ impl Daemon {
}
/// Update the set of feature indicators based on the new settings.
- fn update_feature_indicators_on_settings_changed(&mut self) {
+ async fn update_feature_indicators_on_settings_changed(&mut self) {
// Updated settings may affect the feature indicators, even if they don't change the tunnel
// state (e.g. activating lockdown mode). Note that only the connected and connecting states
// have feature indicators.
@@ -1144,8 +1150,9 @@ impl Daemon {
endpoint,
..
} => {
+ let ip_override = self.parameters_generator.last_relay_was_overridden().await;
let new_feature_indicators =
- compute_feature_indicators(&self.settings.to_settings(), endpoint);
+ compute_feature_indicators(&self.settings.to_settings(), endpoint, ip_override);
// Update and broadcast the new feature indicators if they have changed
if *feature_indicators != new_feature_indicators {
// Make sure to update the daemon's actual tunnel state. Otherwise, feature
diff --git a/mullvad-daemon/src/tunnel.rs b/mullvad-daemon/src/tunnel.rs
index 839f07e299..54bee64e7b 100644
--- a/mullvad-daemon/src/tunnel.rs
+++ b/mullvad-daemon/src/tunnel.rs
@@ -87,6 +87,22 @@ impl ParametersGenerator {
self.0.lock().await.tunnel_options = tunnel_options.clone();
}
+ pub async fn last_relay_was_overridden(&self) -> bool {
+ let inner = self.0.lock().await;
+ let Some(relays) = inner.last_generated_relays.as_ref() else {
+ return false;
+ };
+ match relays {
+ LastSelectedRelays::WireGuard {
+ server_override, ..
+ } => *server_override,
+ #[cfg(not(target_os = "android"))]
+ LastSelectedRelays::OpenVpn {
+ server_override, ..
+ } => *server_override,
+ }
+ }
+
/// Gets the location associated with the last generated tunnel parameters.
pub async fn get_last_location(&self) -> Option<GeoIpLocation> {
let inner = self.0.lock().await;
@@ -106,6 +122,7 @@ impl ParametersGenerator {
wg_entry: entry,
wg_exit: exit,
obfuscator,
+ ..
} => {
entry_hostname = take_hostname(entry);
hostname = exit.hostname.clone();
@@ -114,7 +131,7 @@ impl ParametersGenerator {
location = exit.location.as_ref().cloned().unwrap();
}
#[cfg(not(target_os = "android"))]
- LastSelectedRelays::OpenVpn { relay, bridge } => {
+ LastSelectedRelays::OpenVpn { relay, bridge, .. } => {
hostname = relay.hostname.clone();
bridge_hostname = take_hostname(bridge);
entry_hostname = None;
@@ -158,9 +175,15 @@ impl InnerParametersGenerator {
bridge,
} => {
let bridge_relay = bridge.as_ref().and_then(|bridge| bridge.relay());
+ let server_override = {
+ let first_relay = bridge_relay.unwrap_or(&exit);
+ (first_relay.overridden_ipv4 && endpoint.address.is_ipv4())
+ || (first_relay.overridden_ipv6 && endpoint.address.is_ipv6())
+ };
self.last_generated_relays = Some(LastSelectedRelays::OpenVpn {
relay: exit.clone(),
bridge: bridge_relay.cloned(),
+ server_override,
});
let bridge_settings = bridge.as_ref().map(|bridge| bridge.settings());
Ok(self.create_openvpn_tunnel_parameters(endpoint, data, bridge_settings.cloned()))
@@ -179,10 +202,17 @@ impl InnerParametersGenerator {
WireguardConfig::Singlehop { exit } => (None, exit),
WireguardConfig::Multihop { exit, entry } => (Some(entry), exit),
};
+ let server_override = {
+ let first_relay = wg_entry.as_ref().unwrap_or(&wg_exit);
+ (first_relay.overridden_ipv4 && endpoint.peer.endpoint.is_ipv4())
+ || (first_relay.overridden_ipv6 && endpoint.peer.endpoint.is_ipv6())
+ };
+
self.last_generated_relays = Some(LastSelectedRelays::WireGuard {
wg_entry,
wg_exit,
obfuscator: obfuscator_relay,
+ server_override,
});
Ok(self.create_wireguard_tunnel_parameters(endpoint, data, obfuscator_config))
@@ -315,10 +345,15 @@ enum LastSelectedRelays {
wg_entry: Option<Relay>,
wg_exit: Relay,
obfuscator: Option<Relay>,
+ server_override: bool,
},
/// Represents all relays generated for an OpenVPN tunnel.
/// The traffic flows like this:
/// client -> bridge -> relay -> internet
#[cfg(not(target_os = "android"))]
- OpenVpn { relay: Relay, bridge: Option<Relay> },
+ OpenVpn {
+ relay: Relay,
+ bridge: Option<Relay>,
+ server_override: bool,
+ },
}