Skip to content

Commit aa96f06

Browse files
committed
Propagate inner obfuscation error
1 parent 1198361 commit aa96f06

File tree

3 files changed

+23
-17
lines changed

3 files changed

+23
-17
lines changed

mullvad-relay-selector/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub enum Error {
2020
NoBridge,
2121

2222
#[error("No obfuscators matching current constraints")]
23-
NoObfuscator,
23+
NoObfuscator(#[source] Box<dyn std::error::Error + Send + Sync>),
2424

2525
#[error("No endpoint could be constructed due to {} for relay {:?}", .internal, .relay)]
2626
NoEndpoint {

mullvad-relay-selector/src/relay_selector/helpers.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const SHADOWSOCKS_EXTRA_PORT_RANGES: &[(u16, u16)] = &[(1, u16::MAX)];
2424
pub enum Error {
2525
#[error("Port selection algorithm is broken")]
2626
PortSelectionAlgorithm,
27+
#[error("Found no valid port matching the selected settings")]
28+
NoMatchingPort,
2729
}
2830

2931
/// Picks a relay using [pick_random_relay_weighted], using the `weight` member of each relay
@@ -77,37 +79,38 @@ pub fn get_udp2tcp_obfuscator(
7779
udp2tcp_ports: &[u16],
7880
relay: Relay,
7981
endpoint: &MullvadWireguardEndpoint,
80-
) -> Option<SelectedObfuscator> {
82+
) -> Result<SelectedObfuscator, Error> {
8183
let udp2tcp_endpoint_port =
8284
get_udp2tcp_obfuscator_port(obfuscation_settings_constraint, udp2tcp_ports)?;
8385
let config = ObfuscatorConfig::Udp2Tcp {
8486
endpoint: SocketAddr::new(endpoint.peer.endpoint.ip(), udp2tcp_endpoint_port),
8587
};
8688

87-
Some(SelectedObfuscator { config, relay })
89+
Ok(SelectedObfuscator { config, relay })
8890
}
8991

90-
pub fn get_udp2tcp_obfuscator_port(
92+
fn get_udp2tcp_obfuscator_port(
9193
obfuscation_settings: &Udp2TcpObfuscationSettings,
9294
udp2tcp_ports: &[u16],
93-
) -> Option<u16> {
94-
if let Constraint::Only(desired_port) = obfuscation_settings.port {
95+
) -> Result<u16, Error> {
96+
let port = if let Constraint::Only(desired_port) = obfuscation_settings.port {
9597
udp2tcp_ports
9698
.iter()
9799
.find(|&candidate| desired_port == *candidate)
98100
.copied()
99101
} else {
100102
// There are no specific obfuscation settings to take into consideration in this case.
101103
udp2tcp_ports.choose(&mut thread_rng()).copied()
102-
}
104+
};
105+
port.ok_or(Error::NoMatchingPort)
103106
}
104107

105108
pub fn get_shadowsocks_obfuscator(
106109
settings: &ShadowsocksSettings,
107110
non_extra_port_ranges: &[(u16, u16)],
108111
relay: Relay,
109112
endpoint: &MullvadWireguardEndpoint,
110-
) -> Option<SelectedObfuscator> {
113+
) -> Result<SelectedObfuscator, Error> {
111114
let port = settings.port;
112115
let extra_addrs = match &relay.endpoint_data {
113116
mullvad_types::relay_list::RelayEndpointData::Wireguard(wg) => {
@@ -123,7 +126,7 @@ pub fn get_shadowsocks_obfuscator(
123126
port,
124127
)?;
125128

126-
Some(SelectedObfuscator {
129+
Ok(SelectedObfuscator {
127130
config: ObfuscatorConfig::Shadowsocks { endpoint },
128131
relay,
129132
})
@@ -137,7 +140,7 @@ fn get_shadowsocks_obfuscator_inner(
137140
wg_in_addr_port_ranges: &[(u16, u16)],
138141
extra_in_addrs: &[IpAddr],
139142
desired_port: Constraint<u16>,
140-
) -> Option<SocketAddr> {
143+
) -> Result<SocketAddr, Error> {
141144
// Filter out addresses for the wrong address family
142145
let extra_in_addrs: Vec<_> = extra_in_addrs
143146
.iter()
@@ -164,9 +167,10 @@ fn get_shadowsocks_obfuscator_inner(
164167
Constraint::Only(_port) => None,
165168
// Selected no specific port
166169
Constraint::Any => super::helpers::select_random_port(port_ranges).ok(),
167-
}?;
170+
}
171+
.ok_or(Error::NoMatchingPort)?;
168172

169-
Some(SocketAddr::from((in_ip, selected_port)))
173+
Ok(SocketAddr::from((in_ip, selected_port)))
170174
}
171175

172176
/// Selects a random port number from a list of provided port ranges.
@@ -255,7 +259,7 @@ mod tests {
255259
Constraint::Only(OUT_OF_RANGE_PORT),
256260
);
257261
assert!(
258-
selected_addr.is_none(),
262+
selected_addr.is_err(),
259263
"expected no relay for port outside range, found {selected_addr:?}"
260264
);
261265
}
@@ -336,7 +340,7 @@ mod tests {
336340
Constraint::Only(OUT_OF_RANGE_PORT),
337341
);
338342
assert!(
339-
selected_addr.is_none(),
343+
selected_addr.is_err(),
340344
"expected no match for out-of-range port"
341345
);
342346

@@ -347,7 +351,7 @@ mod tests {
347351
Constraint::Only(IN_RANGE_PORT),
348352
);
349353
assert!(
350-
selected_addr.is_some(),
354+
selected_addr.is_ok(),
351355
"expected match for within-range port"
352356
);
353357
}

mullvad-relay-selector/src/relay_selector/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -794,14 +794,16 @@ impl RelaySelector {
794794
WireguardConfig::Singlehop { exit } => exit,
795795
WireguardConfig::Multihop { entry, .. } => entry,
796796
};
797+
let box_obfsucation_error = |error: helpers::Error| Error::NoObfuscator(Box::new(error));
798+
797799
match &query.wireguard_constraints.obfuscation {
798800
ObfuscationQuery::Off | ObfuscationQuery::Auto => Ok(None),
799801
ObfuscationQuery::Udp2tcp(settings) => {
800802
let udp2tcp_ports = &parsed_relays.parsed_list().wireguard.udp2tcp_ports;
801803

802804
helpers::get_udp2tcp_obfuscator(settings, udp2tcp_ports, obfuscator_relay, endpoint)
803805
.map(Some)
804-
.ok_or(Error::NoObfuscator)
806+
.map_err(box_obfsucation_error)
805807
}
806808
ObfuscationQuery::Shadowsocks(settings) => {
807809
let port_ranges = &parsed_relays
@@ -814,7 +816,7 @@ impl RelaySelector {
814816
obfuscator_relay,
815817
endpoint,
816818
)
817-
.ok_or(Error::NoObfuscator)?;
819+
.map_err(box_obfsucation_error)?;
818820

819821
Ok(Some(obfuscation))
820822
}

0 commit comments

Comments
 (0)