summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-12-06 18:35:59 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-12-09 13:07:46 +0100
commited70be69e6265cf6e5ca3a897a2b2daa7789f0af (patch)
tree270e41a57ef9f5597d71d5b0f1260dc8d1663fa5
parented73ec5502741dd58eb23629d920ac8698a81a77 (diff)
downloadmullvadvpn-ed70be69e6265cf6e5ca3a897a2b2daa7789f0af.tar.xz
mullvadvpn-ed70be69e6265cf6e5ca3a897a2b2daa7789f0af.zip
Migrate multihop state
-rw-r--r--mullvad-daemon/src/migrations/mod.rs2
-rw-r--r--mullvad-daemon/src/migrations/v5.rs199
-rw-r--r--mullvad-daemon/src/relays.rs3
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