Skip to main content

nym_http_api_client/dns/
trial.rs

1// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::dns::*;
5
6use hickory_resolver::{config::NameServerConfig, net::runtime::TokioRuntimeProvider};
7
8impl<C: SharedResolverState> HickoryDnsResolver<C> {
9    /// Do a trial resolution using each nameserver individually to test which are working and which
10    /// fail to complete a lookup. This will always try the full set of default configured resolvers.
11    ///
12    /// This diagnostic always runs over Tokio (via [`TokioRuntimeProvider`]), independent of the
13    /// connection provider `C` this resolver is otherwise configured with.
14    pub async fn trial_nameservers(&self) {
15        let nameservers = default_nameserver_group();
16        for (ns, result) in trial_nameservers_inner(&nameservers).await {
17            if let Err(e) = result {
18                warn!("trial {ns:?} errored: {e}");
19            } else {
20                info!("trial {ns:?} succeeded");
21            }
22        }
23    }
24}
25
26/// Do a trial resolution using each nameserver individually to test which are working and which
27/// fail to complete a lookup.
28pub(crate) async fn trial_nameservers_inner(
29    name_servers: &[NameServerConfig],
30) -> Vec<(NameServerConfig, Result<(), ResolveError>)> {
31    let mut trial_lookups = tokio::task::JoinSet::new();
32
33    for name_server in name_servers {
34        let ns = name_server.clone();
35        trial_lookups.spawn(async { (ns.clone(), trial_lookup(ns, "example.com").await) });
36    }
37
38    trial_lookups.join_all().await
39}
40
41/// Create an independent resolver that has only the provided nameserver and do one lookup for the
42/// provided query target.
43pub(crate) async fn trial_lookup(
44    name_server: NameServerConfig,
45    query: &str,
46) -> Result<(), ResolveError> {
47    debug!("running ns trial {name_server:?} query={query}");
48
49    let resolver = configure_and_build_resolver::<TokioRuntimeProvider>(vec![name_server])?;
50
51    match tokio::time::timeout(DEFAULT_OVERALL_LOOKUP_TIMEOUT, resolver.ipv4_lookup(query)).await {
52        Ok(Ok(_)) => Ok(()),
53        Ok(Err(e)) => Err(e.into()),
54        Err(_) => Err(ResolveError::Timeout),
55    }
56}