#![recursion_limit = "128"]
use std::sync::Arc;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
tokio_main().await;
}
async fn tokio_main() {
let resolver = {
#[cfg(any(unix, windows))]
{
use hickory_resolver::{TokioResolver, name_server::TokioConnectionProvider};
Arc::new(
TokioResolver::builder(TokioConnectionProvider::default())
.expect("failed to create resolver")
.build(),
)
}
#[cfg(not(any(unix, windows)))]
{
use hickory_resolver::{
Resolver,
config::{ResolverConfig, ResolverOpts},
};
Arc::new(Resolver::tokio(
ResolverConfig::quad9(),
ResolverOpts::default(),
))
}
};
let names = ["hickory-dns.org.", "estada.ch.", "wikipedia.org."];
let first_resolve = resolve_list(&names, &*resolver).await;
let cached_resolve = resolve_list(&names, &*resolver).await;
resolver.clear_cache();
let second_resolve = resolve_list(&names, &*resolver).await;
println!("first_resolve: {first_resolve:?}");
println!("cached_resolve: {cached_resolve:?}");
println!("second_resolve: {second_resolve:?}");
drop(resolver);
}
async fn resolve_list<P: hickory_resolver::name_server::ConnectionProvider>(
names: &[&str],
resolver: &hickory_resolver::Resolver<P>,
) -> tokio::time::Duration {
use tokio::time::Instant;
let start_time = Instant::now();
let futures = names
.iter()
.map(|name: &&str| {
let name: String = name.to_string();
let resolver = resolver.clone();
let future = {
let name = name.clone();
tokio::spawn(async move { resolver.txt_lookup(name).await })
};
(name, future)
})
.collect::<Vec<_>>();
for (name, lookup) in futures {
let txts = lookup.await.expect("unable to spawn resolver").map(|txt| {
txt.iter()
.map(|rdata| rdata.to_string())
.collect::<Vec<_>>()
});
println!(" {name} returned to {txts:?}");
}
println!();
start_time.elapsed()
}
#[tokio::test]
async fn test_flush_cache() {
test_support::subscribe();
tokio_main().await;
}