mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
405 lines
9.0 KiB
405 lines
9.0 KiB
// Copyright (c) HashiCorp, Inc. |
|
// SPDX-License-Identifier: BUSL-1.1 |
|
|
|
package dns |
|
|
|
import ( |
|
"net" |
|
"testing" |
|
"time" |
|
|
|
"github.com/miekg/dns" |
|
) |
|
|
|
func Test_HandleRequest_ADDR(t *testing.T) { |
|
testCases := []HandleTestCase{ |
|
{ |
|
name: "test A 'addr.' query, ipv4 response", |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul", // "intentionally missing the trailing dot" |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Answer: []dns.RR{ |
|
&dns.A{ |
|
Hdr: dns.RR_Header{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Rrtype: dns.TypeA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
A: net.ParseIP("192.0.2.10"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test AAAA 'addr.' query, ipv4 response", |
|
// Since we asked for an AAAA record, the A record that resolves from the address is attached as an extra |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul", |
|
Qtype: dns.TypeAAAA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Qtype: dns.TypeAAAA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Extra: []dns.RR{ |
|
&dns.A{ |
|
Hdr: dns.RR_Header{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Rrtype: dns.TypeA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
A: net.ParseIP("192.0.2.10"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test SRV 'addr.' query, ipv4 response", |
|
// Since we asked for a SRV record, the A record that resolves from the address is attached as an extra |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul", |
|
Qtype: dns.TypeSRV, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Qtype: dns.TypeSRV, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Extra: []dns.RR{ |
|
&dns.A{ |
|
Hdr: dns.RR_Header{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Rrtype: dns.TypeA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
A: net.ParseIP("192.0.2.10"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test ANY 'addr.' query, ipv4 response", |
|
// The response to ANY should look the same as the A response |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul", |
|
Qtype: dns.TypeANY, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Qtype: dns.TypeANY, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Answer: []dns.RR{ |
|
&dns.A{ |
|
Hdr: dns.RR_Header{ |
|
Name: "c000020a.addr.dc1.consul.", |
|
Rrtype: dns.TypeA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
A: net.ParseIP("192.0.2.10"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test AAAA 'addr.' query, ipv6 response", |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul", |
|
Qtype: dns.TypeAAAA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Qtype: dns.TypeAAAA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Answer: []dns.RR{ |
|
&dns.AAAA{ |
|
Hdr: dns.RR_Header{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Rrtype: dns.TypeAAAA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test A 'addr.' query, ipv6 response", |
|
// Since we asked for an A record, the AAAA record that resolves from the address is attached as an extra |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul", |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Extra: []dns.RR{ |
|
&dns.AAAA{ |
|
Hdr: dns.RR_Header{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Rrtype: dns.TypeAAAA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test SRV 'addr.' query, ipv6 response", |
|
// Since we asked for an SRV record, the AAAA record that resolves from the address is attached as an extra |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul", |
|
Qtype: dns.TypeSRV, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Qtype: dns.TypeSRV, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Extra: []dns.RR{ |
|
&dns.AAAA{ |
|
Hdr: dns.RR_Header{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Rrtype: dns.TypeAAAA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test ANY 'addr.' query, ipv6 response", |
|
// The response to ANY should look the same as the AAAA response |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul", |
|
Qtype: dns.TypeANY, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Qtype: dns.TypeANY, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Answer: []dns.RR{ |
|
&dns.AAAA{ |
|
Hdr: dns.RR_Header{ |
|
Name: "20010db800010002cafe000000001337.addr.dc1.consul.", |
|
Rrtype: dns.TypeAAAA, |
|
Class: dns.ClassINET, |
|
Ttl: 123, |
|
}, |
|
AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), |
|
}, |
|
}, |
|
}, |
|
}, |
|
{ |
|
name: "test malformed 'addr.' query", |
|
request: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
}, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000.addr.dc1.consul", // too short |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
}, |
|
response: &dns.Msg{ |
|
MsgHdr: dns.MsgHdr{ |
|
Opcode: dns.OpcodeQuery, |
|
Response: true, |
|
Rcode: dns.RcodeNameError, // NXDOMAIN |
|
Authoritative: true, |
|
}, |
|
Compress: true, |
|
Question: []dns.Question{ |
|
{ |
|
Name: "c000.addr.dc1.consul.", |
|
Qtype: dns.TypeA, |
|
Qclass: dns.ClassINET, |
|
}, |
|
}, |
|
Ns: []dns.RR{ |
|
&dns.SOA{ |
|
Hdr: dns.RR_Header{ |
|
Name: "consul.", |
|
Rrtype: dns.TypeSOA, |
|
Class: dns.ClassINET, |
|
Ttl: 4, |
|
}, |
|
Ns: "ns.consul.", |
|
Serial: uint32(time.Now().Unix()), |
|
Mbox: "hostmaster.consul.", |
|
Refresh: 1, |
|
Expire: 3, |
|
Retry: 2, |
|
Minttl: 4, |
|
}, |
|
}, |
|
}, |
|
}, |
|
} |
|
|
|
for _, tc := range testCases { |
|
t.Run(tc.name, func(t *testing.T) { |
|
runHandleTestCases(t, tc) |
|
}) |
|
} |
|
}
|
|
|