diff options
| author | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-10-03 16:01:54 +0200 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2024-10-07 15:40:23 +0200 |
| commit | 5d69b1dbd8c27e5e5c040bdc7050dae474f299c3 (patch) | |
| tree | 5860d7bf966c64e2120c1331d9b00ab82c82a85c | |
| parent | adc7e44b69da58740bd5a18abbc267c319649714 (diff) | |
| download | mullvadvpn-5d69b1dbd8c27e5e5c040bdc7050dae474f299c3.tar.xz mullvadvpn-5d69b1dbd8c27e5e5c040bdc7050dae474f299c3.zip | |
Replace `smart_routing` with `use_multihop_if_necessary` in daemon
Simplify the logic for feature indicators
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 36 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 2 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 1 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/features.rs | 8 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/wireguard.rs | 4 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/mod.rs | 23 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/query.rs | 15 | ||||
| -rw-r--r-- | mullvad-relay-selector/tests/relay_selector.rs | 20 | ||||
| -rw-r--r-- | mullvad-types/src/features.rs | 116 | ||||
| -rw-r--r-- | mullvad-types/src/wireguard.rs | 2 |
10 files changed, 145 insertions, 82 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index e833f1b82c..312e11d84f 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -266,7 +266,7 @@ pub enum DaemonCommand { #[cfg(daita)] SetEnableDaita(ResponseTx<(), settings::Error>, bool), #[cfg(daita)] - SetDaitaSmartRouting(ResponseTx<(), settings::Error>, bool), + SetDaitaUseMultihopIfNecessary(ResponseTx<(), settings::Error>, bool), #[cfg(daita)] SetDaitaSettings(ResponseTx<(), settings::Error>, DaitaSettings), /// Set DNS options or servers to use @@ -1261,7 +1261,9 @@ impl Daemon { #[cfg(daita)] SetEnableDaita(tx, value) => self.on_set_daita_enabled(tx, value).await, #[cfg(daita)] - SetDaitaSmartRouting(tx, value) => self.on_set_daita_smart_routing(tx, value).await, + SetDaitaUseMultihopIfNecessary(tx, value) => { + self.on_set_daita_use_multihop_if_necessary(tx, value).await + } #[cfg(daita)] SetDaitaSettings(tx, daita_settings) => { self.on_set_daita_settings(tx, daita_settings).await @@ -2344,9 +2346,13 @@ impl Daemon { .update(|settings| { settings.tunnel_options.wireguard.daita.enabled = value; - // enable smart-routing automatically with daita + // enable 'use_multihop_if_necessary' automatically with daita if cfg!(not(target_os = "android")) { - settings.tunnel_options.wireguard.daita.smart_routing = value + settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary = value } }) .await; @@ -2376,7 +2382,7 @@ impl Daemon { } #[cfg(daita)] - async fn on_set_daita_smart_routing( + async fn on_set_daita_use_multihop_if_necessary( &mut self, tx: ResponseTx<(), settings::Error>, value: bool, @@ -2385,11 +2391,17 @@ impl Daemon { match self .settings - .update(|settings| settings.tunnel_options.wireguard.daita.smart_routing = value) + .update(|settings| { + settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary = value + }) .await { Ok(settings_changed) => { - Self::oneshot_send(tx, Ok(()), "set_daita_smart_routing response"); + Self::oneshot_send(tx, Ok(()), "set_daita_use_multihop_if_necessary response"); let RelaySettings::Normal(constraints) = &self.settings.relay_settings else { return; // DAITA is not supported for custom relays @@ -2410,7 +2422,7 @@ impl Daemon { } Err(e) => { log::error!("{}", e.display_chain_with_msg("Unable to save settings")); - Self::oneshot_send(tx, Err(e), "set_daita_smart_routing response"); + Self::oneshot_send(tx, Err(e), "set_daita_use_multihop_if_necessary response"); } } } @@ -3024,12 +3036,16 @@ fn new_selector_config(settings: &Settings) -> SelectorConfig { #[cfg(daita)] daita: settings.tunnel_options.wireguard.daita.enabled, #[cfg(daita)] - daita_smart_routing: settings.tunnel_options.wireguard.daita.smart_routing, + daita_use_multihop_if_necessary: settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary, #[cfg(not(daita))] daita: false, #[cfg(not(daita))] - daita_smart_routing: false, + daita_use_multihop_if_necessary: false, quantum_resistant: settings.tunnel_options.wireguard.quantum_resistant, }, diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index b52c214a01..36aa168962 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -356,7 +356,7 @@ impl ManagementService for ManagementServiceImpl { let value = request.into_inner(); log::debug!("set_daita_smart_routing({value})"); let (tx, rx) = oneshot::channel(); - self.send_command_to_daemon(DaemonCommand::SetDaitaSmartRouting(tx, value))?; + self.send_command_to_daemon(DaemonCommand::SetDaitaUseMultihopIfNecessary(tx, value))?; self.wait_for_result(rx).await?.map(Response::new)?; Ok(Response::new(())) } diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index 70d9e1ad2b..9b946d24db 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -264,7 +264,6 @@ enum FeatureIndicator { CUSTOM_MTU = 11; CUSTOM_MSS_FIX = 12; DAITA = 13; - DAITA_SMART_ROUTING = 14; } message ObfuscationEndpoint { diff --git a/mullvad-management-interface/src/types/conversions/features.rs b/mullvad-management-interface/src/types/conversions/features.rs index 85c85b8b77..0471421891 100644 --- a/mullvad-management-interface/src/types/conversions/features.rs +++ b/mullvad-management-interface/src/types/conversions/features.rs @@ -17,8 +17,8 @@ impl From<mullvad_types::features::FeatureIndicator> for proto::FeatureIndicator mullvad_types::features::FeatureIndicator::ServerIpOverride => ServerIpOverride, mullvad_types::features::FeatureIndicator::CustomMtu => CustomMtu, mullvad_types::features::FeatureIndicator::CustomMssFix => CustomMssFix, - mullvad_types::features::FeatureIndicator::Daita => Daita, - mullvad_types::features::FeatureIndicator::DaitaSmartRouting => DaitaSmartRouting, + mullvad_types::features::FeatureIndicator::DaitaDirectOnly => Daita, + mullvad_types::features::FeatureIndicator::Daita => DaitaSmartRouting, } } } @@ -39,8 +39,8 @@ impl From<proto::FeatureIndicator> for mullvad_types::features::FeatureIndicator proto::FeatureIndicator::ServerIpOverride => Self::ServerIpOverride, proto::FeatureIndicator::CustomMtu => Self::CustomMtu, proto::FeatureIndicator::CustomMssFix => Self::CustomMssFix, - proto::FeatureIndicator::Daita => Self::Daita, - proto::FeatureIndicator::DaitaSmartRouting => Self::DaitaSmartRouting, + proto::FeatureIndicator::Daita => Self::DaitaDirectOnly, + proto::FeatureIndicator::DaitaSmartRouting => Self::Daita, } } } diff --git a/mullvad-management-interface/src/types/conversions/wireguard.rs b/mullvad-management-interface/src/types/conversions/wireguard.rs index 9e40b4b526..c6bf643664 100644 --- a/mullvad-management-interface/src/types/conversions/wireguard.rs +++ b/mullvad-management-interface/src/types/conversions/wireguard.rs @@ -78,7 +78,7 @@ impl From<mullvad_types::wireguard::DaitaSettings> for proto::DaitaSettings { fn from(settings: mullvad_types::wireguard::DaitaSettings) -> Self { proto::DaitaSettings { enabled: settings.enabled, - smart_routing: settings.smart_routing, + smart_routing: settings.use_multihop_if_necessary, } } } @@ -88,7 +88,7 @@ impl From<proto::DaitaSettings> for mullvad_types::wireguard::DaitaSettings { fn from(settings: proto::DaitaSettings) -> Self { mullvad_types::wireguard::DaitaSettings { enabled: settings.enabled, - smart_routing: settings.smart_routing, + use_multihop_if_necessary: settings.smart_routing, } } } diff --git a/mullvad-relay-selector/src/relay_selector/mod.rs b/mullvad-relay-selector/src/relay_selector/mod.rs index 6233e2da05..b94a5812a0 100644 --- a/mullvad-relay-selector/src/relay_selector/mod.rs +++ b/mullvad-relay-selector/src/relay_selector/mod.rs @@ -126,7 +126,7 @@ pub struct AdditionalWireguardConstraints { /// If true and multihop is disabled, will set up multihop with an automatic entry relay if /// DAITA is enabled. - pub daita_smart_routing: bool, + pub daita_use_multihop_if_necessary: bool, /// If enabled, select relays that support PQ. pub quantum_resistant: QuantumResistantState, @@ -349,7 +349,7 @@ impl<'a> TryFrom<NormalSelectorConfig<'a>> for RelayQuery { } = wireguard_constraints; let AdditionalWireguardConstraints { daita, - daita_smart_routing, + daita_use_multihop_if_necessary, quantum_resistant, } = additional_constraints; WireguardRelayQuery { @@ -359,7 +359,7 @@ impl<'a> TryFrom<NormalSelectorConfig<'a>> for RelayQuery { entry_location, obfuscation: ObfuscationQuery::from(obfuscation_settings), daita: Constraint::Only(daita), - daita_smart_routing: Constraint::Only(daita_smart_routing), + daita_use_multihop_if_necessary: Constraint::Only(daita_use_multihop_if_necessary), quantum_resistant, } } @@ -738,18 +738,23 @@ impl RelaySelector { Result::<_, Error>::Ok(!candidates.is_empty()) }; - // is `smart_routing` enabled? - let smart_routing = || { + // is `use_multihop_if_necessary` enabled? + let use_multihop_if_necessary = || { query .wireguard_constraints() - .daita_smart_routing + .daita_use_multihop_if_necessary .intersection(Constraint::Only(true)) .is_some() }; - // if we found no matching relays because DAITA was enabled, and `smart_routing` is enabled, - // try enabling multihop and connecting using an automatically selected entry relay. - if candidates.is_empty() && using_daita() && no_relay_because_daita()? && smart_routing() { + // if we found no matching relays because DAITA was enabled, and `use_multihop_if_necessary` + // is enabled, try enabling multihop and connecting using an automatically selected + // entry relay. + if candidates.is_empty() + && using_daita() + && no_relay_because_daita()? + && use_multihop_if_necessary() + { return Self::get_wireguard_auto_multihop_config(query, custom_lists, parsed_relays); } diff --git a/mullvad-relay-selector/src/relay_selector/query.rs b/mullvad-relay-selector/src/relay_selector/query.rs index 2dc81b0833..570a2212cb 100644 --- a/mullvad-relay-selector/src/relay_selector/query.rs +++ b/mullvad-relay-selector/src/relay_selector/query.rs @@ -268,7 +268,7 @@ pub struct WireguardRelayQuery { pub entry_location: Constraint<LocationConstraint>, pub obfuscation: ObfuscationQuery, pub daita: Constraint<bool>, - pub daita_smart_routing: Constraint<bool>, + pub daita_use_multihop_if_necessary: Constraint<bool>, pub quantum_resistant: QuantumResistantState, } @@ -354,7 +354,7 @@ impl WireguardRelayQuery { entry_location: Constraint::Any, obfuscation: ObfuscationQuery::Auto, daita: Constraint::Any, - daita_smart_routing: Constraint::Any, + daita_use_multihop_if_necessary: Constraint::Any, quantum_resistant: QuantumResistantState::Auto, } } @@ -673,9 +673,14 @@ pub mod builder { impl<Multihop, Obfuscation, QuantumResistant> RelayQueryBuilder<Wireguard<Multihop, Obfuscation, bool, QuantumResistant>> { - /// Enable DAITA smart routing. - pub fn daita_smart_routing(mut self, constraint: impl Into<Constraint<bool>>) -> Self { - self.query.wireguard_constraints.daita_smart_routing = constraint.into(); + /// Enable DAITA 'use_multihop_if_necessary'. + pub fn daita_use_multihop_if_necessary( + mut self, + constraint: impl Into<Constraint<bool>>, + ) -> Self { + self.query + .wireguard_constraints + .daita_use_multihop_if_necessary = constraint.into(); self } } diff --git a/mullvad-relay-selector/tests/relay_selector.rs b/mullvad-relay-selector/tests/relay_selector.rs index dc05d04eb2..1ce69b0591 100644 --- a/mullvad-relay-selector/tests/relay_selector.rs +++ b/mullvad-relay-selector/tests/relay_selector.rs @@ -1451,7 +1451,7 @@ fn test_daita() { let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(false) + .daita_use_multihop_if_necessary(false) .build(); let relay = unwrap_entry_relay(relay_selector.get_relay_by_query(query).unwrap()); assert!( @@ -1463,23 +1463,23 @@ fn test_daita() { let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(false) + .daita_use_multihop_if_necessary(false) .location(NON_DAITA_RELAY_LOCATION.clone()) .build(); relay_selector .get_relay_by_query(query) .expect_err("Expected to find no matching relay"); - // Should be able to connect to non-DAITA relay with smart_routing + // Should be able to connect to non-DAITA relay with use_multihop_if_necessary let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(true) + .daita_use_multihop_if_necessary(true) .location(NON_DAITA_RELAY_LOCATION.clone()) .build(); let relay = relay_selector .get_relay_by_query(query) - .expect("Expected to find a relay with daita_smart_routing"); + .expect("Expected to find a relay with daita_use_multihop_if_necessary"); match relay { GetRelay::Wireguard { inner: WireguardConfig::Multihop { exit, entry }, @@ -1493,16 +1493,16 @@ fn test_daita() { ), } - // Should be able to connect to DAITA relay with smart_routing + // Should be able to connect to DAITA relay with use_multihop_if_necessary let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(true) + .daita_use_multihop_if_necessary(true) .location(DAITA_RELAY_LOCATION.clone()) .build(); let relay = relay_selector .get_relay_by_query(query) - .expect("Expected to find a relay with daita_smart_routing"); + .expect("Expected to find a relay with daita_use_multihop_if_necessary"); match relay { GetRelay::Wireguard { inner: WireguardConfig::Singlehop { exit }, @@ -1537,7 +1537,7 @@ fn test_daita() { let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(false) + .daita_use_multihop_if_necessary(false) .multihop() .build(); let relay = relay_selector.get_relay_by_query(query).unwrap(); @@ -1557,7 +1557,7 @@ fn test_daita() { let query = RelayQueryBuilder::new() .wireguard() .daita() - .daita_smart_routing(false) + .daita_use_multihop_if_necessary(false) .multihop() .location(NON_DAITA_RELAY_LOCATION.clone()) .build(); diff --git a/mullvad-types/src/features.rs b/mullvad-types/src/features.rs index ba40e42d18..6f4ea1e9cc 100644 --- a/mullvad-types/src/features.rs +++ b/mullvad-types/src/features.rs @@ -1,6 +1,9 @@ use std::{collections::HashSet, fmt::Display}; -use crate::settings::{DnsState, Settings}; +use crate::{ + relay_constraints::RelaySettings, + settings::{DnsState, Settings}, +}; use serde::{Deserialize, Serialize}; use talpid_types::net::{ObfuscationType, TunnelEndpoint, TunnelType}; @@ -65,14 +68,7 @@ pub enum FeatureIndicator { ServerIpOverride, CustomMtu, CustomMssFix, - - /// Whether DAITA (without smart routing) is in use. - /// Mutually exclusive with [FeatureIndicator::DaitaSmartRouting]. Daita, - - /// Whether DAITA (with smart routing) is in use. - /// Mutually exclusive with [FeatureIndicator::Daita]. - DaitaSmartRouting, } impl FeatureIndicator { @@ -92,7 +88,6 @@ impl FeatureIndicator { FeatureIndicator::CustomMtu => "Custom MTU", FeatureIndicator::CustomMssFix => "Custom MSS", FeatureIndicator::Daita => "DAITA", - FeatureIndicator::DaitaSmartRouting => "DAITA: Smart Routing", } } } @@ -165,28 +160,37 @@ pub fn compute_feature_indicators( let mtu = settings.tunnel_options.wireguard.mtu.is_some(); - let mut daita_smart_routing = false; - let mut multihop = false; + let mut daita = false; + let mut multihop = endpoint.entry_endpoint.is_some(); - if let crate::relay_constraints::RelaySettings::Normal(constraints) = - &settings.relay_settings - { - multihop = endpoint.entry_endpoint.is_some() - && constraints.wireguard_constraints.use_multihop; + #[cfg(daita)] + if endpoint.daita { + daita = true; - #[cfg(daita)] - { - // Detect whether we're using "smart_routing" by checking if multihop is - // in use but not explicitly enabled. - daita_smart_routing = endpoint.daita - && endpoint.entry_endpoint.is_some() - && !constraints.wireguard_constraints.use_multihop - } - }; + let multihop_setting_enabled = + if let RelaySettings::Normal(constraints) = &settings.relay_settings { + constraints.wireguard_constraints.use_multihop + } else { + false + }; - // Daita is mutually exclusive with DaitaSmartRouting - #[cfg(daita)] - let daita = endpoint.daita && !daita_smart_routing; + let daita_use_multihop_if_necessary = settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary; + + // If multihop is disabled in the settings, but enabled automatically by DAITA, we + // will not show the multihop indicator. + let multihop_enable_automatically = multihop && !multihop_setting_enabled; + if multihop_enable_automatically { + debug_assert!( + daita_use_multihop_if_necessary, + "Multihop can only be enabled automatically if DAITA is enabled" + ); + multihop = false; + } + } vec![ (quantum_resistant, FeatureIndicator::QuantumResistance), @@ -194,9 +198,7 @@ pub fn compute_feature_indicators( (udp_tcp, FeatureIndicator::Udp2Tcp), (shadowsocks, FeatureIndicator::Shadowsocks), (mtu, FeatureIndicator::CustomMtu), - #[cfg(daita)] (daita, FeatureIndicator::Daita), - (daita_smart_routing, FeatureIndicator::DaitaSmartRouting), ] } }; @@ -328,13 +330,18 @@ mod tests { expected_indicators ); + if let RelaySettings::Normal(constraints) = &mut settings.relay_settings { + constraints.wireguard_constraints.use_multihop = true; + }; + assert_eq!( + compute_feature_indicators(&settings, &endpoint, false), + expected_indicators, + "The multihop feature indicator should be enabled by the endpoint, not the settings" + ); endpoint.entry_endpoint = Some(Endpoint { address: SocketAddr::from(([1, 2, 3, 4], 443)), protocol: TransportProtocol::Tcp, }); - if let RelaySettings::Normal(constraints) = &mut settings.relay_settings { - constraints.wireguard_constraints.use_multihop = true; - }; expected_indicators.0.insert(FeatureIndicator::Multihop); assert_eq!( compute_feature_indicators(&settings, &endpoint, false), @@ -370,25 +377,57 @@ mod tests { #[cfg(daita)] { + // Multihop and DAITA on endpoint.daita = true; + settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary = true; + expected_indicators.0.insert(FeatureIndicator::Daita); assert_eq!( compute_feature_indicators(&settings, &endpoint, false), expected_indicators ); + // Should not change regardless of whether `use_multihop_if_necessary` is true, since + // multihop is enabled explicitly + settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary = false; + assert_eq!( + compute_feature_indicators(&settings, &endpoint, false), + expected_indicators, + ); + + // Here we mock that multihop was automatically enabled by DAITA. + // We enable `use_multihop_if_necessary` again and disable the multihop setting, while + // keeping the entry relay In this scenario, we should not get a Multihop + // indicator + settings + .tunnel_options + .wireguard + .daita + .use_multihop_if_necessary = true; if let RelaySettings::Normal(constraints) = &mut settings.relay_settings { constraints.wireguard_constraints.use_multihop = false; }; - expected_indicators - .0 - .insert(FeatureIndicator::DaitaSmartRouting); - expected_indicators.0.remove(&FeatureIndicator::Daita); expected_indicators.0.remove(&FeatureIndicator::Multihop); assert_eq!( compute_feature_indicators(&settings, &endpoint, false), expected_indicators, - "DaitaSmartRouting should be enabled" + "DaitaDirectOnly should be enabled" + ); + + // If we also remove the entry relay, we should still not get a multihop indicator + endpoint.entry_endpoint = None; + assert_eq!( + compute_feature_indicators(&settings, &endpoint, false), + expected_indicators, + "DaitaDirectOnly should be enabled" ); } @@ -409,7 +448,6 @@ mod tests { FeatureIndicator::CustomMtu => {} FeatureIndicator::CustomMssFix => {} FeatureIndicator::Daita => {} - FeatureIndicator::DaitaSmartRouting => {} } } } diff --git a/mullvad-types/src/wireguard.rs b/mullvad-types/src/wireguard.rs index c6ec6cec5f..77ed60e1b2 100644 --- a/mullvad-types/src/wireguard.rs +++ b/mullvad-types/src/wireguard.rs @@ -86,7 +86,7 @@ pub struct DaitaSettings { pub enabled: bool, #[serde(default)] - pub smart_routing: bool, + pub use_multihop_if_necessary: bool, } /// Contains account specific wireguard data |
