summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-07-04 13:31:37 +0200
committerLinus Färnstrand <linus@mullvad.net>2017-07-04 13:31:37 +0200
commit0e52a9b1ae4890946e3d04b13a07bd6696be3efb (patch)
tree63699e7ee9e0fae9b3cccb937ba166eb73c2a804
parent76752aa899963977963e09e1b3dd748a1f64cd08 (diff)
parent1a49dd51114103b2ccf1e3c2ec9cd12dfb1ea206 (diff)
downloadmullvadvpn-0e52a9b1ae4890946e3d04b13a07bd6696be3efb.tar.xz
mullvadvpn-0e52a9b1ae4890946e3d04b13a07bd6696be3efb.zip
Merge branch 'broadcast-target-state'
-rw-r--r--mullvad_daemon/src/main.rs33
-rw-r--r--mullvad_daemon/src/management_interface.rs20
-rw-r--r--mullvad_daemon/src/states.rs9
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,