summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJoakim Hulthe <joakim.hulthe@mullvad.net>2024-08-12 17:28:53 +0200
committerJoakim Hulthe <joakim.hulthe@mullvad.net>2024-09-17 11:29:05 +0200
commit09f779cf14749e19cbc7c702ca3314376b06bcc3 (patch)
treebbcf6b345fa0e459b0610c4566495b4089c97f49
parent13af28efa7f73843327b017234640d2c58bbbeea (diff)
downloadmullvadvpn-09f779cf14749e19cbc7c702ca3314376b06bcc3.tar.xz
mullvadvpn-09f779cf14749e19cbc7c702ca3314376b06bcc3.zip
Add `use_anywhere` daita setting
-rw-r--r--mullvad-cli/src/cmds/tunnel.rs7
-rw-r--r--mullvad-daemon/src/lib.rs6
-rw-r--r--mullvad-management-interface/proto/management_interface.proto5
-rw-r--r--mullvad-management-interface/src/types/conversions/wireguard.rs2
-rw-r--r--mullvad-relay-selector/src/relay_selector/mod.rs56
-rw-r--r--mullvad-relay-selector/src/relay_selector/query.rs18
-rw-r--r--mullvad-types/src/wireguard.rs3
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