diff options
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 68 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 13 | ||||
| -rw-r--r-- | mullvad-daemon/src/version_check.rs | 56 |
3 files changed, 60 insertions, 77 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 1979447737..28194733a3 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -32,7 +32,7 @@ use futures::{ Future, Sink, }; use log::{debug, error, info, warn}; -use mullvad_rpc::{AccountsProxy, AppVersionProxy, HttpHandle, WireguardKeyProxy}; +use mullvad_rpc::{AccountsProxy, HttpHandle, WireguardKeyProxy}; use mullvad_types::{ account::{AccountData, AccountToken}, endpoint::MullvadEndpoint, @@ -156,6 +156,8 @@ pub(crate) enum InternalDaemonEvent { AccountToken, oneshot::Sender<std::result::Result<String, mullvad_rpc::Error>>, ), + /// The background job fetching new `AppVersionInfo`s got a new info object. + NewAppVersionInfo(AppVersionInfo), } impl From<TunnelStateTransition> for InternalDaemonEvent { @@ -257,7 +259,6 @@ pub struct Daemon<L: EventListener = ManagementInterfaceEventBroadcaster> { account_history: account_history::AccountHistory, wg_key_proxy: WireguardKeyProxy<HttpHandle>, accounts_proxy: AccountsProxy<HttpHandle>, - version_proxy: AppVersionProxy<HttpHandle>, https_handle: mullvad_rpc::rest::RequestSender, wireguard_key_manager: wireguard::KeyManager, tokio_remote: tokio_core::reactor::Remote, @@ -265,6 +266,7 @@ pub struct Daemon<L: EventListener = ManagementInterfaceEventBroadcaster> { last_generated_relay: Option<Relay>, last_generated_bridge_relay: Option<Relay>, version: String, + app_version_info: AppVersionInfo, shutdown_callbacks: Vec<Box<dyn FnOnce()>>, } @@ -391,15 +393,34 @@ where &cache_dir, ); - let version_check_listener = event_listener.clone(); + let version_check_internal_event_tx = internal_event_tx.clone(); let on_version_check_update = move |app_version_info: &AppVersionInfo| { - version_check_listener.notify_app_version(app_version_info.clone()); + let _ = version_check_internal_event_tx.send(InternalDaemonEvent::NewAppVersionInfo( + app_version_info.clone(), + )); }; - let version_check_future = version_check::spawn( + let app_version_info = match version_check::load_cache(&cache_dir) { + Ok(app_version_info) => app_version_info, + Err(error) => { + log::warn!( + "{}", + error.display_chain_with_msg("Unable to load cached version info") + ); + // If we don't have a cache, start out with sane defaults. + AppVersionInfo { + current_is_supported: true, + current_is_outdated: false, + latest_stable: version.clone(), + latest: version.clone(), + } + } + }; + let version_check_future = version_check::VersionUpdater::new( version.clone(), rpc_handle.clone(), + cache_dir.clone(), on_version_check_update, - &cache_dir, + app_version_info.clone(), ); tokio_remote.spawn(|_| version_check_future); @@ -446,14 +467,14 @@ where account_history, wg_key_proxy: WireguardKeyProxy::new(rpc_handle.clone()), accounts_proxy: AccountsProxy::new(rpc_handle.clone()), - version_proxy: AppVersionProxy::new(rpc_handle), https_handle, + wireguard_key_manager, tokio_remote, relay_selector, last_generated_relay: None, last_generated_bridge_relay: None, version, - wireguard_key_manager, + app_version_info, shutdown_callbacks: vec![], }; @@ -520,6 +541,9 @@ where TriggerShutdown => self.trigger_shutdown_event(), WgKeyEvent(key_event) => self.handle_wireguard_key_event(key_event), NewAccountEvent(account_token, tx) => self.handle_new_account_event(account_token, tx), + NewAppVersionInfo(app_version_info) => { + self.handle_new_app_version_info(app_version_info) + } } Ok(()) } @@ -877,6 +901,11 @@ where }; } + fn handle_new_app_version_info(&mut self, app_version_info: AppVersionInfo) { + self.app_version_info = app_version_info.clone(); + self.event_listener.notify_app_version(app_version_info); + } + fn on_set_target_state( &mut self, tx: oneshot::Sender<std::result::Result<(), ()>>, @@ -1071,23 +1100,12 @@ where } } - fn on_get_version_info( - &mut self, - tx: oneshot::Sender<BoxFuture<AppVersionInfo, mullvad_rpc::Error>>, - ) { - #[cfg(target_os = "linux")] - const PLATFORM: &str = "linux"; - #[cfg(target_os = "macos")] - const PLATFORM: &str = "macos"; - #[cfg(target_os = "windows")] - const PLATFORM: &str = "windows"; - #[cfg(target_os = "android")] - const PLATFORM: &str = "android"; - - let fut = self - .version_proxy - .app_version_check(&self.version, PLATFORM); - Self::oneshot_send(tx, Box::new(fut), "get_version_info response"); + fn on_get_version_info(&mut self, tx: oneshot::Sender<AppVersionInfo>) { + Self::oneshot_send( + tx, + self.app_version_info.clone(), + "get_version_info response", + ); } fn on_get_current_version(&mut self, tx: oneshot::Sender<AppVersion>) { diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 59d9f91097..afa6ad165e 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -233,7 +233,7 @@ pub enum ManagementCommand { /// Verify if the currently set wireguard key is valid. VerifyWireguardKey(OneshotSender<bool>), /// Get information about the currently running and latest app versions - GetVersionInfo(OneshotSender<BoxFuture<version::AppVersionInfo, mullvad_rpc::Error>>), + GetVersionInfo(OneshotSender<version::AppVersionInfo>), /// Get current version of the app GetCurrentVersion(OneshotSender<version::AppVersion>), #[cfg(not(target_os = "android"))] @@ -718,16 +718,7 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetVersionInfo(tx)) - .and_then(|_| rx.map_err(|_| Error::internal_error())) - .and_then(|version_future| { - version_future.map_err(|error| { - log::error!( - "Unable to get version data from API: {}", - error.display_chain() - ); - Self::map_rpc_error(&error) - }) - }); + .and_then(|_| rx.map_err(|_| Error::internal_error())); Box::new(future) } diff --git a/mullvad-daemon/src/version_check.rs b/mullvad-daemon/src/version_check.rs index 29a857eabb..b4ed7939f2 100644 --- a/mullvad-daemon/src/version_check.rs +++ b/mullvad-daemon/src/version_check.rs @@ -28,41 +28,12 @@ const PLATFORM: &str = "windows"; #[cfg(target_os = "android")] const PLATFORM: &str = "android"; -pub fn spawn<F: Fn(&AppVersionInfo) + Send + 'static>( - version: String, - rpc_handle: HttpHandle, - on_version_update: F, - cache_dir: &Path, -) -> VersionUpdater<F> { - let version_proxy = AppVersionProxy::new(rpc_handle); - let cache_path = cache_dir.join(VERSION_INFO_FILENAME); - - let last_app_version_info = match load_cache(&cache_path) { - Ok(app_version_info) => Some(app_version_info), - Err(error) => { - log::warn!( - "{}", - error.display_chain_with_msg("Unable to load cached version info") - ); - None - } - }; - - VersionUpdater::new( - version, - version_proxy, - cache_path, - on_version_update, - last_app_version_info, - ) -} - pub struct VersionUpdater<F: Fn(&AppVersionInfo) + Send + 'static> { version: String, version_proxy: AppVersionProxy<HttpHandle>, - cache_path: PathBuf, + cache_dir: PathBuf, on_version_update: F, - last_app_version_info: Option<AppVersionInfo>, + last_app_version_info: AppVersionInfo, next_update_time: Instant, state: Option<VersionUpdaterState>, } @@ -75,15 +46,16 @@ enum VersionUpdaterState { impl<F: Fn(&AppVersionInfo) + Send + 'static> VersionUpdater<F> { pub fn new( version: String, - version_proxy: AppVersionProxy<HttpHandle>, - cache_path: PathBuf, + rpc_handle: HttpHandle, + cache_dir: PathBuf, on_version_update: F, - last_app_version_info: Option<AppVersionInfo>, + last_app_version_info: AppVersionInfo, ) -> Self { + let version_proxy = AppVersionProxy::new(rpc_handle); Self { version, version_proxy, - cache_path, + cache_dir, on_version_update, last_app_version_info, next_update_time: Instant::now(), @@ -123,11 +95,11 @@ impl<F: Fn(&AppVersionInfo) + Send + 'static> VersionUpdater<F> { true } Ok(Async::Ready(app_version_info)) => { - if Some(&app_version_info) != self.last_app_version_info.as_ref() { + if app_version_info != self.last_app_version_info { log::debug!("Got new version check: {:?}", app_version_info); - write_cache(&app_version_info, &self.cache_path).unwrap(); + write_cache(&app_version_info, &self.cache_dir).unwrap(); (self.on_version_update)(&app_version_info); - self.last_app_version_info = Some(app_version_info); + self.last_app_version_info = app_version_info; } true } @@ -173,13 +145,15 @@ impl<F: Fn(&AppVersionInfo) + Send + 'static> Future for VersionUpdater<F> { } } -fn load_cache(path: &Path) -> Result<AppVersionInfo, Error> { +pub fn load_cache(cache_dir: &Path) -> Result<AppVersionInfo, Error> { + let path = cache_dir.join(VERSION_INFO_FILENAME); log::debug!("Loading version check cache from {}", path.display()); let file = File::open(path).map_err(Error::ReadCachedRelays)?; serde_json::from_reader(io::BufReader::new(file)).map_err(Error::Serialize) } -fn write_cache(app_version_info: &AppVersionInfo, path: &Path) -> Result<(), Error> { +fn write_cache(app_version_info: &AppVersionInfo, cache_dir: &Path) -> Result<(), Error> { + let path = cache_dir.join(VERSION_INFO_FILENAME); log::debug!("Writing version check cache to {}", path.display()); let file = File::create(path).map_err(Error::WriteRelayCache)?; serde_json::to_writer_pretty(io::BufWriter::new(file), app_version_info) @@ -187,7 +161,7 @@ fn write_cache(app_version_info: &AppVersionInfo, path: &Path) -> Result<(), Err } #[derive(err_derive::Error, Debug)] -enum Error { +pub enum Error { #[error(display = "Failed to open app version cache file for reading")] ReadCachedRelays(#[error(cause)] io::Error), |
