diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-07-04 13:31:37 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-07-04 13:31:37 +0200 |
| commit | 0e52a9b1ae4890946e3d04b13a07bd6696be3efb (patch) | |
| tree | 63699e7ee9e0fae9b3cccb937ba166eb73c2a804 | |
| parent | 76752aa899963977963e09e1b3dd748a1f64cd08 (diff) | |
| parent | 1a49dd51114103b2ccf1e3c2ec9cd12dfb1ea206 (diff) | |
| download | mullvadvpn-0e52a9b1ae4890946e3d04b13a07bd6696be3efb.tar.xz mullvadvpn-0e52a9b1ae4890946e3d04b13a07bd6696be3efb.zip | |
Merge branch 'broadcast-target-state'
| -rw-r--r-- | mullvad_daemon/src/main.rs | 33 | ||||
| -rw-r--r-- | mullvad_daemon/src/management_interface.rs | 20 | ||||
| -rw-r--r-- | mullvad_daemon/src/states.rs | 9 |
3 files changed, 41 insertions, 21 deletions
diff --git a/mullvad_daemon/src/main.rs b/mullvad_daemon/src/main.rs index 1f08c753cc..1b5ab91cdc 100644 --- a/mullvad_daemon/src/main.rs +++ b/mullvad_daemon/src/main.rs @@ -26,7 +26,7 @@ mod rpc_info; mod shutdown; use management_interface::{ManagementInterfaceServer, TunnelCommand}; -use states::{SecurityState, TargetState}; +use states::{DaemonState, SecurityState, TargetState}; use std::io; use std::sync::{Arc, Mutex, mpsc}; @@ -126,7 +126,7 @@ struct Daemon { state: TunnelState, // The tunnel_close_handle must only exist in the Connecting and Connected states! tunnel_close_handle: Option<tunnel::CloseHandle>, - last_broadcasted_state: SecurityState, + last_broadcasted_state: DaemonState, target_state: TargetState, shutdown: bool, rx: mpsc::Receiver<DaemonEvent>, @@ -144,12 +144,17 @@ impl Daemon { pub fn new() -> Result<Self> { let (tx, rx) = mpsc::channel(); let management_interface_broadcaster = Self::start_management_interface(tx.clone())?; + let state = TunnelState::NotRunning; + let target_state = TargetState::Unsecured; Ok( Daemon { - state: TunnelState::NotRunning, + state, tunnel_close_handle: None, - last_broadcasted_state: SecurityState::Unsecured, - target_state: TargetState::Unsecured, + target_state, + last_broadcasted_state: DaemonState { + state: state.as_security_state(), + target_state, + }, shutdown: false, rx, tx, @@ -287,11 +292,7 @@ impl Daemon { if new_state != self.state { debug!("State {:?} => {:?}", self.state, new_state); self.state = new_state; - let new_security_state = self.state.as_security_state(); - if self.last_broadcasted_state != new_security_state { - self.last_broadcasted_state = new_security_state; - self.management_interface_broadcaster.notify_new_state(new_security_state); - } + self.broadcast_state(); self.verify_state_consistency()?; self.apply_target_state() } else { @@ -301,6 +302,17 @@ impl Daemon { } } + fn broadcast_state(&mut self) { + let new_daemon_state = DaemonState { + state: self.state.as_security_state(), + target_state: self.target_state, + }; + if self.last_broadcasted_state != new_daemon_state { + self.last_broadcasted_state = new_daemon_state; + self.management_interface_broadcaster.notify_new_state(new_daemon_state); + } + } + // Check that the current state is valid and consistent. fn verify_state_consistency(&self) -> Result<()> { use TunnelState::*; @@ -322,6 +334,7 @@ impl Daemon { if new_state != self.target_state { debug!("Target state {:?} => {:?}", self.target_state, new_state); self.target_state = new_state; + self.broadcast_state(); self.apply_target_state() } else { Ok(()) diff --git a/mullvad_daemon/src/management_interface.rs b/mullvad_daemon/src/management_interface.rs index 4b5a104d5e..65e6e9b788 100644 --- a/mullvad_daemon/src/management_interface.rs +++ b/mullvad_daemon/src/management_interface.rs @@ -7,7 +7,7 @@ use jsonrpc_pubsub::{PubSubHandler, PubSubMetadata, Session, SubscriptionId}; use jsonrpc_ws_server; use serde; -use states::{SecurityState, TargetState}; +use states::{DaemonState, TargetState}; use std::collections::HashMap; use std::collections::hash_map::Entry; @@ -73,10 +73,10 @@ build_rpc_trait! { #[rpc(name = "disconnect")] fn disconnect(&self) -> Result<(), Error>; - /// Returns the current security state of the Mullvad client. Changes to this state will - /// be announced to subscribers of `event`. + /// Returns the current state of the Mullvad client. Changes to this state will + /// be announced to subscribers of `new_state`. #[rpc(async, name = "get_state")] - fn get_state(&self) -> BoxFuture<SecurityState, Error>; + fn get_state(&self) -> BoxFuture<DaemonState, Error>; /// Returns the current public IP of this computer. #[rpc(name = "get_ip")] @@ -90,7 +90,7 @@ build_rpc_trait! { #[pubsub(name = "new_state")] { /// Subscribes to the `new_state` event notifications. #[rpc(name = "new_state_subscribe")] - fn new_state_subscribe(&self, Self::Metadata, pubsub::Subscriber<SecurityState>); + fn new_state_subscribe(&self, Self::Metadata, pubsub::Subscriber<DaemonState>); /// Unsubscribes from the `new_state` event notifications. #[rpc(name = "new_state_unsubscribe")] @@ -116,7 +116,7 @@ pub enum TunnelCommand { /// Change target state. SetTargetState(TargetState), /// Request the current state. - GetState(sync::oneshot::Sender<SecurityState>), + GetState(sync::oneshot::Sender<DaemonState>), /// Set which account token to use for subsequent connection attempts. SetAccount(Option<AccountToken>), /// Request the current account token being used. @@ -125,7 +125,7 @@ pub enum TunnelCommand { #[derive(Default)] struct ActiveSubscriptions { - new_state_subscriptions: RwLock<HashMap<SubscriptionId, pubsub::Sink<SecurityState>>>, + new_state_subscriptions: RwLock<HashMap<SubscriptionId, pubsub::Sink<DaemonState>>>, error_subscriptions: RwLock<HashMap<SubscriptionId, pubsub::Sink<Vec<String>>>>, } @@ -175,7 +175,7 @@ pub struct EventBroadcaster { impl EventBroadcaster { /// Sends a new state update to all `new_state` subscribers of the management interface. - pub fn notify_new_state(&self, new_state: SecurityState) { + pub fn notify_new_state(&self, new_state: DaemonState) { self.notify(&self.subscriptions.new_state_subscriptions, new_state); } @@ -306,7 +306,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem .map_err(|_| Error::internal_error()) } - fn get_state(&self) -> BoxFuture<SecurityState, Error> { + fn get_state(&self) -> BoxFuture<DaemonState, Error> { trace!("get_state"); let (state_tx, state_rx) = sync::oneshot::channel(); match self.tx.lock().unwrap().send(TunnelCommand::GetState(state_tx)) { @@ -333,7 +333,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem fn new_state_subscribe(&self, _meta: Self::Metadata, - subscriber: pubsub::Subscriber<SecurityState>) { + subscriber: pubsub::Subscriber<DaemonState>) { trace!("new_state_subscribe"); Self::subscribe(subscriber, &self.subscriptions.new_state_subscriptions); } diff --git a/mullvad_daemon/src/states.rs b/mullvad_daemon/src/states.rs index 10e543c58a..eb7520d36c 100644 --- a/mullvad_daemon/src/states.rs +++ b/mullvad_daemon/src/states.rs @@ -1,3 +1,9 @@ +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)] +pub struct DaemonState { + pub state: SecurityState, + pub target_state: TargetState, +} + /// Security state of the computer. /// TODO(linus): There is a difference between lockdown(firewall) and tunnel functionality. The /// firewall can be set to prevent any leaks but the tunnel is not connected. Then we are secured, @@ -14,7 +20,8 @@ pub enum SecurityState { /// Represents the state the client strives towards. /// When in `Secured`, the client should keep the computer from leaking and try to /// establish a VPN tunnel if it is not up. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)] +#[serde(rename_all = "snake_case")] pub enum TargetState { Unsecured, Secured, |
