Tweaks algorithm so it's safe with an empty list and adds a PQ test.
This commit is contained in:
parent
f4edb28ef3
commit
b132e8f21b
|
@ -487,22 +487,20 @@ func (d *DNSServer) formatNodeRecord(node *structs.Node, addr, qName string, qTy
|
||||||
return records
|
return records
|
||||||
}
|
}
|
||||||
|
|
||||||
// trimAnswers makes sure a UDP response is not longer than allowed by RFC 1035
|
// trimAnswers makes sure a UDP response is not longer than allowed by RFC 1035.
|
||||||
|
// We first enforce an arbitrary limit, and then make sure the response doesn't
|
||||||
|
// exceed 512 bytes.
|
||||||
func trimAnswers(resp *dns.Msg) (trimmed bool) {
|
func trimAnswers(resp *dns.Msg) (trimmed bool) {
|
||||||
numAnswers := len(resp.Answer)
|
numAnswers := len(resp.Answer)
|
||||||
|
|
||||||
|
// This cuts UDP responses to a useful but limited number of responses.
|
||||||
if numAnswers > maxServiceResponses {
|
if numAnswers > maxServiceResponses {
|
||||||
resp.Answer = resp.Answer[:maxServiceResponses]
|
resp.Answer = resp.Answer[:maxServiceResponses]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the response isn't more than 512 bytes
|
// This enforces the hard limit of 512 bytes per the RFC.
|
||||||
for respBytes := resp.Len(); respBytes > 512; respBytes = resp.Len() {
|
for len(resp.Answer) > 0 && resp.Len() > 512 {
|
||||||
resp.Answer = resp.Answer[:len(resp.Answer)-1]
|
resp.Answer = resp.Answer[:len(resp.Answer)-1]
|
||||||
|
|
||||||
if len(resp.Answer) == 0 {
|
|
||||||
// We've done all we can
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(resp.Answer) < numAnswers
|
return len(resp.Answer) < numAnswers
|
||||||
|
|
|
@ -1991,29 +1991,55 @@ func TestDNS_ServiceLookup_LargeResponses(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m := new(dns.Msg)
|
// Register an equivalent prepared query.
|
||||||
m.SetQuestion("_"+longServiceName+"._master.service.consul.", dns.TypeSRV)
|
{
|
||||||
|
args := &structs.PreparedQueryRequest{
|
||||||
c := new(dns.Client)
|
Datacenter: "dc1",
|
||||||
addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
|
Op: structs.PreparedQueryCreate,
|
||||||
in, _, err := c.Exchange(m, addr.String())
|
Query: &structs.PreparedQuery{
|
||||||
if err != nil && err != dns.ErrTruncated {
|
Name: longServiceName,
|
||||||
t.Fatalf("err: %v", err)
|
Service: structs.ServiceQuery{
|
||||||
|
Service: longServiceName,
|
||||||
|
Tags: []string{"master"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var id string
|
||||||
|
if err := srv.agent.RPC("PreparedQuery.Apply", args, &id); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the response size is RFC 1035-compliant for UDP messages
|
// Look up the service directly and via prepared query.
|
||||||
if in.Len() > 512 {
|
questions := []string{
|
||||||
t.Fatalf("Bad: %#v", in.Len())
|
"_" + longServiceName + "._master.service.consul.",
|
||||||
|
longServiceName + ".query.consul.",
|
||||||
}
|
}
|
||||||
|
for _, question := range questions {
|
||||||
|
m := new(dns.Msg)
|
||||||
|
m.SetQuestion(question, dns.TypeSRV)
|
||||||
|
|
||||||
// We should only have two answers now
|
c := new(dns.Client)
|
||||||
if len(in.Answer) != 2 {
|
addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS)
|
||||||
t.Fatalf("Bad: %#v", len(in.Answer))
|
in, _, err := c.Exchange(m, addr.String())
|
||||||
}
|
if err != nil && err != dns.ErrTruncated {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Check for the truncate bit
|
// Make sure the response size is RFC 1035-compliant for UDP messages
|
||||||
if !in.Truncated {
|
if in.Len() > 512 {
|
||||||
t.Fatalf("should have truncate bit")
|
t.Fatalf("Bad: %#v", in.Len())
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should only have two answers now
|
||||||
|
if len(in.Answer) != 2 {
|
||||||
|
t.Fatalf("Bad: %#v", len(in.Answer))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for the truncate bit
|
||||||
|
if !in.Truncated {
|
||||||
|
t.Fatalf("should have truncate bit")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue