Skip to content

Commit 2dff4ec

Browse files
committed
trust-dns setsockopt with outbound socket configs
Outbound configurations, like outbound-fwmark, outbound-bind-interface, outbound-bind-addr, ... will also applies to the TCP/UDP sockets created by trust-dns DNS resolver. NOTE: On Android platform, DNS sockets will also be protected.
1 parent c1f505f commit 2dff4ec

File tree

17 files changed

+325
-196
lines changed

17 files changed

+325
-196
lines changed

Cargo.lock

+86-104
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "shadowsocks-rust"
3-
version = "1.15.3"
3+
version = "1.16.0"
44
authors = ["Shadowsocks Contributors"]
55
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
66
repository = "https://github.com/shadowsocks/shadowsocks-rust"
@@ -167,7 +167,7 @@ jemallocator = { version = "0.5", optional = true }
167167
snmalloc-rs = { version = "0.3", optional = true }
168168
rpmalloc = { version = "0.2", optional = true }
169169

170-
shadowsocks-service = { version = "1.15.0", path = "./crates/shadowsocks-service" }
170+
shadowsocks-service = { version = "1.16.0", path = "./crates/shadowsocks-service" }
171171

172172
[target.'cfg(unix)'.dependencies]
173173
daemonize = "0.5"

crates/shadowsocks-service/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "shadowsocks-service"
3-
version = "1.15.3"
3+
version = "1.16.0"
44
authors = ["Shadowsocks Contributors"]
55
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
66
repository = "https://github.com/shadowsocks/shadowsocks-rust"
@@ -107,7 +107,8 @@ libc = "0.2.141"
107107
hyper = { version = "0.14.25", optional = true, features = ["full"] }
108108
tower = { version = "0.4", optional = true }
109109

110-
trust-dns-resolver = { version = "0.22", optional = true, features = ["serde-config"] }
110+
# trust-dns-resolver = { version = "0.22", optional = true, features = ["serde-config"] }
111+
trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns.git", optional = true, features = ["serde-config"] }
111112

