summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-06-07 15:16:31 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-06-14 13:59:49 +0200
commitf3acffca0c5da48c854658a19d11eed4104036b0 (patch)
tree8ca38b0a72ebc231b891c244faf52ebb11f9899f /talpid-core/src
parent463042e83845efd09f61cd99feb65db58240bb32 (diff)
downloadmullvadvpn-f3acffca0c5da48c854658a19d11eed4104036b0.tar.xz
mullvadvpn-f3acffca0c5da48c854658a19d11eed4104036b0.zip
Track excluded processes and add CLI command for listing them on Windows
Diffstat (limited to 'talpid-core/src')
-rw-r--r--talpid-core/src/split_tunnel/windows/mod.rs60
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs15
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs6
7 files changed, 100 insertions, 1 deletions
diff --git a/talpid-core/src/split_tunnel/windows/mod.rs b/talpid-core/src/split_tunnel/windows/mod.rs
index 5b5b29e0cc..8b679106ea 100644
--- a/talpid-core/src/split_tunnel/windows/mod.rs
+++ b/talpid-core/src/split_tunnel/windows/mod.rs
@@ -12,15 +12,17 @@ use crate::{
};
use futures::channel::{mpsc, oneshot};
use std::{
+ collections::HashMap,
convert::TryFrom,
ffi::{OsStr, OsString},
io, mem,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
os::windows::io::{AsRawHandle, RawHandle},
+ path::{Path, PathBuf},
ptr,
sync::{
atomic::{AtomicBool, Ordering},
- mpsc as sync_mpsc, Arc, Mutex, Weak,
+ mpsc as sync_mpsc, Arc, Mutex, RwLock, Weak,
},
time::Duration,
};
@@ -102,6 +104,7 @@ pub struct SplitTunnel {
request_tx: RequestTx,
event_thread: Option<std::thread::JoinHandle<()>>,
quit_event: Arc<QuitEvent>,
+ excluded_pids: Arc<RwLock<HashMap<usize, ExcludedProcess>>>,
_route_change_callback: Option<WinNetCallbackHandle>,
daemon_tx: Weak<mpsc::UnboundedSender<TunnelCommand>>,
async_path_update_in_progress: Arc<AtomicBool>,
@@ -148,10 +151,23 @@ struct InterfaceAddresses {
internet_ipv6: Option<Ipv6Addr>,
}
+/// Represents a process that is being excluded from the tunnel.
+#[derive(Debug, Clone)]
+pub struct ExcludedProcess {
+ /// Process identifier.
+ pub pid: u32,
+ /// Path to the image that this process is an instance of.
+ pub image: PathBuf,
+ /// If true, then the process is split because its parent was split,
+ /// not due to its path being in the config.
+ pub inherited: bool,
+}
+
struct EventThreadContext {
handle: Arc<driver::DeviceHandle>,
event_overlapped: OVERLAPPED,
quit_event: Arc<QuitEvent>,
+ excluded_pids: Arc<RwLock<HashMap<usize, ExcludedProcess>>>,
}
unsafe impl Send for EventThreadContext {}
@@ -172,11 +188,13 @@ impl SplitTunnel {
}
let quit_event = Arc::new(QuitEvent::new());
+ let excluded_pids = Arc::new(RwLock::new(HashMap::new()));
let event_context = EventThreadContext {
handle: handle.clone(),
event_overlapped,
quit_event: quit_event.clone(),
+ excluded_pids: excluded_pids.clone(),
};
let event_thread = std::thread::spawn(move || {
@@ -291,6 +309,34 @@ impl SplitTunnel {
reason,
image,
} => {
+ let mut pids = event_context.excluded_pids.write().unwrap();
+ match event_id {
+ EventId::StartSplittingProcess => {
+ if let Some(prev_entry) = pids.get(&process_id) {
+ log::error!("PID collision: {process_id} is already in the list of excluded processes. New image: {:?}. Current image: {:?}", image, prev_entry);
+ }
+ pids.insert(
+ process_id,
+ ExcludedProcess {
+ pid: u32::try_from(process_id)
+ .expect("PID should be containable in a DWORD"),
+ image: Path::new(&image).to_path_buf(),
+ inherited: reason.contains(
+ driver::SplittingChangeReason::BY_INHERITANCE,
+ ),
+ },
+ );
+ }
+ EventId::StopSplittingProcess => {
+ if pids.remove(&process_id).is_none() {
+ log::error!(
+ "Inconsistent process tree: {process_id} was not found"
+ );
+ }
+ }
+ _ => (),
+ }
+
log::trace!(
"{}:\n\tpid: {}\n\treason: {:?}\n\timage: {:?}",
event_str,
@@ -326,6 +372,7 @@ impl SplitTunnel {
_route_change_callback: None,
daemon_tx,
async_path_update_in_progress: Arc::new(AtomicBool::new(false)),
+ excluded_pids,
})
}
@@ -562,6 +609,17 @@ impl SplitTunnel {
self._route_change_callback = None;
self.send_request(Request::RegisterIps(InterfaceAddresses::default()))
}
+
+ /// Return processes that are currently being excluded.
+ pub fn get_processes(&self) -> Result<Vec<ExcludedProcess>, Error> {
+ Ok(self
+ .excluded_pids
+ .read()
+ .unwrap()
+ .values()
+ .cloned()
+ .collect())
+ }
}
impl Drop for SplitTunnel {
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index 80e5e28957..beb29590c1 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -277,6 +277,11 @@ impl ConnectedState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
SameState(self.into())
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ SameState(self.into())
+ }
}
}
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 7536b26b09..64d21086cd 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -390,6 +390,11 @@ impl ConnectingState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
SameState(self.into())
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ SameState(self.into())
+ }
}
}
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index fa91284f6b..281b22b8f2 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -208,6 +208,11 @@ impl TunnelState for DisconnectedState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
SameState(self.into())
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ SameState(self.into())
+ }
None => {
Self::reset_dns(shared_values);
Finished
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index 2a14d881d6..2c42a1a864 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -57,6 +57,11 @@ impl DisconnectingState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
AfterDisconnect::Nothing
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ AfterDisconnect::Nothing
+ }
},
AfterDisconnect::Block(reason) => match command {
Some(TunnelCommand::AllowLan(allow_lan)) => {
@@ -97,6 +102,11 @@ impl DisconnectingState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
AfterDisconnect::Block(reason)
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ AfterDisconnect::Block(reason)
+ }
None => AfterDisconnect::Block(reason),
},
AfterDisconnect::Reconnect(retry_attempt) => match command {
@@ -138,6 +148,11 @@ impl DisconnectingState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
AfterDisconnect::Reconnect(retry_attempt)
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ AfterDisconnect::Reconnect(retry_attempt)
+ }
},
};
diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs
index a11e49d859..d64393a432 100644
--- a/talpid-core/src/tunnel_state_machine/error_state.rs
+++ b/talpid-core/src/tunnel_state_machine/error_state.rs
@@ -209,6 +209,11 @@ impl TunnelState for ErrorState {
shared_values.split_tunnel.set_paths(&paths, result_tx);
SameState(self.into())
}
+ #[cfg(windows)]
+ Some(TunnelCommand::GetExcludedProcesses(result_tx)) => {
+ let _ = result_tx.send(shared_values.split_tunnel.get_processes());
+ SameState(self.into())
+ }
}
}
}
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 6c388a4680..42d20181a4 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -189,6 +189,12 @@ pub enum TunnelCommand {
oneshot::Sender<Result<(), split_tunnel::Error>>,
Vec<OsString>,
),
+ /// Return a list of processes that are currently being split, as well as their
+ /// paths.
+ #[cfg(windows)]
+ GetExcludedProcesses(
+ oneshot::Sender<Result<Vec<split_tunnel::ExcludedProcess>, split_tunnel::Error>>,
+ ),
}
type TunnelCommandReceiver = stream::Fuse<mpsc::UnboundedReceiver<TunnelCommand>>;