Skip to content
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

net: netgo dns resolver does not return addresses on TCP truncated responses #64896

Closed
aojea opened this issue Dec 29, 2023 · 3 comments
Closed
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@aojea
Copy link
Contributor

aojea commented Dec 29, 2023

Long history: https://gist.github.com/aojea/32aeaa86aacebcdd93596ecb70fcba4f

DNS UDP messages may be truncated if there are many records,

https://www.rfc-editor.org/rfc/rfc1035#section-4.2.1

Messages carried by UDP are restricted to 512 bytes (not counting
the IP or UDP headers). Longer messages are truncated and the TC
bit is set in the header.

However, TCP also have a size limitation of 65535 bytes

https://www.rfc-editor.org/rfc/rfc1035#section-4.2.2

The message is prefixed with a two byte length field which gives
the message length, excluding the two byte length field.

These limitations makes that the maximum possible number of A records per RRSet is ~ 4090.

There are environments like Kubernetes that may have larger number of records (5000+) that does not fit in a single message. In this cases, the DNS server sets the Truncated bit on the message to indicate that it could not send the full answer despite is using TCP, see coredns/coredns#3660 (comment)

The existing golang resolver returns errNoAnswerFromDNSServer if it receives a TCP response, discarding all the existing records in the response.

On the contrary, the glibc resolver returns the existing records in the TCP response despite it has the truncated bit set.

We should have the same behaviour in both resolvers, and only retry when the TC bit is set and the connection is UDP,
otherwise, we'll never being able to get an answer and the client will receive an errNoAnswerFromDNSServer, that is not the same behavior as in the glibc resolver.

@aojea
Copy link
Contributor Author

aojea commented Dec 29, 2023

@gopherbot
Copy link

Change https://go.dev/cl/552418 mentions this issue: net: don't retry truncated TCP responses

@mateusz834 mateusz834 added the NeedsFix The path to resolution is known, but the work has not been done. label Dec 29, 2023
@seankhliao seankhliao changed the title net: golang dns resolver does not return addressed on TCP truncated responses net: netgo dns resolver does not return addresses on TCP truncated responses Dec 29, 2023
@bcmills
Copy link
Contributor

bcmills commented Jan 2, 2024

(attn @ianlancetaylor @neild)

@bcmills bcmills added this to the Backlog milestone Jan 2, 2024
ezz-no pushed a commit to ezz-no/go-ezzno that referenced this issue Feb 18, 2024
UDP messages may be truncated:

https://www.rfc-editor.org/rfc/rfc1035#section-4.2.1

> Messages carried by UDP are restricted to 512 bytes (not counting
> the IP or UDP headers). Longer messages are truncated and the TC
> bit is set in the header.

However, TCP also have a size limitation of 65535 bytes

https://www.rfc-editor.org/rfc/rfc1035#section-4.2.2

> The message is prefixed with a two byte length field which gives
the message length, excluding the two byte length field.

These limitations makes that the maximum possible number of A records
per RRSet is ~ 4090.

There are environments like Kubernetes that may have larger number of
records (5000+) that does not fit in a single message. In this cases,
the DNS server sets the Truncated bit on the message to indicate that
it could not send the full answer despite is using TCP.

We should only retry when the TC bit is set and the connection is UDP,
otherwise, we'll never being able to get an answer and the client will
receive an errNoAnswerFromDNSServer, that is a different behavior than
the existing in the glibc resolver, that returns all the existing
addresses in the TCP truncated response.

Fixes golang#64896

Signed-off-by: Antonio Ojea <aojea@google.com>
Change-Id: I1bc2c85f67668765fa60b5c0378c9e1e1756dff2
Reviewed-on: https://go-review.googlesource.com/c/go/+/552418
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Gudger <ian@iangudger.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Mateusz Poliwczak <mpoliwczak34@gmail.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants