summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--mullvad-daemon/src/lib.rs17
-rw-r--r--mullvad-daemon/src/version_check.rs58
3 files changed, 55 insertions, 21 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82e677657a..da02ee2af8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@ Line wrap the file at 100 chars. Th
### Fixed
- Don't try to replace WireGuard key if account has too many keys already.
+- Fix bogus update notification caused by an outdated cache.
#### Windows
- Fix regression due to which a TAP adapter issue was not given as the specific block reason when
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 9a9e42e697..cce096fd96 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -407,22 +407,7 @@ where
&cache_dir,
);
- 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::PRODUCT_VERSION.to_owned(),
- latest: version::PRODUCT_VERSION.to_owned(),
- }
- }
- };
+ let app_version_info = version_check::load_cache(&cache_dir);
let version_check_future = version_check::VersionUpdater::new(
rpc_handle.clone(),
cache_dir.clone(),
diff --git a/mullvad-daemon/src/version_check.rs b/mullvad-daemon/src/version_check.rs
index 45352d3e2d..33e8fb86af 100644
--- a/mullvad-daemon/src/version_check.rs
+++ b/mullvad-daemon/src/version_check.rs
@@ -1,6 +1,8 @@
+use crate::version::PRODUCT_VERSION;
use futures::{sync::mpsc::UnboundedSender, Async, Future, Poll};
use mullvad_rpc::{AppVersionProxy, HttpHandle};
use mullvad_types::version::AppVersionInfo;
+use serde::{Deserialize, Serialize};
use std::{
fs::File,
io,
@@ -33,6 +35,22 @@ const PLATFORM: &str = "windows";
const PLATFORM: &str = "android";
+#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
+struct CachedAppVersionInfo {
+ #[serde(flatten)]
+ pub version_info: AppVersionInfo,
+ pub cached_from_version: String,
+}
+
+impl From<AppVersionInfo> for CachedAppVersionInfo {
+ fn from(version_info: AppVersionInfo) -> CachedAppVersionInfo {
+ CachedAppVersionInfo {
+ version_info,
+ cached_from_version: PRODUCT_VERSION.to_owned(),
+ }
+ }
+}
+
#[derive(err_derive::Error, Debug)]
#[error(no_from)]
pub enum Error {
@@ -50,6 +68,9 @@ pub enum Error {
#[error(display = "Failed to check the latest app version")]
Download(#[error(source)] mullvad_rpc::Error),
+
+ #[error(display = "Clearing version check cache due to a version mismatch")]
+ CacheVersionMismatch,
}
impl<T> From<TimeoutError<T>> for Error {
@@ -101,7 +122,7 @@ impl<T: From<AppVersionInfo>> VersionUpdater<T> {
) -> Box<dyn Future<Item = AppVersionInfo, Error = Error> + Send + 'static> {
let download_future = self
.version_proxy
- .app_version_check(&crate::version::PRODUCT_VERSION.to_owned(), PLATFORM)
+ .app_version_check(&PRODUCT_VERSION.to_owned(), PLATFORM)
.map_err(Error::Download);
let future = Timer::default().timeout(download_future, DOWNLOAD_TIMEOUT);
Box::new(future)
@@ -113,7 +134,8 @@ impl<T: From<AppVersionInfo>> VersionUpdater<T> {
self.cache_path.display()
);
let file = File::create(&self.cache_path).map_err(Error::WriteRelayCache)?;
- serde_json::to_writer_pretty(io::BufWriter::new(file), &self.last_app_version_info)
+ let cached_app_version = CachedAppVersionInfo::from(self.last_app_version_info.clone());
+ serde_json::to_writer_pretty(io::BufWriter::new(file), &cached_app_version)
.map_err(Error::Serialize)
}
}
@@ -182,9 +204,35 @@ impl<T: From<AppVersionInfo>> Future for VersionUpdater<T> {
}
}
-pub fn load_cache(cache_dir: &Path) -> Result<AppVersionInfo, Error> {
+fn try_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)
+ let file = File::open(&path).map_err(Error::ReadCachedRelays)?;
+ let version_info: CachedAppVersionInfo =
+ serde_json::from_reader(io::BufReader::new(file)).map_err(Error::Serialize)?;
+
+ if version_info.cached_from_version == PRODUCT_VERSION {
+ Ok(version_info.version_info)
+ } else {
+ Err(Error::CacheVersionMismatch)
+ }
+}
+
+pub fn load_cache(cache_dir: &Path) -> AppVersionInfo {
+ match try_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: PRODUCT_VERSION.to_owned(),
+ latest: PRODUCT_VERSION.to_owned(),
+ }
+ }
+ }
}