summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-08-14 12:53:56 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-08-16 09:13:30 +0200
commit7b305bf624fe19e783fba8a46edf9fa54ed0d1d0 (patch)
treeff66a2349b7f35a2c8f04bd0e1170a6e7f80b940
parent68998722a44687acf39e018a501dc3b290df370a (diff)
downloadmullvadvpn-7b305bf624fe19e783fba8a46edf9fa54ed0d1d0.tar.xz
mullvadvpn-7b305bf624fe19e783fba8a46edf9fa54ed0d1d0.zip
Propagate inner obfuscation error
-rw-r--r--mullvad-relay-selector/src/error.rs2
-rw-r--r--mullvad-relay-selector/src/relay_selector/helpers.rs32
-rw-r--r--mullvad-relay-selector/src/relay_selector/mod.rs6
3 files changed, 23 insertions, 17 deletions
diff --git a/mullvad-relay-selector/src/error.rs b/mullvad-relay-selector/src/error.rs
index 3e70f2429b..aefd931da6 100644
--- a/mullvad-relay-selector/src/error.rs
+++ b/mullvad-relay-selector/src/error.rs
@@ -20,7 +20,7 @@ pub enum Error {
NoBridge,
#[error("No obfuscators matching current constraints")]
- NoObfuscator,
+ NoObfuscator(#[source] Box<dyn std::error::Error + Send + Sync>),
#[error("No endpoint could be constructed due to {} for relay {:?}", .internal, .relay)]
NoEndpoint {
diff --git a/mullvad-relay-selector/src/relay_selector/helpers.rs b/mullvad-relay-selector/src/relay_selector/helpers.rs
index fd30c47043..27e3960320 100644
--- a/mullvad-relay-selector/src/relay_selector/helpers.rs
+++ b/mullvad-relay-selector/src/relay_selector/helpers.rs
@@ -24,6 +24,8 @@ const SHADOWSOCKS_EXTRA_PORT_RANGES: &[(u16, u16)] = &[(1, u16::MAX)];
pub enum Error {
#[error("Port selection algorithm is broken")]
PortSelectionAlgorithm,
+ #[error("Found no valid port matching the selected settings")]
+ NoMatchingPort,
}
/// Picks a relay using [pick_random_relay_weighted], using the `weight` member of each relay
@@ -77,21 +79,21 @@ pub fn get_udp2tcp_obfuscator(
udp2tcp_ports: &[u16],
relay: Relay,
endpoint: &MullvadWireguardEndpoint,
-) -> Option<SelectedObfuscator> {
+) -> Result<SelectedObfuscator, Error> {
let udp2tcp_endpoint_port =
get_udp2tcp_obfuscator_port(obfuscation_settings_constraint, udp2tcp_ports)?;
let config = ObfuscatorConfig::Udp2Tcp {
endpoint: SocketAddr::new(endpoint.peer.endpoint.ip(), udp2tcp_endpoint_port),
};
- Some(SelectedObfuscator { config, relay })
+ Ok(SelectedObfuscator { config, relay })
}
-pub fn get_udp2tcp_obfuscator_port(
+fn get_udp2tcp_obfuscator_port(
obfuscation_settings: &Udp2TcpObfuscationSettings,
udp2tcp_ports: &[u16],
-) -> Option<u16> {
- if let Constraint::Only(desired_port) = obfuscation_settings.port {
+) -> Result<u16, Error> {
+ let port = if let Constraint::Only(desired_port) = obfuscation_settings.port {
udp2tcp_ports
.iter()
.find(|&candidate| desired_port == *candidate)
@@ -99,7 +101,8 @@ pub fn get_udp2tcp_obfuscator_port(
} else {
// There are no specific obfuscation settings to take into consideration in this case.
udp2tcp_ports.choose(&mut thread_rng()).copied()
- }
+ };
+ port.ok_or(Error::NoMatchingPort)
}
pub fn get_shadowsocks_obfuscator(
@@ -107,7 +110,7 @@ pub fn get_shadowsocks_obfuscator(
non_extra_port_ranges: &[(u16, u16)],
relay: Relay,
endpoint: &MullvadWireguardEndpoint,
-) -> Option<SelectedObfuscator> {
+) -> Result<SelectedObfuscator, Error> {
let port = settings.port;
let extra_addrs = match &relay.endpoint_data {
mullvad_types::relay_list::RelayEndpointData::Wireguard(wg) => {
@@ -123,7 +126,7 @@ pub fn get_shadowsocks_obfuscator(
port,
)?;
- Some(SelectedObfuscator {
+ Ok(SelectedObfuscator {
config: ObfuscatorConfig::Shadowsocks { endpoint },
relay,
})
@@ -137,7 +140,7 @@ fn get_shadowsocks_obfuscator_inner(
wg_in_addr_port_ranges: &[(u16, u16)],
extra_in_addrs: &[IpAddr],
desired_port: Constraint<u16>,
-) -> Option<SocketAddr> {
+) -> Result<SocketAddr, Error> {
// Filter out addresses for the wrong address family
let extra_in_addrs: Vec<_> = extra_in_addrs
.iter()
@@ -164,9 +167,10 @@ fn get_shadowsocks_obfuscator_inner(
Constraint::Only(_port) => None,
// Selected no specific port
Constraint::Any => super::helpers::select_random_port(port_ranges).ok(),
- }?;
+ }
+ .ok_or(Error::NoMatchingPort)?;
- Some(SocketAddr::from((in_ip, selected_port)))
+ Ok(SocketAddr::from((in_ip, selected_port)))
}
/// Selects a random port number from a list of provided port ranges.
@@ -255,7 +259,7 @@ mod tests {
Constraint::Only(OUT_OF_RANGE_PORT),
);
assert!(
- selected_addr.is_none(),
+ selected_addr.is_err(),
"expected no relay for port outside range, found {selected_addr:?}"
);
}
@@ -336,7 +340,7 @@ mod tests {
Constraint::Only(OUT_OF_RANGE_PORT),
);
assert!(
- selected_addr.is_none(),
+ selected_addr.is_err(),
"expected no match for out-of-range port"
);
@@ -347,7 +351,7 @@ mod tests {
Constraint::Only(IN_RANGE_PORT),
);
assert!(
- selected_addr.is_some(),
+ selected_addr.is_ok(),
"expected match for within-range port"
);
}
diff --git a/mullvad-relay-selector/src/relay_selector/mod.rs b/mullvad-relay-selector/src/relay_selector/mod.rs
index 853431f155..b60bb86f3c 100644
--- a/mullvad-relay-selector/src/relay_selector/mod.rs
+++ b/mullvad-relay-selector/src/relay_selector/mod.rs
@@ -794,6 +794,8 @@ impl RelaySelector {
WireguardConfig::Singlehop { exit } => exit,
WireguardConfig::Multihop { entry, .. } => entry,
};
+ let box_obfsucation_error = |error: helpers::Error| Error::NoObfuscator(Box::new(error));
+
match &query.wireguard_constraints.obfuscation {
ObfuscationQuery::Off | ObfuscationQuery::Auto => Ok(None),
ObfuscationQuery::Udp2tcp(settings) => {
@@ -801,7 +803,7 @@ impl RelaySelector {
helpers::get_udp2tcp_obfuscator(settings, udp2tcp_ports, obfuscator_relay, endpoint)
.map(Some)
- .ok_or(Error::NoObfuscator)
+ .map_err(box_obfsucation_error)
}
ObfuscationQuery::Shadowsocks(settings) => {
let port_ranges = &parsed_relays
@@ -814,7 +816,7 @@ impl RelaySelector {
obfuscator_relay,
endpoint,
)
- .ok_or(Error::NoObfuscator)?;
+ .map_err(box_obfsucation_error)?;
Ok(Some(obfuscation))
}