diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-02-25 11:26:49 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-03-14 12:08:52 +0100 |
| commit | f1ca2b65ef82f4450e1a9f1cfbde2956b8aeb37f (patch) | |
| tree | 26a54dda71e1a00aca56b892757229d0c5bd6c5d | |
| parent | a200d37d76735730b1cf6b41651ecd5dc5bf5eb0 (diff) | |
| download | mullvadvpn-f1ca2b65ef82f4450e1a9f1cfbde2956b8aeb37f.tar.xz mullvadvpn-f1ca2b65ef82f4450e1a9f1cfbde2956b8aeb37f.zip | |
Cache/rate-limit device validity check
| -rw-r--r-- | mullvad-daemon/src/device.rs | 32 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 2 |
2 files changed, 32 insertions, 2 deletions
diff --git a/mullvad-daemon/src/device.rs b/mullvad-daemon/src/device.rs index 07686e1fcc..4b98c5b414 100644 --- a/mullvad-daemon/src/device.rs +++ b/mullvad-daemon/src/device.rs @@ -19,7 +19,7 @@ use std::{ future::Future, path::Path, sync::{Arc, Mutex}, - time::Duration, + time::{Duration, SystemTime}, }; use talpid_core::{ future_retry::{constant_interval, retry_future, retry_future_n, ExponentialBackoff, Jittered}, @@ -45,6 +45,9 @@ const RETRY_BACKOFF_INTERVAL_INITIAL: Duration = Duration::from_secs(4); const RETRY_BACKOFF_INTERVAL_FACTOR: u32 = 5; const RETRY_BACKOFF_INTERVAL_MAX: Duration = Duration::from_secs(24 * 60 * 60); +/// How long to keep the known status for [AccountManager::validate_device_cached]. +const DEVICE_VALIDITY_CACHE_DURATION: Duration = Duration::from_secs(30); + pub struct DeviceKeyEvent(pub DeviceData); #[derive(err_derive::Error, Debug)] @@ -102,6 +105,7 @@ pub(crate) struct AccountManager { struct AccountManagerInner { data: Option<DeviceData>, rotation_interval: RotationInterval, + last_validation: Option<SystemTime>, } impl AccountManager { @@ -119,6 +123,7 @@ impl AccountManager { let inner = Arc::new(Mutex::new(AccountManagerInner { data: device_data, rotation_interval: RotationInterval::default(), + last_validation: None, })); let (cache_update_tx, mut cache_update_rx): ( @@ -366,6 +371,31 @@ impl AccountManager { } } + /// Same as [Self::validate_device] but returns [ValidationResult::Valid] (or [Error::NoDevice]) + /// if the last check was recent. + pub async fn validate_device_cached(&mut self) -> Result<ValidationResult, Error> { + let last_validation = { + let inner = self.inner.lock().unwrap(); + if inner.data.is_none() { + return Err(Error::NoDevice); + } + inner.last_validation.clone() + }; + + if last_validation + .and_then(|last_check| SystemTime::now().duration_since(last_check).ok()) + .map(|elapsed| elapsed < DEVICE_VALIDITY_CACHE_DURATION) + .unwrap_or(false) + { + return Ok(ValidationResult::Valid); + } + + let result = self.validate_device().await; + let mut inner = self.inner.lock().unwrap(); + inner.last_validation = Some(SystemTime::now()); + result + } + fn start_key_rotation(&mut self) { self.stop_key_rotation(); diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index f8102f8c3f..9277d45335 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -1021,7 +1021,7 @@ where self.wg_retry_attempt += 1; if self.wg_check_validity && self.wg_retry_attempt % WG_DEVICE_CHECK_THRESHOLD == 0 { - match self.account_manager.validate_device().await { + match self.account_manager.validate_device_cached().await { Ok(status) => { self.handle_validation_result(status); self.wg_check_validity = false; |
