Skip to main content

Crate dns

Crate dns 

Available on crate features dns and std only.
Expand description

DNS support for Rama.

§Resolvers

Rama ships with several client::resolver::DnsResolver implementations. The most commonly used ones are re-exported from client:

client::resolver::DnsResolver is the aggregate of the address, CNAME, TXT, and SVCB/HTTPS resolver traits. Implement those traits yourself to plug in another resolver, and combine resolvers with the chain / tuple / variant adapters under client. client::resolver::DnsTxtResolver yields one wire::Txt per DNS TXT resource record; each value preserves that record’s character-string boundaries.

§Picking a resolver for high-QPS workloads

On Apple platforms (AppleDnsResolver, via DNSServiceQueryRecord + AsyncFd) and Windows (WindowsDnsResolver, via DnsQueryEx with a completion callback on the system thread pool), the native resolvers are fully asynchronous and scale naturally — no tokio blocking-pool traffic.

On Linux hosts whose NSS configuration selects nss-resolve, LinuxDnsResolver first tries systemd-resolved’s varlink socket, which is likewise fully asynchronous. This path can also be enabled or disabled explicitly through LinuxDnsResolver::builder(). Where the daemon is not selected or available it falls back to res_nsearch / getaddrinfo, and there — as with client::TokioDnsResolver (via getaddrinfo) — each lookup occupies a tokio blocking-pool thread for the duration of the libc call. Under sustained high-concurrency DNS load (typical for forward proxies) that pool can become a bottleneck. For such workloads prefer the pure-Rust client::HickoryDnsResolver (gated behind the hickory feature), which speaks DNS directly over async UDP/TCP and gives finer control over caching and upstream selection.

§Global DNS resolver

Rama uses a process-wide shared DNS resolver by default. If nothing is installed explicitly, it lazily initialises to client::NativeDnsResolver on first use — i.e. the best native resolver for the current platform.

Use client::try_init_global_dns_resolver or client::init_global_dns_resolver to install a different resolver (e.g. client::HickoryDnsResolver under the hickory feature, or your own implementation). This has to happen before the first lookup; both initialisers fail / panic if the global resolver has already been initialised.

client::GlobalDnsResolver is a thin handle that defers fetching the global resolver until it’s actually used — handy when you want to pass a resolver around without forcing it to be constructed yet.

§DNS wire data

The wire module provides provider-neutral DNS wire vocabulary. It decodes A, AAAA, CNAME, and TXT RDATA as well as the shared RDATA used by SVCB and HTTPS records. DNS names, TXT string boundaries, and unknown service parameters are preserved.

wire::Message parses an RFC 1035 message on top of that vocabulary: header flags including wire::ResponseCode, the question section, and the answer section, with compression resolved and RDATA decoded into typed values. Parsing stops after the answer section, keeps whatever decoded before a malformed record unless the strict constructors are used, and leaves normalisation policy to the caller.

§Rama

Crate used by the end-user rama crate and rama crate authors alike.

Learn more about rama:

Modules§

client
dial9dial9
Pre-defined dial9 events for DNS lookups.
wire
DNS wire-format vocabulary and parsing.