summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mullvad-daemon/src/lib.rs68
-rw-r--r--mullvad-daemon/src/management_interface.rs13
-rw-r--r--mullvad-daemon/src/version_check.rs56
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),