-
Notifications
You must be signed in to change notification settings - Fork 16
transport: Allow changing DNS resolver config #384
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
base: master
Are you sure you want to change the base?
Conversation
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.
Hey @ZettaScript, IMO an option to use a system resolver makes sense and is also useful when local resolution should be different from what 8.8.8.8 provides.
The PR looks good, but should be extended to all the transports to not configure the resolver individually for TCP, WS, WebRTC, etc. The best place for config would be Litep2pConfig
(and its ConfigBuilder
), from where the resolver can be distributed to all the transports.
src/transport/common/listener.rs
Outdated
pub async fn lookup_ip(self) -> Result<SocketAddr, DnsError> { | ||
pub async fn lookup_ip( | ||
self, | ||
resolver: impl Borrow<TokioAsyncResolver>, |
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.
What is the motivation behind Borrow
here? I don't think there are other types than TokioAsyncResolver
that can be borrowed as such.
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.
To be able to pass TokioAsyncResolver
, or a reference, or an Arc
. I often find this pattern convenient, but I can simply use a reference if it's not needed.
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 think there is no need to use impl
in the function definition here, as we know exactly what type we are using.
src/transport/tcp/config.rs
Outdated
|
||
/// DNS resolver config. | ||
pub resolver_config: hickory_resolver::config::ResolverConfig, | ||
|
||
/// DNS resolver options. | ||
pub resolver_opts: hickory_resolver::config::ResolverOpts, |
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.
Ideally this should be universal to all the transports, including WS, QUIC, 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.
I'm not sure how to do that. Should TransportBuilder::new
accept a new argument for the resolver? or a new field in TransportHandle
?
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.
Sorry, missed this. Yes, TransportBuilder:new
accepting a new argument is fine.
Thanks for reporting regarding clippy — seems the clippy CI step is not enforcing things. |
src/transport/tcp/config.rs
Outdated
/// DNS resolver config. | ||
pub resolver_config: hickory_resolver::config::ResolverConfig, | ||
|
||
/// DNS resolver options. | ||
pub resolver_opts: hickory_resolver::config::ResolverOpts, | ||
} |
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 alternative here would be to have a new dedicated option to read from the system config, similar to:
/// Defaults to false (ie current behavior).
pub use_system_dns_config: bool,
The advantage is that we can change the hickory DNS resolver under the hood without breaking the API. We are getting close to the finish line and we should strive to keep the API as stable as possible.
Indeed I would also lean towards @dmitry-markin suggestion here, we should make this available on the main litep2p config.
One option to achive this: transform the pub use_system_dns_config
into pub(crate) use_system_dns_config
flag in the TCP config (ie users cannot modify it directly). Add the flag to the main litep2p config, and populate the tcp_config.use_system_dns_config
from the litep2p_config.use_system_dns_config
. We have a precedent for the identify configs to showcase this in more details
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.
Now hickory types are private, only the flag is public.
If both Litep2pConfig
and transport's config have the flag, it can be modified from different places and the outcome won't be obvious. For example, what if websocket_config.use_system_dns_config
is false, tcp_config.use_system_dns_config
is true and litep2p_config.use_system_dns_config
is true?
Since transport's config must be added explicitly to the builder anyway (if I get it right), having a common flag seems mostly noise.
Also, if reading system's config fails, should it return a new Error
variant? I don't want to silently fallback to default, because it's troublesome to debug for users.
Hey @ZettaScript, I have updated hickory-resolver in #386. Let's base the refactoring on the latest version. |
Our CI step `Run clippy` did not treat warnings as errors. Therefore, the process terminated with exit code zero even when the clippy rules were not followed. This PR ensures the clippy rules are enforced by our CI. While at it, this PR fixes the clippy rules by `--fix` and manually fixes bits where needed. Since the code inside tokio::select and logs is not formatted by rustfmt, I've only paid attention to our production code. There might be a few places in our tests where these lines are long or not properly formatted. Detected by: #384 --------- Signed-off-by: Alexandru Vasile <[email protected]>
The branch is rebased on master. I am still unsure about the duplicated |
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.
Thank you for rebasing on master! One thing you could do in a similar situation is merge master. Force-pushing breaks the review history in an already opened PRs.
See the inline comment for dealing with duplicate use_system_dns_config
and early failure.
src/transport/tcp/config.rs
Outdated
@@ -80,6 +80,9 @@ pub struct Config { | |||
/// How long should litep2p wait for a substream to be opened before considering | |||
/// the substream rejected. | |||
pub substream_open_timeout: std::time::Duration, | |||
|
|||
/// Use system's DNS config. | |||
pub use_system_dns_config: bool, |
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.
We can remove use_system_dns_config
from transport configs completely. Ideally, we want to initialize the resolver early to fail the initialization of Litep2p
object in case we can't read the system config. For this, we can initialize the resolver once in Litep2p::new
(returning a new error type there) and pass it to every transport via TransportBuilder::new
. The arguments of the latter will need to be extended with an explicit resolver argument to not clutter Config
with a private field.
Now the resolver is configured and initialized in |
Hey, looks good! Passing the unused arg is fine. WebRTC in litep2p only implements "server mode", so no resolver is needed. With QUIC, can you investigate, please, why the resolver is not used, so we don't end up in a situation where different transport resolvers work differently? |
Co-authored-by: Dmitry Markin <[email protected]>
Thanks!
I'll investigate. (never worked with QUIC before) |
The are a few issues about QUIC but none about QUIC+DNS. |
You are right, QUIC doesn't currently support dialing DNS addresses. I've created an issue for this: #406 No need to address anything in this PR. |
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.
Looks good, thank you! I will let @lexnv also review the PR, and after this we can merge it.
Co-authored-by: Dmitry Markin <[email protected]>
Fixes #383
I don't exactly know the implications of storing the resolver there but it looks reasonable to me (more than recreating it at each lookup).
Default config has the same behavior as before (Google servers), but now it can be changed.
I guess it's a semver-breaking change but unless using something like a static
OnceCell
I see no other way.Also, please consider using (and enforcing) cargo clippy, it helps contributors cleaning their edits without having to scroll over preexisting warnings.