[GH-ISSUE #2188] Not convenient to call bind_with_addr to make a AsyncResolver #912

Open
opened 2026-03-16 00:51:10 +03:00 by kerem · 6 comments
Owner

Originally created by @hainesc on GitHub (Apr 20, 2024).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2188

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Maybe I have missed something, but AFAIK, it is not convenient to call bind_with_addr when I want to make dns resolver with a specific network interface.

Now I can write as below:

let (config, options) = trust_dns_resolver::system_conf::read_system_conf()?;

// but how can I set bind addr for config here. Since `set_bind_addr` is a method of `NameServerConfigGroup`, but `name_servers` in ResolverConfig is not public.

let provider = ...
let resolver = trust_dns_resolver::new_with_conn(config, options, provider)

I don't like copy the code how trust_dns_resolver::system_conf::read_system_conf() does and set bind addr there.

Describe the solution you'd like
A clear and concise description of what you want to happen.

And I think make a method named set_bind_addr for ResolverConfig will be a simple solution.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

https://github.com/hickory-dns/hickory-dns/blob/main/crates/resolver/src/config.rs#L827

Originally created by @hainesc on GitHub (Apr 20, 2024). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2188 **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] Maybe I have missed something, but AFAIK, it is not convenient to call bind_with_addr when I want to make dns resolver with a specific network interface. Now I can write as below: ``` let (config, options) = trust_dns_resolver::system_conf::read_system_conf()?; // but how can I set bind addr for config here. Since `set_bind_addr` is a method of `NameServerConfigGroup`, but `name_servers` in ResolverConfig is not public. let provider = ... let resolver = trust_dns_resolver::new_with_conn(config, options, provider) ``` I don't like copy the code how trust_dns_resolver::system_conf::read_system_conf() does and set bind addr there. **Describe the solution you'd like** A clear and concise description of what you want to happen. And I think make a method named `set_bind_addr` for ResolverConfig will be a simple solution. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. https://github.com/hickory-dns/hickory-dns/blob/main/crates/resolver/src/config.rs#L827
Author
Owner

@hainesc commented on GitHub (Apr 20, 2024):

If that is acceptable, I can make a PR ASAP.

<!-- gh-comment-id:2067609494 --> @hainesc commented on GitHub (Apr 20, 2024): If that is acceptable, I can make a PR ASAP.
Author
Owner

@hainesc commented on GitHub (Apr 20, 2024):

Related issue:
https://github.com/hickory-dns/hickory-dns/issues/2087

<!-- gh-comment-id:2067610647 --> @hainesc commented on GitHub (Apr 20, 2024): Related issue: https://github.com/hickory-dns/hickory-dns/issues/2087
Author
Owner

@djc commented on GitHub (Apr 22, 2024):

bind_addr is a public property of NameServerConfig so by itself that seems easy enough to change. I guess it might be okay to expose a groups_mut() accessor on ResolverConfig and a servers_mut() accessor on NameServerGroup?

<!-- gh-comment-id:2069314665 --> @djc commented on GitHub (Apr 22, 2024): `bind_addr` is a public property of `NameServerConfig` so by itself that seems easy enough to change. I guess it might be okay to expose a `groups_mut()` accessor on `ResolverConfig` and a `servers_mut()` accessor on `NameServerGroup`?
Author
Owner

@bluejekyll commented on GitHub (May 18, 2024):

We could definitely make NameServer and NameServerGroup configuration more ergonomic. I haven't revisited these interfaces in a while, there are probably better patterns that could be adopted.

<!-- gh-comment-id:2119020987 --> @bluejekyll commented on GitHub (May 18, 2024): We could definitely make NameServer and NameServerGroup configuration more ergonomic. I haven't revisited these interfaces in a while, there are probably better patterns that could be adopted.
Author
Owner

@GICodeWarrior commented on GitHub (Jul 9, 2024):

I will try and summarize my current understanding of the situation and then summarize a few options.

Current Situation

  1. Sometimes it's useful to build a configuration based on the system configuration (i.e. system_conf::read_system_conf()) with some modifications. (e.g. custom bind address, timeout, protocol, etc.)
  2. Modifying the configuration can be difficult or impossible without initializing a new configuration entirely. For example:
    • Bind address is configured on the NameServerGroup held by ResolverConfig
    • Timeout is configured on ResolverOpts
    • Protocol is configured on instances of NameServerConfig within the NameServerGroup held by ResolverConfig
  3. Given the multiple layers of nesting and current mutability constraints, it's difficult to modify an existing configuration.

