diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-08-18 09:02:21 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-08-18 10:51:58 +0200 |
| commit | ba966fee57d9de61997bef4d7dcf6539af26c037 (patch) | |
| tree | 3299982d13cfd1a53f7166257a9af1fc1e8469d9 | |
| parent | 0abee355c21eb00a221842b39ab41bc26fa0b663 (diff) | |
| download | mullvadvpn-ba966fee57d9de61997bef4d7dcf6539af26c037.tar.xz mullvadvpn-ba966fee57d9de61997bef4d7dcf6539af26c037.zip | |
Fail if QUIC address set is empty
| -rw-r--r-- | Cargo.lock | 7 | ||||
| -rw-r--r-- | mullvad-api/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-api/src/relay_list.rs | 10 | ||||
| -rw-r--r-- | mullvad-management-interface/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-management-interface/src/types/conversions/relay_list.rs | 4 | ||||
| -rw-r--r-- | mullvad-relay-selector/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/matcher.rs | 19 | ||||
| -rw-r--r-- | mullvad-relay-selector/tests/relay_selector.rs | 3 | ||||
| -rw-r--r-- | mullvad-types/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-types/src/relay_list.rs | 13 | ||||
| -rw-r--r-- | test/Cargo.lock | 7 |
11 files changed, 46 insertions, 21 deletions
diff --git a/Cargo.lock b/Cargo.lock index 885f34c313..2f5e37fc2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2877,6 +2877,7 @@ dependencies = [ "tokio-socks", "tower 0.5.1", "uuid", + "vec1", ] [[package]] @@ -3082,6 +3083,7 @@ dependencies = [ "tonic", "tonic-build", "tower 0.5.1", + "vec1", ] [[package]] @@ -3164,6 +3166,7 @@ dependencies = [ "serde_json", "talpid-types", "thiserror 2.0.9", + "vec1", ] [[package]] @@ -3222,6 +3225,7 @@ dependencies = [ "talpid-types", "thiserror 2.0.9", "uuid", + "vec1", ] [[package]] @@ -6274,6 +6278,9 @@ name = "vec1" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab68b56840f69efb0fefbe3ab6661499217ffdc58e2eef7c3f6f69835386322" +dependencies = [ + "serde", +] [[package]] name = "version_check" diff --git a/mullvad-api/Cargo.toml b/mullvad-api/Cargo.toml index 5764d9378b..1ffd0bc08c 100644 --- a/mullvad-api/Cargo.toml +++ b/mullvad-api/Cargo.toml @@ -47,6 +47,7 @@ tokio-rustls = { version = "0.26.0", features = [ tokio-socks = "0.5.1" rustls-pemfile = "2.1.3" uuid = { version = "1.4.1", features = ["v4"] } +vec1 = { workspace = true, features = ["serde"] } mullvad-api-constants = { path = "./mullvad-api-constants" } mullvad-encrypted-dns-proxy = { path = "../mullvad-encrypted-dns-proxy" } diff --git a/mullvad-api/src/relay_list.rs b/mullvad-api/src/relay_list.rs index 28ce37aec0..6fdc073efd 100644 --- a/mullvad-api/src/relay_list.rs +++ b/mullvad-api/src/relay_list.rs @@ -5,6 +5,7 @@ use crate::rest; use hyper::{StatusCode, body::Incoming, header}; use mullvad_types::{location, relay_list}; use talpid_types::net::wireguard; +use vec1::Vec1; use std::{ collections::{BTreeMap, HashSet}, @@ -386,9 +387,12 @@ struct Daita {} struct Quic { /// In-addresses for the QUIC obfuscator. /// - /// There may be 0, 1 or 2 in IPs, depending on how many masque-proxy daemons running on the - /// relay. Hopefully the API will tell use the correct amount🤞. - addr_in: Vec<IpAddr>, + /// # Note + /// + /// This set must be non-empty. + /// + /// The primary IPs of the relay will be included if and only if they are listed here. + addr_in: Vec1<IpAddr>, /// Authorization token token: String, /// Hostname where masque proxy is hosted diff --git a/mullvad-management-interface/Cargo.toml b/mullvad-management-interface/Cargo.toml index e502ddeecf..29c84537be 100644 --- a/mullvad-management-interface/Cargo.toml +++ b/mullvad-management-interface/Cargo.toml @@ -25,6 +25,7 @@ prost = { workspace = true } prost-types = { workspace = true } futures = { workspace = true } tokio = { workspace = true, features = ["rt"] } +vec1 = { workspace = true } parity-tokio-ipc = { workspace = true } [target.'cfg(unix)'.dependencies] diff --git a/mullvad-management-interface/src/types/conversions/relay_list.rs b/mullvad-management-interface/src/types/conversions/relay_list.rs index 08ec379ba9..f7979725fe 100644 --- a/mullvad-management-interface/src/types/conversions/relay_list.rs +++ b/mullvad-management-interface/src/types/conversions/relay_list.rs @@ -5,6 +5,8 @@ use std::{ str::FromStr, }; +use vec1::Vec1; + use crate::types::{FromProtobufTypeError, conversions::bytes_to_pubkey, proto}; use super::net::try_transport_protocol_from_i32; @@ -186,6 +188,8 @@ impl TryFrom<proto::relay::relay_data::wireguard::Quic> for mullvad_types::relay .into_iter() .map(parse_addr) .collect::<Result<Vec<IpAddr>, FromProtobufTypeError>>()?; + let addr_in = Vec1::try_from_vec(addr_in) + .map_err(|_err| FromProtobufTypeError::InvalidArgument("Invalid QUIC object"))?; Ok(Self::new(addr_in, token, domain)) } } diff --git a/mullvad-relay-selector/Cargo.toml b/mullvad-relay-selector/Cargo.toml index dc3da3a5d6..3bb0f7665e 100644 --- a/mullvad-relay-selector/Cargo.toml +++ b/mullvad-relay-selector/Cargo.toml @@ -20,6 +20,7 @@ rand = "0.8.5" serde_json = { workspace = true } talpid-types = { path = "../talpid-types" } +vec1 = { workspace = true } mullvad-types = { path = "../mullvad-types" } intersection-derive = { path = "../mullvad-types/intersection-derive"} diff --git a/mullvad-relay-selector/src/relay_selector/matcher.rs b/mullvad-relay-selector/src/relay_selector/matcher.rs index f6bf70f494..6b76eecef8 100644 --- a/mullvad-relay-selector/src/relay_selector/matcher.rs +++ b/mullvad-relay-selector/src/relay_selector/matcher.rs @@ -145,18 +145,13 @@ fn filter_on_obfuscation( ) } // QUIC is only enabled on some relays - ObfuscationQuery::Quic => relay.wireguard().is_some_and(|wg| { - if let Some(quic) = wg.quic() { - // Only include relay if it has addresses for the selected IP version - matches!( - (query.ip_version, quic.in_ipv4(), quic.in_ipv6()), - (Constraint::Only(IpVersion::V4), Some(_), _) - | (Constraint::Only(IpVersion::V6), _, Some(_)) - | (Constraint::Any, _, _) - ) - } else { - false - } + ObfuscationQuery::Quic => relay.wireguard().is_some_and(|wg| match wg.quic() { + Some(quic) => match query.ip_version { + Constraint::Any => true, + Constraint::Only(IpVersion::V4) => quic.in_ipv4().is_some(), + Constraint::Only(IpVersion::V6) => quic.in_ipv6().is_some(), + }, + None => false, }), // Other relays are compatible with this query ObfuscationQuery::Off | ObfuscationQuery::Auto | ObfuscationQuery::Udp2tcp(_) => true, diff --git a/mullvad-relay-selector/tests/relay_selector.rs b/mullvad-relay-selector/tests/relay_selector.rs index ad91c192d5..87a089af62 100644 --- a/mullvad-relay-selector/tests/relay_selector.rs +++ b/mullvad-relay-selector/tests/relay_selector.rs @@ -32,6 +32,7 @@ use mullvad_types::{ WireguardRelayEndpointData, }, }; +use vec1::vec1; static DUMMY_LOCATION: LazyLock<Location> = LazyLock::new(|| Location { country: "Sweden".to_string(), @@ -72,7 +73,7 @@ static RELAYS: LazyLock<RelayList> = LazyLock::new(|| RelayList { WireguardRelayEndpointData::new(WIREGUARD_PUBKEY.clone()) .set_daita(true) .set_quic(Quic::new( - vec![ + vec1![ "185.213.154.68".parse().unwrap(), "2a03:1b20:5:f011::a09f".parse().unwrap(), ], diff --git a/mullvad-types/Cargo.toml b/mullvad-types/Cargo.toml index 5878767458..36efa91eda 100644 --- a/mullvad-types/Cargo.toml +++ b/mullvad-types/Cargo.toml @@ -19,6 +19,7 @@ log = { workspace = true } regex = "1" serde = { workspace = true, features = ["derive"] } uuid = { version = "1.4.1", features = ["v4", "serde" ] } +vec1 = { workspace = true } talpid-types = { path = "../talpid-types" } intersection-derive = { path = "intersection-derive" } diff --git a/mullvad-types/src/relay_list.rs b/mullvad-types/src/relay_list.rs index b8f528bba2..ee3c107b7e 100644 --- a/mullvad-types/src/relay_list.rs +++ b/mullvad-types/src/relay_list.rs @@ -6,6 +6,7 @@ use std::{ ops::RangeInclusive, }; use talpid_types::net::{TransportProtocol, proxy::Shadowsocks, wireguard}; +use vec1::Vec1; /// Stores a list of relays for each country obtained from the API using /// `mullvad_api::RelayListProxy`. This can also be passed to frontends. @@ -143,8 +144,11 @@ impl Relay { pub struct Quic { /// In-addresses for the QUIC obfuscator. /// - /// There may be 0, 1 or 2 in IPs, depending on how many masque-proxy daemons running on the - /// relay. Hopefully the API will tell use the correct amount🤞. + /// # Note + /// + /// This set must be non-empty. + /// + /// The primary IPs of the relay will be included if and only if they are listed here. addr_in: HashSet<IpAddr>, /// Authorization token token: String, @@ -153,10 +157,9 @@ pub struct Quic { } impl Quic { - pub fn new(addr_in: impl IntoIterator<Item = IpAddr>, token: String, domain: String) -> Self { - let addr_in = HashSet::from_iter(addr_in); + pub fn new(addr_in: Vec1<IpAddr>, token: String, domain: String) -> Self { Self { - addr_in, + addr_in: addr_in.into_iter().collect(), token, domain, } diff --git a/test/Cargo.lock b/test/Cargo.lock index fe99ba1cab..af17315717 100644 --- a/test/Cargo.lock +++ b/test/Cargo.lock @@ -2119,6 +2119,7 @@ dependencies = [ "tokio-socks", "tower 0.5.1", "uuid", + "vec1", ] [[package]] @@ -2167,6 +2168,7 @@ dependencies = [ "tonic", "tonic-build", "tower 0.5.1", + "vec1", ] [[package]] @@ -2194,6 +2196,7 @@ dependencies = [ "serde_json", "talpid-types", "thiserror 2.0.3", + "vec1", ] [[package]] @@ -2211,6 +2214,7 @@ dependencies = [ "talpid-types", "thiserror 2.0.3", "uuid", + "vec1", ] [[package]] @@ -4385,6 +4389,9 @@ name = "vec1" version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab68b56840f69efb0fefbe3ab6661499217ffdc58e2eef7c3f6f69835386322" +dependencies = [ + "serde", +] [[package]] name = "version_check" |
