diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2018-09-07 13:39:57 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2018-09-08 09:39:17 +0200 |
| commit | 08feb489b790f76fbb10c9ab64eda9444d0bdfdd (patch) | |
| tree | a56957294779b4c7bbb43180b6238a98b4bf6838 | |
| parent | ac9d0098d5fcb2d710620af476e972f8d11318ec (diff) | |
| download | mullvadvpn-08feb489b790f76fbb10c9ab64eda9444d0bdfdd.tar.xz mullvadvpn-08feb489b790f76fbb10c9ab64eda9444d0bdfdd.zip | |
Add subscription for settings changes to management interface
| -rw-r--r-- | mullvad-daemon/src/main.rs | 23 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 59 |
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) } } |
