Skip to content

Commit aea3c07

Browse files
committed
Remove dependency on relay-selector in mullvad-api
1 parent 7ebf941 commit aea3c07

File tree

4 files changed

+79
-67
lines changed

4 files changed

+79
-67
lines changed

mullvad-api/src/access_mode.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use futures::{
1515
StreamExt,
1616
};
1717
use mullvad_encrypted_dns_proxy::state::EncryptedDnsProxyState;
18-
use mullvad_relay_selector::RelaySelector;
19-
use mullvad_types::access_method::{
20-
AccessMethod, AccessMethodSetting, BuiltInAccessMethod, Id, Settings,
18+
use mullvad_types::{
19+
access_method::{AccessMethod, AccessMethodSetting, BuiltInAccessMethod, Id, Settings},
20+
relay_list::ShadowsocksBridgeProvider,
2121
};
2222
use std::{marker::PhantomData, net::SocketAddr, path::PathBuf};
2323
use talpid_types::net::{proxy::CustomProxy, AllowedEndpoint, Endpoint, TransportProtocol};
@@ -251,7 +251,7 @@ pub struct AccessModeSelector<P> {
251251
cmd_rx: mpsc::UnboundedReceiver<Message>,
252252
cache_dir: PathBuf,
253253
/// Used for selecting a Bridge when the `Mullvad Bridges` access method is used.
254-
relay_selector: RelaySelector,
254+
bridge_provider: Box<dyn ShadowsocksBridgeProvider>,
255255
/// Used for selecting a config for the 'Encrypted DNS proxy' access method.
256256
encrypted_dns_proxy_cache: EncryptedDnsProxyState,
257257
access_method_settings: Settings,
@@ -270,7 +270,7 @@ where
270270
{
271271
pub async fn spawn(
272272
cache_dir: PathBuf,
273-
relay_selector: RelaySelector,
273+
bridge_provider: Box<dyn ShadowsocksBridgeProvider>,
274274
#[cfg_attr(not(feature = "api-override"), allow(unused_mut))]
275275
mut access_method_settings: Settings,
276276
#[cfg(feature = "api-override")] api_endpoint: ApiEndpoint,
@@ -294,7 +294,7 @@ where
294294
let (index, next) = Self::find_next_active(0, &access_method_settings);
295295
let initial_connection_mode = Self::resolve_inner_with_default(
296296
&next,
297-
&relay_selector,
297+
&bridge_provider,
298298
&mut encrypted_dns_proxy_cache,
299299
&address_cache,
300300
)
@@ -309,7 +309,7 @@ where
309309
api_endpoint,
310310
cmd_rx,
311311
cache_dir,
312-
relay_selector,
312+
bridge_provider,
313313
encrypted_dns_proxy_cache,
314314
access_method_settings,
315315
address_cache,
@@ -537,7 +537,7 @@ where
537537
) -> Option<ResolvedConnectionMode> {
538538
Self::resolve_inner(
539539
&access_method,
540-
&self.relay_selector,
540+
&self.bridge_provider,
541541
&mut self.encrypted_dns_proxy_cache,
542542
&self.address_cache,
543543
)
@@ -546,13 +546,16 @@ where
546546

547547
async fn resolve_inner(
548548
access_method: &AccessMethodSetting,
549-
relay_selector: &RelaySelector,
549+
bridge_provider: &Box<dyn ShadowsocksBridgeProvider>,
550550
encrypted_dns_proxy_cache: &mut EncryptedDnsProxyState,
551551
address_cache: &AddressCache,
552552
) -> Option<ResolvedConnectionMode> {
553-
let connection_mode =
554-
Self::resolve_connection_mode(access_method, relay_selector, encrypted_dns_proxy_cache)
555-
.await?;
553+
let connection_mode = Self::resolve_connection_mode(
554+
access_method,
555+
bridge_provider,
556+
encrypted_dns_proxy_cache,
557+
)
558+
.await?;
556559
let endpoint =
557560
resolve_allowed_endpoint::<P>(&connection_mode, address_cache.get_address().await);
558561
Some(ResolvedConnectionMode {
@@ -570,7 +573,7 @@ where
570573
) -> ResolvedConnectionMode {
571574
Self::resolve_inner_with_default(
572575
&access_method,
573-
&self.relay_selector,
576+
&self.bridge_provider,
574577
&mut self.encrypted_dns_proxy_cache,
575578
&self.address_cache,
576579
)
@@ -579,13 +582,13 @@ where
579582

580583
async fn resolve_inner_with_default(
581584
access_method: &AccessMethodSetting,
582-
relay_selector: &RelaySelector,
585+
bridge_provider: &Box<dyn ShadowsocksBridgeProvider>,
583586
encrypted_dns_proxy_cache: &mut EncryptedDnsProxyState,
584587
address_cache: &AddressCache,
585588
) -> ResolvedConnectionMode {
586589
match Self::resolve_inner(
587590
access_method,
588-
relay_selector,
591+
bridge_provider,
589592
encrypted_dns_proxy_cache,
590593
address_cache,
591594
)
@@ -609,14 +612,14 @@ where
609612

610613
async fn resolve_connection_mode(
611614
access_method: &AccessMethodSetting,
612-
relay_selector: &RelaySelector,
615+
bridge_provider: &Box<dyn ShadowsocksBridgeProvider>,
613616
encrypted_dns_proxy_cache: &mut EncryptedDnsProxyState,
614617
) -> Option<ApiConnectionMode> {
615618
let connection_mode = {
616619
match &access_method.access_method {
617620
AccessMethod::BuiltIn(BuiltInAccessMethod::Direct) => ApiConnectionMode::Direct,
618621
AccessMethod::BuiltIn(BuiltInAccessMethod::Bridge) => {
619-
let Some(bridge) = relay_selector.get_bridge_forced() else {
622+
let Some(bridge) = bridge_provider.get_bridge_forced() else {
620623
log::warn!("Could not select a Mullvad bridge");
621624
log::debug!("The relay list might be empty");
622625
return None;

mullvad-daemon/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -706,10 +706,12 @@ impl Daemon {
706706
.set_config(SelectorConfig::from_settings(settings));
707707
});
708708

709+
let bridge_provider = Box::new(relay_selector.clone());
710+
709711
let (access_mode_handler, access_mode_provider) =
710712
mullvad_api::access_mode::AccessModeSelector::<AllowedClientsSelector>::spawn(
711713
config.cache_dir.clone(),
712-
relay_selector.clone(),
714+
bridge_provider,
713715
settings.api_access_methods.clone(),
714716
#[cfg(feature = "api-override")]
715717
config.endpoint.clone(),

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

+52-49
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use mullvad_types::{
3939
OpenVpnConstraints, RelayConstraints, RelayOverride, RelaySettings, ResolvedBridgeSettings,
4040
WireguardConstraints,
4141
},
42-
relay_list::{Relay, RelayEndpointData, RelayList},
42+
relay_list::{Relay, RelayEndpointData, RelayList, ShadowsocksBridgeProvider},
4343
settings::Settings,
4444
wireguard::QuantumResistantState,
4545
CustomTunnelEndpoint, Intersection,
@@ -53,9 +53,10 @@ use talpid_types::{
5353
ErrorExt,
5454
};
5555

56-
/// [`WIREGUARD_RETRY_ORDER`] defines an ordered set of relay parameters which the relay selector should
57-
/// prioritize on successive connection attempts. Note that these will *never* override user
58-
/// preferences. See [the documentation on `RelayQuery`][RelayQuery] for further details.
56+
/// [`WIREGUARD_RETRY_ORDER`] defines an ordered set of relay parameters which the relay selector
57+
/// should should prioritize on successive connection attempts. Note that these will *never*
58+
/// override user preferences. See [the documentation on `RelayQuery`][RelayQuery] for further
59+
/// details.
5960
///
6061
/// This list should be kept in sync with the expected behavior defined in `docs/relay-selector.md`
6162
pub static WIREGUARD_RETRY_ORDER: LazyLock<Vec<RelayQuery>> = LazyLock::new(|| {
@@ -83,8 +84,8 @@ pub static WIREGUARD_RETRY_ORDER: LazyLock<Vec<RelayQuery>> = LazyLock::new(|| {
8384
]
8485
});
8586

86-
/// [`OPENVPN_RETRY_ORDER`] defines an ordered set of relay parameters which the relay selector should
87-
/// prioritize on successive connection attempts. Note that these will *never* override user
87+
/// [`OPENVPN_RETRY_ORDER`] defines an ordered set of relay parameters which the relay selector
88+
/// should prioritize on successive connection attempts. Note that these will *never* override user
8889
/// preferences. See [the documentation on `RelayQuery`][RelayQuery] for further details.
8990
///
9091
/// This list should be kept in sync with the expected behavior defined in `docs/relay-selector.md`
@@ -435,6 +436,47 @@ impl<'a> TryFrom<NormalSelectorConfig<'a>> for RelayQuery {
435436
}
436437
}
437438

439+
impl ShadowsocksBridgeProvider for RelaySelector {
440+
/// Returns a non-custom bridge based on the relay and bridge constraints, ignoring the bridge
441+
/// state.
442+
fn get_bridge_forced(&self) -> Option<Shadowsocks> {
443+
let parsed_relays = &self.parsed_relays.lock().unwrap().parsed_list().clone();
444+
let config = self.config.lock().unwrap();
445+
let specialized_config = SpecializedSelectorConfig::from(&*config);
446+
447+
let near_location = match specialized_config {
448+
SpecializedSelectorConfig::Normal(config) => RelayQuery::try_from(config.clone())
449+
.ok()
450+
.and_then(|user_preferences| {
451+
Self::get_relay_midpoint(&user_preferences, parsed_relays, config.custom_lists)
452+
}),
453+
SpecializedSelectorConfig::Custom(_) => None,
454+
};
455+
456+
let bridge_settings = &config.bridge_settings;
457+
let constraints = match bridge_settings.resolve() {
458+
Ok(ResolvedBridgeSettings::Normal(settings)) => InternalBridgeConstraints {
459+
location: settings.location.clone(),
460+
providers: settings.providers.clone(),
461+
ownership: settings.ownership,
462+
transport_protocol: Constraint::Only(TransportProtocol::Tcp),
463+
},
464+
_ => InternalBridgeConstraints {
465+
location: Constraint::Any,
466+
providers: Constraint::Any,
467+
ownership: Constraint::Any,
468+
transport_protocol: Constraint::Only(TransportProtocol::Tcp),
469+
},
470+
};
471+
472+
let custom_lists = &config.custom_lists;
473+
Self::get_proxy_settings(parsed_relays, &constraints, near_location, custom_lists)
474+
.map(|(settings, _relay)| settings)
475+
.inspect_err(|error| log::error!("Failed to get bridge: {error}"))
476+
.ok()
477+
}
478+
}
479+
438480
impl RelaySelector {
439481
/// Returns a new `RelaySelector` backed by relays cached on disk.
440482
pub fn new(
@@ -507,45 +549,6 @@ impl RelaySelector {
507549
self.parsed_relays.lock().unwrap().last_updated()
508550
}
509551

510-
/// Returns a non-custom bridge based on the relay and bridge constraints, ignoring the bridge
511-
/// state.
512-
pub fn get_bridge_forced(&self) -> Option<Shadowsocks> {
513-
let parsed_relays = &self.parsed_relays.lock().unwrap().parsed_list().clone();
514-
let config = self.config.lock().unwrap();
515-
let specialized_config = SpecializedSelectorConfig::from(&*config);
516-
517-
let near_location = match specialized_config {
518-
SpecializedSelectorConfig::Normal(config) => RelayQuery::try_from(config.clone())
519-
.ok()
520-
.and_then(|user_preferences| {
521-
Self::get_relay_midpoint(&user_preferences, parsed_relays, config.custom_lists)
522-
}),
523-
SpecializedSelectorConfig::Custom(_) => None,
524-
};
525-
526-
let bridge_settings = &config.bridge_settings;
527-
let constraints = match bridge_settings.resolve() {
528-
Ok(ResolvedBridgeSettings::Normal(settings)) => InternalBridgeConstraints {
529-
location: settings.location.clone(),
530-
providers: settings.providers.clone(),
531-
ownership: settings.ownership,
532-
transport_protocol: Constraint::Only(TransportProtocol::Tcp),
533-
},
534-
_ => InternalBridgeConstraints {
535-
location: Constraint::Any,
536-
providers: Constraint::Any,
537-
ownership: Constraint::Any,
538-
transport_protocol: Constraint::Only(TransportProtocol::Tcp),
539-
},
540-
};
541-
542-
let custom_lists = &config.custom_lists;
543-
Self::get_proxy_settings(parsed_relays, &constraints, near_location, custom_lists)
544-
.map(|(settings, _relay)| settings)
545-
.inspect_err(|error| log::error!("Failed to get bridge: {error}"))
546-
.ok()
547-
}
548-
549552
/// Returns random relay and relay endpoint matching `query`.
550553
pub fn get_relay_by_query(&self, query: RelayQuery) -> Result<GetRelay, Error> {
551554
let config_guard = self.config.lock().unwrap();
@@ -697,10 +700,10 @@ impl RelaySelector {
697700
parsed_relays: &RelayList,
698701
custom_lists: &CustomListsSettings,
699702
) -> Result<GetRelay, Error> {
700-
// FIXME: A bit of defensive programming - calling `get_wireguard_relay_inner` with a query that
701-
// doesn't specify Wireguard as the desired tunnel type is not valid and will lead
702-
// to unwanted behavior. This should be seen as a workaround, and it would be nicer
703-
// to lift this invariant to be checked by the type system instead.
703+
// FIXME: A bit of defensive programming - calling `get_wireguard_relay_inner` with a query
704+
// that doesn't specify Wireguard as the desired tunnel type is not valid and will
705+
// lead to unwanted behavior. This should be seen as a workaround, and it would be
706+
// nicer to lift this invariant to be checked by the type system instead.
704707
let mut query = query.clone();
705708
query.set_tunnel_protocol(TunnelType::Wireguard)?;
706709
Self::get_wireguard_relay_inner(&query, custom_lists, parsed_relays)

mullvad-types/src/relay_list.rs

+4
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,7 @@ impl ShadowsocksEndpointData {
251251
}
252252
}
253253
}
254+
255+
pub trait ShadowsocksBridgeProvider: Send + Sync {
256+
fn get_bridge_forced(&self) -> Option<Shadowsocks>;
257+
}

0 commit comments

Comments
 (0)