summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian Holmin <sebastian.holmin@mullvad.net>2024-10-03 16:01:54 +0200
committerSebastian Holmin <sebastian.holmin@mullvad.net>2024-10-07 15:40:23 +0200
commit5d69b1dbd8c27e5e5c040bdc7050dae474f299c3 (patch)
tree5860d7bf966c64e2120c1331d9b00ab82c82a85c
parentadc7e44b69da58740bd5a18abbc267c319649714 (diff)
downloadmullvadvpn-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.rs36
-rw-r--r--mullvad-daemon/src/management_interface.rs2
-rw-r--r--mullvad-management-interface/proto/management_interface.proto1
-rw-r--r--mullvad-management-interface/src/types/conversions/features.rs8
-rw-r--r--mullvad-management-interface/src/types/conversions/wireguard.rs4
-rw-r--r--mullvad-relay-selector/src/relay_selector/mod.rs23
-rw-r--r--mullvad-relay-selector/src/relay_selector/query.rs15
-rw-r--r--mullvad-relay-selector/tests/relay_selector.rs20
-rw-r--r--mullvad-types/src/features.rs116
-rw-r--r--mullvad-types/src/wireguard.rs2
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