summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mullvad-daemon/src/main.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index 7ec19da7bd..3479a231a1 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -41,6 +41,7 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex, mpsc};
use std::thread;
+use talpid_core::firewall::{Firewall, FirewallProxy, SecurityPolicy};
use talpid_core::mpsc::IntoSender;
use talpid_core::net::{Endpoint, TransportProtocol};
use talpid_core::tunnel::{self, TunnelEvent, TunnelMonitor};
@@ -60,6 +61,9 @@ error_chain!{
description("Error in the management interface")
display("Management interface error: {}", msg)
}
+ FirewallError {
+ description("Firewall error")
+ }
InvalidSettings(msg: &'static str) {
description("Invalid settings")
display("Invalid Settings: {}", msg)
@@ -147,6 +151,8 @@ struct Daemon {
tx: mpsc::Sender<DaemonEvent>,
management_interface_broadcaster: management_interface::EventBroadcaster,
settings: settings::Settings,
+ firewall: FirewallProxy,
+ remote_endpoint: Option<Endpoint>,
// Just for testing. A cyclic iterator iterating over the hardcoded remotes,
// picking a new one for each retry.
@@ -172,7 +178,10 @@ impl Daemon {
rx,
tx,
management_interface_broadcaster,
+ firewall: FirewallProxy::new()
+ .chain_err(|| ErrorKind::FirewallError)?,
settings: settings::Settings::load().chain_err(|| "Unable to read settings")?,
+ remote_endpoint: None,
remote_iter: REMOTES.iter().cloned().cycle(),
},
)
@@ -241,6 +250,9 @@ impl Daemon {
fn handle_tunnel_event(&mut self, tunnel_event: TunnelEvent) -> Result<()> {
info!("Tunnel event: {:?}", tunnel_event);
if self.state == TunnelState::Connecting && tunnel_event == TunnelEvent::Up {
+ let remote = self.remote_endpoint.unwrap();
+ let tunnel_interface = "utun1".to_owned();
+ self.set_security_policy(SecurityPolicy::Connected(remote, tunnel_interface))?;
self.set_state(TunnelState::Connected)
} else if self.state == TunnelState::Connected && tunnel_event == TunnelEvent::Down {
self.kill_tunnel()
@@ -253,6 +265,8 @@ impl Daemon {
if let Err(e) = result.chain_err(|| "Tunnel exited in an unexpected way") {
error!("{}", e.display());
}
+ self.remote_endpoint = None;
+ self.reset_security_policy()?;
self.tunnel_close_handle = None;
self.set_state(TunnelState::NotRunning)
}
@@ -411,10 +425,13 @@ impl Daemon {
let account_token = self.settings
.get_account_token()
.ok_or(ErrorKind::InvalidSettings("No account token"))?;
+ self.set_security_policy(SecurityPolicy::Connecting(remote))?;
let tunnel_monitor = self.spawn_tunnel_monitor(remote, &account_token)?;
self.tunnel_close_handle = Some(tunnel_monitor.close_handle());
self.spawn_tunnel_monitor_wait_thread(tunnel_monitor);
- self.set_state(TunnelState::Connecting)
+ self.set_state(TunnelState::Connecting)?;
+ self.remote_endpoint = Some(remote);
+ Ok(())
}
fn spawn_tunnel_monitor(&self, remote: Endpoint, account_token: &str) -> Result<TunnelMonitor> {
@@ -459,6 +476,16 @@ impl Daemon {
pub fn shutdown_handle(&self) -> DaemonShutdownHandle {
DaemonShutdownHandle { tx: self.tx.clone() }
}
+
+ fn set_security_policy(&mut self, policy: SecurityPolicy) -> Result<()> {
+ debug!("Set security policy: {:?}", policy);
+ self.firewall.apply_policy(policy).chain_err(|| ErrorKind::FirewallError)
+ }
+
+ fn reset_security_policy(&mut self) -> Result<()> {
+ debug!("Reset security policy");
+ self.firewall.reset_policy().chain_err(|| ErrorKind::FirewallError)
+ }
}
struct DaemonShutdownHandle {