Custom Global DNS Resolver

Whilst working with dns lookups, and tls libraries, I stumbled upon the problem that Rust always uses getaddrinfo, which is not interchangable.

And I was wondering if there is might be an option, to change it globally. (like with the global allocator)

Can you elaborate your use case(s) for a custom resolver? Can they not be satisfied by a third party crate?

The issue here is that the stdlib is hardcoded to use getaddrinfo from the libc (for example, in ToSocketAddr when resolving a hostname). Since it's hardcoded, one can't make the stdlib use a third party crate like dns-lookup.

This is similar to the allocator case, where there are allocators in the stdlib but until Rust had the allocator API one couldn't swap Rust's internal allocator for some crate.

It totally makes sense to have the concept of a global dns resolver in the stdlib, and if Rust ever have capabilities, dns resolving would make a nice capability as well (so that you can set the dns resolver to a dummy one when calling a certain function, for example)


I generally agree: you should be able to substitute out many things the standard library calls. I don't necessarily think you should be able to substitute out the resolver called by x86_64-unknown-linux-musl, for instance, but I've thought for a while about having an x86_64-unknown-custom where everything is a capability you can override. So, for instance, you could substitute out the network stack. See SSH and User-mode IP WireGuard · Fly for an example of why you might want to do that.

1 Like

If all public interfaces use ToSocketAddrs then you can pre-resolve and pass in a &[SocketAddr] instead of a name, or it's even possible to customise how that behaves when calling:

struct TrustDnsResolved<'a>(&trust_dns_client::client::SyncClient<...>, &'a str);

impl ToSocketAddrs for TrustDnsResolved<'_> {
    type Iter = impl Iterator<Item = SocketAddr>;

    fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
        self.0.query(self.1.parse()?, ...)....

let stream = TcpStream::connect(TrustDnsResolved(&client, ""))?;

The major issue is when somewhere within libraries they are taking strings and resolving those themselves. Those libraries could allow customising how they resolve domains instead of relying on the stdlib for it.

1 Like

Libs definitely should use ToSocketAddr as arguments for addresses, like its normally done with Path etc.

Implementing ToSocketAddrs for custom dns resolution seems to be reasonable approach, but in some scenarios its not practicable like for example (my scenario) when using clap, serde, etc (String -> SocketAddr).

And generally if you want to change the dns, it should apply for the whole program.

1 Like

There's a semi-related issue of potentially moving ToSocketAddrs to core, and how that would work.

Right now the glue from ToSocketAddrs to system DNS libraries happens by way of sys_common::net::LookupHost (which is invoked from resolve_socket_addr, which is called by ToSocketAddrs). It would be nice to be able to customize this somehow, and such customization may be necessary to move the traits into core.

I'm not sure what that customization would look like though. It could be a lang item, but my understanding is new lang items are now added only as a last resort.

We can't really add more things like #[global_allocator] and #[panic_handler] as they need to be defined somewhere when a crate using them is included. If libcore uses one, a definition would always be mandatory. We can't require the user to provide the definition as that would break backward compatibility. The only thing we could do is provide a default in libcore, but then it would have to be a panicking definition. And it would break people trying to link libcore manually. While there is no guarantee that this will remain working, there are several users of this.

Maybe use containers to override the DNS resolver on the OS level then?

Or you can override the getaddrinfo function, which will also apply to any C code loaded into the program.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.