Skip to content

Commit d3e2922

Browse files
committed
Logging elapse time for DNS resolving and ACL checking
fix #269
1 parent edab23b commit d3e2922

File tree

4 files changed

+98
-35
lines changed

4 files changed

+98
-35
lines changed

src/context.rs

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::{
1313
use std::{net::IpAddr, time::Duration};
1414

1515
use bloomfilter::Bloom;
16-
use log::warn;
16+
use log::{log_enabled, warn};
1717
#[cfg(feature = "local-dns-relay")]
1818
use lru_time_cache::LruCache;
1919
use spin::Mutex;
@@ -293,9 +293,36 @@ impl Context {
293293

294294
/// Perform a DNS resolution
295295
pub async fn dns_resolve(&self, host: &str, port: u16) -> io::Result<Vec<SocketAddr>> {
296-
#[cfg(feature = "local-dns-relay")]
297-
return self.local_dns().lookup_ip(host, port).await;
298-
#[cfg(not(feature = "local-dns-relay"))]
296+
if log_enabled!(log::Level::Debug) {
297+
use log::debug;
298+
use std::time::Instant;
299+
300+
let start = Instant::now();
301+
let result = self.dns_resolve_inner(host, port).await;
302+
let elapsed = Instant::now() - start;
303+
debug!(
304+
"DNS resolved {}:{} elapsed: {}.{:03}s, {:?}",
305+
host,
306+
port,
307+
elapsed.as_secs(),
308+
elapsed.subsec_millis(),
309+
result
310+
);
311+
result
312+
} else {
313+
self.dns_resolve_inner(host, port).await
314+
}
315+
}
316+
317+
#[cfg(feature = "local-dns-relay")]
318+
#[inline(always)]
319+
async fn dns_resolve_inner(&self, host: &str, port: u16) -> io::Result<Vec<SocketAddr>> {
320+
self.local_dns().lookup_ip(host, port).await
321+
}
322+
323+
#[cfg(not(feature = "local-dns-relay"))]
324+
#[inline(always)]
325+
async fn dns_resolve_inner(&self, host: &str, port: u16) -> io::Result<Vec<SocketAddr>> {
299326
resolve(self, host, port).await
300327
}
301328

@@ -327,23 +354,23 @@ impl Context {
327354
pub fn check_client_blocked(&self, addr: &SocketAddr) -> bool {
328355
match self.acl() {
329356
None => false,
330-
Some(ref a) => a.check_client_blocked(addr),
357+
Some(a) => a.check_client_blocked(addr),
331358
}
332359
}
333360

334361
/// Check outbound address ACL (for server)
335362
pub fn check_outbound_blocked(&self, addr: &Address) -> bool {
336363
match self.acl() {
337364
None => false,
338-
Some(ref a) => a.check_outbound_blocked(addr),
365+
Some(a) => a.check_outbound_blocked(addr),
339366
}
340367
}
341368

342369
/// Check resolved outbound address ACL (for server)
343370
pub fn check_resolved_outbound_blocked(&self, addr: &SocketAddr) -> bool {
344371
match self.acl() {
345372
None => false,
346-
Some(ref a) => a.check_resolved_outbound_blocked(addr),
373+
Some(a) => a.check_resolved_outbound_blocked(addr),
347374
}
348375
}
349376

@@ -354,7 +381,7 @@ impl Context {
354381
!= match self.acl() {
355382
// Proxy everything by default
356383
None => true,
357-
Some(ref a) => a.check_ip_in_proxy_list(addr),
384+
Some(a) => a.check_ip_in_proxy_list(addr),
358385
};
359386
let mut reverse_lookup_cache = self.reverse_lookup_cache.lock();
360387
match reverse_lookup_cache.get_mut(addr) {
@@ -374,10 +401,12 @@ impl Context {
374401
}
375402
}
376403

377-
pub fn acl(&self) -> &Option<AccessControl> {
378-
&self.config.acl
404+
/// Get ACL control instance
405+
pub fn acl(&self) -> Option<&AccessControl> {
406+
self.config.acl.as_ref()
379407
}
380408

409+
/// Get local DNS connector
381410
#[cfg(feature = "local-dns-relay")]
382411
pub fn local_dns(&self) -> &LocalUpstream {
383412
&self.local_dns
@@ -388,21 +417,43 @@ impl Context {
388417
match self.acl() {
389418
// Proxy everything by default
390419
None => false,
391-
Some(ref a) => {
392-
#[cfg(feature = "local-dns-relay")]
393-
{
394-
if let Address::SocketAddress(ref saddr) = target {
395-
// do the reverse lookup in our local cache
396-
let mut reverse_lookup_cache = self.reverse_lookup_cache.lock();
397-
// if a qname is found
398-
if let Some(forward) = reverse_lookup_cache.get(&saddr.ip()) {
399-
return !*forward;
400-
}
401-
}
420+
Some(a) => {
421+
if log_enabled!(log::Level::Debug) {
422+
use log::debug;
423+
use std::time::Instant;
424+
425+
let start = Instant::now();
426+
let r = self.check_target_bypassed_with_acl(a, target).await;
427+
let elapsed = Instant::now() - start;
428+
debug!(
429+
"check bypassing {} elapsed {}.{:03}s, result: {}",
430+
target,
431+
elapsed.as_secs(),
432+
elapsed.subsec_millis(),
433+
if r { "bypassed" } else { "proxied" }
434+
);
435+
r
436+
} else {
437+
self.check_target_bypassed_with_acl(a, target).await
438+
}
439+
}
440+
}
441+
}
442+
443+
#[inline(always)]
444+
async fn check_target_bypassed_with_acl(&self, a: &AccessControl, target: &Address) -> bool {
445+
#[cfg(feature = "local-dns-relay")]
446+
{
447+
if let Address::SocketAddress(ref saddr) = target {
448+
// do the reverse lookup in our local cache
449+
let mut reverse_lookup_cache = self.reverse_lookup_cache.lock();
450+
// if a qname is found
451+
if let Some(forward) = reverse_lookup_cache.get(&saddr.ip()) {
452+
return !*forward;
402453
}
403-
a.check_target_bypassed(self, target).await
404454
}
405455
}
456+
a.check_target_bypassed(self, target).await
406457
}
407458

408459
/// Get client flow statistics

src/relay/dns_resolver/tokio_dns_resolver.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
sync::atomic::{AtomicBool, Ordering},
55
};
66

7-
use log::warn;
7+
use log::{trace, warn};
88
use tokio::net::lookup_host;
99

1010
use crate::context::Context;
@@ -16,6 +16,10 @@ pub async fn resolve(_: &Context, addr: &str, port: u16) -> io::Result<Vec<Socke
1616
warn!("Tokio resolver is used. Performance might deteriorate.");
1717
}
1818

19+
if cfg!(not(feature = "trust-dns")) {
20+
trace!("DNS resolving {}:{} with tokio", addr, port);
21+
}
22+
1923
match lookup_host((addr, port)).await {
2024
Ok(v) => Ok(v.collect()),
2125
Err(err) => {

src/relay/dns_resolver/trust_dns_resolver.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,25 @@ pub async fn create_resolver(dns: Option<ResolverConfig>, ipv6_first: bool) -> i
8484
/// Perform a DNS resolution
8585
pub async fn resolve(context: &Context, addr: &str, port: u16) -> io::Result<Vec<SocketAddr>> {
8686
match context.dns_resolver() {
87-
Some(resolver) => match resolver.lookup_ip(addr).await {
88-
Ok(lookup_result) => Ok(lookup_result.iter().map(|ip| SocketAddr::new(ip, port)).collect()),
89-
Err(err) => {
90-
let err = Error::new(
91-
ErrorKind::Other,
92-
format!("dns resolve {}:{} error: {}", addr, port, err),
93-
);
94-
Err(err)
87+
Some(resolver) => {
88+
trace!("DNS resolving {}:{} with trust-dns", addr, port);
89+
90+
match resolver.lookup_ip(addr).await {
91+
Ok(lookup_result) => Ok(lookup_result.iter().map(|ip| SocketAddr::new(ip, port)).collect()),
92+
Err(err) => {
93+
let err = Error::new(
94+
ErrorKind::Other,
95+
format!("dns resolve {}:{} error: {}", addr, port, err),
96+
);
97+
Err(err)
98+
}
9599
}
96-
},
100+
}
97101
// Fallback to tokio's DNS resolver
98-
None => tokio_resolve(context, addr, port).await,
102+
None => {
103+
trace!("DNS resolving {}:{} with tokio (fallback)", addr, port);
104+
105+
tokio_resolve(context, addr, port).await
106+
}
99107
}
100108
}

src/relay/dnsrelay/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn check_name_in_proxy_list(acl: &AccessControl, name: &Name) -> Option<bool> {
8383
}
8484

8585
/// given the query, determine whether remote/local query should be used, or inconclusive
86-
fn should_forward_by_query(acl: &Option<AccessControl>, query: &Query) -> Option<bool> {
86+
fn should_forward_by_query(acl: Option<&AccessControl>, query: &Query) -> Option<bool> {
8787
if let Some(acl) = acl {
8888
if query.query_class() != DNSClass::IN {
8989
// unconditionally use default for all non-IN queries
@@ -105,7 +105,7 @@ fn should_forward_by_query(acl: &Option<AccessControl>, query: &Query) -> Option
105105

106106
/// given the local response, determine whether remote response should be used instead
107107
fn should_forward_by_response(
108-
acl: &Option<AccessControl>,
108+
acl: Option<&AccessControl>,
109109
local_response: &io::Result<Message>,
110110
query: &Query,
111111
) -> bool {

0 commit comments

Comments
 (0)