Skip to content

Commit e1a194c

Browse files
committed
Add local SOCKS bridge test
1 parent 3f4d3f5 commit e1a194c

File tree

1 file changed

+105
-1
lines changed

1 file changed

+105
-1
lines changed

test/test-manager/src/tests/tunnel.rs

+105-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use mullvad_types::relay_constraints::{
1111
Udp2TcpObfuscationSettings, WireguardConstraints,
1212
};
1313
use mullvad_types::wireguard;
14+
use std::net::SocketAddr;
1415
use talpid_types::net::{
15-
proxy::{CustomProxy, Socks5Remote},
16+
proxy::{CustomProxy, Socks5Local, Socks5Remote},
1617
TransportProtocol, TunnelType,
1718
};
1819
use test_macro::test_function;
@@ -666,3 +667,106 @@ pub async fn test_remote_socks_bridge(
666667

667668
Ok(())
668669
}
670+
671+
/// Try to connect to an OpenVPN relay via a local, passwordless SOCKS5 server.
672+
/// * No outgoing traffic to the bridge/entry relay is observed from the SUT.
673+
/// * The conncheck reports an unexpected exit relay.
674+
#[test_function]
675+
pub async fn test_local_socks_bridge(
676+
_: TestContext,
677+
rpc: ServiceClient,
678+
mut mullvad_client: MullvadProxyClient,
679+
) -> Result<(), Error> {
680+
let remote_addr = SocketAddr::from((
681+
crate::vm::network::NON_TUN_GATEWAY,
682+
crate::vm::network::SOCKS5_PORT,
683+
));
684+
let socks_server = rpc
685+
.start_tcp_forward("127.0.0.1:0".parse().unwrap(), remote_addr)
686+
.await
687+
.expect("failed to start TCP forward");
688+
689+
mullvad_client
690+
.set_bridge_state(relay_constraints::BridgeState::On)
691+
.await
692+
.expect("failed to enable bridge mode");
693+
694+
mullvad_client
695+
.set_bridge_settings(BridgeSettings {
696+
bridge_type: BridgeType::Custom,
697+
normal: BridgeConstraints::default(),
698+
custom: Some(CustomProxy::Socks5Local(
699+
Socks5Local::new_with_transport_protocol(
700+
remote_addr,
701+
socks_server.bind_addr().port(),
702+
TransportProtocol::Tcp,
703+
),
704+
)),
705+
})
706+
.await
707+
.expect("failed to update bridge settings");
708+
709+
set_relay_settings(
710+
&mut mullvad_client,
711+
RelaySettings::Normal(RelayConstraints {
712+
tunnel_protocol: Constraint::Only(TunnelType::OpenVpn),
713+
..Default::default()
714+
}),
715+
)
716+
.await
717+
.expect("failed to update relay settings");
718+
719+
//
720+
// Connect to VPN
721+
//
722+
723+
connect_and_wait(&mut mullvad_client).await?;
724+
725+
let (entry, exit) = match mullvad_client.get_tunnel_state().await? {
726+
mullvad_types::states::TunnelState::Connected { endpoint, .. } => {
727+
(endpoint.proxy.unwrap().endpoint, endpoint.endpoint)
728+
}
729+
actual => {
730+
panic!("unexpected tunnel state. Expected `TunnelState::Connected` but got {actual:?}")
731+
}
732+
};
733+
734+
log::info!(
735+
"Selected entry bridge {entry_addr} & exit relay {exit_addr}",
736+
entry_addr = entry.address,
737+
exit_addr = exit.address
738+
);
739+
740+
// Start recording outgoing packets. Their destination will be verified
741+
// against the bridge's IP address later.
742+
let monitor = start_packet_monitor(
743+
move |packet| packet.destination.ip() == entry.address.ip(),
744+
MonitorOptions::default(),
745+
)
746+
.await;
747+
748+
//
749+
// Verify exit IP
750+
//
751+
752+
log::info!("Verifying exit server");
753+
754+
assert!(
755+
helpers::using_mullvad_exit(&rpc).await,
756+
"expected Mullvad exit IP"
757+
);
758+
759+
//
760+
// Verify entry IP
761+
//
762+
763+
log::info!("Verifying entry server");
764+
765+
let monitor_result = monitor.into_result().await.unwrap();
766+
assert!(
767+
!monitor_result.packets.is_empty(),
768+
"detected no traffic to entry server",
769+
);
770+
771+
Ok(())
772+
}

0 commit comments

Comments
 (0)