diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-03-30 18:27:19 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-03-31 15:45:47 +0200 |
| commit | 31a88ca249cc2d02da4fe327f5b296610c67c764 (patch) | |
| tree | 781aa626fefa575b3acdddc40fed604fd38d1db4 | |
| parent | d4092cd05fb1199419094cfb3eeab015023a5434 (diff) | |
| download | mullvadvpn-31a88ca249cc2d02da4fe327f5b296610c67c764.tar.xz mullvadvpn-31a88ca249cc2d02da4fe327f5b296610c67c764.zip | |
Use async file I/O for settings
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 90 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 122 |
2 files changed, 124 insertions, 88 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 53206249a6..1dbec22163 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -555,10 +555,10 @@ where ); - let mut settings = SettingsPersister::load(&settings_dir); + let mut settings = SettingsPersister::load(&settings_dir).await; if version::is_beta_version() { - let _ = settings.set_show_beta_releases(true); + let _ = settings.set_show_beta_releases(true).await; } let app_version_info = version_check::load_cache(&cache_dir); @@ -1111,21 +1111,22 @@ where self.on_remove_account_from_history(tx, account_token).await } ClearAccountHistory(tx) => self.on_clear_account_history(tx).await, - UpdateRelaySettings(tx, update) => self.on_update_relay_settings(tx, update), - SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan), + UpdateRelaySettings(tx, update) => self.on_update_relay_settings(tx, update).await, + SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan).await, SetShowBetaReleases(tx, enabled) => self.on_set_show_beta_releases(tx, enabled).await, SetBlockWhenDisconnected(tx, block_when_disconnected) => { self.on_set_block_when_disconnected(tx, block_when_disconnected) + .await } - SetAutoConnect(tx, auto_connect) => self.on_set_auto_connect(tx, auto_connect), - SetOpenVpnMssfix(tx, mssfix_arg) => self.on_set_openvpn_mssfix(tx, mssfix_arg), + SetAutoConnect(tx, auto_connect) => self.on_set_auto_connect(tx, auto_connect).await, + SetOpenVpnMssfix(tx, mssfix_arg) => self.on_set_openvpn_mssfix(tx, mssfix_arg).await, SetBridgeSettings(tx, bridge_settings) => { - self.on_set_bridge_settings(tx, bridge_settings) + self.on_set_bridge_settings(tx, bridge_settings).await } - SetBridgeState(tx, bridge_state) => self.on_set_bridge_state(tx, bridge_state), - SetEnableIpv6(tx, enable_ipv6) => self.on_set_enable_ipv6(tx, enable_ipv6), - SetDnsOptions(tx, dns_servers) => self.on_set_dns_options(tx, dns_servers), - SetWireguardMtu(tx, mtu) => self.on_set_wireguard_mtu(tx, mtu), + SetBridgeState(tx, bridge_state) => self.on_set_bridge_state(tx, bridge_state).await, + SetEnableIpv6(tx, enable_ipv6) => self.on_set_enable_ipv6(tx, enable_ipv6).await, + SetDnsOptions(tx, dns_servers) => self.on_set_dns_options(tx, dns_servers).await, + SetWireguardMtu(tx, mtu) => self.on_set_wireguard_mtu(tx, mtu).await, SetWireguardRotationInterval(tx, interval) => { self.on_set_wireguard_rotation_interval(tx, interval).await } @@ -1471,7 +1472,10 @@ where &mut self, account_token: Option<String>, ) -> Result<bool, settings::Error> { - let account_changed = self.settings.set_account_token(account_token.clone())?; + let account_changed = self + .settings + .set_account_token(account_token.clone()) + .await?; if account_changed { self.event_listener .notify_settings(self.settings.to_settings()); @@ -1556,7 +1560,7 @@ where let mut last_error = Ok(()); - if let Err(e) = self.settings.reset() { + if let Err(e) = self.settings.reset().await { log::error!("Failed to reset settings - {}", e); last_error = Err(Error::ClearSettingsError(e)); } @@ -1629,12 +1633,12 @@ where Self::oneshot_send(tx, result, "clear_split_tunnel_processes response"); } - fn on_update_relay_settings( + async fn on_update_relay_settings( &mut self, tx: ResponseTx<(), settings::Error>, update: RelaySettingsUpdate, ) { - let save_result = self.settings.update_relay_settings(update); + let save_result = self.settings.update_relay_settings(update).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "update_relay_settings response"); @@ -1652,8 +1656,8 @@ where } } - fn on_set_allow_lan(&mut self, tx: ResponseTx<(), settings::Error>, allow_lan: bool) { - let save_result = self.settings.set_allow_lan(allow_lan); + async fn on_set_allow_lan(&mut self, tx: ResponseTx<(), settings::Error>, allow_lan: bool) { + let save_result = self.settings.set_allow_lan(allow_lan).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_allow_lan response"); @@ -1675,7 +1679,7 @@ where tx: ResponseTx<(), settings::Error>, enabled: bool, ) { - let save_result = self.settings.set_show_beta_releases(enabled); + let save_result = self.settings.set_show_beta_releases(enabled).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_show_beta_releases response"); @@ -1693,14 +1697,15 @@ where } } - fn on_set_block_when_disconnected( + async fn on_set_block_when_disconnected( &mut self, tx: ResponseTx<(), settings::Error>, block_when_disconnected: bool, ) { let save_result = self .settings - .set_block_when_disconnected(block_when_disconnected); + .set_block_when_disconnected(block_when_disconnected) + .await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_block_when_disconnected response"); @@ -1719,8 +1724,12 @@ where } } - fn on_set_auto_connect(&mut self, tx: ResponseTx<(), settings::Error>, auto_connect: bool) { - let save_result = self.settings.set_auto_connect(auto_connect); + async fn on_set_auto_connect( + &mut self, + tx: ResponseTx<(), settings::Error>, + auto_connect: bool, + ) { + let save_result = self.settings.set_auto_connect(auto_connect).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set auto-connect response"); @@ -1736,12 +1745,12 @@ where } } - fn on_set_openvpn_mssfix( + async fn on_set_openvpn_mssfix( &mut self, tx: ResponseTx<(), settings::Error>, mssfix_arg: Option<u16>, ) { - let save_result = self.settings.set_openvpn_mssfix(mssfix_arg); + let save_result = self.settings.set_openvpn_mssfix(mssfix_arg).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_openvpn_mssfix response"); @@ -1763,12 +1772,12 @@ where } } - fn on_set_bridge_settings( + async fn on_set_bridge_settings( &mut self, tx: ResponseTx<(), settings::Error>, new_settings: BridgeSettings, ) { - match self.settings.set_bridge_settings(new_settings) { + match self.settings.set_bridge_settings(new_settings).await { Ok(settings_changes) => { if settings_changes { self.event_listener @@ -1788,12 +1797,12 @@ where } } - fn on_set_bridge_state( + async fn on_set_bridge_state( &mut self, tx: ResponseTx<(), settings::Error>, bridge_state: BridgeState, ) { - let result = match self.settings.set_bridge_state(bridge_state) { + let result = match self.settings.set_bridge_state(bridge_state).await { Ok(settings_changed) => { if settings_changed { self.event_listener @@ -1815,8 +1824,8 @@ where } - fn on_set_enable_ipv6(&mut self, tx: ResponseTx<(), settings::Error>, enable_ipv6: bool) { - let save_result = self.settings.set_enable_ipv6(enable_ipv6); + async fn on_set_enable_ipv6(&mut self, tx: ResponseTx<(), settings::Error>, enable_ipv6: bool) { + let save_result = self.settings.set_enable_ipv6(enable_ipv6).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_enable_ipv6 response"); @@ -1834,8 +1843,12 @@ where } } - fn on_set_dns_options(&mut self, tx: ResponseTx<(), settings::Error>, dns_options: DnsOptions) { - let save_result = self.settings.set_dns_options(dns_options.clone()); + async fn on_set_dns_options( + &mut self, + tx: ResponseTx<(), settings::Error>, + dns_options: DnsOptions, + ) { + let save_result = self.settings.set_dns_options(dns_options.clone()).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_dns_options response"); @@ -1854,8 +1867,12 @@ where } } - fn on_set_wireguard_mtu(&mut self, tx: ResponseTx<(), settings::Error>, mtu: Option<u16>) { - let save_result = self.settings.set_wireguard_mtu(mtu); + async fn on_set_wireguard_mtu( + &mut self, + tx: ResponseTx<(), settings::Error>, + mtu: Option<u16>, + ) { + let save_result = self.settings.set_wireguard_mtu(mtu).await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_wireguard_mtu response"); @@ -1882,7 +1899,10 @@ where tx: ResponseTx<(), settings::Error>, interval: Option<RotationInterval>, ) { - let save_result = self.settings.set_wireguard_rotation_interval(interval); + let save_result = self + .settings + .set_wireguard_rotation_interval(interval) + .await; match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, Ok(()), "set_wireguard_rotation_interval response"); diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs index abdd06127c..7862e21cd6 100644 --- a/mullvad-daemon/src/settings.rs +++ b/mullvad-daemon/src/settings.rs @@ -1,3 +1,5 @@ +#[cfg(not(target_os = "android"))] +use futures::TryFutureExt; use log::{debug, error, info}; use mullvad_types::{ relay_constraints::{BridgeSettings, BridgeState, RelaySettingsUpdate}, @@ -5,12 +7,11 @@ use mullvad_types::{ wireguard::RotationInterval, }; use std::{ - fs::{self, File}, - io, ops::Deref, path::{Path, PathBuf}, }; use talpid_types::ErrorExt; +use tokio::{fs, io}; const SETTINGS_FILE: &str = "settings.json"; @@ -54,9 +55,9 @@ pub struct SettingsPersister { impl SettingsPersister { /// Loads user settings from file. If no file is present it returns the defaults. - pub fn load(settings_dir: &Path) -> Self { + pub async fn load(settings_dir: &Path) -> Self { let path = settings_dir.join(SETTINGS_FILE); - let (mut settings, mut should_save) = Self::load_settings(&path); + let (mut settings, mut should_save) = Self::load_settings(&path).await; // Force IPv6 to be enabled on Android if cfg!(target_os = "android") { @@ -67,7 +68,7 @@ impl SettingsPersister { let mut persister = SettingsPersister { settings, path }; if should_save { - if let Err(error) = persister.save() { + if let Err(error) = persister.save().await { error!( "{}", error.display_chain_with_msg("Failed to save updated settings") @@ -78,8 +79,8 @@ impl SettingsPersister { persister } - fn load_settings(path: &Path) -> (Settings, bool) { - let error = match Self::load_settings_from_file(path) { + async fn load_settings(path: &Path) -> (Settings, bool) { + let error = match Self::load_settings_from_file(path).await { Ok(value) => return value, Err(error) => error, }; @@ -90,7 +91,7 @@ impl SettingsPersister { "No settings file found. Attempting migration from Windows update backup location" ); match windows::migrate_after_windows_update() { - Ok(Some(())) => match Self::load_settings_from_file(path) { + Ok(Some(())) => match Self::load_settings_from_file(path).await { Ok(value) => return value, Err(error) => error, }, @@ -113,10 +114,10 @@ impl SettingsPersister { (Settings::default(), true) } - fn load_settings_from_file(path: &Path) -> Result<(Settings, bool), LoadSettingsError> { + async fn load_settings_from_file(path: &Path) -> Result<(Settings, bool), LoadSettingsError> { info!("Loading settings from {}", path.display()); - let settings_bytes = fs::read(path).map_err(|error| { + let settings_bytes = fs::read(path).await.map_err(|error| { if error.kind() == io::ErrorKind::NotFound { LoadSettingsError::FileNotFound } else { @@ -133,29 +134,32 @@ impl SettingsPersister { } /// Serializes the settings and saves them to the file it was loaded from. - fn save(&mut self) -> Result<(), Error> { + async fn save(&mut self) -> Result<(), Error> { debug!("Writing settings to {}", self.path.display()); - let mut file = File::create(&self.path) - .map_err(|e| Error::WriteError(self.path.display().to_string(), e))?; - serde_json::to_writer_pretty(&mut file, &self.settings).map_err(Error::SerializeError)?; - file.sync_all() + let buffer = serde_json::to_string_pretty(&self.settings).map_err(Error::SerializeError)?; + fs::write(&self.path, &buffer) + .await .map_err(|e| Error::WriteError(self.path.display().to_string(), e)) } /// Resets default settings #[cfg(not(target_os = "android"))] - pub fn reset(&mut self) -> Result<(), Error> { + pub async fn reset(&mut self) -> Result<(), Error> { self.settings = Settings::default(); - self.save().or_else(|e| { - log::error!( - "{}", - e.display_chain_with_msg("Unable to save default settings") - ); - log::info!("Will attempt to remove settings file"); - fs::remove_file(&self.path) - .map_err(|e| Error::DeleteError(self.path.display().to_string(), e)) - }) + let path = self.path.clone(); + self.save() + .or_else(|e| async move { + log::error!( + "{}", + e.display_chain_with_msg("Unable to save default settings") + ); + log::info!("Will attempt to remove settings file"); + fs::remove_file(&path) + .map_err(|e| Error::DeleteError(path.display().to_string(), e)) + .await + }) + .await } pub fn to_settings(&self) -> Settings { @@ -164,22 +168,28 @@ impl SettingsPersister { /// Changes account number to the one given. Also saves the new settings to disk. /// The boolean in the Result indicates if the account token changed or not - pub fn set_account_token(&mut self, account_token: Option<String>) -> Result<bool, Error> { + pub async fn set_account_token( + &mut self, + account_token: Option<String>, + ) -> Result<bool, Error> { let should_save = self.settings.set_account_token(account_token); - self.update(should_save) + self.update(should_save).await } - pub fn update_relay_settings(&mut self, update: RelaySettingsUpdate) -> Result<bool, Error> { + pub async fn update_relay_settings( + &mut self, + update: RelaySettingsUpdate, + ) -> Result<bool, Error> { let should_save = self.settings.update_relay_settings(update); - self.update(should_save) + self.update(should_save).await } - pub fn set_allow_lan(&mut self, allow_lan: bool) -> Result<bool, Error> { + pub async fn set_allow_lan(&mut self, allow_lan: bool) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.allow_lan, allow_lan); - self.update(should_save) + self.update(should_save).await } - pub fn set_block_when_disconnected( + pub async fn set_block_when_disconnected( &mut self, block_when_disconnected: bool, ) -> Result<bool, Error> { @@ -187,43 +197,43 @@ impl SettingsPersister { &mut self.settings.block_when_disconnected, block_when_disconnected, ); - self.update(should_save) + self.update(should_save).await } - pub fn set_auto_connect(&mut self, auto_connect: bool) -> Result<bool, Error> { + pub async fn set_auto_connect(&mut self, auto_connect: bool) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.auto_connect, auto_connect); - self.update(should_save) + self.update(should_save).await } - pub fn set_openvpn_mssfix(&mut self, openvpn_mssfix: Option<u16>) -> Result<bool, Error> { + pub async fn set_openvpn_mssfix(&mut self, openvpn_mssfix: Option<u16>) -> Result<bool, Error> { let should_save = Self::update_field( &mut self.settings.tunnel_options.openvpn.mssfix, openvpn_mssfix, ); - self.update(should_save) + self.update(should_save).await } - pub fn set_enable_ipv6(&mut self, enable_ipv6: bool) -> Result<bool, Error> { + pub async fn set_enable_ipv6(&mut self, enable_ipv6: bool) -> Result<bool, Error> { let should_save = Self::update_field( &mut self.settings.tunnel_options.generic.enable_ipv6, enable_ipv6, ); - self.update(should_save) + self.update(should_save).await } - pub fn set_dns_options(&mut self, options: DnsOptions) -> Result<bool, Error> { + pub async fn set_dns_options(&mut self, options: DnsOptions) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.tunnel_options.dns_options, options); - self.update(should_save) + self.update(should_save).await } - pub fn set_wireguard_mtu(&mut self, mtu: Option<u16>) -> Result<bool, Error> { + pub async fn set_wireguard_mtu(&mut self, mtu: Option<u16>) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.tunnel_options.wireguard.options.mtu, mtu); - self.update(should_save) + self.update(should_save).await } - pub fn set_wireguard_rotation_interval( + pub async fn set_wireguard_rotation_interval( &mut self, interval: Option<RotationInterval>, ) -> Result<bool, Error> { @@ -231,23 +241,29 @@ impl SettingsPersister { &mut self.settings.tunnel_options.wireguard.rotation_interval, interval, ); - self.update(should_save) + self.update(should_save).await } - pub fn set_show_beta_releases(&mut self, show_beta_releases: bool) -> Result<bool, Error> { + pub async fn set_show_beta_releases( + &mut self, + show_beta_releases: bool, + ) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.show_beta_releases, show_beta_releases); - self.update(should_save) + self.update(should_save).await } - pub fn set_bridge_settings(&mut self, bridge_settings: BridgeSettings) -> Result<bool, Error> { + pub async fn set_bridge_settings( + &mut self, + bridge_settings: BridgeSettings, + ) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.bridge_settings, bridge_settings); - self.update(should_save) + self.update(should_save).await } - pub fn set_bridge_state(&mut self, bridge_state: BridgeState) -> Result<bool, Error> { + pub async fn set_bridge_state(&mut self, bridge_state: BridgeState) -> Result<bool, Error> { let should_save = self.settings.set_bridge_state(bridge_state); - self.update(should_save) + self.update(should_save).await } fn update_field<T: Eq>(field: &mut T, new_value: T) -> bool { @@ -259,9 +275,9 @@ impl SettingsPersister { } } - fn update(&mut self, should_save: bool) -> Result<bool, Error> { + async fn update(&mut self, should_save: bool) -> Result<bool, Error> { if should_save { - self.save().map(|_| true) + self.save().await.map(|_| true) } else { Ok(false) } |
