Skip to content

Commit

Permalink
✨ Implement HTTP ping
Browse files Browse the repository at this point in the history
  • Loading branch information
mokeyish committed Mar 11, 2023
1 parent 36c0454 commit 11e6d50
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 50 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ tracing-subscriber = { version = "0.3", features = [
] }
# tracing-appender = "0.2"
tokio = { version = "1.21", features = ["time", "rt", "signal", "macros"] }
tokio-rustls = "0.23.4"
url = "2.3.1"
trust-dns-proto = { version = "0.22.0", git = "https://github.com/bluejekyll/trust-dns.git", rev = "5492bde"}
trust-dns-resolver = { version = "0.22.0", features = ["serde-config"] , git = "https://github.com/bluejekyll/trust-dns.git", rev = "5492bde"}
trust-dns-server = { version = "0.22.0", features = ["resolver"] , git = "https://github.com/bluejekyll/trust-dns.git", rev = "5492bde"}
webpki-roots = "0.22.1"
rustls = "0.20.0"
rustls = { version = "0.20.0", features = ["dangerous_configuration"]}
rustls-native-certs = { version = "0.6.2", git = "https://github.com/mokeyish/rustls-native-certs.git" }
lru = { version = "0.10", default-features = false}
once_cell = "1.16.0"
Expand Down
2 changes: 2 additions & 0 deletions src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct DnsContext {
pub fastest_speed: Duration,
pub source: LookupFrom,
pub no_cache: bool,
pub background: bool
}

impl DnsContext {
Expand All @@ -38,6 +39,7 @@ impl DnsContext {
fastest_speed: Default::default(),
source: Default::default(),
no_cache: false,
background: false
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/dns_conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,8 @@ pub enum SpeedCheckMode {
None,
Ping,
Tcp(u16),
Http(u16),
Https(u16),
}

impl Default for SpeedCheckMode {
Expand All @@ -1393,6 +1395,14 @@ impl FromStr for SpeedCheckMode {
Ok(SpeedCheckMode::Ping)
} else if let Some(port) = s.strip_prefix("tcp:") {
u16::from_str(port).map(SpeedCheckMode::Tcp).map_err(|_| ())
} else if let Some(port) = s.strip_prefix("http:") {
u16::from_str(port)
.map(SpeedCheckMode::Http)
.map_err(|_| ())
} else if let Some(port) = s.strip_prefix("https:") {
u16::from_str(port)
.map(SpeedCheckMode::Https)
.map_err(|_| ())
} else {
Err(())
}
Expand Down
2 changes: 2 additions & 0 deletions src/dns_mw_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ impl DomainPrefetcher {
let now = Instant::now();
let mut ctx =
DnsContext::new(query.name(), cfg.clone(), Default::default());

ctx.background = true;

if let Ok(lookup) =
client.execute(&mut ctx, &query.clone().into()).await
Expand Down
30 changes: 28 additions & 2 deletions src/dns_mw_ns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ impl Middleware<DnsContext, DnsRequest, DnsResponse, DnsError> for NameServerMid
if rtype.is_ip_addr() {
let cfg = ctx.cfg();

let opts = match ctx.domain_rule.as_ref() {
let mut opts = match ctx.domain_rule.as_ref() {
Some(rule) => LookupIpOptions {
response_strategy: rule.response_mode.unwrap_or_else(|| cfg.response_mode()),
response_strategy: rule.get(|n|n.response_mode).unwrap_or_else(|| cfg.response_mode()),
speed_check_mode: if rule.speed_check_mode.is_empty() {
cfg.speed_check_mode().clone()
} else {
Expand All @@ -128,6 +128,10 @@ impl Middleware<DnsContext, DnsRequest, DnsResponse, DnsError> for NameServerMid
},
};

if ctx.background {
opts.response_strategy = ResponseMode::FastestIp;
}

match lookup_ip(name_server_group.deref(), name.clone(), rtype, &opts).await {
Ok(lookup_ip) => Ok(lookup_ip.into()),
Err(err) => Err(err),
Expand Down Expand Up @@ -197,6 +201,28 @@ async fn lookup_ip(
.map(|ip| PingAddr::Tcp(SocketAddr::new(*ip, *port)))
.collect::<Vec<_>>()
}
SpeedCheckMode::Http(port) => {
debug!(
"Speed test {} http ping {:?} port {}",
lookup_ip.query().name(),
ips,
port
);
ips.iter()
.map(|ip| PingAddr::Http(SocketAddr::new(*ip, *port)))
.collect::<Vec<_>>()
},
SpeedCheckMode::Https(port) => {
debug!(
"Speed test {} https ping {:?} port {}",
lookup_ip.query().name(),
ips,
port
);
ips.iter()
.map(|ip| PingAddr::Https(SocketAddr::new(*ip, *port)))
.collect::<Vec<_>>()
},
};

ping_tasks.push(ping_fastest(ping_dests, ping_ops).boxed());
Expand Down
8 changes: 8 additions & 0 deletions src/dns_rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ impl DomainRuleTreeNode {
pub fn zone(&self) -> Option<&Arc<DomainRuleTreeNode>> {
self.zone.as_ref()
}

pub fn get<T>(&self, f: impl Fn(&Self) -> Option<T>) -> Option<T> {
f(self).or_else(|| {
self.zone()
.map(|z| f(z))
.unwrap_or_default()
})
}
}

impl Deref for DomainRuleTreeNode {
Expand Down
Loading

0 comments on commit 11e6d50

Please sign in to comment.