Skip to content

Commit

Permalink
net: send EDNS(0) packet length in DNS query
Browse files Browse the repository at this point in the history
Advertise to DNS resolvers that we are willing and able to accept up
to 1232 bytes in a DNS packet. The value 1232 was chosen based on
https://dnsflagday.net/2020/.

For golang#6464
For golang#21160
For golang#44135
For golang#51127
Fixes golang#51153

Change-Id: If9182d5210bfe047cf0a4d46163effc6812ab677
Reviewed-on: https://go-review.googlesource.com/c/go/+/386016
Trust: Ian Lance Taylor <[email protected]>
Run-TryBot: Ian Lance Taylor <[email protected]>
Reviewed-by: Damien Neil <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
ianlancetaylor committed Mar 3, 2022
1 parent d367205 commit 301fd8a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/net/dnsclient_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err er
if err := b.Question(q); err != nil {
return 0, nil, nil, err
}

// Accept packets up to maxDNSPacketSize. RFC 6891.
if err := b.StartAdditionals(); err != nil {
return 0, nil, nil, err
}
var rh dnsmessage.ResourceHeader
if err := rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false); err != nil {
return 0, nil, nil, err
}
if err := b.OPTResource(rh, dnsmessage.OPTResource{}); err != nil {
return 0, nil, nil, err
}

tcpReq, err = b.Finish()
udpReq = tcpReq[2:]
l := len(tcpReq) - 2
Expand Down
55 changes: 55 additions & 0 deletions src/net/dnsclient_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2161,3 +2161,58 @@ func TestRootNS(t *testing.T) {
t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0])
}
}

// Test that we advertise support for a larger DNS packet size.
// This isn't a great test as it just tests the dnsmessage package
// against itself.
func TestDNSPacketSize(t *testing.T) {
fake := fakeDNSServer{
rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
if len(q.Additionals) == 0 {
t.Error("missing EDNS record")
} else if opt, ok := q.Additionals[0].Body.(*dnsmessage.OPTResource); !ok {
t.Errorf("additional record type %T, expected OPTResource", q.Additionals[0])
} else if len(opt.Options) != 0 {
t.Errorf("found %d Options, expected none", len(opt.Options))
} else {
got := int(q.Additionals[0].Header.Class)
t.Logf("EDNS packet size == %d", got)
if got != maxDNSPacketSize {
t.Errorf("EDNS packet size == %d, want %d", got, maxDNSPacketSize)
}
}

// Hand back a dummy answer to verify that
// LookupIPAddr completes.
r := dnsmessage.Message{
Header: dnsmessage.Header{
ID: q.Header.ID,
Response: true,
RCode: dnsmessage.RCodeSuccess,
},
Questions: q.Questions,
}
if q.Questions[0].Type == dnsmessage.TypeA {
r.Answers = []dnsmessage.Resource{
{
Header: dnsmessage.ResourceHeader{
Name: q.Questions[0].Name,
Type: dnsmessage.TypeA,
Class: dnsmessage.ClassINET,
Length: 4,
},
Body: &dnsmessage.AResource{
A: TestAddr,
},
},
}
}
return r, nil
},
}

r := &Resolver{PreferGo: true, Dial: fake.DialContext}
if _, err := r.LookupIPAddr(context.Background(), "go.dev"); err != nil {
t.Errorf("lookup failed: %v", err)
}
}

0 comments on commit 301fd8a

Please sign in to comment.