diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-12-22 13:03:25 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2024-01-08 09:04:49 +0100 |
| commit | 0dbebfd86be58d7b5e8ae92f637a3cdbc88b62db (patch) | |
| tree | 2ac0841fce76224ea381df274116f46b267ede3e | |
| parent | 10c990ee1d296970ecd60fbde0ce147ca922ec99 (diff) | |
| download | mullvadvpn-0dbebfd86be58d7b5e8ae92f637a3cdbc88b62db.tar.xz mullvadvpn-0dbebfd86be58d7b5e8ae92f637a3cdbc88b62db.zip | |
Remove `ApiEndpointUpdateHandler`
Previously, the `mullvad-api` would tell the `mullvad-daemon` that it
wanted a new API endpoint by calling a certain callback
(`ApiEndpointUpdateCallback`), which would asynchronously resolve a new
API endpoint and tell the daemon to punch an appropriate hole in the
firewall for that particular endpoint before the `mullvad-api` crate
would consume it.
The logic of the callback can be moved inside `AccessModeSelector`,
which simplifies the contract between `mullvad-daemon` and `mullvad-api`
somewhat.
| -rw-r--r-- | mullvad-api/src/bin/relay_list.rs | 2 | ||||
| -rw-r--r-- | mullvad-api/src/lib.rs | 20 | ||||
| -rw-r--r-- | mullvad-api/src/proxy.rs | 38 | ||||
| -rw-r--r-- | mullvad-api/src/rest.rs | 49 | ||||
| -rw-r--r-- | mullvad-daemon/src/api.rs | 53 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 10 | ||||
| -rw-r--r-- | mullvad-problem-report/src/lib.rs | 1 | ||||
| -rw-r--r-- | mullvad-setup/src/main.rs | 1 | ||||
| -rw-r--r-- | test/test-manager/src/tests/account.rs | 5 |
9 files changed, 41 insertions, 138 deletions
diff --git a/mullvad-api/src/bin/relay_list.rs b/mullvad-api/src/bin/relay_list.rs index ffb65c28b2..c016b4c8a1 100644 --- a/mullvad-api/src/bin/relay_list.rs +++ b/mullvad-api/src/bin/relay_list.rs @@ -13,7 +13,7 @@ async fn main() { let relay_list_request = RelayListProxy::new( runtime - .mullvad_rest_handle(ApiConnectionMode::Direct.into_repeat(), |_| async { true }) + .mullvad_rest_handle(ApiConnectionMode::Direct.into_repeat()) .await, ) .relay_list(None) diff --git a/mullvad-api/src/lib.rs b/mullvad-api/src/lib.rs index ae7929deec..237ed100d4 100644 --- a/mullvad-api/src/lib.rs +++ b/mullvad-api/src/lib.rs @@ -18,7 +18,7 @@ use std::{ path::Path, sync::OnceLock, }; -use talpid_types::{net::AllowedEndpoint, ErrorExt}; +use talpid_types::ErrorExt; pub mod availability; use availability::{ApiAvailability, ApiAvailabilityHandle}; @@ -216,19 +216,6 @@ pub enum Error { ApiCheckError(#[error(source)] availability::Error), } -/// Closure that receives the next API (real or proxy) endpoint to use for `api.mullvad.net`. -/// It should return a future that determines whether to reject the new endpoint or not. -pub trait ApiEndpointUpdateCallback: Fn(AllowedEndpoint) -> Self::AcceptedNewEndpoint { - type AcceptedNewEndpoint: Future<Output = bool> + Send; -} - -impl<U, T: Future<Output = bool> + Send> ApiEndpointUpdateCallback for U -where - U: Fn(AllowedEndpoint) -> T, -{ - type AcceptedNewEndpoint = T; -} - impl Runtime { /// Create a new `Runtime`. pub fn new(handle: tokio::runtime::Handle) -> Result<Self, Error> { @@ -305,7 +292,6 @@ impl Runtime { &self, sni_hostname: Option<String>, proxy_provider: T, - new_address_callback: impl ApiEndpointUpdateCallback + Send + Sync + 'static, #[cfg(target_os = "android")] socket_bypass_tx: Option<mpsc::Sender<SocketBypassRequest>>, ) -> rest::RequestServiceHandle { rest::RequestService::spawn( @@ -313,7 +299,6 @@ impl Runtime { self.api_availability.handle(), self.address_cache.clone(), proxy_provider, - new_address_callback, #[cfg(target_os = "android")] socket_bypass_tx, ) @@ -326,13 +311,11 @@ impl Runtime { >( &self, proxy_provider: T, - new_address_callback: impl ApiEndpointUpdateCallback + Send + Sync + 'static, ) -> rest::MullvadRestHandle { let service = self .new_request_service( Some(API.host.clone()), proxy_provider, - new_address_callback, #[cfg(target_os = "android")] self.socket_bypass_tx.clone(), ) @@ -353,7 +336,6 @@ impl Runtime { self.new_request_service( None, ApiConnectionMode::Direct.into_repeat(), - |_| async { true }, #[cfg(target_os = "android")] None, ) diff --git a/mullvad-api/src/proxy.rs b/mullvad-api/src/proxy.rs index 3c7d071d92..2b4821ba64 100644 --- a/mullvad-api/src/proxy.rs +++ b/mullvad-api/src/proxy.rs @@ -8,7 +8,7 @@ use std::{ task::{self, Poll}, }; use talpid_types::{ - net::{proxy, AllowedClients, Endpoint, TransportProtocol}, + net::{proxy, Endpoint, TransportProtocol}, ErrorExt, }; use tokio::{ @@ -70,6 +70,16 @@ impl fmt::Display for ProxyConfig { } } +impl From<proxy::CustomProxy> for ProxyConfig { + fn from(value: proxy::CustomProxy) -> Self { + match value { + proxy::CustomProxy::Shadowsocks(shadowsocks) => ProxyConfig::Shadowsocks(shadowsocks), + proxy::CustomProxy::Socks5Local(socks) => ProxyConfig::Socks5Local(socks), + proxy::CustomProxy::Socks5Remote(socks) => ProxyConfig::Socks5Remote(socks), + } + } +} + impl ApiConnectionMode { /// Reads the proxy config from `CURRENT_CONFIG_FILENAME`. /// This returns `ApiConnectionMode::Direct` if reading from disk fails for any reason. @@ -139,32 +149,6 @@ impl ApiConnectionMode { } } - #[cfg(unix)] - pub fn allowed_clients(&self) -> AllowedClients { - match self { - ApiConnectionMode::Proxied(ProxyConfig::Socks5Local(_)) => AllowedClients::All, - ApiConnectionMode::Direct | ApiConnectionMode::Proxied(_) => AllowedClients::Root, - } - } - - #[cfg(windows)] - pub fn allowed_clients(&self) -> AllowedClients { - match self { - ApiConnectionMode::Proxied(ProxyConfig::Socks5Local(_)) => AllowedClients::all(), - ApiConnectionMode::Direct | ApiConnectionMode::Proxied(_) => { - let daemon_exe = std::env::current_exe().expect("failed to obtain executable path"); - vec![ - daemon_exe - .parent() - .expect("missing executable parent directory") - .join("mullvad-problem-report.exe"), - daemon_exe, - ] - .into() - } - } - } - pub fn is_proxy(&self) -> bool { *self != ApiConnectionMode::Direct } diff --git a/mullvad-api/src/rest.rs b/mullvad-api/src/rest.rs index 6332c1266e..9f1e88a751 100644 --- a/mullvad-api/src/rest.rs +++ b/mullvad-api/src/rest.rs @@ -24,10 +24,7 @@ use std::{ sync::{Arc, Weak}, time::Duration, }; -use talpid_types::{ - net::{AllowedEndpoint, Endpoint, TransportProtocol}, - ErrorExt, -}; +use talpid_types::ErrorExt; #[cfg(feature = "api-override")] use crate::API; @@ -123,36 +120,24 @@ impl Error { } } -use super::ApiEndpointUpdateCallback; - /// A service that executes HTTP requests, allowing for on-demand termination of all in-flight /// requests -pub(crate) struct RequestService< - T: Stream<Item = ApiConnectionMode>, - F: ApiEndpointUpdateCallback + Send, -> { +pub(crate) struct RequestService<T: Stream<Item = ApiConnectionMode>> { command_tx: Weak<mpsc::UnboundedSender<RequestCommand>>, command_rx: mpsc::UnboundedReceiver<RequestCommand>, connector_handle: HttpsConnectorWithSniHandle, client: hyper::Client<HttpsConnectorWithSni, hyper::Body>, proxy_config_provider: T, - new_address_callback: F, - address_cache: AddressCache, api_availability: ApiAvailabilityHandle, } -impl< - T: Stream<Item = ApiConnectionMode> + Unpin + Send + 'static, - F: ApiEndpointUpdateCallback + Send + Sync + 'static, - > RequestService<T, F> -{ +impl<T: Stream<Item = ApiConnectionMode> + Unpin + Send + 'static> RequestService<T> { /// Constructs a new request service. pub async fn spawn( sni_hostname: Option<String>, api_availability: ApiAvailabilityHandle, address_cache: AddressCache, mut proxy_config_provider: T, - new_address_callback: F, #[cfg(target_os = "android")] socket_bypass_tx: Option<mpsc::Sender<SocketBypassRequest>>, ) -> RequestServiceHandle { let (connector, connector_handle) = HttpsConnectorWithSni::new( @@ -184,8 +169,6 @@ impl< connector_handle, client, proxy_config_provider, - new_address_callback, - address_cache, api_availability, }; let handle = RequestServiceHandle { tx: command_tx }; @@ -203,26 +186,14 @@ impl< } RequestCommand::NextApiConfig(completion_tx) => { #[cfg(feature = "api-override")] - if API.force_direct_connection { - log::debug!("Ignoring API connection mode"); - let _ = completion_tx.send(Ok(())); - return; - } + let force_direct_connection = API.force_direct_connection; + #[cfg(not(feature = "api-override"))] + let force_direct_connection = false; - if let Some(new_config) = self.proxy_config_provider.next().await { - let endpoint = match new_config.get_endpoint() { - Some(endpoint) => endpoint, - None => Endpoint::from_socket_address( - self.address_cache.get_address().await, - TransportProtocol::Tcp, - ), - }; - let clients = new_config.allowed_clients(); - let allowed_endpoint = AllowedEndpoint { endpoint, clients }; - // Switch to new connection mode unless rejected by address change callback - if (self.new_address_callback)(allowed_endpoint).await { - self.connector_handle.set_connection_mode(new_config); - } + if force_direct_connection { + log::debug!("Ignoring API connection mode"); + } else if let Some(connection_mode) = self.proxy_config_provider.next().await { + self.connector_handle.set_connection_mode(connection_mode); } let _ = completion_tx.send(Ok(())); diff --git a/mullvad-daemon/src/api.rs b/mullvad-daemon/src/api.rs index 6efec8112b..e680d80ef1 100644 --- a/mullvad-daemon/src/api.rs +++ b/mullvad-daemon/src/api.rs @@ -22,10 +22,7 @@ use mullvad_relay_selector::RelaySelector; use mullvad_types::access_method::{AccessMethod, AccessMethodSetting, BuiltInAccessMethod}; use std::{net::SocketAddr, path::PathBuf}; use talpid_core::mpsc::Sender; -use talpid_types::net::{ - proxy::{self, CustomProxy}, - AllowedClients, AllowedEndpoint, Endpoint, TransportProtocol, -}; +use talpid_types::net::{AllowedClients, AllowedEndpoint, Endpoint, TransportProtocol}; pub enum Message { Get(ResponseTx<ResolvedConnectionMode>), @@ -434,44 +431,26 @@ impl AccessModeSelector { } /// Ad-hoc version of [`std::convert::From::from`], but since some -/// [`ApiConnectionMode`]s require extra logic/data from -/// [`ApiConnectionModeProvider`] the standard [`std::convert::From`] trait -/// can not be implemented. +/// [`ApiConnectionMode`]s require extra logic/data from [`RelaySelector`] to be +/// instantiated the standard [`std::convert::From`] trait can not be +/// implemented. fn resolve_connection_mode( access_method: AccessMethod, relay_selector: &RelaySelector, ) -> ApiConnectionMode { match access_method { - AccessMethod::BuiltIn(access_method) => match access_method { - BuiltInAccessMethod::Direct => ApiConnectionMode::Direct, - BuiltInAccessMethod::Bridge => relay_selector - .get_bridge_forced() - .and_then(|settings| match settings { - CustomProxy::Shadowsocks(settings) => Some(ApiConnectionMode::Proxied( - ProxyConfig::Shadowsocks(proxy::Shadowsocks::new( - settings.endpoint, - settings.cipher, - settings.password, - )), - )), - _ => { - log::error!("Received unexpected proxy settings type"); - None - } - }) - .unwrap_or(ApiConnectionMode::Direct), - }, - AccessMethod::Custom(access_method) => match access_method { - CustomProxy::Shadowsocks(shadowsocks) => { - ApiConnectionMode::Proxied(ProxyConfig::Shadowsocks(shadowsocks)) - } - CustomProxy::Socks5Local(socks) => { - ApiConnectionMode::Proxied(ProxyConfig::Socks5Local(socks)) - } - CustomProxy::Socks5Remote(socks) => { - ApiConnectionMode::Proxied(ProxyConfig::Socks5Remote(socks)) - } - }, + AccessMethod::BuiltIn(BuiltInAccessMethod::Direct) => ApiConnectionMode::Direct, + AccessMethod::BuiltIn(BuiltInAccessMethod::Bridge) => relay_selector + .get_bridge_forced() + .map(ProxyConfig::from) + .map(ApiConnectionMode::Proxied) + .unwrap_or_else(|| { + log::error!( + "Received unexpected proxy settings type. Defaulting to direct API connection" + ); + ApiConnectionMode::Direct + }), + AccessMethod::Custom(config) => ApiConnectionMode::Proxied(ProxyConfig::from(config)), } } diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index f505ac94e4..88d78a961d 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -672,8 +672,6 @@ where let api_availability = api_runtime.availability_handle(); api_availability.suspend(); - let endpoint_updater = api::ApiEndpointUpdaterHandle::new(); - let migration_data = migrations::migrate_all(&cache_dir, &settings_dir) .await .unwrap_or_else(|error| { @@ -715,10 +713,7 @@ where ); let api_handle = api_runtime - .mullvad_rest_handle( - Box::pin(connection_modes_handler.clone().into_stream()), - endpoint_updater.callback(), - ) + .mullvad_rest_handle(Box::pin(connection_modes_handler.clone().into_stream())) .await; let migration_complete = if let Some(migration_data) = migration_data { @@ -823,9 +818,6 @@ where .await .map_err(Error::TunnelError)?; - endpoint_updater - .set_tunnel_command_tx(Arc::downgrade(tunnel_state_machine_handle.command_tx())); - api::forward_offline_state(api_availability.clone(), offline_state_rx); let relay_list_listener = event_listener.clone(); diff --git a/mullvad-problem-report/src/lib.rs b/mullvad-problem-report/src/lib.rs index 707b1d4e8b..1f687b4570 100644 --- a/mullvad-problem-report/src/lib.rs +++ b/mullvad-problem-report/src/lib.rs @@ -305,7 +305,6 @@ async fn send_problem_report_inner( ApiConnectionMode::try_from_cache(cache_dir) .await .into_repeat(), - |_| async { true }, ) .await, ); diff --git a/mullvad-setup/src/main.rs b/mullvad-setup/src/main.rs index bcae459442..f89baeb049 100644 --- a/mullvad-setup/src/main.rs +++ b/mullvad-setup/src/main.rs @@ -165,7 +165,6 @@ async fn remove_device() -> Result<(), Error> { ApiConnectionMode::try_from_cache(&cache_path) .await .into_repeat(), - |_| async { true }, ) .await, ); diff --git a/test/test-manager/src/tests/account.rs b/test/test-manager/src/tests/account.rs index 78eb42adc4..8b30f85768 100644 --- a/test/test-manager/src/tests/account.rs +++ b/test/test-manager/src/tests/account.rs @@ -237,10 +237,7 @@ pub async fn new_device_client() -> DevicesProxy { let api = mullvad_api::Runtime::new(tokio::runtime::Handle::current()) .expect("failed to create api runtime"); let rest_handle = api - .mullvad_rest_handle( - mullvad_api::proxy::ApiConnectionMode::Direct.into_repeat(), - |_| async { true }, - ) + .mullvad_rest_handle(mullvad_api::proxy::ApiConnectionMode::Direct.into_repeat()) .await; DevicesProxy::new(rest_handle) } |
