diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-08-21 14:06:08 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-08-22 20:24:38 +0200 |
| commit | b42d608e4f666c0d3cf020395db2e7b42963e6f2 (patch) | |
| tree | bb759418736f7a26d54e471fa52d3c5d312a72f9 /mullvad-daemon/src | |
| parent | 283d1eb046c1a36d35e1f924ca6a5b3006a9fd1d (diff) | |
| download | mullvadvpn-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/src')
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 21 | ||||
| -rw-r--r-- | mullvad-daemon/src/tunnel.rs | 39 |
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, + }, } |
