Skip to content

Commit

Permalink
Let relay selector pick entry & exit nodes in test_bridge
Browse files Browse the repository at this point in the history
We have seen `test_bridge` fail due to high latency if slow + far-away
servers were selected. Hopefully delegating the task of picking
appropriate entry & exit relays will help mitigate this.
  • Loading branch information
MarkusPettersson98 committed Nov 16, 2023
1 parent f82bb8c commit 04d0d6a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 68 deletions.
19 changes: 0 additions & 19 deletions test/test-manager/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,25 +449,6 @@ pub fn unreachable_wireguard_tunnel() -> talpid_types::net::wireguard::Connectio
}
}

/// Find a relay from the daemon's relay list that matches `critera`.
///
/// * `mullvad_client` - An interface to the Mullvad daemon.
/// * `critera` - A function used to determine which relays to include in random selection.
pub async fn relay<Filter>(
mullvad_client: &mut ManagementServiceClient,
criteria: Filter,
) -> Result<Relay, Error>
where
Filter: Fn(&Relay) -> bool,
{
filter_relays(mullvad_client, criteria)
.await?
.pop()
.ok_or(Error::Other(
"No mathing bridge was found in the relay list".to_string(),
))
}

/// Randomly select an entry and exit node from the daemon's relay list.
/// The exit node is distinct from the entry node.
///
Expand Down
94 changes: 45 additions & 49 deletions test/test-manager/src/tests/tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,90 +202,86 @@ pub async fn test_bridge(
rpc: ServiceClient,
mut mullvad_client: ManagementServiceClient,
) -> Result<(), Error> {
let entry = helpers::relay(&mut mullvad_client, |bridge| {
bridge.active && matches!(bridge.endpoint_data, RelayEndpointData::Bridge)
})
.await?;
let exit = helpers::relay(&mut mullvad_client, |relay| {
relay.active && matches!(relay.endpoint_data, RelayEndpointData::Openvpn)
})
.await?;

log::info!(
"Selected entry bridge {entry}:{entry_ip} & exit relay {exit}:{exit_ip}",
entry = entry.hostname,
entry_ip = entry.ipv4_addr_in.to_string(),
exit = exit.hostname,
exit_ip = exit.ipv4_addr_in.to_string()
);

//
// Enable bridge mode
//

log::info!("Updating bridge settings");

mullvad_client
.set_bridge_state(types::BridgeState::from(BridgeState::On))
.await
.expect("failed to enable bridge mode");

let bridge_settings = BridgeSettings::Normal(BridgeConstraints {
location: helpers::into_constraint(&entry),
..Default::default()
});

set_bridge_settings(&mut mullvad_client, bridge_settings)
.await
.expect("failed to update bridge settings");

let relay_settings = RelaySettings::Normal(RelayConstraints {
location: helpers::into_constraint(&exit),
tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
..Default::default()
});
set_bridge_settings(
&mut mullvad_client,
BridgeSettings::Normal(BridgeConstraints::default()),
)
.await
.expect("failed to update bridge settings");

set_relay_settings(&mut mullvad_client, relay_settings)
.await
.expect("failed to update relay settings");
set_relay_settings(
&mut mullvad_client,
RelaySettings::Normal(RelayConstraints {
tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
..Default::default()
}),
)
.await
.expect("failed to update relay settings");

//
// Connect to VPN
//

log::info!("Connect to OpenVPN relay via bridge");

connect_and_wait(&mut mullvad_client)
.await
.expect("connect_and_wait");

let tunnel = helpers::get_tunnel_state(&mut mullvad_client).await;
let (entry, exit) = match tunnel {
mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
(endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
}
_ => return Err(Error::DaemonError("daemon entered error state".to_string())),
};

log::info!(
"Selected entry bridge {entry_ip} & exit relay {exit_ip}",
entry_ip = entry.address.ip().to_string(),
exit_ip = exit.address.ip().to_string()
);

// Start recording outgoing packets. Their destination will be verified
// against the bridge's IP address later.
let monitor = start_packet_monitor(
move |packet| packet.destination.ip() == entry.ipv4_addr_in,
move |packet| packet.destination.ip() == entry.address.ip(),
MonitorOptions::default(),
)
.await;

connect_and_wait(&mut mullvad_client)
.await
.expect("connect_and_wait");

//
// Verify entry IP
// Verify exit IP
//

log::info!("Verifying entry server");
log::info!("Verifying exit server");

let monitor_result = monitor.into_result().await.unwrap();
assert!(
!monitor_result.packets.is_empty(),
"detected no traffic to entry server",
helpers::using_mullvad_exit(&rpc).await,
"expected Mullvad exit IP"
);

//
// Verify exit IP
// Verify entry IP
//

log::info!("Verifying exit server");
log::info!("Verifying entry server");

let monitor_result = monitor.into_result().await.unwrap();
assert!(
helpers::using_mullvad_exit(&rpc).await,
"expected Mullvad exit IP"
!monitor_result.packets.is_empty(),
"detected no traffic to entry server",
);

disconnect_and_wait(&mut mullvad_client).await?;
Expand Down

0 comments on commit 04d0d6a

Please sign in to comment.