112113
idna = "0.3"
113114
ipnet = "2.7"
@@ -121,7 +122,7 @@ smoltcp = { version = "0.9", optional = true, default-features = false, features
121122
serde = { version = "1.0", features = ["derive"] }
122123
json5 = "0.4"
123124

124-
shadowsocks = { version = "1.15.3", path = "../shadowsocks", default-features = false }
125+
shadowsocks = { version = "1.16.0", path = "../shadowsocks", default-features = false }
125126

126127
# Just for the ioctl call macro
127128
[target.'cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]

crates/shadowsocks-service/src/config.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -2112,26 +2112,12 @@ impl Config {
21122112
};
21132113

21142114
if protocol.enable_udp() {
2115-
c.add_name_server(NameServerConfig {
2116-
socket_addr,
2117-
protocol: Protocol::Udp,
2118-
tls_dns_name: None,
2119-
trust_nx_responses: false,
2120-
#[cfg(any(feature = "dns-over-tls", feature = "dns-over-https"))]
2121-
tls_config: None,
2122-
bind_addr: None,
2123-
});
2115+
let ns_config = NameServerConfig::new(socket_addr, Protocol::Udp);
2116+
c.add_name_server(ns_config);
21242117
}
21252118
if protocol.enable_tcp() {
2126-
c.add_name_server(NameServerConfig {
2127-
socket_addr,
2128-
protocol: Protocol::Tcp,
2129-
tls_dns_name: None,
2130-
trust_nx_responses: false,
2131-
#[cfg(any(feature = "dns-over-tls", feature = "dns-over-https"))]
2132-
tls_config: None,
2133-
bind_addr: None,
2134-
});
2119+
let ns_config = NameServerConfig::new(socket_addr, Protocol::Tcp);
2120+
c.add_name_server(ns_config);
21352121
}
21362122
}
21372123

crates/shadowsocks-service/src/dns/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub async fn build_dns_resolver(dns: DnsConfig, ipv6_first: bool, connect_opts:
2323
};
2424

2525
if !force_system_builtin {
26-
return match DnsResolver::trust_dns_system_resolver(ipv6_first).await {
26+
return match DnsResolver::trust_dns_system_resolver(connect_opts.clone()).await {
2727
Ok(r) => Some(r),
2828
Err(err) => {
2929
warn!(
@@ -41,7 +41,7 @@ pub async fn build_dns_resolver(dns: DnsConfig, ipv6_first: bool, connect_opts:
4141
None
4242
}
4343
#[cfg(feature = "trust-dns")]
44-
DnsConfig::TrustDns(dns) => match DnsResolver::trust_dns_resolver(dns, ipv6_first).await {
44+
DnsConfig::TrustDns(dns) => match DnsResolver::trust_dns_resolver(dns, connect_opts.clone()).await {
4545
Ok(r) => Some(r),
4646
Err(err) => {
4747
use log::warn;

crates/shadowsocks-service/src/local/dns/dns_resolver.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::{
44
io::{self, ErrorKind},
5-
net::SocketAddr,
5+
net::{Ipv4Addr, Ipv6Addr, SocketAddr},
66
};
77

88
use async_trait::async_trait;
@@ -175,8 +175,8 @@ fn store_dns(res: Message, port: u16) -> Vec<SocketAddr> {
175175
let mut vaddr = Vec::new();
176176
for record in res.answers() {
177177
match record.data() {
178-
Some(RData::A(addr)) => vaddr.push(SocketAddr::new((*addr).into(), port)),
179-
Some(RData::AAAA(addr)) => vaddr.push(SocketAddr::new((*addr).into(), port)),
178+
Some(RData::A(addr)) => vaddr.push(SocketAddr::new(Ipv4Addr::from(*addr).into(), port)),
179+
Some(RData::AAAA(addr)) => vaddr.push(SocketAddr::new(Ipv6Addr::from(*addr).into(), port)),
180180
Some(rdata) => {
181181
trace!("skipped rdata {:?}", rdata);
182182
}

crates/shadowsocks-service/src/local/dns/server.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,8 @@ fn should_forward_by_response(
413413
return true;
414414
}
415415
let forward = match $rec.data() {
416-
Some(RData::A(ip)) => acl.check_ip_in_proxy_list(&IpAddr::V4(*ip)),
417-
Some(RData::AAAA(ip)) => acl.check_ip_in_proxy_list(&IpAddr::V6(*ip)),
416+
Some(RData::A(ip)) => acl.check_ip_in_proxy_list(&IpAddr::V4((*ip).into())),
417+
Some(RData::AAAA(ip)) => acl.check_ip_in_proxy_list(&IpAddr::V6((*ip).into())),
418418
// MX records cause type A additional section processing for the host specified by EXCHANGE.
419419
Some(RData::MX(mx)) => examine_name!(mx.exchange(), $is_answer),
420420
// NS records cause both the usual additional section processing to locate a type A record...
@@ -498,8 +498,16 @@ impl DnsClient {
498498
for rec in result.answers() {
499499
trace!("dns answer: {:?}", rec);
500500
match rec.data() {
501-
Some(RData::A(ip)) => self.context.add_to_reverse_lookup_cache((*ip).into(), forward).await,
502-
Some(RData::AAAA(ip)) => self.context.add_to_reverse_lookup_cache((*ip).into(), forward).await,
501+
Some(RData::A(ip)) => {
502+
self.context
503+
.add_to_reverse_lookup_cache(Ipv4Addr::from(*ip).into(), forward)
504+
.await
505+
}
506+
Some(RData::AAAA(ip)) => {
507+
self.context
508+
.add_to_reverse_lookup_cache(Ipv6Addr::from(*ip).into(), forward)
509+
.await
510+
}
503511
_ => (),
504512
}
505513
}

crates/shadowsocks/Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "shadowsocks"
3-
version = "1.15.3"
3+
version = "1.16.0"
44
authors = ["Shadowsocks Contributors"]
55
description = "shadowsocks is a fast tunnel proxy that helps you bypass firewalls."
66
repository = "https://github.com/shadowsocks/shadowsocks-rust"
@@ -68,7 +68,8 @@ socket2 = { version = "0.5", features = ["all"] }
6868
tokio = { version = "1.9.0", features = ["io-util", "macros", "net", "parking_lot", "process", "rt", "sync", "time"] }
6969
tokio-tfo = "0.2.0"
7070

71-
trust-dns-resolver = { version = "0.22", optional = true }
71+
# trust-dns-resolver = { version = "0.22", optional = true }
72+
trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns.git", optional = true }
7273
arc-swap = { version = "1.6", optional = true }
7374
notify = { version = "5.1.0", optional = true }
7475

crates/shadowsocks/src/dns_resolver/resolver.rs

+33-25
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ use tokio::net::lookup_host;
2020
#[cfg(feature = "trust-dns")]
2121
use tokio::task::JoinHandle;
2222
#[cfg(feature = "trust-dns")]
23-
use trust_dns_resolver::{config::ResolverConfig, TokioAsyncResolver};
23+
use trust_dns_resolver::config::ResolverConfig;
24+
25+
#[cfg(feature = "trust-dns")]
26+
use crate::net::ConnectOpts;
27+
28+
#[cfg(feature = "trust-dns")]
29+
use super::trust_dns_resolver::DnsResolver as TrustDnsResolver;
2430

2531
/// Abstract DNS resolver
2632
#[async_trait]
@@ -31,8 +37,8 @@ pub trait DnsResolve {
3137

3238
#[cfg(feature = "trust-dns")]
3339
pub struct TrustDnsSystemResolver {
34-
resolver: ArcSwap<TokioAsyncResolver>,
35-
ipv6_first: bool,
40+
resolver: ArcSwap<TrustDnsResolver>,
41+
connect_opts: ConnectOpts,
3642
}
3743

3844
/// Collections of DNS resolver
@@ -44,11 +50,12 @@ pub enum DnsResolver {
4450
#[cfg(feature = "trust-dns")]
4551
TrustDnsSystem {
4652
inner: Arc<TrustDnsSystemResolver>,
53+
#[cfg(all(feature = "trust-dns", unix, not(target_os = "android")))]
4754
abortable: JoinHandle<()>,
4855
},
4956
/// Trust-DNS resolver
5057
#[cfg(feature = "trust-dns")]
51-
TrustDns(TokioAsyncResolver),
58+
TrustDns(TrustDnsResolver),
5259
/// Customized Resolver
5360
Custom(Box<dyn DnsResolve + Send + Sync>),
5461
}
@@ -75,6 +82,7 @@ impl Debug for DnsResolver {
7582
#[cfg(feature = "trust-dns")]
7683
impl Drop for DnsResolver {
7784
fn drop(&mut self) {
85+
#[cfg(all(feature = "trust-dns", unix, not(target_os = "android")))]
7886
if let DnsResolver::TrustDnsSystem { ref abortable, .. } = *self {
7987
abortable.abort();
8088
}
@@ -187,7 +195,7 @@ async fn trust_dns_notify_update_dns(resolver: Arc<TrustDnsSystemResolver>) -> n
187195
// Update once for all those Modify events
188196
time::sleep(Duration::from_secs(1)).await;
189197

190-
match create_resolver(None, resolver.ipv6_first).await {
198+
match create_resolver(None, resolver.connect_opts.clone()).await {
191199
Ok(r) => {
192200
debug!("auto-reload {DNS_RESOLV_FILE_PATH}");
193201

@@ -208,12 +216,6 @@ async fn trust_dns_notify_update_dns(resolver: Arc<TrustDnsSystemResolver>) -> n
208216
Ok(())
209217
}
210218

211-
#[cfg(all(feature = "trust-dns", any(not(unix), target_os = "android")))]
212-
async fn trust_dns_notify_update_dns(resolver: Arc<TrustDnsSystemResolver>) -> notify::Result<()> {
213-
let _ = resolver.ipv6_first; // use it for supressing warning
214-
futures::future::pending().await
215-
}
216-
217219
impl DnsResolver {
218220
/// Use system DNS resolver. Tokio will call `getaddrinfo` in blocking pool.
219221
pub fn system_resolver() -> DnsResolver {
@@ -224,33 +226,39 @@ impl DnsResolver {
224226
///
225227
/// On *nix system, it will try to read configurations from `/etc/resolv.conf`.
226228
#[cfg(feature = "trust-dns")]
227-
pub async fn trust_dns_system_resolver(ipv6_first: bool) -> io::Result<DnsResolver> {
229+
pub async fn trust_dns_system_resolver(connect_opts: ConnectOpts) -> io::Result<DnsResolver> {
228230
use super::trust_dns_resolver::create_resolver;
229231

230-
let resolver = create_resolver(None, ipv6_first).await?;
232+
let resolver = create_resolver(None, connect_opts.clone()).await?;
231233

232234
let inner = Arc::new(TrustDnsSystemResolver {
233235
resolver: ArcSwap::from(Arc::new(resolver)),
234-
ipv6_first,
236+
connect_opts,
235237
});
236238

237-
let abortable = {
238-
let inner = inner.clone();
239-
tokio::spawn(async {
240-
if let Err(err) = trust_dns_notify_update_dns(inner).await {
241-
error!("failed to watch DNS system configuration changes, error: {}", err);
242-
}
243-
})
244-
};
239+
cfg_if! {
240+
if #[cfg(all(feature = "trust-dns", unix, not(target_os = "android")))] {
241+
let abortable = {
242+
let inner = inner.clone();
243+
tokio::spawn(async {
244+
if let Err(err) = trust_dns_notify_update_dns(inner).await {
245+
error!("failed to watch DNS system configuration changes, error: {}", err);
246+
}
247+
})
248+
};
245249

246-
Ok(DnsResolver::TrustDnsSystem { inner, abortable })
250+
Ok(DnsResolver::TrustDnsSystem { inner, abortable })
251+
} else {
252+
Ok(DnsResolver::TrustDnsSystem { inner })
253+
}
254+
}
247255
}
248256

249257
/// Use trust-dns DNS resolver (with DNS cache)
250258
#[cfg(feature = "trust-dns")]
251-
pub async fn trust_dns_resolver(dns: ResolverConfig, ipv6_first: bool) -> io::Result<DnsResolver> {
259+
pub async fn trust_dns_resolver(dns: ResolverConfig, connect_opts: ConnectOpts) -> io::Result<DnsResolver> {
252260
use super::trust_dns_resolver::create_resolver;
253-
Ok(DnsResolver::TrustDns(create_resolver(Some(dns), ipv6_first).await?))
261+
Ok(DnsResolver::TrustDns(create_resolver(Some(dns), connect_opts).await?))
254262
}
255263

256264
/// Custom DNS resolver

0 commit comments

Comments
 (0)