summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-11-23 17:50:51 +0100
committerDavid Lönnhager <david.l@mullvad.net>2022-11-24 13:12:01 +0100
commitcb03e7b6c75f5beaff8aba1d51a26159931acde3 (patch)
treed7275af43b1dc826aa78377c1af57c4b0ef23120
parentba1e6301b8a638c9fc15233dfc889350c8a6f64c (diff)
downloadmullvadvpn-cb03e7b6c75f5beaff8aba1d51a26159931acde3.tar.xz
mullvadvpn-cb03e7b6c75f5beaff8aba1d51a26159931acde3.zip
Exclude obfuscation socket from the tunnel on Android
-rw-r--r--talpid-wireguard/src/lib.rs40
-rw-r--r--tunnel-obfuscation/src/lib.rs8
-rw-r--r--tunnel-obfuscation/src/udp2tcp.rs5
3 files changed, 48 insertions, 5 deletions
diff --git a/talpid-wireguard/src/lib.rs b/talpid-wireguard/src/lib.rs
index 89da37acb1..28e12e0238 100644
--- a/talpid-wireguard/src/lib.rs
+++ b/talpid-wireguard/src/lib.rs
@@ -121,11 +121,25 @@ const PSK_EXCHANGE_TIMEOUT_MULTIPLIER: u32 = 2;
/// Simple wrapper that automatically cancels the future which runs an obfuscator.
struct ObfuscatorHandle {
abort_handle: FutureAbortHandle,
+ #[cfg(target_os = "android")]
+ remote_socket_fd: std::os::unix::io::RawFd,
}
impl ObfuscatorHandle {
- pub fn new(abort_handle: FutureAbortHandle) -> Self {
- Self { abort_handle }
+ pub fn new(
+ abort_handle: FutureAbortHandle,
+ #[cfg(target_os = "android")] remote_socket_fd: std::os::unix::io::RawFd,
+ ) -> Self {
+ Self {
+ abort_handle,
+ #[cfg(target_os = "android")]
+ remote_socket_fd,
+ }
+ }
+
+ #[cfg(target_os = "android")]
+ pub fn remote_socket_fd(&self) -> std::os::unix::io::RawFd {
+ self.remote_socket_fd
}
pub fn abort(&self) {
@@ -172,8 +186,13 @@ async fn maybe_create_obfuscator(
.await
.map_err(Error::CreateObfuscatorError)?;
let endpoint = obfuscator.endpoint();
+
log::trace!("Patching first WireGuard peer to become {:?}", endpoint);
first_peer.endpoint = endpoint;
+
+ #[cfg(target_os = "android")]
+ let remote_socket_fd = obfuscator.remote_socket_fd();
+
let (runner, abort_handle) = abortable(async move {
match obfuscator.run().await {
Ok(_) => {
@@ -190,7 +209,11 @@ async fn maybe_create_obfuscator(
}
});
tokio::spawn(runner);
- return Ok(Some(ObfuscatorHandle::new(abort_handle)));
+ return Ok(Some(ObfuscatorHandle::new(
+ abort_handle,
+ #[cfg(target_os = "android")]
+ remote_socket_fd,
+ )));
}
}
}
@@ -230,7 +253,7 @@ impl WireguardMonitor {
&Self::patch_allowed_ips(&config, psk_negotiation.is_some()),
log_path,
args.resource_dir,
- args.tun_provider,
+ args.tun_provider.clone(),
#[cfg(target_os = "windows")]
args.route_manager.clone(),
#[cfg(target_os = "windows")]
@@ -238,6 +261,15 @@ impl WireguardMonitor {
)?;
let iface_name = tunnel.get_interface_name();
+ #[cfg(target_os = "android")]
+ if let Some(remote_socket_fd) = obfuscator.as_ref().map(|obfs| obfs.remote_socket_fd()) {
+ // Exclude remote obfuscation socket or bridge
+ log::debug!("Excluding remote socket fd from the tunnel");
+ if let Err(error) = args.tun_provider.lock().unwrap().bypass(remote_socket_fd) {
+ log::error!("Failed to exclude remote socket fd: {error}");
+ }
+ }
+
let event_callback = Box::new(on_event.clone());
let (pinger_tx, pinger_rx) = sync_mpsc::channel();
let monitor = WireguardMonitor {
diff --git a/tunnel-obfuscation/src/lib.rs b/tunnel-obfuscation/src/lib.rs
index c59fa284fd..07ab422dd7 100644
--- a/tunnel-obfuscation/src/lib.rs
+++ b/tunnel-obfuscation/src/lib.rs
@@ -18,8 +18,14 @@ pub enum Error {
#[async_trait]
pub trait Obfuscator: Send {
- fn endpoint(&self) -> SocketAddr;
async fn run(self: Box<Self>) -> Result<()>;
+
+ /// Returns the address of the local socket.
+ fn endpoint(&self) -> SocketAddr;
+
+ /// Returns the file descriptor of the outbound socket.
+ #[cfg(target_os = "android")]
+ fn remote_socket_fd(&self) -> std::os::unix::io::RawFd;
}
pub enum Settings {
diff --git a/tunnel-obfuscation/src/udp2tcp.rs b/tunnel-obfuscation/src/udp2tcp.rs
index a91bcb8085..386236b446 100644
--- a/tunnel-obfuscation/src/udp2tcp.rs
+++ b/tunnel-obfuscation/src/udp2tcp.rs
@@ -78,6 +78,11 @@ impl Obfuscator for Udp2Tcp {
.map_err(Error::RunObfuscator)
.map_err(crate::Error::RunUdp2TcpObfuscator)
}
+
+ #[cfg(target_os = "android")]
+ fn remote_socket_fd(&self) -> std::os::unix::io::RawFd {
+ self.instance.remote_tcp_fd()
+ }
}
pub async fn create_obfuscator(settings: &Udp2TcpSettings) -> Result<Box<dyn Obfuscator>> {