Some Improvement Options

These are still high level thoughts and not mutually exclusive. Based on your feedback I can make a more narrow/specific proposal if useful.

  1. Mutable nested accessors - add accessors where necessary to grant mutable access to nested configuration structures (Possibly least invasive)
  2. Top-level mutators - add functions to grant mutation of specific nested configuration parameters (e.g. set_bind_addr on ResolverConfig that pushes the address into each NameServerConfig within the NameServerGroup)
  3. Less nesting - combine some configuration structs to reduce access complexity (e.g. move NameServerGroup functionality into ResolverConfig and/or move ResolverOpts into ResolverConfig)
  4. Builder pattern - redesign the configuration to use the builder pattern

Please let me know your thoughts.

<!-- gh-comment-id:2216319931 --> @GICodeWarrior commented on GitHub (Jul 9, 2024): I will try and summarize my current understanding of the situation and then summarize a few options. ### Current Situation 1. Sometimes it's useful to build a configuration based on the system configuration (i.e. `system_conf::read_system_conf()`) with some modifications. (e.g. custom bind address, timeout, protocol, etc.) 2. Modifying the configuration can be difficult or impossible without initializing a new configuration entirely. For example: * Bind address is configured on the `NameServerGroup` held by `ResolverConfig` * Timeout is configured on `ResolverOpts` * Protocol is configured on instances of `NameServerConfig` within the `NameServerGroup` held by `ResolverConfig` 3. Given the multiple layers of nesting and current mutability constraints, it's difficult to modify an existing configuration. ### Some Improvement Options These are still high level thoughts and not mutually exclusive. Based on your feedback I can make a more narrow/specific proposal if useful. 1. Mutable nested accessors - add accessors where necessary to grant mutable access to nested configuration structures (Possibly least invasive) 2. Top-level mutators - add functions to grant mutation of specific nested configuration parameters (e.g. `set_bind_addr` on `ResolverConfig` that pushes the address into each `NameServerConfig` within the `NameServerGroup`) 3. Less nesting - combine some configuration structs to reduce access complexity (e.g. move `NameServerGroup` functionality into `ResolverConfig` and/or move `ResolverOpts` into `ResolverConfig`) 4. Builder pattern - redesign the configuration to use the builder pattern * https://doc.rust-lang.org/1.0.0/style/ownership/builders.html * To facilitate variants of the system configuration, `ResolverConfigBuilder` could include a `from` method or static method accepting an existing ResolverConfig to copy options from Please let me know your thoughts.
Author
Owner

@djc commented on GitHub (Jul 9, 2024):

That sounds about right!

On your options:

  1. Mutable nested accessors: I think this would be a straightforward improvement on the current state
  2. Top-level mutators: this doesn't feel like a great idea, because it would more tightly couple all of the configuration types and create a sprawl of configuration API; your example of having a set_bind_addr() that implicitly updates all NameSserverConfig also feels a little too magic
  3. Less nesting: I think that might be a good idea? To me the more obvious API would have ResolverOpts be part of ResolverConfig (perhaps by flattening it) and maybe also dissolve the NameServerConfigGroup type. Another aspect here is how we configure TLS, which might also want some refactoring (you can find earlier issues/PRs from @daxpedda about this -- for example, it would be nice to get rid of the static TLS configs).
  4. Builder pattern: could potentially make sense, but I think we should probably reorganize the configuration a bit first.
<!-- gh-comment-id:2216869992 --> @djc commented on GitHub (Jul 9, 2024): That sounds about right! On your options: 1. Mutable nested accessors: I think this would be a straightforward improvement on the current state 2. Top-level mutators: this doesn't feel like a great idea, because it would more tightly couple all of the configuration types and create a sprawl of configuration API; your example of having a `set_bind_addr()` that implicitly updates all `NameSserverConfig` also feels a little too magic 3. Less nesting: I think that might be a good idea? To me the more obvious API would have `ResolverOpts` be part of `ResolverConfig` (perhaps by flattening it) and maybe also dissolve the `NameServerConfigGroup` type. Another aspect here is how we configure TLS, which might also want some refactoring (you can find earlier issues/PRs from @daxpedda about this -- for example, it would be nice to get rid of the static TLS configs). 4. Builder pattern: could potentially make sense, but I think we should probably reorganize the configuration a bit first.
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#912
No description provided.