# Custom Global DNS Resolver

**URL:** <https://internals.rust-lang.org/t/custom-global-dns-resolver/18667>\
**Category:** internals\
**Created:** [April 12, 2023, 6:25pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667 "2023-04-12T18:25:18Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Valaphee](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/valaphee/32/10755_2.png) [@Valaphee](https://internals.rust-lang.org/u/Valaphee)\
**Post date:** [April 12, 2023, 6:25pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/1 "2023-04-12T18:25:18Z")

</div>

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

> <https://github.com/rust-lang/rust/blob/master/library/std/src/sys_common/net.rs#L207>

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

---

<div class="post-metadata">

**Author:** ![eggyal](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eggyal/32/7947_2.png) [@eggyal](https://internals.rust-lang.org/u/eggyal)\
**Post date:** [April 12, 2023, 8:53pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/2 "2023-04-12T20:53:57Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![dlight](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dlight/32/8462_2.png) [@dlight](https://internals.rust-lang.org/u/dlight)\
**Post date:** [April 13, 2023, 5:46am UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/3 "2023-04-13T05:46:43Z")

</div>

> [@eggyal](#):
>
> 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](https://doc.rust-lang.org/std/net/trait.ToSocketAddrs.html) when resolving a hostname). Since it's hardcoded, one can't make the stdlib use a third party crate like [dns-lookup](https://crates.io/crates/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)

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [April 13, 2023, 6:08am UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/4 "2023-04-13T06:08:34Z")

</div>

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](https://fly.io/blog/ssh-and-user-mode-ip-wireguard/) for an example of why you might want to do that.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [April 13, 2023, 8:33am UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/5 "2023-04-13T08:33:50Z")

</div>

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:

```rust
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, "example.org"))?;

```

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.

---

<div class="post-metadata">

**Author:** ![Valaphee](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/valaphee/32/10755_2.png) [@Valaphee](https://internals.rust-lang.org/u/Valaphee)\
**Post date:** [April 13, 2023, 8:57pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/6 "2023-04-13T20:57:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [April 14, 2023, 4:27pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/7 "2023-04-14T16:27:57Z")

</div>

There's a semi-related issue of [potentially moving `ToSocketAddrs` to `core`](https://github.com/rust-lang/rfcs/pull/2832/files/bd6b5499ace48c898351bbb81b6882a4ac1e1bb3#diff-753a880e8823be27042611729ea6c7404921e26472f5223dfd49896ce8cca81fR80), 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.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [April 15, 2023, 11:56am UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/8 "2023-04-15T11:56:10Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)\
**Post date:** [April 15, 2023, 2:04pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/9 "2023-04-15T14:04:20Z")

</div>

> [@Valaphee](#):
>
> And generally if you want to change the dns, it should apply for the whole program.

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

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [April 15, 2023, 2:19pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/10 "2023-04-15T14:19:19Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [July 14, 2023, 2:19pm UTC](https://internals.rust-lang.org/t/custom-global-dns-resolver/18667/11 "2023-07-14T14:19:54Z")

</div>

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