diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-12-06 18:35:59 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-12-09 13:07:46 +0100 |
| commit | ed70be69e6265cf6e5ca3a897a2b2daa7789f0af (patch) | |
| tree | 270e41a57ef9f5597d71d5b0f1260dc8d1663fa5 | |
| parent | ed73ec5502741dd58eb23629d920ac8698a81a77 (diff) | |
| download | mullvadvpn-ed70be69e6265cf6e5ca3a897a2b2daa7789f0af.tar.xz mullvadvpn-ed70be69e6265cf6e5ca3a897a2b2daa7789f0af.zip | |
Migrate multihop state
| -rw-r--r-- | mullvad-daemon/src/migrations/mod.rs | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/migrations/v5.rs | 199 | ||||
| -rw-r--r-- | mullvad-daemon/src/relays.rs | 3 |
3 files changed, 202 insertions, 2 deletions
diff --git a/mullvad-daemon/src/migrations/mod.rs b/mullvad-daemon/src/migrations/mod.rs index 6e0bc2c61e..2e20e3cc36 100644 --- a/mullvad-daemon/src/migrations/mod.rs +++ b/mullvad-daemon/src/migrations/mod.rs @@ -9,6 +9,7 @@ mod v1; mod v2; mod v3; mod v4; +mod v5; const SETTINGS_FILE: &str = "settings.json"; @@ -71,6 +72,7 @@ pub async fn migrate_all(cache_dir: &Path, settings_dir: &Path) -> Result<()> { v2::migrate(&mut settings)?; v3::migrate(&mut settings)?; v4::migrate(&mut settings)?; + v5::migrate(&mut settings)?; account_history::migrate_location(cache_dir, settings_dir).await; account_history::migrate_formats(settings_dir, &mut settings).await?; diff --git a/mullvad-daemon/src/migrations/v5.rs b/mullvad-daemon/src/migrations/v5.rs new file mode 100644 index 0000000000..70a0fb0f11 --- /dev/null +++ b/mullvad-daemon/src/migrations/v5.rs @@ -0,0 +1,199 @@ +use super::{Error, Result}; +use mullvad_types::settings::SettingsVersion; + +pub fn migrate(settings: &mut serde_json::Value) -> Result<()> { + if !version_matches(settings) { + return Ok(()); + } + + let wireguard_constraints = || -> Option<&serde_json::Value> { + settings + .get("relay_settings")? + .get("normal")? + .get("wireguard_constraints") + }(); + if let Some(constraints) = wireguard_constraints { + if let Some(location) = constraints.get("entry_location") { + if constraints.get("use_multihop").is_none() { + if location.is_null() { + // "Null" is no longer valid. It is not an option. + settings["relay_settings"]["normal"]["wireguard_constraints"] + .as_object_mut() + .ok_or(Error::NoMatchingVersion)? + .remove("entry_location"); + } else { + settings["relay_settings"]["normal"]["wireguard_constraints"]["use_multihop"] = + serde_json::json!(true); + } + } + } + } + + // Note: Not incrementing the version number + + Ok(()) +} + +fn version_matches(settings: &mut serde_json::Value) -> bool { + settings + .get("settings_version") + .map(|version| version == SettingsVersion::V5 as u64) + .unwrap_or(false) +} + +#[cfg(test)] +mod test { + use super::{migrate, version_matches}; + use serde_json; + + pub const V5_SETTINGS_V1: &str = r#" +{ + "account_token": "1234", + "relay_settings": { + "normal": { + "location": { + "only": { + "country": "se" + } + }, + "tunnel_protocol": "any", + "wireguard_constraints": { + "port": "any", + "ip_version": "any", + "entry_location": "any" + }, + "openvpn_constraints": { + "port": { + "only": { + "protocol": "udp", + "port": { + "only": 1195 + } + } + } + } + } + }, + "bridge_settings": { + "normal": { + "location": "any" + } + }, + "bridge_state": "auto", + "allow_lan": true, + "block_when_disconnected": false, + "auto_connect": false, + "tunnel_options": { + "openvpn": { + "mssfix": null + }, + "wireguard": { + "mtu": null, + "rotation_interval": { + "secs": 86400, + "nanos": 0 + } + }, + "generic": { + "enable_ipv6": false + }, + "dns_options": { + "state": "default", + "default_options": { + "block_ads": false, + "block_trackers": false + }, + "custom_options": { + "addresses": [ + "1.1.1.1", + "1.2.3.4" + ] + } + } + }, + "settings_version": 5 +} +"#; + + pub const V5_SETTINGS_V2: &str = r#" +{ + "account_token": "1234", + "relay_settings": { + "normal": { + "location": { + "only": { + "country": "se" + } + }, + "tunnel_protocol": "any", + "wireguard_constraints": { + "port": "any", + "ip_version": "any", + "use_multihop": true, + "entry_location": "any" + }, + "openvpn_constraints": { + "port": { + "only": { + "protocol": "udp", + "port": { + "only": 1195 + } + } + } + } + } + }, + "bridge_settings": { + "normal": { + "location": "any" + } + }, + "bridge_state": "auto", + "allow_lan": true, + "block_when_disconnected": false, + "auto_connect": false, + "tunnel_options": { + "openvpn": { + "mssfix": null + }, + "wireguard": { + "mtu": null, + "rotation_interval": { + "secs": 86400, + "nanos": 0 + } + }, + "generic": { + "enable_ipv6": false + }, + "dns_options": { + "state": "default", + "default_options": { + "block_ads": false, + "block_trackers": false + }, + "custom_options": { + "addresses": [ + "1.1.1.1", + "1.2.3.4" + ] + } + } + }, + "settings_version": 5 +} +"#; + + #[test] + fn test_v5_v1_migration() { + let mut old_settings = serde_json::from_str(V5_SETTINGS_V1).unwrap(); + + assert!(version_matches(&mut old_settings)); + + migrate(&mut old_settings).unwrap(); + let new_settings: serde_json::Value = serde_json::from_str(V5_SETTINGS_V2).unwrap(); + + assert_eq!(&old_settings, &new_settings); + } +} diff --git a/mullvad-daemon/src/relays.rs b/mullvad-daemon/src/relays.rs index 48b46dca9a..803deac988 100644 --- a/mullvad-daemon/src/relays.rs +++ b/mullvad-daemon/src/relays.rs @@ -1432,8 +1432,7 @@ mod test { assert_ne!(exit_relay.hostname, specific_hostname); relay_constraints.location = Constraint::Only(location_specific); - relay_constraints.wireguard_constraints.entry_location = - Constraint::Only(location_general); + relay_constraints.wireguard_constraints.entry_location = Constraint::Only(location_general); // The entry must not equal the exit let (exit_relay, _entry_relay, exit_endpoint) = relay_selector |
