diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-08-14 12:53:56 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-08-16 09:13:30 +0200 |
| commit | 7b305bf624fe19e783fba8a46edf9fa54ed0d1d0 (patch) | |
| tree | ff66a2349b7f35a2c8f04bd0e1170a6e7f80b940 | |
| parent | 68998722a44687acf39e018a501dc3b290df370a (diff) | |
| download | mullvadvpn-7b305bf624fe19e783fba8a46edf9fa54ed0d1d0.tar.xz mullvadvpn-7b305bf624fe19e783fba8a46edf9fa54ed0d1d0.zip | |
Propagate inner obfuscation error
| -rw-r--r-- | mullvad-relay-selector/src/error.rs | 2 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/helpers.rs | 32 | ||||
| -rw-r--r-- | mullvad-relay-selector/src/relay_selector/mod.rs | 6 |
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)) } |
