summaryrefslogtreecommitdiffhomepage
path: root/test/test-manager
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2023-11-22 16:18:18 +0100
committerDavid Lönnhager <david.l@mullvad.net>2023-11-22 16:18:18 +0100
commitf7eb43c9170176a59019f5ba3eb5bed08c413058 (patch)
tree5e358a22218210c560c44006585cf411d1ddb23b /test/test-manager
parent6b0b627bc042da11496bd0ced8662557962572ef (diff)
parent56970baac0773952d2153dc0719faa1bc699ad91 (diff)
downloadmullvadvpn-f7eb43c9170176a59019f5ba3eb5bed08c413058.tar.xz
mullvadvpn-f7eb43c9170176a59019f5ba3eb5bed08c413058.zip
Merge branch 'fix-macos-tests' into main
Diffstat (limited to 'test/test-manager')
-rw-r--r--test/test-manager/src/tests/account.rs3
-rw-r--r--test/test-manager/src/tests/dns.rs84
-rw-r--r--test/test-manager/src/tests/helpers.rs69
-rw-r--r--test/test-manager/src/tests/install.rs10
-rw-r--r--test/test-manager/src/tests/mod.rs1
-rw-r--r--test/test-manager/src/tests/settings.rs42
-rw-r--r--test/test-manager/src/tests/tunnel.rs118
-rw-r--r--test/test-manager/src/tests/tunnel_state.rs67
8 files changed, 205 insertions, 189 deletions
diff --git a/test/test-manager/src/tests/account.rs b/test/test-manager/src/tests/account.rs
index 5b1991abb5..92c95346b2 100644
--- a/test/test-manager/src/tests/account.rs
+++ b/test/test-manager/src/tests/account.rs
@@ -107,12 +107,13 @@ pub async fn test_too_many_devices(
)
.await
.unwrap();
- assert!(ui_result.success());
if let Err(error) = clear_devices(&device_client).await {
log::error!("Failed to clear devices: {error}");
}
+ assert!(ui_result.success());
+
Ok(())
}
diff --git a/test/test-manager/src/tests/dns.rs b/test/test-manager/src/tests/dns.rs
index 310d5eb0dc..89755c3fd6 100644
--- a/test/test-manager/src/tests/dns.rs
+++ b/test/test-manager/src/tests/dns.rs
@@ -9,9 +9,12 @@ use mullvad_management_interface::{types, ManagementServiceClient};
use mullvad_types::{relay_constraints::RelaySettings, ConnectionConfig, CustomTunnelEndpoint};
use talpid_types::net::wireguard;
use test_macro::test_function;
-use test_rpc::{Interface, ServiceClient};
+use test_rpc::ServiceClient;
-use super::{helpers::connect_and_wait, Error, TestContext};
+use super::{
+ helpers::{self, connect_and_wait, set_relay_settings},
+ Error, TestContext,
+};
use crate::network_monitor::{
start_packet_monitor_until, start_tunnel_packet_monitor_until, Direction, IpHeaderProtocols,
MonitorOptions,
@@ -22,8 +25,6 @@ use crate::vm::network::{
CUSTOM_TUN_REMOTE_TUN_ADDR, NON_TUN_GATEWAY,
};
-use super::helpers::set_relay_settings;
-
/// How long to wait for expected "DNS queries" to appear
const MONITOR_TIMEOUT: Duration = Duration::from_secs(5);
@@ -47,7 +48,7 @@ pub async fn test_dns_leak_default(
leak_test_dns(
&rpc,
&mut mullvad_client,
- Interface::Tunnel,
+ true,
IpAddr::V4(CUSTOM_TUN_REMOTE_TUN_ADDR),
)
.await
@@ -82,7 +83,7 @@ pub async fn test_dns_leak_custom_public_ip(
.await
.expect("failed to configure DNS server");
- leak_test_dns(&rpc, &mut mullvad_client, Interface::Tunnel, CONFIG_IP).await
+ leak_test_dns(&rpc, &mut mullvad_client, true, CONFIG_IP).await
}
/// Test whether DNS leaks can be produced when using a custom private IP. This test succeeds if and
@@ -114,7 +115,7 @@ pub async fn test_dns_leak_custom_private_ip(
.await
.expect("failed to configure DNS server");
- leak_test_dns(&rpc, &mut mullvad_client, Interface::NonTunnel, CONFIG_IP).await
+ leak_test_dns(&rpc, &mut mullvad_client, false, CONFIG_IP).await
}
/// See whether it is possible to send "DNS queries" to a particular whitelisted destination on
@@ -124,11 +125,9 @@ pub async fn test_dns_leak_custom_private_ip(
async fn leak_test_dns(
rpc: &ServiceClient,
mullvad_client: &mut ManagementServiceClient,
- interface: Interface,
+ use_tun: bool,
whitelisted_dest: IpAddr,
) -> Result<(), Error> {
- let use_tun = interface == Interface::Tunnel;
-
//
// Connect to local wireguard relay
//
@@ -137,24 +136,32 @@ async fn leak_test_dns(
.await
.expect("failed to connect to custom wg relay");
- let guest_ip = rpc
- .get_interface_ip(Interface::NonTunnel)
+ let nontun_iface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to find non-tun interface");
+ let tunnel_iface = helpers::get_tunnel_interface(mullvad_client.clone())
+ .await
+ .expect("failed to find tunnel interface");
+
+ let nontun_ip = rpc
+ .get_interface_ip(nontun_iface.clone())
.await
.expect("failed to obtain guest IP");
let tunnel_ip = rpc
- .get_interface_ip(Interface::Tunnel)
+ .get_interface_ip(tunnel_iface.clone())
.await
.expect("failed to obtain tunnel IP");
log::debug!("Tunnel (guest) IP: {tunnel_ip}");
- log::debug!("Non-tunnel (guest) IP: {guest_ip}");
+ log::debug!("Non-tunnel (guest) IP: {nontun_ip}");
//
// Spoof DNS packets
//
let tun_bind_addr = SocketAddr::new(tunnel_ip, 0);
- let guest_bind_addr = SocketAddr::new(guest_ip, 0);
+ let nontun_bind_addr = SocketAddr::new(nontun_ip, 0);
let whitelisted_dest = SocketAddr::new(whitelisted_dest, 53);
let blocked_dest_local = "10.64.100.100:53".parse().unwrap();
@@ -216,40 +223,35 @@ async fn leak_test_dns(
// send to allowed dest
spoof_packets(
&rpc,
- Some(Interface::Tunnel),
+ Some(tunnel_iface.clone()),
tun_bind_addr,
whitelisted_dest,
),
spoof_packets(
&rpc,
- Some(Interface::NonTunnel),
- guest_bind_addr,
+ Some(nontun_iface.clone()),
+ nontun_bind_addr,
whitelisted_dest,
),
// send to blocked local dest
spoof_packets(
&rpc,
- Some(Interface::Tunnel),
+ Some(tunnel_iface.clone()),
tun_bind_addr,
blocked_dest_local,
),
spoof_packets(
&rpc,
- Some(Interface::NonTunnel),
- guest_bind_addr,
+ Some(nontun_iface.clone()),
+ nontun_bind_addr,
blocked_dest_local,
),
// send to blocked public dest
+ spoof_packets(&rpc, Some(tunnel_iface), tun_bind_addr, blocked_dest_public,),
spoof_packets(
&rpc,
- Some(Interface::Tunnel),
- tun_bind_addr,
- blocked_dest_public,
- ),
- spoof_packets(
- &rpc,
- Some(Interface::NonTunnel),
- guest_bind_addr,
+ Some(nontun_iface),
+ nontun_bind_addr,
blocked_dest_public,
),
)
@@ -578,17 +580,25 @@ async fn run_dns_config_test<
}
}
- let guest_ip = rpc
- .get_interface_ip(Interface::NonTunnel)
+ let nontun_iface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to find non-tun interface");
+ let tunnel_iface = helpers::get_tunnel_interface(mullvad_client.clone())
+ .await
+ .expect("failed to find tunnel interface");
+
+ let nontun_ip = rpc
+ .get_interface_ip(nontun_iface)
.await
.expect("failed to obtain guest IP");
let tunnel_ip = rpc
- .get_interface_ip(Interface::Tunnel)
+ .get_interface_ip(tunnel_iface)
.await
.expect("failed to obtain tunnel IP");
log::debug!("Tunnel (guest) IP: {tunnel_ip}");
- log::debug!("Non-tunnel (guest) IP: {guest_ip}");
+ log::debug!("Non-tunnel (guest) IP: {nontun_ip}");
let monitor = create_monitor().await;
@@ -661,19 +671,21 @@ async fn connect_local_wg_relay(mullvad_client: &mut ManagementServiceClient) ->
async fn spoof_packets(
rpc: &ServiceClient,
- interface: Option<Interface>,
+ interface: Option<String>,
bind_addr: SocketAddr,
dest: SocketAddr,
) {
let tcp_rpc = rpc.clone();
+ let tcp_interface = interface.clone();
let tcp_send = async move {
log::debug!("sending to {}/tcp from {}", dest, bind_addr);
- let _ = tcp_rpc.send_tcp(interface, bind_addr, dest).await;
+ let _ = tcp_rpc.send_tcp(tcp_interface, bind_addr, dest).await;
};
let udp_rpc = rpc.clone();
+ let udp_interface = interface.clone();
let udp_send = async move {
log::debug!("sending to {}/udp from {}", dest, bind_addr);
- let _ = udp_rpc.send_udp(interface, bind_addr, dest).await;
+ let _ = udp_rpc.send_udp(udp_interface, bind_addr, dest).await;
};
let _ = tokio::join!(tcp_send, udp_send);
}
diff --git a/test/test-manager/src/tests/helpers.rs b/test/test-manager/src/tests/helpers.rs
index ea876bbbbe..5b1c0a9903 100644
--- a/test/test-manager/src/tests/helpers.rs
+++ b/test/test-manager/src/tests/helpers.rs
@@ -1,7 +1,7 @@
use super::{config::TEST_CONFIG, Error, PING_TIMEOUT, WAIT_FOR_TUNNEL_STATE_TIMEOUT};
use crate::network_monitor::{start_packet_monitor, MonitorOptions};
use futures::StreamExt;
-use mullvad_management_interface::{types, ManagementServiceClient};
+use mullvad_management_interface::{types, ManagementServiceClient, MullvadProxyClient};
use mullvad_types::{
location::Location,
relay_constraints::{
@@ -19,7 +19,7 @@ use std::{
time::Duration,
};
use talpid_types::net::wireguard::{PeerConfig, PrivateKey, TunnelConfig};
-use test_rpc::{package::Package, AmIMullvad, Interface, ServiceClient};
+use test_rpc::{package::Package, AmIMullvad, ServiceClient};
use tokio::time::timeout;
#[macro_export]
@@ -82,17 +82,30 @@ pub async fn using_mullvad_exit(rpc: &ServiceClient) -> bool {
.mullvad_exit_ip
}
+/// Get VPN tunnel interface name
+pub async fn get_tunnel_interface(rpc: ManagementServiceClient) -> Option<String> {
+ let mut client = MullvadProxyClient::from_rpc_client(rpc);
+ match client.get_tunnel_state().await.ok()? {
+ TunnelState::Connecting { endpoint, .. } | TunnelState::Connected { endpoint, .. } => {
+ endpoint.tunnel_interface
+ }
+ _ => None,
+ }
+}
+
/// Sends a number of probes and returns the number of observed packets (UDP, TCP, or ICMP)
pub async fn send_guest_probes(
rpc: ServiceClient,
- interface: Option<Interface>,
+ interface: String,
destination: SocketAddr,
) -> Result<ProbeResult, Error> {
+ const MONITOR_DURATION: Duration = Duration::from_secs(8);
+
let pktmon = start_packet_monitor(
move |packet| packet.destination.ip() == destination.ip(),
MonitorOptions {
direction: Some(crate::network_monitor::Direction::In),
- timeout: Some(Duration::from_secs(3)),
+ timeout: Some(MONITOR_DURATION),
..Default::default()
},
)
@@ -100,7 +113,7 @@ pub async fn send_guest_probes(
let send_handle = tokio::spawn(send_guest_probes_without_monitor(
rpc,
- interface,
+ Some(interface),
destination,
));
@@ -132,12 +145,12 @@ pub async fn send_guest_probes(
/// Send one probe per transport protocol to `destination` without running a packet monitor
pub async fn send_guest_probes_without_monitor(
rpc: ServiceClient,
- interface: Option<Interface>,
+ interface: Option<String>,
destination: SocketAddr,
) {
- let bind_addr = if let Some(interface) = interface {
+ let bind_addr = if let Some(ref interface) = interface {
SocketAddr::new(
- rpc.get_interface_ip(interface)
+ rpc.get_interface_ip(interface.clone())
.await
.expect("failed to obtain interface IP"),
0,
@@ -147,9 +160,19 @@ pub async fn send_guest_probes_without_monitor(
};
let tcp_rpc = rpc.clone();
- let tcp_send = async move { tcp_rpc.send_tcp(interface, bind_addr, destination).await };
+ let tcp_interface = interface.clone();
+ let tcp_send = async move {
+ tcp_rpc
+ .send_tcp(tcp_interface, bind_addr, destination)
+ .await
+ };
let udp_rpc = rpc.clone();
- let udp_send = async move { udp_rpc.send_udp(interface, bind_addr, destination).await };
+ let udp_interface = interface.clone();
+ let udp_send = async move {
+ udp_rpc
+ .send_udp(udp_interface, bind_addr, destination)
+ .await
+ };
let icmp = async move { ping_with_timeout(&rpc, destination.ip(), interface).await };
let _ = tokio::join!(tcp_send, udp_send, icmp);
}
@@ -157,7 +180,7 @@ pub async fn send_guest_probes_without_monitor(
pub async fn ping_with_timeout(
rpc: &ServiceClient,
dest: IpAddr,
- interface: Option<Interface>,
+ interface: Option<String>,
) -> Result<(), Error> {
timeout(PING_TIMEOUT, rpc.send_ping(interface, dest))
.await
@@ -449,30 +472,6 @@ pub fn unreachable_wireguard_tunnel() -> talpid_types::net::wireguard::Connectio
}
}
-/// Randomly select an entry and exit node from the daemon's relay list.
-/// The exit node is distinct from the entry node.
-///
-/// * `mullvad_client` - An interface to the Mullvad daemon.
-/// * `critera` - A function used to determine which relays to include in random selection.
-pub async fn random_entry_and_exit<Filter>(
- mullvad_client: &mut ManagementServiceClient,
- criteria: Filter,
-) -> Result<(Relay, Relay), Error>
-where
- Filter: Fn(&Relay) -> bool,
-{
- use itertools::Itertools;
- // Pluck the first 2 relays and return them as a tuple.
- // This will fail if there are less than 2 relays in the relay list.
- filter_relays(mullvad_client, criteria)
- .await?
- .into_iter()
- .next_tuple()
- .ok_or(Error::Other(
- "failed to randomly select two relays from daemon's relay list".to_string(),
- ))
-}
-
/// Return a filtered version of the daemon's relay list.
///
/// * `mullvad_client` - An interface to the Mullvad daemon.
diff --git a/test/test-manager/src/tests/install.rs b/test/test-manager/src/tests/install.rs
index 04d401a22d..37a89f5fc8 100644
--- a/test/test-manager/src/tests/install.rs
+++ b/test/test-manager/src/tests/install.rs
@@ -11,7 +11,7 @@ use std::{
};
use test_macro::test_function;
use test_rpc::meta::Os;
-use test_rpc::{mullvad_daemon::ServiceStatus, Interface, ServiceClient};
+use test_rpc::{mullvad_daemon::ServiceStatus, ServiceClient};
/// Install the last stable version of the app and verify that it is running.
#[test_function(priority = -200)]
@@ -102,10 +102,14 @@ pub async fn test_upgrade_app(ctx: TestContext, rpc: ServiceClient) -> Result<()
// Begin monitoring outgoing traffic and pinging
//
+ let guest_iface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to obtain default interface");
let guest_ip = rpc
- .get_interface_ip(Interface::NonTunnel)
+ .get_interface_ip(guest_iface)
.await
- .expect("failed to obtain tunnel IP");
+ .expect("failed to obtain non-tun IP");
log::debug!("Guest IP: {guest_ip}");
log::debug!("Monitoring outgoing traffic");
diff --git a/test/test-manager/src/tests/mod.rs b/test/test-manager/src/tests/mod.rs
index b35f1b9b7a..ada613ca34 100644
--- a/test/test-manager/src/tests/mod.rs
+++ b/test/test-manager/src/tests/mod.rs
@@ -63,6 +63,7 @@ pub enum Error {
#[error(display = "Failed to parse gRPC response")]
InvalidGrpcResponse(#[error(source)] types::FromProtobufTypeError),
+ #[cfg(target_os = "macos")]
#[error(display = "An error occurred: {}", _0)]
Other(String),
}
diff --git a/test/test-manager/src/tests/settings.rs b/test/test-manager/src/tests/settings.rs
index 4c5808f790..aea81028fe 100644
--- a/test/test-manager/src/tests/settings.rs
+++ b/test/test-manager/src/tests/settings.rs
@@ -1,5 +1,5 @@
use super::helpers;
-use super::helpers::{connect_and_wait, disconnect_and_wait, get_tunnel_state, send_guest_probes};
+use super::helpers::{connect_and_wait, get_tunnel_state, send_guest_probes};
use super::{Error, TestContext};
use crate::assert_tunnel_state;
use crate::vm::network::DUMMY_LAN_INTERFACE_IP;
@@ -8,7 +8,7 @@ use mullvad_management_interface::ManagementServiceClient;
use mullvad_types::states::TunnelState;
use std::net::{IpAddr, SocketAddr};
use test_macro::test_function;
-use test_rpc::{Interface, ServiceClient};
+use test_rpc::ServiceClient;
/// Verify that traffic to private IPs is blocked when
/// "local network sharing" is disabled, but not blocked
@@ -46,11 +46,12 @@ pub async fn test_lan(
log::info!("Test whether outgoing LAN traffic is blocked");
+ let default_interface = rpc.get_default_interface().await?;
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface.clone(), lan_destination).await?;
assert!(
detected_probes.none(),
- "observed unexpected outgoing LAN packets"
+ "observed unexpected outgoing LAN packets: {detected_probes:?}"
);
//
@@ -71,14 +72,12 @@ pub async fn test_lan(
log::info!("Test whether outgoing LAN traffic is blocked");
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface, lan_destination).await?;
assert!(
detected_probes.all(),
- "did not observe all outgoing LAN packets"
+ "did not observe all outgoing LAN packets: {detected_probes:?}"
);
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}
@@ -133,15 +132,20 @@ pub async fn test_lockdown(
// Ensure all destinations are unreachable
//
+ let default_interface = rpc.get_default_interface().await?;
+
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination).await?;
- assert!(detected_probes.none(), "observed outgoing packets to LAN");
+ send_guest_probes(rpc.clone(), default_interface.clone(), lan_destination).await?;
+ assert!(
+ detected_probes.none(),
+ "observed outgoing packets to LAN: {detected_probes:?}"
+ );
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface.clone(), inet_destination).await?;
assert!(
detected_probes.none(),
- "observed outgoing packets to internet"
+ "observed outgoing packets to internet: {detected_probes:?}"
);
//
@@ -160,17 +164,17 @@ pub async fn test_lockdown(
//
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface.clone(), lan_destination).await?;
assert!(
detected_probes.all(),
- "did not observe some outgoing packets"
+ "did not observe some outgoing packets: {detected_probes:?}"
);
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface.clone(), inet_destination).await?;
assert!(
detected_probes.none(),
- "observed outgoing packets to internet"
+ "observed outgoing packets to internet: {detected_probes:?}"
);
//
@@ -191,10 +195,10 @@ pub async fn test_lockdown(
// Send traffic outside the tunnel to sanity check that the internet is *not* reachable via non-
// tunnel interfaces.
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination).await?;
+ send_guest_probes(rpc.clone(), default_interface, inet_destination).await?;
assert!(
detected_probes.none(),
- "observed outgoing packets to internet"
+ "observed outgoing packets to internet: {detected_probes:?}"
);
//
@@ -205,7 +209,5 @@ pub async fn test_lockdown(
.await
.expect("failed to disable lockdown mode");
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}
diff --git a/test/test-manager/src/tests/tunnel.rs b/test/test-manager/src/tests/tunnel.rs
index 1f1d61670e..6f759d7826 100644
--- a/test/test-manager/src/tests/tunnel.rs
+++ b/test/test-manager/src/tests/tunnel.rs
@@ -10,14 +10,13 @@ use mullvad_types::relay_constraints::{
OpenVpnConstraints, RelayConstraints, RelaySettings, SelectedObfuscation, TransportPort,
Udp2TcpObfuscationSettings, WireguardConstraints,
};
-use mullvad_types::relay_list::{Relay, RelayEndpointData};
use mullvad_types::wireguard;
use pnet_packet::ip::IpNextHeaderProtocols;
use talpid_types::net::{TransportProtocol, TunnelType};
use test_macro::test_function;
use test_rpc::meta::Os;
use test_rpc::mullvad_daemon::ServiceStatus;
-use test_rpc::{Interface, ServiceClient};
+use test_rpc::ServiceClient;
/// Set up an OpenVPN tunnel, UDP as well as TCP.
/// This test fails if a working tunnel cannot be set up.
@@ -123,18 +122,14 @@ pub async fn test_wireguard_tunnel(
Ok(())
}
-/// Use udp2tcp obfuscation. This test connects to a
-/// WireGuard relay over TCP. It fails if no outgoing TCP
-/// traffic to the relay is observed on the expected port.
+/// Use udp2tcp obfuscation. This test connects to a WireGuard relay over TCP. It fails if no
+/// outgoing TCP traffic to the relay is observed on the expected port.
#[test_function]
pub async fn test_udp2tcp_tunnel(
_: TestContext,
rpc: ServiceClient,
mut mullvad_client: ManagementServiceClient,
) -> Result<(), Error> {
- // TODO: check if src <-> target / tcp is observed (only)
- // TODO: ping a public IP on the fake network (not possible using real relay)
-
mullvad_client
.set_obfuscation_settings(types::ObfuscationSettings::from(ObfuscationSettings {
selected_obfuscation: SelectedObfuscation::Udp2Tcp,
@@ -158,18 +153,19 @@ pub async fn test_udp2tcp_tunnel(
connect_and_wait(&mut mullvad_client).await?;
+ let endpoint = match helpers::get_tunnel_state(&mut mullvad_client).await {
+ mullvad_types::states::TunnelState::Connected { endpoint, .. } => endpoint.endpoint,
+ _ => panic!("unexpected tunnel state"),
+ };
+
//
// Set up packet monitor
//
- let guest_ip = rpc
- .get_interface_ip(Interface::NonTunnel)
- .await
- .expect("failed to obtain inet interface IP");
-
let monitor = start_packet_monitor(
move |packet| {
- packet.source.ip() != guest_ip || (packet.protocol == IpNextHeaderProtocols::Tcp)
+ packet.destination.ip() == endpoint.address.ip()
+ && packet.protocol == IpNextHeaderProtocols::Tcp
},
MonitorOptions::default(),
)
@@ -185,9 +181,10 @@ pub async fn test_udp2tcp_tunnel(
);
let monitor_result = monitor.into_result().await.unwrap();
- assert_eq!(monitor_result.discarded_packets, 0);
-
- disconnect_and_wait(&mut mullvad_client).await?;
+ assert!(
+ !monitor_result.packets.is_empty(),
+ "detected no tcp traffic",
+ );
Ok(())
}
@@ -235,22 +232,19 @@ pub async fn test_bridge(
log::info!("Connect to OpenVPN relay via bridge");
- connect_and_wait(&mut mullvad_client)
- .await
- .expect("connect_and_wait");
+ connect_and_wait(&mut mullvad_client).await?;
- let tunnel = helpers::get_tunnel_state(&mut mullvad_client).await;
- let (entry, exit) = match tunnel {
+ let (entry, exit) = match helpers::get_tunnel_state(&mut mullvad_client).await {
mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
(endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
}
- _ => return Err(Error::DaemonError("daemon entered error state".to_string())),
+ _ => panic!("unexpected tunnel state"),
};
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()
+ "Selected entry bridge {entry_addr} & exit relay {exit_addr}",
+ entry_addr = entry.address,
+ exit_addr = exit.address
);
// Start recording outgoing packets. Their destination will be verified
@@ -284,14 +278,11 @@ pub async fn test_bridge(
"detected no traffic to entry server",
);
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}
/// Test whether WireGuard multihop works. This fails if:
-/// * No outgoing traffic to the entry relay is
-/// observed from the SUT.
+/// * No outgoing traffic to the entry relay is observed from the SUT.
/// * The conncheck reports an unexpected exit relay.
#[test_function]
pub async fn test_multihop(
@@ -299,24 +290,12 @@ pub async fn test_multihop(
rpc: ServiceClient,
mut mullvad_client: ManagementServiceClient,
) -> Result<(), Error> {
- //
- // Set relays to use
- //
-
- log::info!("Select relay");
- let relay_filter = |relay: &Relay| {
- relay.active && matches!(relay.endpoint_data, RelayEndpointData::Wireguard(_))
- };
- let (entry, exit) = helpers::random_entry_and_exit(&mut mullvad_client, relay_filter).await?;
- let exit_constraint = helpers::into_constraint(&exit);
let wireguard_constraints = WireguardConstraints {
use_multihop: true,
- entry_location: helpers::into_constraint(&entry),
..Default::default()
};
let relay_settings = RelaySettings::Normal(RelayConstraints {
- location: exit_constraint,
wireguard_constraints,
..Default::default()
});
@@ -329,25 +308,32 @@ pub async fn test_multihop(
// Connect
//
- let monitor = start_packet_monitor(
- move |packet| {
- packet.destination.ip() == entry.ipv4_addr_in
- && packet.protocol == IpNextHeaderProtocols::Udp
- },
- MonitorOptions::default(),
- )
- .await;
+ log::info!("Connect using WG multihop");
connect_and_wait(&mut mullvad_client).await?;
+ let (entry, exit) = match helpers::get_tunnel_state(&mut mullvad_client).await {
+ mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
+ (endpoint.entry_endpoint.unwrap(), endpoint.endpoint)
+ }
+ _ => panic!("unexpected tunnel state"),
+ };
+
+ log::info!(
+ "Selected entry {entry_addr} & exit relay {exit_addr}",
+ entry_addr = entry.address,
+ exit_addr = exit.address
+ );
+
//
- // Verify entry IP
+ // Record outgoing packets to the entry relay
//
- log::info!("Verifying entry server");
-
- let monitor_result = monitor.into_result().await.unwrap();
- assert!(!monitor_result.packets.is_empty(), "no matching packets",);
+ let monitor = start_packet_monitor(
+ move |packet| packet.destination.ip() == entry.address.ip(),
+ MonitorOptions::default(),
+ )
+ .await;
//
// Verify exit IP
@@ -358,7 +344,14 @@ pub async fn test_multihop(
"expected Mullvad exit IP"
);
- disconnect_and_wait(&mut mullvad_client).await?;
+ //
+ // Verify entry IP
+ //
+
+ log::info!("Verifying entry server");
+
+ let monitor_result = monitor.into_result().await.unwrap();
+ assert!(!monitor_result.packets.is_empty(), "no matching packets",);
Ok(())
}
@@ -473,7 +466,7 @@ pub async fn test_quantum_resistant_tunnel(
//
connect_and_wait(&mut mullvad_client).await?;
- check_tunnel_psk(&rpc, false).await;
+ check_tunnel_psk(&rpc, &mullvad_client, false).await;
log::info!("Setting tunnel protocol to WireGuard");
@@ -497,7 +490,7 @@ pub async fn test_quantum_resistant_tunnel(
//
connect_and_wait(&mut mullvad_client).await?;
- check_tunnel_psk(&rpc, true).await;
+ check_tunnel_psk(&rpc, &mullvad_client, true).await;
assert!(
helpers::using_mullvad_exit(&rpc).await,
@@ -507,11 +500,14 @@ pub async fn test_quantum_resistant_tunnel(
Ok(())
}
-async fn check_tunnel_psk(rpc: &ServiceClient, should_have_psk: bool) {
+async fn check_tunnel_psk(
+ rpc: &ServiceClient,
+ mullvad_client: &ManagementServiceClient,
+ should_have_psk: bool,
+) {
match rpc.get_os().await.expect("failed to get OS") {
Os::Linux => {
- let name = rpc
- .get_interface_name(Interface::Tunnel)
+ let name = helpers::get_tunnel_interface(mullvad_client.clone())
.await
.expect("failed to get tun name");
let output = rpc
diff --git a/test/test-manager/src/tests/tunnel_state.rs b/test/test-manager/src/tests/tunnel_state.rs
index 87fda3b685..eb78828fd0 100644
--- a/test/test-manager/src/tests/tunnel_state.rs
+++ b/test/test-manager/src/tests/tunnel_state.rs
@@ -1,6 +1,6 @@
use super::helpers::{
- self, connect_and_wait, disconnect_and_wait, get_tunnel_state, send_guest_probes,
- set_relay_settings, unreachable_wireguard_tunnel, wait_for_tunnel_state,
+ self, connect_and_wait, get_tunnel_state, send_guest_probes, set_relay_settings,
+ unreachable_wireguard_tunnel, wait_for_tunnel_state,
};
use super::{ui, Error, TestContext};
use crate::assert_tunnel_state;
@@ -17,7 +17,7 @@ use mullvad_types::{
use std::net::{IpAddr, SocketAddr};
use talpid_types::net::{Endpoint, TransportProtocol, TunnelEndpoint, TunnelType};
use test_macro::test_function;
-use test_rpc::{Interface, ServiceClient};
+use test_rpc::ServiceClient;
/// Verify that outgoing TCP, UDP, and ICMP packets can be observed
/// in the disconnected state. The purpose is mostly to rule prevent
@@ -40,8 +40,13 @@ pub async fn test_disconnected_state(
log::info!("Sending packets to {inet_destination}");
+ let non_tunnel_interface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to obtain non-tun interface");
+
let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination).await?;
+ send_guest_probes(rpc.clone(), non_tunnel_interface, inet_destination).await?;
assert!(
detected_probes.all(),
"did not see (all) outgoing packets to destination: {detected_probes:?}",
@@ -118,26 +123,31 @@ pub async fn test_connecting_state(
// Leak test
//
+ let non_tunnel_interface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to obtain non-tun interface");
+
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination)
+ send_guest_probes(rpc.clone(), non_tunnel_interface.clone(), inet_destination)
.await?
.none(),
"observed unexpected outgoing packets (inet)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination)
+ send_guest_probes(rpc.clone(), non_tunnel_interface.clone(), lan_destination)
.await?
.none(),
"observed unexpected outgoing packets (lan)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_dns)
+ send_guest_probes(rpc.clone(), non_tunnel_interface.clone(), inet_dns)
.await?
.none(),
"observed unexpected outgoing packets (DNS, inet)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_dns)
+ send_guest_probes(rpc.clone(), non_tunnel_interface, lan_dns)
.await?
.none(),
"observed unexpected outgoing packets (DNS, lan)"
@@ -145,14 +155,6 @@ pub async fn test_connecting_state(
assert_tunnel_state!(&mut mullvad_client, TunnelState::Connecting { .. });
- //
- // Disconnect
- //
-
- log::info!("Disconnecting");
-
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}
@@ -201,39 +203,36 @@ pub async fn test_error_state(
// Leak test
//
+ let default_interface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to obtain non-tun interface");
+
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination)
+ send_guest_probes(rpc.clone(), default_interface.clone(), inet_destination)
.await?
.none(),
"observed unexpected outgoing packets (inet)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_destination)
+ send_guest_probes(rpc.clone(), default_interface.clone(), lan_destination)
.await?
.none(),
"observed unexpected outgoing packets (lan)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_dns)
+ send_guest_probes(rpc.clone(), default_interface.clone(), inet_dns)
.await?
.none(),
"observed unexpected outgoing packets (DNS, inet)"
);
assert!(
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), lan_dns)
+ send_guest_probes(rpc.clone(), default_interface, lan_dns)
.await?
.none(),
"observed unexpected outgoing packets (DNS, lan)"
);
- //
- // Disconnect
- //
-
- log::info!("Disconnecting");
-
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}
@@ -318,11 +317,15 @@ pub async fn test_connected_state(
log::info!("Test whether outgoing non-tunnel traffic is blocked");
- let detected_probes =
- send_guest_probes(rpc.clone(), Some(Interface::NonTunnel), inet_destination).await?;
+ let nontun_iface = rpc
+ .get_default_interface()
+ .await
+ .expect("failed to find non-tun interface");
+
+ let detected_probes = send_guest_probes(rpc.clone(), nontun_iface, inet_destination).await?;
assert!(
detected_probes.none(),
- "observed unexpected outgoing packets"
+ "observed unexpected outgoing packets: {detected_probes:?}"
);
assert!(
@@ -330,7 +333,5 @@ pub async fn test_connected_state(
"expected Mullvad exit IP"
);
- disconnect_and_wait(&mut mullvad_client).await?;
-
Ok(())
}