summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-09-07 13:39:57 +0200
committerLinus Färnstrand <linus@mullvad.net>2018-09-08 09:39:17 +0200
commit08feb489b790f76fbb10c9ab64eda9444d0bdfdd (patch)
treea56957294779b4c7bbb43180b6238a98b4bf6838
parentac9d0098d5fcb2d710620af476e972f8d11318ec (diff)
downloadmullvadvpn-08feb489b790f76fbb10c9ab64eda9444d0bdfdd.tar.xz
mullvadvpn-08feb489b790f76fbb10c9ab64eda9444d0bdfdd.zip
Add subscription for settings changes to management interface
-rw-r--r--mullvad-daemon/src/main.rs23
-rw-r--r--mullvad-daemon/src/management_interface.rs59
2 files changed, 72 insertions, 10 deletions
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index 4470a86e30..582e9bbc87 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -441,6 +441,8 @@ impl Daemon {
Ok(account_changed) => {
Self::oneshot_send(tx, (), "set_account response");
if account_changed {
+ self.management_interface_broadcaster
+ .notify_settings(&self.settings);
if account_token_cleared {
info!("Disconnecting because account token was cleared");
let _ = self.set_target_state(TargetState::Unsecured);
@@ -513,6 +515,8 @@ impl Daemon {
match save_result.chain_err(|| "Unable to save settings") {
Ok(settings_changed) => {
if settings_changed {
+ self.management_interface_broadcaster
+ .notify_settings(&self.settings);
self.send_tunnel_command(TunnelCommand::AllowLan(allow_lan));
}
Self::oneshot_send(tx, (), "set_allow_lan response");
@@ -529,7 +533,13 @@ impl Daemon {
fn on_set_auto_connect(&mut self, tx: OneshotSender<()>, auto_connect: bool) -> Result<()> {
let save_result = self.settings.set_auto_connect(auto_connect);
match save_result.chain_err(|| "Unable to save settings") {
- Ok(_settings_changed) => Self::oneshot_send(tx, (), "set auto-connect response"),
+ Ok(settings_changed) => {
+ Self::oneshot_send(tx, (), "set auto-connect response");
+ if settings_changed {
+ self.management_interface_broadcaster
+ .notify_settings(&self.settings);
+ }
+ }
Err(e) => error!("{}", e.display_chain()),
}
Ok(())
@@ -550,7 +560,13 @@ impl Daemon {
) -> Result<()> {
let save_result = self.settings.set_openvpn_mssfix(mssfix_arg);
match save_result.chain_err(|| "Unable to save settings") {
- Ok(_) => Self::oneshot_send(tx, (), "set_openvpn_mssfix response"),
+ Ok(settings_changed) => {
+ Self::oneshot_send(tx, (), "set_openvpn_mssfix response");
+ if settings_changed {
+ self.management_interface_broadcaster
+ .notify_settings(&self.settings);
+ }
+ }
Err(e) => error!("{}", e.display_chain()),
};
Ok(())
@@ -562,8 +578,9 @@ impl Daemon {
match save_result.chain_err(|| "Unable to save settings") {
Ok(settings_changed) => {
Self::oneshot_send(tx, (), "set_enable_ipv6 response");
-
if settings_changed {
+ self.management_interface_broadcaster
+ .notify_settings(&self.settings);
info!("Initiating tunnel restart because the enable IPv6 setting changed");
self.reconnect_tunnel();
}
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 383693bb27..05903f61b0 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -15,6 +15,9 @@ use mullvad_types::relay_list::RelayList;
use mullvad_types::states::TargetState;
use mullvad_types::version;
+use serde;
+use settings::Settings;
+
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::path::PathBuf;
@@ -149,6 +152,17 @@ build_rpc_trait! {
#[rpc(name = "new_state_unsubscribe")]
fn new_state_unsubscribe(&self, SubscriptionId) -> BoxFuture<(), Error>;
}
+
+ #[pubsub(name = "settings")] {
+ /// Subscribes to the `settings` event notifications. Getting notified as soon as any
+ /// daemon settings change.
+ #[rpc(name = "settings_subscribe")]
+ fn settings_subscribe(&self, Self::Metadata, pubsub::Subscriber<Settings>);
+
+ /// Unsubscribes from the `settings` event notifications.
+ #[rpc(name = "settings_unsubscribe")]
+ fn settings_unsubscribe(&self, SubscriptionId) -> BoxFuture<(), Error>;
+ }
}
}
@@ -198,9 +212,15 @@ pub enum ManagementCommand {
Shutdown,
}
+#[derive(Default)]
+struct ActiveSubscriptions {
+ new_state_subscriptions: RwLock<HashMap<SubscriptionId, pubsub::Sink<TunnelStateTransition>>>,
+ settings_subscriptions: RwLock<HashMap<SubscriptionId, pubsub::Sink<Settings>>>,
+}
+
pub struct ManagementInterfaceServer {
server: talpid_ipc::IpcServer,
- subscriptions: Arc<RwLock<HashMap<SubscriptionId, pubsub::Sink<TunnelStateTransition>>>>,
+ subscriptions: Arc<ActiveSubscriptions>,
}
impl ManagementInterfaceServer {
@@ -248,22 +268,37 @@ impl ManagementInterfaceServer {
/// A handle that allows broadcasting messages to all subscribers of the management interface.
pub struct EventBroadcaster {
- subscriptions: Arc<RwLock<HashMap<SubscriptionId, pubsub::Sink<TunnelStateTransition>>>>,
+ subscriptions: Arc<ActiveSubscriptions>,
}
impl EventBroadcaster {
/// Sends a new state update to all `new_state` subscribers of the management interface.
pub fn notify_new_state(&self, new_state: TunnelStateTransition) {
debug!("Broadcasting new state to listeners: {:?}", new_state);
- let subscriptions = self.subscriptions.read().unwrap();
+ self.notify(&self.subscriptions.new_state_subscriptions, new_state);
+ }
+
+ /// Sends settings to all `settings` subscribers of the management interface.
+ pub fn notify_settings(&self, settings: &Settings) {
+ self.notify(&self.subscriptions.settings_subscriptions, settings.clone());
+ }
+
+ fn notify<T>(
+ &self,
+ subscriptions_lock: &RwLock<HashMap<SubscriptionId, pubsub::Sink<T>>>,
+ value: T,
+ ) where
+ T: serde::Serialize + Clone,
+ {
+ let subscriptions = subscriptions_lock.read().unwrap();
for sink in subscriptions.values() {
- let _ = sink.notify(Ok(new_state.clone())).wait();
+ let _ = sink.notify(Ok(value.clone())).wait();
}
}
}
struct ManagementInterface<T: From<ManagementCommand> + 'static + Send> {
- subscriptions: Arc<RwLock<HashMap<SubscriptionId, pubsub::Sink<TunnelStateTransition>>>>,
+ subscriptions: Arc<ActiveSubscriptions>,
tx: Mutex<IntoSender<ManagementCommand, T>>,
cache_dir: PathBuf,
}
@@ -621,12 +656,22 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi
subscriber: pubsub::Subscriber<TunnelStateTransition>,
) {
debug!("new_state_subscribe");
- Self::subscribe(subscriber, &self.subscriptions);
+ Self::subscribe(subscriber, &self.subscriptions.new_state_subscriptions);
}
fn new_state_unsubscribe(&self, id: SubscriptionId) -> BoxFuture<(), Error> {
debug!("new_state_unsubscribe");
- Self::unsubscribe(id, &self.subscriptions)
+ Self::unsubscribe(id, &self.subscriptions.new_state_subscriptions)
+ }
+
+ fn settings_subscribe(&self, _: Self::Metadata, subscriber: pubsub::Subscriber<Settings>) {
+ debug!("settings_subscribe");
+ Self::subscribe(subscriber, &self.subscriptions.settings_subscriptions);
+ }
+
+ fn settings_unsubscribe(&self, id: SubscriptionId) -> BoxFuture<(), Error> {
+ debug!("settings_unsubscribe");
+ Self::unsubscribe(id, &self.subscriptions.settings_subscriptions)
}
}