DnsNameResolver: Allways call bind() during bootstrap#13817
Conversation
|
@idelpivnitskiy PTAL... I think we talked about this before. |
Motivation: We should always call `bind(...)` during bootstrap to allow easier debugging as if not explicit binding the OS will do it anyway. Before calling explicit bind we would not have limited visiblity when logging: ``` 10:18:45.466 [main] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0x798ced86] WRITE: UDP, [10844: /127.0.0.1:49443], DefaultDnsQuestion(somehost.netty.io. IN TXT) ``` After explicit bind the local address / port is included as well: ``` 10:21:30.366 [nioEventLoopGroup-2-1] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0xa118f365, L:/[0:0:0:0:0:0:0:0]:54165] WRITE: UDP, [15418: /127.0.0.1:56439], DefaultDnsQuestion(lastname.com. IN AAAA) ``` Modifications: - Always explicitly call bind(...) Result: Better debuggability
ad52e53 to
3cbb2e7
Compare
Motivation: We should always call `bind(...)` during bootstrap to allow easier debugging as if not explicit binding the OS will do it anyway. Before calling explicit bind we would not have limited visiblity when logging: ``` 10:18:45.466 [main] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0x798ced86] WRITE: UDP, [10844: /127.0.0.1:49443], DefaultDnsQuestion(somehost.netty.io. IN TXT) ``` After explicit bind the local address / port is included as well: ``` 10:21:30.366 [nioEventLoopGroup-2-1] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0xa118f365, L:/[0:0:0:0:0:0:0:0]:54165] WRITE: UDP, [15418: /127.0.0.1:56439], DefaultDnsQuestion(lastname.com. IN AAAA) ``` Modifications: - Always explicitly call bind(...) Result: Better debuggability
idelpivnitskiy
left a comment
There was a problem hiding this comment.
Yes, thanks a lot for adding this!
Motivation: We should always call `bind(...)` during bootstrap to allow easier debugging as if not explicit binding the OS will do it anyway. Before calling explicit bind we would not have limited visiblity when logging: ``` 10:18:45.466 [main] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0x798ced86] WRITE: UDP, [10844: /127.0.0.1:49443], DefaultDnsQuestion(somehost.netty.io. IN TXT) ``` After explicit bind the local address / port is included as well: ``` 10:21:30.366 [nioEventLoopGroup-2-1] DEBUG i.netty.resolver.dns.DnsQueryContext - [id: 0xa118f365, L:/[0:0:0:0:0:0:0:0]:54165] WRITE: UDP, [15418: /127.0.0.1:56439], DefaultDnsQuestion(lastname.com. IN AAAA) ``` Modifications: - Always explicitly call bind(...) Result: Better debuggability
|
Before the modification, no port is bound when the new DnsNameResolver () object is created. A random UDP port is bound only after reslove is invoked. After the modification, a UDP port is bound as long as a DnsNameResolver object is created. However, in software such as vert.x, there are many new DnsNameResolver objects that find that the address has been resolved without triggering reslove. I think this modification leads to a lot of unnecessary UDP listening in use. Is this reasonable? |
|
I like that the address is bind by default, but maybe there should be a way to opt-out for use-cases like mentioned above |
|
@idelpivnitskiy @llchry I am happy to review a PR to disable it as opt-out. |
how about revoke this PR? |
|
my2c: the default behavior should be to bind to an address because it significantly complicates debuggability of any netty library that uses dns resolver if the port is not visible in logs. Also, per my observations, most libs create a single resolver (and reuse it to get advantage of a shared cache) and therefore bind only a single local port. Projects that behave differently may have a way to opt-out. |
|
If I'm using netty directly, netty provides various configurations that allow for various cases to be handled. When using some other dependent library, it's possible that these configurations are hidden. |
|
This caused an odd breakage for us in a very specific platform: When running Redisson in a JDK 8 container in Kubernetes, Redisson attempts to resolve the Redis hostname to make a connection and the channel to the DNS name server wasn't open...then this future gets added and hangs forever: https://github.com/netty/netty/blob/netty-4.1.108.Final/resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryContext.java#L253-L267 We're not sure why, but running the same code in a JDK 17 container in Kubernetes works fine. It also works outside of Kubernetes on both JDK 8 and 17. |
|
Hello, When we performed netty DNS resolver upgrade (to 4.1.108), we also noticed that our Java process is using multiple UDP ports. Here is the stack trace: "tcp-client-loop-nio-2@40650" tid=0xb8 nid=NA runnable Security scanners reporting UDP port usage which needs explanation. Appreciate your help. |
That will be a question to reactor-netty maintainers. Not sure what they do at that layer, but typically it's enough to have a single
Each
For a lifetime of |
|
Thank you so much @idelpivnitskiy. I will reach out to reactor-netty maintainers and will update this thread as well. |
|
If we have this configuration below, the
what kind of configuration do you mean because (the code snippet is extracted from https://gist.github.com/violetagg/ec457f300be46f457c30f358855ca13b) When
As a result |
|
@violetagg thanks for clarifying. If you are using @amitlpande then in this setup it's expected to have number of DNS resolvers equal to the total number of |
|
@idelpivnitskiy Yes, I agree. However, is there a scope for refactoring like I mentioned in - #14338 (comment)? Also, as suggested on the thread, It might be an acceptable stopgap solution to downgrade if there are no public vulnerabilities in the downgraded version. |
|
I think either (1) netty should have a way to opt out from this behavior when users have a reason for that or (2) whoever has access to configure
|
That's not a good solution. Downgrade is highly inconvenient, unpredictable (someone else can upgrade forward), exposes to potential future vulnerabilities, or inability to use new features directly or via other dependencies that use netty on the same classpath. |
Motivation: We prefer to bind by default for better debug logging (see netty#13817). However, some users expressed concerns with this behavior change because it eagerly binds a UDP port even when allocated resolver is not used. Modifications: - Keep default behavior to bind, but allow configuring `null` for `DnsNameResolverBuilder.localAddress(...)` to preserve pre-existing behavior. Result: Users can opt-in for pre-existing behavior of lazy port binding on resolve.
Motivation: We prefer to bind by default for better debug logging (see #13817). However, some users expressed concerns with this behavior change because it eagerly binds a UDP port even when allocated resolver is not used. Modifications: - Keep default behavior to bind, but allow configuring `null` for `DnsNameResolverBuilder.localAddress(...)` to preserve pre-existing behavior. Result: Users can force pre-existing behavior of lazy port binding on resolve.
Motivation: We prefer to bind by default for better debug logging (see #13817). However, some users expressed concerns with this behavior change because it eagerly binds a UDP port even when allocated resolver is not used. Modifications: - Keep default behavior to bind, but allow configuring `null` for `DnsNameResolverBuilder.localAddress(...)` to preserve pre-existing behavior. Result: Users can force pre-existing behavior of lazy port binding on resolve.
Motivation: We prefer to bind by default for better debug logging (see #13817). However, some users expressed concerns with this behavior change because it eagerly binds a UDP port even when allocated resolver is not used. Modifications: - Keep default behavior to bind, but allow configuring `null` for `DnsNameResolverBuilder.localAddress(...)` to preserve pre-existing behavior. Result: Users can force pre-existing behavior of lazy port binding on resolve.
Is there a non-unhealthy version of the solution? |
|
#14375 made it possible for users to use |
|
Hi, I understand that:
My concerns are specifically about why this behavior is now default:
Based on my past experience with libraries using Netty (maybe I miss bigger pictures) —which tend to allocate resources more lazily—I'm curious: is it a new pattern of Netty development, that resources could be allocated more proactively? Thanks for your consideration! |
Motivation:
We should always call
bind(...)during bootstrap to allow easier debugging as if not explicit binding the OS will do it anyway. Before calling explicit bind we would not have limited visiblity when logging:After explicit bind the local address / port is included as well:
Modifications:
Result:
Better debuggability