use dusa_collection_utils::{core::logger::LogLevel, log};
use std::error::Error;
use std::net::IpAddr;
use trust_dns_resolver::{
config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts},
AsyncResolver,
};
pub async fn resolve_url(
url: &str,
resolver_addr: Option<IpAddr>,
) -> Result<Option<Vec<IpAddr>>, Box<dyn Error>> {
let address: IpAddr = match resolver_addr {
Some(given) => match given {
IpAddr::V4(ipv4_addr) => IpAddr::from(ipv4_addr),
IpAddr::V6(ipv6_addr) => IpAddr::from(ipv6_addr),
},
None => IpAddr::from([1, 1, 1, 1]),
};
let resolver = format!("{}:53", address);
let resolver_config = ResolverConfig::from_parts(
None, vec![], vec![NameServerConfig {
socket_addr: resolver.parse()?,
protocol: Protocol::Udp,
tls_dns_name: None,
trust_negative_responses: true,
bind_addr: None,
}],
);
let resolver_opts = ResolverOpts::default();
let resolver = AsyncResolver::tokio(resolver_config, resolver_opts);
match resolver.lookup_ip(url).await {
Ok(response) => {
let ips: Vec<_> = response.iter().collect();
Ok(Some(ips))
}
Err(err) => {
log!(LogLevel::Error, "Failed to resolve {}: {}", url, err);
Ok(None)
}
}
}