async_traceroute/traceroute/utils/
dns.rs1use std::net::IpAddr;
2
3use domain::base::Name;
4use domain::resolv::lookup::lookup_host;
5use domain::resolv::stub::StubResolver;
6
7pub async fn dns_lookup(hostname: &str) -> Option<Vec<IpAddr>> {
8 let hostname = match Name::bytes_from_str(hostname) {
9 Ok(hostname) => hostname,
10 Err(_) => return None,
11 };
12
13 let stub_resolver = StubResolver::new();
14
15
16 match lookup_host(&&stub_resolver, hostname).await {
17 Ok(answers) => {
18 let ip_addrs: Vec<_> = answers
19 .iter()
20 .collect();
21
22 if ip_addrs.is_empty() { None } else { Some(ip_addrs) }
23 }
24 Err(_) => None,
25 }
26}
27
28pub async fn dns_lookup_first_ipv4_addr(hostname: &str) -> Option<IpAddr> {
29 if let Some(ip_addrs) = dns_lookup(hostname).await {
30 for ip_addr in ip_addrs.iter() {
31 if ip_addr.is_ipv4() {
32 return Some(*ip_addr)
33 }
34 }
35 }
36
37 None
38}
39
40pub async fn reverse_dns_lookup(ip_address: &IpAddr) -> Option<Vec<String>> {
41 let resolver = StubResolver::new();
42 match resolver.lookup_addr(*ip_address).await {
43 Ok(addrs) => {
44 let hostnames: Vec<_> = addrs.into_iter()
45 .map(|addr| addr.to_string())
46 .collect();
47
48 if hostnames.is_empty() { None } else { Some(hostnames) }
49 },
50 Err(_) => None
51 }
52}
53
54pub async fn reverse_dns_lookup_first_hostname(ip_address: &IpAddr) -> Option<String> {
55 reverse_dns_lookup(ip_address)
56 .await
57 .map(|hostnames|
58 hostnames.first()
59 .expect("hostnames should contain at least one hostname")
60 .to_string())
61}