1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
use mullvad_api::{
ApiEndpoint,
access_mode::AccessMethodResolver,
proxy::{ApiConnectionMode, ProxyConfig},
};
use mullvad_encrypted_dns_proxy::state::EncryptedDnsProxyState;
use mullvad_types::access_method::{AccessMethod, BuiltInAccessMethod};
use talpid_types::net::{
AllowedClients, AllowedEndpoint, Endpoint, TransportProtocol, proxy::CustomProxy,
};
use tonic::async_trait;
use super::{
address_cache_provider::SwiftAddressCacheWrapper,
shadowsocks_loader::SwiftShadowsocksLoaderWrapper,
};
#[derive(Debug)]
pub struct SwiftAccessMethodResolver {
endpoint: ApiEndpoint,
domain: String,
state: EncryptedDnsProxyState,
bridge_provider: SwiftShadowsocksLoaderWrapper,
address_cache: SwiftAddressCacheWrapper,
}
impl SwiftAccessMethodResolver {
pub fn new(
endpoint: ApiEndpoint,
domain: String,
state: EncryptedDnsProxyState,
bridge_provider: SwiftShadowsocksLoaderWrapper,
address_cache: SwiftAddressCacheWrapper,
) -> Self {
Self {
endpoint,
domain,
state,
bridge_provider,
address_cache,
}
}
}
#[async_trait]
impl AccessMethodResolver for SwiftAccessMethodResolver {
async fn resolve_access_method_setting(
&mut self,
access_method: &AccessMethod,
) -> Option<(AllowedEndpoint, ApiConnectionMode)> {
let connection_mode = match access_method {
AccessMethod::BuiltIn(BuiltInAccessMethod::Direct) => ApiConnectionMode::Direct,
AccessMethod::BuiltIn(BuiltInAccessMethod::Bridge) => {
let bridge = self.bridge_provider.get_bridges()?;
let proxy = CustomProxy::Shadowsocks(bridge);
ApiConnectionMode::Proxied(ProxyConfig::from(proxy))
}
AccessMethod::BuiltIn(BuiltInAccessMethod::EncryptedDnsProxy) => {
if let Err(error) = self.state.fetch_configs(self.domain.as_str()).await {
log::error!("{error:#?}");
}
let Some(edp) = self.state.next_configuration() else {
log::warn!("Could not select next Encrypted DNS proxy config");
return None;
};
ApiConnectionMode::Proxied(ProxyConfig::from(edp))
}
AccessMethod::Custom(config) => {
ApiConnectionMode::Proxied(ProxyConfig::from(config.clone()))
}
};
let allowed_endpoint = {
let endpoint = connection_mode.get_endpoint().unwrap_or_else(|| {
Endpoint::from_socket_address(
self.endpoint.address.unwrap(),
TransportProtocol::Tcp,
)
});
let clients = AllowedClients::All;
AllowedEndpoint { endpoint, clients }
};
Some((allowed_endpoint, connection_mode))
}
async fn default_connection_mode(&self) -> AllowedEndpoint {
let endpoint =
Endpoint::from_socket_address(self.address_cache.get_addrs(), TransportProtocol::Tcp);
AllowedEndpoint {
endpoint,
clients: AllowedClients::All,
}
}
}
|