diff --git a/.changelog/10401.txt b/.changelog/10401.txt
new file mode 100644
index 0000000000..86ef317ee2
--- /dev/null
+++ b/.changelog/10401.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+dns: return an empty answer when asked for an addr dns with type other then A and AAAA.
+```
diff --git a/agent/dns.go b/agent/dns.go
index cad5ac0f33..85ae5c4d6f 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -782,6 +782,7 @@ func (d *DNSServer) doDispatch(network string, remoteAddr net.Addr, req, resp *d
case "addr":
//
.addr.. - addr must be the second label, datacenter is optional
+
if len(queryParts) != 1 {
return invalid()
}
@@ -793,8 +794,8 @@ func (d *DNSServer) doDispatch(network string, remoteAddr net.Addr, req, resp *d
if err != nil {
return invalid()
}
-
- resp.Answer = append(resp.Answer, &dns.A{
+ //check if the query type is A for IPv4 or ANY
+ aRecord := &dns.A{
Hdr: dns.RR_Header{
Name: qName + d.domain,
Rrtype: dns.TypeA,
@@ -802,15 +803,20 @@ func (d *DNSServer) doDispatch(network string, remoteAddr net.Addr, req, resp *d
Ttl: uint32(cfg.NodeTTL / time.Second),
},
A: ip,
- })
+ }
+ if req.Question[0].Qtype != dns.TypeA && req.Question[0].Qtype != dns.TypeANY {
+ resp.Extra = append(resp.Answer, aRecord)
+ } else {
+ resp.Answer = append(resp.Answer, aRecord)
+ }
// IPv6
case 16:
ip, err := hex.DecodeString(queryParts[0])
if err != nil {
return invalid()
}
-
- resp.Answer = append(resp.Answer, &dns.AAAA{
+ //check if the query type is AAAA for IPv6 or ANY
+ aaaaRecord := &dns.AAAA{
Hdr: dns.RR_Header{
Name: qName + d.domain,
Rrtype: dns.TypeAAAA,
@@ -818,7 +824,12 @@ func (d *DNSServer) doDispatch(network string, remoteAddr net.Addr, req, resp *d
Ttl: uint32(cfg.NodeTTL / time.Second),
},
AAAA: ip,
- })
+ }
+ if req.Question[0].Qtype != dns.TypeAAAA && req.Question[0].Qtype != dns.TypeANY {
+ resp.Extra = append(resp.Extra, aaaaRecord)
+ } else {
+ resp.Answer = append(resp.Answer, aaaaRecord)
+ }
}
}
return true
diff --git a/agent/dns_test.go b/agent/dns_test.go
index 3f3f32a717..5cfe582069 100644
--- a/agent/dns_test.go
+++ b/agent/dns_test.go
@@ -6044,7 +6044,7 @@ func TestDNS_AddressLookup(t *testing.T) {
}
for question, answer := range cases {
m := new(dns.Msg)
- m.SetQuestion(question, dns.TypeSRV)
+ m.SetQuestion(question, dns.TypeA)
c := new(dns.Client)
in, _, err := c.Exchange(m, a.DNSAddr())
@@ -6052,20 +6052,73 @@ func TestDNS_AddressLookup(t *testing.T) {
t.Fatalf("err: %v", err)
}
- if len(in.Answer) != 1 {
- t.Fatalf("Bad: %#v", in)
- }
+ require.Len(t, in.Answer, 1)
+ require.Equal(t, dns.TypeA, in.Answer[0].Header().Rrtype)
aRec, ok := in.Answer[0].(*dns.A)
- if !ok {
- t.Fatalf("Bad: %#v", in.Answer[0])
- }
- if aRec.A.To4().String() != answer {
- t.Fatalf("Bad: %#v", aRec)
- }
- if aRec.Hdr.Ttl != 0 {
- t.Fatalf("Bad: %#v", in.Answer[0])
- }
+ require.True(t, ok)
+ require.Equal(t, aRec.A.To4().String(), answer)
+ require.Zero(t, aRec.Hdr.Ttl)
+ }
+}
+
+func TestDNS_AddressLookupANY(t *testing.T) {
+ if testing.Short() {
+ t.Skip("too slow for testing.Short")
+ }
+
+ t.Parallel()
+ a := NewTestAgent(t, "")
+ defer a.Shutdown()
+ testrpc.WaitForLeader(t, a.RPC, "dc1")
+
+ // Look up the addresses
+ cases := map[string]string{
+ "7f000001.addr.dc1.consul.": "127.0.0.1",
+ }
+ for question, answer := range cases {
+ m := new(dns.Msg)
+ m.SetQuestion(question, dns.TypeANY)
+
+ c := new(dns.Client)
+ in, _, err := c.Exchange(m, a.DNSAddr())
+
+ require.NoError(t, err)
+ require.Len(t, in.Answer, 1)
+ require.Equal(t, in.Answer[0].Header().Rrtype, dns.TypeA)
+ aRec, ok := in.Answer[0].(*dns.A)
+ require.True(t, ok)
+ require.Equal(t, aRec.A.To4().String(), answer)
+ require.Zero(t, aRec.Hdr.Ttl)
+
+ }
+}
+
+func TestDNS_AddressLookupInvalidType(t *testing.T) {
+ if testing.Short() {
+ t.Skip("too slow for testing.Short")
+ }
+
+ t.Parallel()
+ a := NewTestAgent(t, "")
+ defer a.Shutdown()
+ testrpc.WaitForLeader(t, a.RPC, "dc1")
+
+ // Look up the addresses
+ cases := map[string]string{
+ "7f000001.addr.dc1.consul.": "",
+ }
+ for question := range cases {
+ m := new(dns.Msg)
+ m.SetQuestion(question, dns.TypeSRV)
+
+ c := new(dns.Client)
+ in, _, err := c.Exchange(m, a.DNSAddr())
+ require.NoError(t, err)
+ require.Zero(t, in.Rcode)
+ require.Nil(t, in.Answer)
+ require.NotNil(t, in.Extra)
+ require.Len(t, in.Extra, 1)
}
}
@@ -6086,7 +6139,7 @@ func TestDNS_AddressLookupIPV6(t *testing.T) {
}
for question, answer := range cases {
m := new(dns.Msg)
- m.SetQuestion(question, dns.TypeSRV)
+ m.SetQuestion(question, dns.TypeAAAA)
c := new(dns.Client)
in, _, err := c.Exchange(m, a.DNSAddr())
@@ -6098,6 +6151,9 @@ func TestDNS_AddressLookupIPV6(t *testing.T) {
t.Fatalf("Bad: %#v", in)
}
+ if in.Answer[0].Header().Rrtype != dns.TypeAAAA {
+ t.Fatalf("Invalid type: %#v", in.Answer[0])
+ }
aaaaRec, ok := in.Answer[0].(*dns.AAAA)
if !ok {
t.Fatalf("Bad: %#v", in.Answer[0])
@@ -6111,6 +6167,37 @@ func TestDNS_AddressLookupIPV6(t *testing.T) {
}
}
+func TestDNS_AddressLookupIPV6InvalidType(t *testing.T) {
+ if testing.Short() {
+ t.Skip("too slow for testing.Short")
+ }
+
+ t.Parallel()
+ a := NewTestAgent(t, "")
+ defer a.Shutdown()
+ testrpc.WaitForLeader(t, a.RPC, "dc1")
+
+ // Look up the addresses
+ cases := map[string]string{
+ "2607002040050808000000000000200e.addr.consul.": "2607:20:4005:808::200e",
+ "2607112040051808ffffffffffff200e.addr.consul.": "2607:1120:4005:1808:ffff:ffff:ffff:200e",
+ }
+ for question := range cases {
+ m := new(dns.Msg)
+ m.SetQuestion(question, dns.TypeSRV)
+
+ c := new(dns.Client)
+ in, _, err := c.Exchange(m, a.DNSAddr())
+ if err != nil {
+ t.Fatalf("err: %v", err)
+ }
+
+ if in.Answer != nil {
+ t.Fatalf("Bad: %#v", in)
+ }
+ }
+}
+
// TestDNS_NonExistentDC_Server verifies NXDOMAIN is returned when
// Consul server agent is queried for a service in a non-existent
// domain.