Skip to content

Commit

Permalink
Merge branch 'test_ui_tunnel_settings-fails-a-lot-des-1351'
Browse files Browse the repository at this point in the history
  • Loading branch information
Serock3 committed Nov 14, 2024
2 parents d4d0d48 + 90ee7b5 commit 7db530d
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ test('App should connect', async () => {

const relay = page.getByTestId('hostname-line');
const inIp = page.locator(':text("In") + span');
const outIp = page.locator(':text("Out") + div > span');
// If IPv6 is enabled, there will be two "Out" IPs, one for IPv4 and one for IPv6
// Selecting the first resolves to the IPv4 address regardless of the IP setting
const outIp = page.locator(':text("Out") + div > span').first();

await expect(relay).toHaveText(process.env.HOSTNAME!);
await expect(inIp).not.toBeVisible();
Expand Down
9 changes: 5 additions & 4 deletions mullvad-daemon/src/custom_list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{new_selector_config, Daemon, Error};
use crate::{Daemon, Error};
use mullvad_relay_selector::SelectorConfig;
use mullvad_types::{
constraints::Constraint,
custom_list::{CustomList, Id},
Expand Down Expand Up @@ -38,7 +39,7 @@ impl Daemon {

if let Ok(true) = settings_changed {
self.relay_selector
.set_config(new_selector_config(&self.settings));
.set_config(SelectorConfig::from_settings(&self.settings));

if self.change_should_cause_reconnect(Some(id)) {
log::info!("Initiating tunnel restart because a selected custom list was deleted");
Expand All @@ -65,7 +66,7 @@ impl Daemon {

if let Ok(true) = settings_changed {
self.relay_selector
.set_config(new_selector_config(&self.settings));
.set_config(SelectorConfig::from_settings(&self.settings));

if self.change_should_cause_reconnect(Some(list_id)) {
log::info!("Initiating tunnel restart because a selected custom list changed");
Expand All @@ -89,7 +90,7 @@ impl Daemon {

if let Ok(true) = settings_changed {
self.relay_selector
.set_config(new_selector_config(&self.settings));
.set_config(SelectorConfig::from_settings(&self.settings));

if self.change_should_cause_reconnect(None) {
log::info!("Initiating tunnel restart because a selected custom list was deleted");
Expand Down
40 changes: 3 additions & 37 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ use futures::{
};
use geoip::GeoIpHandler;
use management_interface::ManagementInterfaceServer;
use mullvad_relay_selector::{
AdditionalRelayConstraints, AdditionalWireguardConstraints, RelaySelector, SelectorConfig,
};
use mullvad_relay_selector::{RelaySelector, SelectorConfig};
#[cfg(target_os = "android")]
use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken};
#[cfg(any(windows, target_os = "android", target_os = "macos"))]
Expand Down Expand Up @@ -636,7 +634,7 @@ impl Daemon {
settings_event_listener.notify_settings(settings.to_owned());
});

let initial_selector_config = new_selector_config(&settings);
let initial_selector_config = SelectorConfig::from_settings(&settings);
let relay_selector = RelaySelector::new(
initial_selector_config,
resource_dir.join(RELAYS_FILENAME),
Expand All @@ -648,7 +646,7 @@ impl Daemon {
// Notify relay selector of changes to the settings/selector config
settings_relay_selector
.clone()
.set_config(new_selector_config(settings));
.set_config(SelectorConfig::from_settings(settings));
});

let (access_mode_handler, access_mode_provider) = api::AccessModeSelector::spawn(
Expand Down Expand Up @@ -3045,38 +3043,6 @@ impl DaemonShutdownHandle {
}
}

fn new_selector_config(settings: &Settings) -> SelectorConfig {
let additional_constraints = AdditionalRelayConstraints {
wireguard: AdditionalWireguardConstraints {
#[cfg(daita)]
daita: settings.tunnel_options.wireguard.daita.enabled,
#[cfg(daita)]
daita_use_multihop_if_necessary: settings
.tunnel_options
.wireguard
.daita
.use_multihop_if_necessary,

#[cfg(not(daita))]
daita: false,
#[cfg(not(daita))]
daita_use_multihop_if_necessary: false,

quantum_resistant: settings.tunnel_options.wireguard.quantum_resistant,
},
};

SelectorConfig {
relay_settings: settings.relay_settings.clone(),
additional_constraints,
bridge_state: settings.bridge_state,
bridge_settings: settings.bridge_settings.clone(),
obfuscation_settings: settings.obfuscation_settings.clone(),
custom_lists: settings.custom_lists.clone(),
relay_overrides: settings.relay_overrides.clone(),
}
}

/// Consume a oneshot sender of `T1` and return a sender that takes a different type `T2`.
/// `forwarder` should map `T1` back to `T2` and send the result back to the original receiver.
fn oneshot_map<T1: Send + 'static, T2: Send + 'static>(
Expand Down
2 changes: 1 addition & 1 deletion mullvad-relay-selector/src/relay_selector/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl<'a> ResolvedLocationConstraint<'a> {
ResolvedLocationConstraint(custom_list.locations.iter().collect())
})
.unwrap_or_else(|| {
log::warn!("Resolved non-existent custom list");
log::warn!("Resolved non-existent custom list with id {list_id:?}");
ResolvedLocationConstraint(vec![])
}),
}),
Expand Down
34 changes: 34 additions & 0 deletions mullvad-relay-selector/src/relay_selector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,40 @@ pub struct SelectorConfig {
pub bridge_settings: BridgeSettings,
}

impl SelectorConfig {
pub fn from_settings(settings: &Settings) -> Self {
let additional_constraints = AdditionalRelayConstraints {
wireguard: AdditionalWireguardConstraints {
#[cfg(daita)]
daita: settings.tunnel_options.wireguard.daita.enabled,
#[cfg(daita)]
daita_use_multihop_if_necessary: settings
.tunnel_options
.wireguard
.daita
.use_multihop_if_necessary,

#[cfg(not(daita))]
daita: false,
#[cfg(not(daita))]
daita_use_multihop_if_necessary: false,

quantum_resistant: settings.tunnel_options.wireguard.quantum_resistant,
},
};

Self {
relay_settings: settings.relay_settings.clone(),
additional_constraints,
bridge_state: settings.bridge_state,
bridge_settings: settings.bridge_settings.clone(),
obfuscation_settings: settings.obfuscation_settings.clone(),
custom_lists: settings.custom_lists.clone(),
relay_overrides: settings.relay_overrides.clone(),
}
}
}

/// Extra relay constraints not specified in `relay_settings`.
#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct AdditionalRelayConstraints {
Expand Down
20 changes: 17 additions & 3 deletions test/test-manager/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,10 @@ pub async fn constrain_to_relay(
}
}

let settings = mullvad_client.get_settings().await?;
// Construct a relay selector with up-to-date information from the runnin daemon's relay list
let relay_list = mullvad_client.get_relay_locations().await?;
let relay_selector = RelaySelector::from_list(SelectorConfig::default(), relay_list);
let relay_selector = get_daemon_relay_selector(&settings, relay_list);
// Select an(y) appropriate relay for the given query and constrain the daemon to only connect
// to that specific relay (when connecting).
let relay = relay_selector.get_relay_by_query(query.clone())?;
Expand All @@ -735,6 +736,17 @@ pub async fn constrain_to_relay(
Ok(exit)
}

/// Get a mirror of the relay selector used by the daemon.
///
/// This can be used to query the relay selector without triggering a tunnel state change in the
/// daemon.
fn get_daemon_relay_selector(
settings: &mullvad_types::settings::Settings,
relay_list: mullvad_types::relay_list::RelayList,
) -> RelaySelector {
RelaySelector::from_list(SelectorConfig::from_settings(settings), relay_list)
}

/// Convenience function for constructing a constraint from a given [`Relay`].
///
/// # Panics
Expand Down Expand Up @@ -1190,8 +1202,9 @@ pub mod custom_lists {
// Expose all custom list variants as a shorthand.
pub use List::*;

/// Mapping between [List] to daemon custom lists. Since custom list ids are assigned by the daemon at the creation
/// of the custom list settings object, we can't map a custom list name to a specific list before runtime.
/// Mapping between [List] to daemon custom lists. Since custom list ids are assigned by the
/// daemon at the creation of the custom list settings object, we can't map a custom list
/// name to a specific list before runtime.
static IDS: LazyLock<Mutex<HashMap<List, Id>>> = LazyLock::new(|| Mutex::new(HashMap::new()));

/// Pre-defined (well-typed) custom lists which may be useuful in different test scenarios.
Expand Down Expand Up @@ -1281,6 +1294,7 @@ pub mod custom_lists {
.create_custom_list(custom_list.name())
.await?;
let mut daemon_dito = find_custom_list(mullvad_client, &custom_list.name()).await?;
assert_eq!(id, daemon_dito.id);
for locations in custom_list.locations() {
daemon_dito.locations.insert(locations);
}
Expand Down
10 changes: 9 additions & 1 deletion test/test-manager/src/tests/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,19 @@ pub async fn test_ui_tunnel_settings(
rpc: ServiceClient,
mut mullvad_client: MullvadProxyClient,
) -> anyhow::Result<()> {
// NOTE: This test connects multiple times using various settings, some of which may cauase a
// significant increase in connection time, e.g. multihop and OpenVPN. For this reason, it is
// preferable to only target low latency servers.
use helpers::custom_lists::LowLatency;

// tunnel-state.spec precondition: a single WireGuard relay should be selected
log::info!("Select WireGuard relay");
let entry = helpers::constrain_to_relay(
&mut mullvad_client,
RelayQueryBuilder::new().wireguard().build(),
RelayQueryBuilder::new()
.wireguard()
.location(LowLatency)
.build(),
)
.await?;

Expand Down

0 comments on commit 7db530d

Please sign in to comment.