[GH-ISSUE #1968] Extremely slow resolution on Windows #833

Closed
opened 2026-03-16 00:29:05 +03:00 by kerem · 10 comments
Owner

Originally created by @NotNite on GitHub (Jun 12, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1968

Describe the bug
On my machine, TokioAsyncResolver takes a very long time to resolve any DNS record - up to a minute! - regardless of domain, record type, or configured DNS servers in Windows. I don't even know why this is happening, because I can't actually repro it on my other machines - only on this specific Windows machine (Linux machines on same network work fine). I encountered this from a library I was using that depends on trust_dns_resolver. I'm mainly posting this in hopes that anyone has idea for better debugging steps so we can work it out together.

To Reproduce

use trust_dns_resolver::{proto::rr::RecordType, TokioAsyncResolver};

#[tokio::main]
async fn main() {
    let resolver = TokioAsyncResolver::tokio_from_system_conf().unwrap();
    let records = resolver.lookup("rust-lang.org", RecordType::A).await.ok();
    println!("{:?}", records);
}

Expected behavior
Not take 20.046 seconds to resolve rust-lang.org.

System:

  • OS: Windows 10
  • Architecture: x86_64
  • Version 22H2 (19045.2965)
  • rustc version: rustc 1.72.0-nightly (37998ab50 2023-06-11)

Version:
Crate: trust_dns_resolver
Version: 0.22.0

Originally created by @NotNite on GitHub (Jun 12, 2023). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1968 **Describe the bug** On my machine, `TokioAsyncResolver` takes a very long time to resolve any DNS record - up to a minute! - regardless of domain, record type, or configured DNS servers in Windows. I don't even know *why* this is happening, because I can't actually repro it on my other machines - only on this specific Windows machine (Linux machines on same network work fine). I encountered this from a library I was using that depends on `trust_dns_resolver`. I'm mainly posting this in hopes that anyone has idea for better debugging steps so we can work it out together. **To Reproduce** ```rs use trust_dns_resolver::{proto::rr::RecordType, TokioAsyncResolver}; #[tokio::main] async fn main() { let resolver = TokioAsyncResolver::tokio_from_system_conf().unwrap(); let records = resolver.lookup("rust-lang.org", RecordType::A).await.ok(); println!("{:?}", records); } ``` **Expected behavior** Not take 20.046 seconds to resolve rust-lang.org. **System:** - OS: Windows 10 - Architecture: x86_64 - Version 22H2 (19045.2965) - rustc version: rustc 1.72.0-nightly (37998ab50 2023-06-11) **Version:** Crate: trust_dns_resolver Version: 0.22.0
Author
Owner

@djc commented on GitHub (Jun 12, 2023):

Set up a basic tracing-subscriber to get a feel for which part is slow? Investigate what the system config amounts to on this system?

<!-- gh-comment-id:1586854881 --> @djc commented on GitHub (Jun 12, 2023): Set up a basic tracing-subscriber to get a feel for which part is slow? Investigate what the system config amounts to on this system?
Author
Owner

@bluejekyll commented on GitHub (Jun 12, 2023):

We've had other reports of trust-dns cycling through interfaces on Windows. We don't have a lot of folks contributing to the project from Windows, so it's sadly not as well supported as macOS and Linux. If you do have some time to investigate this, that would be really helpful to this project!

<!-- gh-comment-id:1588122318 --> @bluejekyll commented on GitHub (Jun 12, 2023): We've had other reports of trust-dns cycling through interfaces on Windows. We don't have a lot of folks contributing to the project from Windows, so it's sadly not as well supported as macOS and Linux. If you do have some time to investigate this, that would be really helpful to this project!
Author
Owner

@mat-1 commented on GitHub (Jul 15, 2023):

Note that this can be worked around by specifying a different resolver. The mongodb crate readme has an example.

<!-- gh-comment-id:1636650324 --> @mat-1 commented on GitHub (Jul 15, 2023): Note that this can be worked around by specifying a different resolver. The [mongodb crate readme](https://github.com/mongodb/mongo-rust-driver#windows-dns-note) has an example.
Author
Owner

@Firaenix commented on GitHub (Sep 12, 2023):

I’m also running into this issue, I will do some investigating when I have some time

<!-- gh-comment-id:1715700974 --> @Firaenix commented on GitHub (Sep 12, 2023): I’m also running into this issue, I will do some investigating when I have some time
Author
Owner

@mokeyish commented on GitHub (Sep 12, 2023):

Are you sure this can be reproduced? I don't seem to have encountered this problem, it has always been faster. You can download this program from here and see if it is too slow.

https://github.com/mokeyish/smartdns-rs#installing

<!-- gh-comment-id:1715867027 --> @mokeyish commented on GitHub (Sep 12, 2023): Are you sure this can be reproduced? I don't seem to have encountered this problem, it has always been faster. You can download this program from here and see if it is too slow. https://github.com/mokeyish/smartdns-rs#installing
Author
Owner

@Firaenix commented on GitHub (Sep 18, 2023):

I can confirm that the slowdown is due to the amount and type of name_servers returned from the ipconfig crate, at least on my Windows machine. I would assume that depending on the machine it would differ but when trimming the following list down to a single DNS server from my Ethernet adapter, the lookup is in the milliseconds.

trust-dns-resolver is currently taking all adapters, including Virtual Machine adapters and Bluetooth and flat_map-ing the dns_servers in a naive way, if I removed all adapters that are not up, are not WiFi or Ethernet and are not Virtual adapters, it solved the performance issues for me.

I guess there is further discussion that needs to be had around if we do want to include Virtual adapters or bluetooth adapters.

What i've basically done in testing is add the following if statements to the flat_map

fn get_name_servers() -> ResolveResult<Vec<NameServerConfig>> {
    let adapters = get_adapters()?;
    let mut name_servers = vec![];

    for dns_server in adapters
        .iter()
        .flat_map(|adapter| {
            // If the adapter is not operating, ignore them
            if adapter.oper_status() != OperStatus::IfOperStatusUp {
                return [].iter();
            }

            // Only support Ethernet and WiFi devices
            if !(adapter.if_type() == IfType::Ieee80211 || adapter.if_type() == IfType::EthernetCsmacd) {
                return [].iter();
            }
           
            // Lazy removal of Virtual adapters or Hyper-V adapters
            if adapter.description().contains("Hyper-V") || adapter.description().contains("Virtual") {
                return [].iter();
            }

            adapter.dns_servers().iter()
        })
    {
        let socket_addr = SocketAddr::new(*dns_server, 53);
        name_servers.push(NameServerConfig {
            socket_addr,
            protocol: Protocol::Udp,
            tls_dns_name: None,
            trust_negative_responses: false,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
            bind_addr: None,
        });
        name_servers.push(NameServerConfig {
            socket_addr,
            protocol: Protocol::Tcp,
            tls_dns_name: None,
            trust_negative_responses: false,
            #[cfg(feature = "dns-over-rustls")]
            tls_config: None,
            bind_addr: None,
        });
    }
    Ok(name_servers)
}

Edit: More than happy to make a PR if this quick fix is good enough

Below is the list of adapters that were detected on my machine along with their DNS servers.
image

<!-- gh-comment-id:1722853328 --> @Firaenix commented on GitHub (Sep 18, 2023): I can confirm that the slowdown is due to the amount and type of name_servers returned from the ipconfig crate, at least on my Windows machine. I would assume that depending on the machine it would differ but when trimming the following list down to a single DNS server from my Ethernet adapter, the lookup is in the milliseconds. trust-dns-resolver is currently taking all adapters, including Virtual Machine adapters and Bluetooth and flat_map-ing the dns_servers in a naive way, if I removed all adapters that are not up, are not WiFi or Ethernet and are not Virtual adapters, it solved the performance issues for me. I guess there is further discussion that needs to be had around if we do want to include Virtual adapters or bluetooth adapters. What i've basically done in testing is add the following if statements to the flat_map ```rust fn get_name_servers() -> ResolveResult<Vec<NameServerConfig>> { let adapters = get_adapters()?; let mut name_servers = vec![]; for dns_server in adapters .iter() .flat_map(|adapter| { // If the adapter is not operating, ignore them if adapter.oper_status() != OperStatus::IfOperStatusUp { return [].iter(); } // Only support Ethernet and WiFi devices if !(adapter.if_type() == IfType::Ieee80211 || adapter.if_type() == IfType::EthernetCsmacd) { return [].iter(); } // Lazy removal of Virtual adapters or Hyper-V adapters if adapter.description().contains("Hyper-V") || adapter.description().contains("Virtual") { return [].iter(); } adapter.dns_servers().iter() }) { let socket_addr = SocketAddr::new(*dns_server, 53); name_servers.push(NameServerConfig { socket_addr, protocol: Protocol::Udp, tls_dns_name: None, trust_negative_responses: false, #[cfg(feature = "dns-over-rustls")] tls_config: None, bind_addr: None, }); name_servers.push(NameServerConfig { socket_addr, protocol: Protocol::Tcp, tls_dns_name: None, trust_negative_responses: false, #[cfg(feature = "dns-over-rustls")] tls_config: None, bind_addr: None, }); } Ok(name_servers) } ``` Edit: More than happy to make a PR if this quick fix is good enough Below is the list of adapters that were detected on my machine along with their DNS servers. ![image](https://github.com/bluejekyll/trust-dns/assets/8898038/1b4ba17e-701a-4363-9934-31870e182458)
Author
Owner

@bluejekyll commented on GitHub (Sep 18, 2023):

trust-dns-resolver is currently taking all adapters, including Virtual Machine adapters and Bluetooth and flat_map-ing the dns_servers in a naive way,

Yes, this sounds like exactly what others have noticed. I don't know what the "fix" is as I'm not using Windows and can't investigate. If you have a proposed change you'd like to put forward in a PR, I think we'd all be grateful.

<!-- gh-comment-id:1724073274 --> @bluejekyll commented on GitHub (Sep 18, 2023): > trust-dns-resolver is currently taking all adapters, including Virtual Machine adapters and Bluetooth and flat_map-ing the dns_servers in a naive way, Yes, this sounds like exactly what others have noticed. I don't know what the "fix" is as I'm not using Windows and can't investigate. If you have a proposed change you'd like to put forward in a PR, I think we'd all be grateful.
Author
Owner

@djc commented on GitHub (Sep 19, 2023):

I'd suggest we should use something more like a deny list than an allow list here, to avoid unpleasant surprises? I think it makes sense to require IfOperStatusUp and deny Csmacd, not sure about the virtual stuff. I think Tailscale might like to be an adapter, for example...

<!-- gh-comment-id:1725208729 --> @djc commented on GitHub (Sep 19, 2023): I'd suggest we should use something more like a deny list than an allow list here, to avoid unpleasant surprises? I think it makes sense to require `IfOperStatusUp` and deny `Csmacd`, not sure about the virtual stuff. I think Tailscale might like to be an adapter, for example...
Author
Owner

@Firaenix commented on GitHub (Sep 28, 2023):

I agree, I'm not sure if there is some generally accepted method of choosing which adapters to use in Windows-land.

In regard to Tailscale on Windows it comes up as an "Unsupported" type adapter and not a virtual adapter so it wasn't impacted by the virtual adapter exclusions but by the Ethernet and Wifi exclusions. Your point still stands though.

It is still surprisingly slow if you still have the WSL adapter in the adapter list though. I also believe that depending on the Windows install/users machine hardware and software installed there will be varying names for virtual adapters so it's hard to just disable them all.

<!-- gh-comment-id:1738387025 --> @Firaenix commented on GitHub (Sep 28, 2023): I agree, I'm not sure if there is some generally accepted method of choosing which adapters to use in Windows-land. In regard to Tailscale on Windows it comes up as an "Unsupported" type adapter and not a virtual adapter so it wasn't impacted by the virtual adapter exclusions but by the Ethernet and Wifi exclusions. Your point still stands though. It is still surprisingly slow if you still have the WSL adapter in the adapter list though. I also believe that depending on the Windows install/users machine hardware and software installed there will be varying names for virtual adapters so it's hard to just disable them all.
Author
Owner

@redactedontop commented on GitHub (Mar 24, 2025):

Why was a fix not implemented yet?

<!-- gh-comment-id:2748389055 --> @redactedontop commented on GitHub (Mar 24, 2025): Why was a fix not implemented yet?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#833
No description provided.