[GH-ISSUE #1073] [resolver] ResolverOpts timeout value is not respected #596

Open
opened 2026-03-15 23:21:45 +03:00 by kerem · 2 comments
Owner

Originally created by @balboah on GitHub (Apr 13, 2020).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1073

When using the resolver async lookup, queries might never time out or run for much longer than configured. It's especially bad in the TLS based configurations as in the provided example.
This causes a memory leak for the stalled async lookups.

To Reproduce

  1. run nc -l 127.0.0.1 1443 in one shell
  2. run the example below in another shell
  3. wait for a timeout (or not) :)
example main.rs
use std::net::IpAddr;
use std::time::Duration;

use tokio::runtime::Builder;

use trust_dns_client::rr::{Name, RecordType};
use trust_dns_resolver::config::ResolverConfig;
use trust_dns_resolver::config::{NameServerConfigGroup, ResolverOpts};
use trust_dns_resolver::TokioAsyncResolver;

fn main() {
  let mut runtime = Builder::new()
    .threaded_scheduler()
    .core_threads(1)
    .enable_all()
    .build()
    .unwrap();

  let dns_name = "cloudflare-dns.com";
  let dns_ips: Vec<IpAddr> = vec!["127.0.0.1".parse().unwrap()];
  let ns = NameServerConfigGroup::from_ips_https(&dns_ips, 1443, dns_name.to_string());
  let options = ResolverOpts {
    timeout: Duration::from_secs(5), // this is the default value
    preserve_intermediates: true,

    ..ResolverOpts::default()
  };
  let config = ResolverConfig::from_parts(None, vec![], ns);
  let resolver = runtime
    .block_on(TokioAsyncResolver::new(
      config,
      options,
      runtime.handle().clone(),
    ))
    .unwrap();

  let name: Name = format!("example.com.").parse().unwrap();
  runtime
    .block_on(resolver.lookup(name, RecordType::A, Default::default()))
    .unwrap();
}

Expected behaviour

I expect the timeout configuration to be the total timeout of:

  • connecting
  • writing & reading a result

I'm also expecting the nameserver pool to handle re-cycling for established connections if they fail to respond within the specified timeout.

System:

  • OS: macOS

Version:
Crate: resolver
Version: 76a377

Additional context
I was able to work around the memory leak by wrapping the resolver.lookup inside tokio::time::timeout. However I'm not sure how soon the underlying nameserver pool connection with the dns server will re-connect. This is especially sensitive when switching between IPv4 & IPv6 endpoints.

Originally created by @balboah on GitHub (Apr 13, 2020). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1073 When using the resolver async lookup, queries might never time out or run for much longer than configured. It's especially bad in the TLS based configurations as in the provided example. This causes a memory leak for the stalled async lookups. **To Reproduce** 1. run `nc -l 127.0.0.1 1443` in one shell 1. run the example below in another shell 1. wait for a timeout (or not) :) <details><summary>example main.rs</summary> ```rust use std::net::IpAddr; use std::time::Duration; use tokio::runtime::Builder; use trust_dns_client::rr::{Name, RecordType}; use trust_dns_resolver::config::ResolverConfig; use trust_dns_resolver::config::{NameServerConfigGroup, ResolverOpts}; use trust_dns_resolver::TokioAsyncResolver; fn main() { let mut runtime = Builder::new() .threaded_scheduler() .core_threads(1) .enable_all() .build() .unwrap(); let dns_name = "cloudflare-dns.com"; let dns_ips: Vec<IpAddr> = vec!["127.0.0.1".parse().unwrap()]; let ns = NameServerConfigGroup::from_ips_https(&dns_ips, 1443, dns_name.to_string()); let options = ResolverOpts { timeout: Duration::from_secs(5), // this is the default value preserve_intermediates: true, ..ResolverOpts::default() }; let config = ResolverConfig::from_parts(None, vec![], ns); let resolver = runtime .block_on(TokioAsyncResolver::new( config, options, runtime.handle().clone(), )) .unwrap(); let name: Name = format!("example.com.").parse().unwrap(); runtime .block_on(resolver.lookup(name, RecordType::A, Default::default())) .unwrap(); } ``` </details> **Expected behaviour** I expect the timeout configuration to be the total timeout of: - connecting - writing & reading a result I'm also expecting the nameserver pool to handle re-cycling for established connections if they fail to respond within the specified timeout. **System:** - OS: macOS **Version:** Crate: resolver Version: 76a377 **Additional context** I was able to work around the memory leak by wrapping the `resolver.lookup` inside `tokio::time::timeout`. However I'm not sure how soon the underlying nameserver pool connection with the dns server will re-connect. This is especially sensitive when switching between IPv4 & IPv6 endpoints.
Author
Owner

@bluejekyll commented on GitHub (Apr 13, 2020):

These could be related? #989

There are a bunch of tests in this area, so I'm surprised by this one.

<!-- gh-comment-id:613068134 --> @bluejekyll commented on GitHub (Apr 13, 2020): These could be related? #989 There are a bunch of tests in this area, so I'm surprised by this one.
Author
Owner

@balboah commented on GitHub (Apr 14, 2020):

I'd say it's not related since this issue is also apparent when only one nameserver is listed and the warning in #989 is not shown. Also this is only one request in the example. I should also add that clear text based lookups have an actual timeout of ~15s instead of the configured 5s. But they do timeout.

<!-- gh-comment-id:613266464 --> @balboah commented on GitHub (Apr 14, 2020): I'd say it's not related since this issue is also apparent when only one nameserver is listed and the warning in #989 is not shown. Also this is only one request in the example. I should also add that clear text based lookups have an actual timeout of ~15s instead of the configured 5s. But they do timeout.
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#596
No description provided.