diff options
| author | Joakim Hulthe <joakim.hulthe@mullvad.net> | 2024-08-12 17:28:53 +0200 |
|---|---|---|
| committer | Joakim Hulthe <joakim.hulthe@mullvad.net> | 2024-09-17 11:29:05 +0200 |
| commit | 09f779cf14749e19cbc7c702ca3314376b06bcc3 (patch) | |
| tree | bbcf6b345fa0e459b0610c4566495b4089c97f49 | |
| parent | 13af28efa7f73843327b017234640d2c58bbbeea (diff) | |
| download | mullvadvpn-09f779cf14749e19cbc7c702ca3314376b06bcc3.tar.xz mullvadvpn-09f779cf14749e19cbc7c702ca3314376b06bcc3.zip | |
Add `use_anywhere` daita setting
| -rw-r--r-- | mullvad-cli/src/cmds/tunnel.rs | 7 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 6 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 5 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/wireguard.rs | 2 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/mod.rs | 56 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/query.rs | 18 | ||||
| -rw-r--r-- | mullvad-types/src/wireguard.rs | 3 |
7 files changed, 86 insertions, 11 deletions
diff --git a/mullvad-cli/src/cmds/tunnel.rs b/mullvad-cli/src/cmds/tunnel.rs index 0937cc8229..2464334cc6 100644 --- a/mullvad-cli/src/cmds/tunnel.rs +++ b/mullvad-cli/src/cmds/tunnel.rs @@ -196,8 +196,11 @@ impl Tunnel { #[cfg(daita)] if let Some(daita) = daita { - rpc.set_daita_settings(DaitaSettings { enabled: *daita }) - .await?; + rpc.set_daita_settings(DaitaSettings { + enabled: *daita, + use_anywhere: true, /* TODO */ + }) + .await?; println!("DAITA setting has been updated"); } diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index a25a835227..4a437e6e24 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -2931,8 +2931,14 @@ fn new_selector_config(settings: &Settings) -> SelectorConfig { wireguard: AdditionalWireguardConstraints { #[cfg(daita)] daita: settings.tunnel_options.wireguard.daita.enabled, + #[cfg(daita)] + daita_use_anywhere: settings.tunnel_options.wireguard.daita.use_anywhere, + #[cfg(not(daita))] daita: false, + #[cfg(not(daita))] + daita_use_anywhere: false, + quantum_resistant: settings.tunnel_options.wireguard.quantum_resistant, }, }; diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index e705c63788..4a7d46d003 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -541,7 +541,10 @@ message QuantumResistantState { State state = 1; } -message DaitaSettings { bool enabled = 1; } +message DaitaSettings { + bool enabled = 1; + bool use_anywhere = 2; +} message TunnelOptions { message OpenvpnOptions { optional uint32 mssfix = 1; } diff --git a/mullvad-management-interface/src/types/conversions/wireguard.rs b/mullvad-management-interface/src/types/conversions/wireguard.rs index b4e3bcaef7..cf30a8cc99 100644 --- a/mullvad-management-interface/src/types/conversions/wireguard.rs +++ b/mullvad-management-interface/src/types/conversions/wireguard.rs @@ -78,6 +78,7 @@ impl From<mullvad_types::wireguard::DaitaSettings> for proto::DaitaSettings { fn from(settings: mullvad_types::wireguard::DaitaSettings) -> Self { proto::DaitaSettings { enabled: settings.enabled, + use_anywhere: settings.use_anywhere, } } } @@ -87,6 +88,7 @@ impl From<proto::DaitaSettings> for mullvad_types::wireguard::DaitaSettings { fn from(settings: proto::DaitaSettings) -> Self { mullvad_types::wireguard::DaitaSettings { enabled: settings.enabled, + use_anywhere: settings.use_anywhere, } } } diff --git a/mullvad-relay-selector/src/relay_selector/mod.rs b/mullvad-relay-selector/src/relay_selector/mod.rs index dc495b05aa..45268a8eae 100644 --- a/mullvad-relay-selector/src/relay_selector/mod.rs +++ b/mullvad-relay-selector/src/relay_selector/mod.rs @@ -124,6 +124,11 @@ pub struct AdditionalWireguardConstraints { /// If true, select WireGuard relays that support DAITA. If false, select any /// server. pub daita: bool, + + /// If true and multihop is disabled, will set up multihop with an automatic entry relay if + /// DAITA is enabled. + pub daita_use_anywhere: bool, + /// If enabled, select relays that support PQ. pub quantum_resistant: QuantumResistantState, } @@ -345,6 +350,7 @@ impl<'a> TryFrom<NormalSelectorConfig<'a>> for RelayQuery { } = wireguard_constraints; let AdditionalWireguardConstraints { daita, + daita_use_anywhere, quantum_resistant, } = additional_constraints; WireguardRelayQuery { @@ -354,6 +360,7 @@ impl<'a> TryFrom<NormalSelectorConfig<'a>> for RelayQuery { entry_location, obfuscation: ObfuscationQuery::from(obfuscation_settings), daita: Constraint::Only(daita), + daita_use_anywhere: Constraint::Only(daita_use_anywhere), quantum_resistant, } } @@ -718,12 +725,61 @@ impl RelaySelector { parsed_relays: &ParsedRelays, ) -> Result<WireguardConfig, Error> { let candidates = filter_matching_relay_list(query, parsed_relays, custom_lists); + + // are we using daita? + let using_daita = || query.wireguard_constraints().daita == Constraint::Only(true); + + // is the `candidates` list empty because DAITA is enabled? + let no_relay_because_daita = || { + let mut query = query.clone(); + let mut wireguard_constraints = query.wireguard_constraints().clone(); + wireguard_constraints.daita = Constraint::Any; + query.set_wireguard_constraints(wireguard_constraints)?; + let candidates = filter_matching_relay_list(&query, parsed_relays, custom_lists); + Result::<_, Error>::Ok(!candidates.is_empty()) + }; + + // is `use_anywhere` enabled? + let use_anywhere = || { + query + .wireguard_constraints() + .daita_use_anywhere + .intersection(Constraint::Only(true)) + .is_some() + }; + + // if we found no matching relays because DAITA was enabled, and `use_anywhere` is enabled, + // try enabling multihop and connecting using an automatically selected entry relay. + if candidates.is_empty() && using_daita() && no_relay_because_daita()? && use_anywhere() { + return Self::get_wireguard_auto_multihop_config(query, custom_lists, parsed_relays); + } + helpers::pick_random_relay(&candidates) .cloned() .map(WireguardConfig::singlehop) .ok_or(Error::NoRelay) } + /// Select a valid Wireguard exit relay, together with with an automatically chosen entry relay. + /// + /// # Returns + /// * An `Err` if no entry/exit relay can be chosen + /// * `Ok(WireguardInner::Multihop)` otherwise + fn get_wireguard_auto_multihop_config( + query: &RelayQuery, + custom_lists: &CustomListsSettings, + parsed_relays: &ParsedRelays, + ) -> Result<WireguardConfig, Error> { + // Modify the query to enable multihop + let mut query = query.clone(); + let mut wireguard_constraints = query.wireguard_constraints().clone(); + wireguard_constraints.use_multihop = Constraint::Only(true); + wireguard_constraints.entry_location = Constraint::Any; // TODO: smarter location selection + query.set_wireguard_constraints(wireguard_constraints)?; + + Self::get_wireguard_multihop_config(&query, custom_lists, parsed_relays) + } + /// This function selects a valid entry and exit relay to be used in a multihop configuration. /// /// # Returns diff --git a/mullvad-relay-selector/src/relay_selector/query.rs b/mullvad-relay-selector/src/relay_selector/query.rs index 67fe43e2a3..cf9fc475ba 100644 --- a/mullvad-relay-selector/src/relay_selector/query.rs +++ b/mullvad-relay-selector/src/relay_selector/query.rs @@ -28,7 +28,7 @@ //! queries and ensure that queries are built in a type-safe manner, reducing the risk //! of runtime errors and improving code readability. -use crate::{AdditionalWireguardConstraints, Error}; +use crate::Error; use mullvad_types::{ constraints::Constraint, relay_constraints::{ @@ -261,6 +261,7 @@ pub struct WireguardRelayQuery { pub entry_location: Constraint<LocationConstraint>, pub obfuscation: ObfuscationQuery, pub daita: Constraint<bool>, + pub daita_use_anywhere: Constraint<bool>, pub quantum_resistant: QuantumResistantState, } @@ -346,6 +347,7 @@ impl WireguardRelayQuery { entry_location: Constraint::Any, obfuscation: ObfuscationQuery::Auto, daita: Constraint::Any, + daita_use_anywhere: Constraint::Any, quantum_resistant: QuantumResistantState::Auto, } } @@ -367,14 +369,14 @@ impl Default for WireguardRelayQuery { } } -impl From<WireguardRelayQuery> for AdditionalWireguardConstraints { - /// The mapping from [`WireguardRelayQuery`] to [`AdditionalWireguardConstraints`]. +impl From<WireguardRelayQuery> for WireguardConstraints { + /// The mapping from [`WireguardRelayQuery`] to [`WireguardConstraints`]. fn from(value: WireguardRelayQuery) -> Self { - AdditionalWireguardConstraints { - daita: value - .daita - .unwrap_or(AdditionalWireguardConstraints::default().daita), - quantum_resistant: value.quantum_resistant, + WireguardConstraints { + port: value.port, + ip_version: value.ip_version, + entry_location: value.entry_location, + use_multihop: value.use_multihop.unwrap_or(false), } } } diff --git a/mullvad-types/src/wireguard.rs b/mullvad-types/src/wireguard.rs index c920e9f0af..8f66657589 100644 --- a/mullvad-types/src/wireguard.rs +++ b/mullvad-types/src/wireguard.rs @@ -80,6 +80,9 @@ pub struct QuantumResistantStateParseError; #[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)] pub struct DaitaSettings { pub enabled: bool, + + #[serde(default)] + pub use_anywhere: bool, } /// Contains account specific wireguard data |
