mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 03:05:51 +03:00
[GH-ISSUE #2190] Bind address in ResolverConfig does not take effort for AsyncResolver #913
Labels
No labels
blocked
breaking-change
bug
bug:critical
bug:tests
cleanup
compliance
compliance
compliance
crate:all
crate:client
crate:native-tls
crate:proto
crate:recursor
crate:resolver
crate:resolver
crate:rustls
crate:server
crate:util
dependencies
docs
duplicate
easy
easy
enhance
enhance
enhance
feature:dns-over-https
feature:dns-over-quic
feature:dns-over-tls
feature:dnsssec
feature:global_lb
feature:mdns
feature:tsig
features:edns
has workaround
ops
perf
platform:WASM
platform:android
platform:fuchsia
platform:linux
platform:macos
platform:windows
pull-request
question
test
tools
tools
trust
unclear
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hickory-dns#913
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @hainesc on GitHub (Apr 22, 2024).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2190
Describe the bug
A clear and concise description of what the bug is.
When I set bind_addr in ResolverConfig when make AsyncResolver, I expect that the UDP packets of DNS query would bind this SocketAddr, But it does not work!
To Reproduce
Steps to reproduce the behavior:
Source Code
Dependencies of Cargo.toml
Build and run
Expected behavior
A clear and concise description of what you expected to happen.
The last line of log should use bind_addr: 192.168.1.109:64665
System:
Version:
Crate: [e.g. client, server, resolver]
Version: [e.g. 0.9.1]
Additional context
Add any other context about the problem here.
@djc commented on GitHub (Apr 22, 2024):
IIRC a UDP DNS client doesn't bind to a single address (it uses ~one address per query) because otherwise it would be to easy to spoof responses.
Why is it important that UDP messages come from a single address? What's the use case for this?
@hainesc commented on GitHub (Apr 22, 2024):
I am agree with you that most of time, we don't need to bind a specific iface to do dns query. But sometimes we need, when I have more than one ifaces in my machine, which connect different networks.
And also, it is a feature that we can bind a specific iface, that means we can bind a specific iface if we want. For most network library for example tokio, socket2, as you see, they all support this feature.
Thanks.
@djc commented on GitHub (Apr 22, 2024):
@bluejekyll maybe
bind_addrshould take anIpAddrinstead of aSocketAddr?@hainesc commented on GitHub (Apr 23, 2024):
I think it should take a SocketAddr, because most of other library take a SocketAddr. for example, glibc, tokio.
https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
And more, in hickory dns, we have used SocketAddr for bind_addr, see:
https://github.com/hickory-dns/hickory-dns/blob/main/crates/proto/src/udp/udp_stream.rs#L245
Thanks.
@djc commented on GitHub (Apr 23, 2024):
IMO using a
SocketAddrfor binding an UDP socket is surprising since, AIUI, our UDP client sockets don't want to stick to one port as I mentioned in a previous comment. In general I feel like the notion of a singlebind_addris a little confusing since we could potentially bind any number of clients (UDP, TCP, DoT, DoH, DoQ) which can't all bind to the same port.@hainesc commented on GitHub (Apr 23, 2024):
Most of cases, the users specific the port to 0 which means random port by system.
See: https://github.com/hickory-dns/hickory-dns/blob/main/crates/proto/src/udp/udp_stream.rs#L291
@djc commented on GitHub (Apr 23, 2024):
It doesn't feel like you're actually reading my comments, so I'm going to stop engaging with this issue now.
@bluejekyll commented on GitHub (May 3, 2024):
Looking at this more, I think @djc, is making a very good point that for this interface, we want a bind_addr that is just the IP address, and not the port. The port should be randomly chosen based on our logic which works to enforce a random port is always used for each connection. For that reason, I think we want the PR to continue to use the random port logic that we have, but allow for the bind address to be set.
@hainesc commented on GitHub (May 4, 2024):
SocketAddrwith port 0 which means the port will later be automatically chosen when connect. This behavior has been documented in here https://man7.org/linux/man-pages/man7/ip.7.html. So if the user wants specific IP(for most of cases), he can use port 0.connect(2)operating-system function in Linux,let socket = tokio::net::TcpSocket::new_v4().unwrap(); socket.connect(socketaddr)in rust. For some user at least for me, it is a inertial thinking when I want specific a bind_addr.@bluejekyll commented on GitHub (May 5, 2024):
Not sure why you wanted to close this? My sense is that allowing the bind address is a good thing. We don’t trust the OS to distribute the port addresses in general, which is why the library has a random function to ensure it’s somewhat randomly distributed across the port space.
I see that you believe we should accept SocketAddr and use the port as an indication of using random selection logic, and I get your reasoning, but in this case we will be issuing multiple requests from this interface. In order to issue multiple requests to the same remote address, those must be on separate ports, otherwise we run afoul of the response spoofing that the random port selection is intended to prevent.
so it leads me to believe that we want to guide people in the proper direction, and only take IpAdrr as the bind address, and always randomize the port. Do you have a particular use case where you want the port to be static and non-zero ever?