mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 03:05:51 +03:00
[GH-ISSUE #1973] UdpClientStream fails to parse large responses #835
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#835
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 @nmittler on GitHub (Jun 20, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1973
Describe the bug
I'm trying to build a local test for truncation, and ran into an issue. The test uses
UdpClientStreamto call a local server (Catalog+InMemoryAuthority) which responds a large record set resulting in a UDP payload of 2080 bytes (verified via WireShark). Running with tracing enabled, I see:Digging in a little further, I see that the client is only seeing
2048of the2080bytes. The MTU forlo0is16384, so it's not being truncated down the stack (Wireshark confirms).The problem appears to be that
UdpClientStreamexplicitly limits the size of the reply buffer to 2048. Since each read assumes a complete UDP packet, parsing fails.To Reproduce
See description.
Expected behavior
Replies larger than 2048 bytes should be supported by
UdpClientStream.Docs for tokio UdpSocket indicate that reads should generally be done with the max UDP packet size of 65536. It may be a larger buffer than we'd like in general, but it would at least be correct.
System:
Version:
Crate: client, server
Version: 0.22.0
Additional context
NA
@nmittler commented on GitHub (Jun 20, 2023):
@bluejekyll
Related to this is the fact that DNS truncation (TC=1) doesn't appear to be happening in my test. EDNS has max_payload set to 512 (the default), yet the response still comes through without truncation.
I believe that issue may be related to the fact that
BinEncoderuses aMaximalBufwith a maximum ofu16::max_value(). IIUC, this could be why there is no truncation for a payload of2080.I'm happy to raise this as a separate bug if you think it's a real issue.
@djc commented on GitHub (Jun 20, 2023):
Maybe run a little
git blameon theUdpClientStreamcode to figure out if there were changes to the size of the buffer? It's tricky because I guess we only have one shot to receive, but we might not want to keep a 64k buffer allocated throughout the lifetime of the stream when it's unlikely we'll use the entire size of the buffer.@nmittler commented on GitHub (Jun 20, 2023):
@djc Yeah that was my thought as well. Perhaps we could use the EDNS max_payload value from the request if available, to trim this down a bit? And/or we could use the MTU of the network interface ... this would likely only be large-ish for a loopback interface.
FYI, the 2048 value goes back all the way to the initial implementation: https://github.com/bluejekyll/trust-dns/pull/46.
@nmittler commented on GitHub (Jun 21, 2023):
@bluejekyll @djc I threw together a WIP PR: #1975. Right now it just uses MTU, but we can expand it. Should probably also have a proper e2e test specifically for this problem.
@djc commented on GitHub (Jun 21, 2023):
I guess the MTU is accurate for loopback interfaces at least, but I suppose actual network path MTUs would be constrained by any number of other interfaces on the path to the remote, so it's maybe not very meaningful? Additionally at least the crates I've looked at so far for retrieving the MTU are pretty heavyweight dependencies which IMO isn't very attractive.