-
Notifications
You must be signed in to change notification settings - Fork 235
refactor!: use a single DNS resolver #3167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/3167/docs/iroh/ Last updated: 2025-02-06T13:15:56Z |
iroh/src/dns.rs
Outdated
host: N, | ||
timeout: Duration, | ||
) -> impl Future<Output = Result<impl Iterator<Item = IpAddr>>>; | ||
|
||
/// Looks up node info by DNS name. | ||
fn lookup_by_name(&self, name: &str) -> impl Future<Output = Result<NodeAddr>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not move the others as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went forward with this and moved the node_info module and the lookup methods for nodes to iroh_relay as well.
This means iroh_relay now has a dependency on pkarr (because the functions to parse node info from pkarr packets live on the same structs as parsing from hickory dns records) - without default features though, so should be fine (includes neither the relay nor the dht clients).
I pushed another round of commits:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like these changes overall! Mostly some nitpicking.
I haven't looked at it, but this should take into account #2901 so that whatever it wants will still be possible with this DNS interface.
iroh-relay/src/dns.rs
Outdated
} | ||
|
||
/// Lookup a TXT record. | ||
pub async fn lookup_txt(&self, query: impl IntoName) -> Result<TxtLookup, ResolveError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Howe come this doesn't have a timeout while the ipv4 & ipv6 looksups do?
I'm also confused by the return type, it's owned by hickory but not pub use
? I'm sure I missed something because otherwise that shouldn't work.
Anyway, long way to say that we should own all our types and not re-export new types from external crates. We can newtype them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these methods were so far left as-is from the existing implementations in the extension traits.
I added a timeout to be in line with the others.
Also tried out adding newtypes for TxtLookup
. It turned out OK. At the same time I though I realized that we still have quite a few hickory_resolver
or hickory_proto
types exposed, e.g. the IntoName
trait is used in most of the methods on DnsResolver
. Do we want to newtype everything we expose? I'll do a review of the API next, but many of these hickory types are composed or match with other hickory types, so to cover the full API surface of a Dns resolver that will be quite some newtyping, methods etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remaining usage of hickory-proto
is now the IntoName
trait, which efficiently converts String
, &str
and Name
s into the Name
struct from hickory_proto
.
url: &Url, | ||
prefer_ipv6: bool, | ||
timeout: Duration, | ||
) -> Result<IpAddr> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit an odd API, why not return impl Iterator<Item = IpAddr>
like for the other resolve methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taken over from existing usage. Likely we want to change that, yes - it is not used much so will be a simple change to align with the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit an odd API, why not return impl Iterator<Item = IpAddr> like for the other resolve methods?
the point of this method when I last touched it, is to handle the turning the iterator into a single address, for you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just more nits, like before nothing serious. Overall this is good.
iroh-relay/src/dns.rs
Outdated
impl From<TokioResolver> for DnsResolver { | ||
fn from(resolver: TokioResolver) -> Self { | ||
DnsResolver(resolver) | ||
} | ||
} | ||
|
||
/// TXT records returned from [`DnsResolver::lookup_txt`] | ||
#[derive(Debug, Clone)] | ||
pub struct TxtLookup(pub(self) hickory_resolver::lookup::TxtLookup); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL about pub(self)
(had to look this up in https://doc.rust-lang.org/reference/visibility-and-privacy.html#r-vis.scoped.self). I'm confused why this even exists in rust? Seems like leaving it off is exactly the same, so why do folks want to spell it out sometimes? What is the motivation here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, dunno, removed it :)
iroh-relay/src/dns/node_info.rs
Outdated
/// subsequent labels. | ||
/// | ||
/// Returns a [`NodeId`] if parsed successfully, otherwise `None`. | ||
pub fn node_id_from_domain_name(name: &str) -> Option<NodeId> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a pkarr helper method. Is there any reason to make all this pub? Maybe this stuff was already pub, but I guess we haven't tried to make the pub API here much smaller yet. If we don't want to reduce the amount of pub in this PR to keep concerns separate (I often prefer this in my own PRs) I'm also fine to leave this here for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was only used in iroh::test_utils
- moved it there.
iroh-relay/src/dns.rs
Outdated
} | ||
|
||
/// Create a new DNS resolver configured with a single UDP DNS nameserver. | ||
pub fn with_single_nameserver(nameserver: SocketAddr) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would probably prefer with_namesever
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree, renamed
I pushed another round of commits:
There's now three remaining uses of
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The From<HickoryResolver>
is probably fine as an external type? Can this still get you into trouble if they update it?
…of `iroh`, replace with `ToString` (#3173) ## Description Removes `IntoName` trait from `hickory_proto` from the public API of `iroh::dns` module, to not commit to hickory types in our potential 1.0 API. Replaces the `impl IntoName` with `impl ToString`, which covers all our existing usages. This might incur a small perfomance penalty if you already have a hickory `Name` at the call site, but I don't think it will matter in practice. ## Breaking Changes * The methods in `iroh::dns::DnsResolver` now take an `impl ToString` instead of `impl hickory_proto::rr::domain::IntoName` for their `host` argument ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist - [ ] Self-review. - [ ] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] Tests if relevant. - [ ] All breaking changes documented.
We should revisit this before 1.0. I think the impl is no different than a method that takes the TokioResolver, which means we cannot update hickory major version without that being a semver breaking change to iroh... But I'd leave figuring out a solution to a followup PR. |
Hum, yes. You're probably right. 👍 |
Description
We used to have more-or-less identical code in various places to set a static DNS resolver and add a few extension methods on the
hickory_resolver::TokioResolver
. This PR cleans this up and makes all of iroh use the same resolver, defined in a single place, as a newtype struct around theTokioResolver
fromhickory_resolver
:Adds a newtype struct
DnsResolver
aroundhickory_resolver::TokioResolver
iniroh_relay::dns
. It lives (for now) iniroh_relay
, because this is a the bottom of our dependency chain: bothiroh
andiroh-net-report
need to use it as well, and both depend oniroh_relay
.Adds most methods from the previous extension traits to the
DnsResolver
structChanges all imports to use this
DnsResolver
now instead of the previous type alias to TokioResolverRemoves all now-obsolete duplicate extension traits and type aliases and duplicated tests
Removes the global
static
DnsResolver that was accessible viairoh::dns::default_resolver
. This means that by default multiple endpoints in the same app would not share the DnsResolver. However, I'd say a) it is not too common to use multiple endpoints, and b) if you do and want to share the DnsResolver, you can still do so by creating the DnsResolver yourself and cloning it into the endpoint builder.Cleans up and aligns the various methods on
DnsResolver
, and newtype the types from hickory so that this public iroh API does not depend on hickory types (apart from aFrom<TokioResolver> for DnsResolver
, which is deferred to a follow-up to investigate)The only place outside of tests and examples where a new
DnsResolver
is constructed is in endpoint builder if no custom DnsResolver is set. This means: As long as an app has a single endpoint only, there will only be one DnsResolver.Breaking Changes
iroh::dns::resolver
andiroh::dns::default_resolver
are removed. There is no static, global DNS resolver anymore. If you want to share a DNS resolver between endpoints, create the resolver yourself withiroh::dns::DnsResolver::new
and clone it into the endpoint builders (inEndpointBuilder::dns_resolver
). If you want to reuse the DNS resolver from an endpoint, you can access it withEndpoint::dns_resolver
and clone it to wherever you need it.iroh::dns::DnsResolver
used to be a type alias and now is a reexport ofiroh_relay::dns::DnsResolver
structiroh::dns::node_info
module is now a reexport ofiroh_relay::dns::node_info
iroh::dns::node_info::{IrohAttr, TxtAttrs, node_id_from_hickory_name}
are no longer public. Useiroh::dns::DnsResolver::lookup_node_by_id
oriroh::dns::DnsResolver::lookup_node_by_domain_name
to lookup node info from DNS.iroh::dns::node_info::{to_z32, from_z32}
are removed. Use the methods oniroh::dns::node_info::NodeIdExt
trait instead.iroh::discovery::dns::{N0_DNS_NODE_ORIGIN_PROD, N0_DNS_NODE_ORIGIN_STAGING}
are now reexports ofiroh_relay::dns::{N0_DNS_NODE_ORIGIN_PROD, N0_DNS_NODE_ORIGIN_STAGING}
iroh::dns::ResolverExt
is removed. Use the methods oniroh::dns::DnsResolver
instead.The methods in
iroh::dns::DnsResolver
now take animpl ToString
instead ofimpl hickory_proto::rr::domain::IntoName
for theirhost
argumentiroh::test_utils::create_dns_resolver
is removed, useiroh::dns::DnsResolver::new
insteadNotes & open questions
Change checklist