Skip to content

Commit

Permalink
Adds support for DNS recurse truncation. (#2467)
Browse files Browse the repository at this point in the history
* Return message from recurse even if truncated

Signed-off-by: Evan Farrar <efarrar@pivotal.io>

* Tweaks unit test.
  • Loading branch information
slackpad authored Nov 3, 2016
1 parent 7d2fcb0 commit 7b98ae9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion command/agent/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ func (d *DNSServer) handleRecurse(resp dns.ResponseWriter, req *dns.Msg) {
var err error
for _, recursor := range d.recursors {
r, rtt, err = c.Exchange(req, recursor)
if err == nil {
if err == nil || err == dns.ErrTruncated {
// Compress the response; we don't know if the incoming
// response was compressed or not, so by not compressing
// we might generate an invalid packet on the way out.
Expand Down
54 changes: 54 additions & 0 deletions command/agent/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ func makeRecursor(t *testing.T, answer []dns.RR) *dns.Server {
return server
}

func makeRecursorWithMessage(t *testing.T, answer dns.Msg) *dns.Server {
dnsConf := nextConfig()
dnsAddr := fmt.Sprintf("%s:%d", dnsConf.Addresses.DNS, dnsConf.Ports.DNS)
mux := dns.NewServeMux()
mux.HandleFunc(".", func(resp dns.ResponseWriter, msg *dns.Msg) {
answer.SetReply(msg)
if err := resp.WriteMsg(&answer); err != nil {
t.Fatalf("err: %s", err)
}
})
server := &dns.Server{
Addr: dnsAddr,
Net: "udp",
Handler: mux,
}
go server.ListenAndServe()
return server
}

// dnsCNAME returns a DNS CNAME record struct
func dnsCNAME(src, dest string) *dns.CNAME {
return &dns.CNAME{
Expand Down Expand Up @@ -1823,6 +1842,41 @@ func TestDNS_Recurse(t *testing.T) {
}
}

func TestDNS_Recurse_Truncation(t *testing.T) {
answerMessage := dns.Msg{
MsgHdr: dns.MsgHdr{Truncated: true},
Answer: []dns.RR{dnsA("apple.com", "1.2.3.4")},
}

recursor := makeRecursorWithMessage(t, answerMessage)
defer recursor.Shutdown()

dir, srv := makeDNSServerConfig(t, func(c *Config) {
c.DNSRecursor = recursor.Addr
}, nil)
defer os.RemoveAll(dir)
defer srv.agent.Shutdown()

m := new(dns.Msg)
m.SetQuestion("apple.com.", dns.TypeANY)

c := new(dns.Client)
addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
in, _, err := c.Exchange(m, addr.String())
if err == nil || err != dns.ErrTruncated {
t.Fatalf("err: %v", err)
}
if in.Truncated != true {
t.Fatalf("err: message should have been truncated %v", in)
}
if len(in.Answer) == 0 {
t.Fatalf("Bad: Truncated message ignored, expected some reply %#v", in)
}
if in.Rcode != dns.RcodeSuccess {
t.Fatalf("Bad: %#v", in)
}
}

func TestDNS_RecursorTimeout(t *testing.T) {
serverClientTimeout := 3 * time.Second
testClientTimeout := serverClientTimeout + 5*time.Second
Expand Down

0 comments on commit 7b98ae9

Please sign in to comment.