plugin/file: Fix in wrong answers returned when wildcard and concrete records exist (#4599)
* plugin/file: Fix in wrong answers returned when wildcard and concrete records exist Signed-off-by: Jason Du <xdu@infoblox.com> * Remove superfluous change Signed-off-by: Jason Du <xdu@infoblox.com> * Re-implementation and new test case If the domain's terminal is neither the matching wildcard, nor a domian directly under the wildcard, return NXDOMAIN Signed-off-by: Jason Du <xdu@infoblox.com> * Fix empty non-terminal & add test case Signed-off-by: Jason Du <xdu@infoblox.com> * Cleanup Signed-off-by: Jason Du <xdu@infoblox.com> * Fix case on domain name with character before * and add more test cases Signed-off-by: Jason Du <xdu@infoblox.com> * Use different IPs for records in cornerCasesWildcard zone file Signed-off-by: Jason Du <xdu@infoblox.com>
This commit is contained in:
parent
5f41d8eb1f
commit
fbf3f07f46
3 changed files with 110 additions and 6 deletions
|
@ -56,10 +56,10 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
found, shot bool
|
found, shot bool
|
||||||
parts string
|
parts string
|
||||||
i int
|
i, maxLabelNum int
|
||||||
elem, wildElem *tree.Elem
|
elem, wildElem, nextElem *tree.Elem
|
||||||
)
|
)
|
||||||
|
|
||||||
loop, _ := ctx.Value(dnsserver.LoopKey{}).(int)
|
loop, _ := ctx.Value(dnsserver.LoopKey{}).(int)
|
||||||
|
@ -92,6 +92,12 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nextElem, found = tr.Next(parts); found {
|
||||||
|
if dns.IsSubDomain(parts, nextElem.Name()) {
|
||||||
|
maxLabelNum = z.origLen + i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elem, found = tr.Search(parts)
|
elem, found = tr.Search(parts)
|
||||||
if !found {
|
if !found {
|
||||||
// Apex will always be found, when we are here we can search for a wildcard
|
// Apex will always be found, when we are here we can search for a wildcard
|
||||||
|
@ -201,8 +207,18 @@ func (z *Zone) Lookup(ctx context.Context, state request.Request, qname string)
|
||||||
|
|
||||||
// Found wildcard.
|
// Found wildcard.
|
||||||
if wildElem != nil {
|
if wildElem != nil {
|
||||||
auth := ap.ns(do)
|
// if the domain's longest matching parent domain is subdomain of the wildcard,
|
||||||
|
// in other words, the domain‘s max number of labels matched is >= number of labels of the wildcard
|
||||||
|
if maxLabelNum >= dns.CountLabel(wildElem.Name()) {
|
||||||
|
ret := ap.soa(do)
|
||||||
|
if do {
|
||||||
|
nsec := typeFromElem(wildElem, dns.TypeNSEC, do)
|
||||||
|
ret = append(ret, nsec...)
|
||||||
|
}
|
||||||
|
return nil, ret, nil, NameError
|
||||||
|
}
|
||||||
|
|
||||||
|
auth := ap.ns(do)
|
||||||
if rrs := wildElem.TypeForWildcard(dns.TypeCNAME, qname); len(rrs) > 0 {
|
if rrs := wildElem.TypeForWildcard(dns.TypeCNAME, qname); len(rrs) > 0 {
|
||||||
ctx = context.WithValue(ctx, dnsserver.LoopKey{}, loop+1)
|
ctx = context.WithValue(ctx, dnsserver.LoopKey{}, loop+1)
|
||||||
return z.externalLookup(ctx, state, wildElem, rrs)
|
return z.externalLookup(ctx, state, wildElem, rrs)
|
||||||
|
|
|
@ -95,6 +95,12 @@ var dnsTestCases = []test.Case{
|
||||||
},
|
},
|
||||||
Ns: miekAuth,
|
Ns: miekAuth,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Qname: "ent.miek.nl.", Qtype: dns.TypeA,
|
||||||
|
Ns: []dns.RR{
|
||||||
|
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -193,4 +199,6 @@ www IN CNAME a
|
||||||
archive IN CNAME a
|
archive IN CNAME a
|
||||||
|
|
||||||
srv IN SRV 10 10 8080 a.miek.nl.
|
srv IN SRV 10 10 8080 a.miek.nl.
|
||||||
mx IN MX 10 a.miek.nl.`
|
mx IN MX 10 a.miek.nl.
|
||||||
|
|
||||||
|
test.ent IN A 139.162.196.79`
|
||||||
|
|
|
@ -266,6 +266,76 @@ func TestLookupMultiWildcard(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cornerCasesWildcardTestCases = []test.Case{
|
||||||
|
{
|
||||||
|
Qname: "r.c.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Answer: []dns.RR{test.A(`r.c.d.example.org. 3600 IN A 127.0.1.56`)},
|
||||||
|
Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "something.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Answer: []dns.RR{test.A(`something.d.example.org. 3600 IN A 127.0.1.53`)},
|
||||||
|
Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "else.something.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Answer: []dns.RR{test.A(`else.something.d.example.org. 3600 IN A 127.0.1.53`)},
|
||||||
|
Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "something.c.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Ns: []dns.RR{test.SOA(`example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600`)},
|
||||||
|
Rcode: dns.RcodeNameError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "something.r.c.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Ns: []dns.RR{test.SOA(`example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600`)},
|
||||||
|
Rcode: dns.RcodeNameError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "z.+.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Answer: []dns.RR{test.A(`z.+.d.example.org. 3600 IN A 127.0.1.54`)},
|
||||||
|
Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "x.&.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Answer: []dns.RR{test.A(`x.&.d.example.org. 3600 IN A 127.0.1.55`)},
|
||||||
|
Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Qname: "something.x.&.d.example.org.", Qtype: dns.TypeA,
|
||||||
|
Ns: []dns.RR{test.SOA(`example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600`)},
|
||||||
|
Rcode: dns.RcodeNameError,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLookupCornerCasesWildcard(t *testing.T) {
|
||||||
|
const name = "example.org."
|
||||||
|
zone, err := Parse(strings.NewReader(cornerCasesWildcard), name, "stdin", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expect no error when reading zone, got %q", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{name: zone}, Names: []string{name}}}
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
for _, tc := range cornerCasesWildcardTestCases {
|
||||||
|
m := tc.Msg()
|
||||||
|
|
||||||
|
rec := dnstest.NewRecorder(&test.ResponseWriter{})
|
||||||
|
_, err := fm.ServeDNS(ctx, rec, m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected no error, got %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := rec.Msg
|
||||||
|
if err := test.SortAndCheck(resp, tc); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const exampleOrg = `; example.org test file
|
const exampleOrg = `; example.org test file
|
||||||
$TTL 3600
|
$TTL 3600
|
||||||
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
|
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
|
||||||
|
@ -296,3 +366,13 @@ example.org. IN NS b.iana-servers.net.
|
||||||
*.intern.example.org. IN A 127.0.1.52
|
*.intern.example.org. IN A 127.0.1.52
|
||||||
foo.example.org. IN A 127.0.0.54
|
foo.example.org. IN A 127.0.0.54
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const cornerCasesWildcard = `; example.org test file with wildcard corner cases
|
||||||
|
$TTL 3600
|
||||||
|
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
|
||||||
|
example.org. IN NS b.iana-servers.net.
|
||||||
|
*.d.example.org. IN A 127.0.1.53
|
||||||
|
z.+.d.example.org. IN A 127.0.1.54
|
||||||
|
x.&.d.example.org. IN A 127.0.1.55
|
||||||
|
r.c.d.example.org. IN A 127.0.1.56
|
||||||
|
`
|
||||||
|
|
Loading…
Add table
Reference in a new issue