From 07c7ac80e75bfca33bda1a97729414825b34d7f9 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Mon, 24 Jul 2017 14:21:40 -0700 Subject: [PATCH] middleware/file: fix multiple wildcards (#787) Don't hold on to the *first* wildcard you'll find, but keep searching, there may be one even deeper in the tree. Also add multi level wildcard test Fixes #776 --- middleware/file/lookup.go | 10 ++--- middleware/file/wildcard_test.go | 67 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go index 5726adbcd..36db27dc4 100644 --- a/middleware/file/lookup.go +++ b/middleware/file/lookup.go @@ -76,7 +76,6 @@ func (z *Zone) Lookup(state request.Request, qname string) ([]dns.RR, []dns.RR, // // If not found, we check the potential wildcard, and use that for further processing. // If not found and no wildcard we will process this as an NXDOMAIN response. - // for { parts, shot = z.nameFromRight(qname, i) // We overshot the name, break and check if we previously found something. @@ -88,12 +87,11 @@ func (z *Zone) Lookup(state request.Request, qname string) ([]dns.RR, []dns.RR, if !found { // Apex will always be found, when we are here we can search for a wildcard // and save the result of that search. So when nothing match, but we have a - // wildcard we should expand the wildcard. There can only be one wildcard, - // so when we found one, we won't look for another. + // wildcard we should expand the wildcard. - if wildElem == nil { - wildcard := replaceWithAsteriskLabel(parts) - wildElem, _ = z.Tree.Search(wildcard) + wildcard := replaceWithAsteriskLabel(parts) + if wild, found := z.Tree.Search(wildcard); found { + wildElem = wild } // Keep on searching, because maybe we hit an empty-non-terminal (which aren't diff --git a/middleware/file/wildcard_test.go b/middleware/file/wildcard_test.go index 335bd4706..29a6adb33 100644 --- a/middleware/file/wildcard_test.go +++ b/middleware/file/wildcard_test.go @@ -266,6 +266,65 @@ func TestLookupApexWildcard(t *testing.T) { } } +var multiWildcardTestCases = []test.Case{ + { + Qname: "foo.example.org.", Qtype: dns.TypeA, + Answer: []dns.RR{test.A(`foo.example.org. 3600 IN A 127.0.0.54`)}, + Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)}, + }, + { + Qname: "bar.example.org.", Qtype: dns.TypeA, + Answer: []dns.RR{test.A(`bar.example.org. 3600 IN A 127.0.0.53`)}, + Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)}, + }, + { + Qname: "bar.intern.example.org.", Qtype: dns.TypeA, + Answer: []dns.RR{test.A(`bar.intern.example.org. 3600 IN A 127.0.1.52`)}, + Ns: []dns.RR{test.NS(`example.org. 3600 IN NS b.iana-servers.net.`)}, + }, +} + +func TestLookupMultiWildcard(t *testing.T) { + const name = "example.org." + zone, err := Parse(strings.NewReader(doubleWildcard), 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 multiWildcardTestCases { + m := tc.Msg() + + rec := dnsrecorder.New(&test.ResponseWriter{}) + _, err := fm.ServeDNS(ctx, rec, m) + if err != nil { + t.Errorf("Expected no error, got %v\n", err) + return + } + + resp := rec.Msg + sort.Sort(test.RRSet(resp.Answer)) + sort.Sort(test.RRSet(resp.Ns)) + sort.Sort(test.RRSet(resp.Extra)) + + if !test.Header(t, tc, resp) { + t.Logf("%v\n", resp) + continue + } + if !test.Section(t, tc, test.Answer, resp.Answer) { + t.Logf("%v\n", resp) + } + if !test.Section(t, tc, test.Ns, resp.Ns) { + t.Logf("%v\n", resp) + } + if !test.Section(t, tc, test.Extra, resp.Extra) { + t.Logf("%v\n", resp) + } + } +} + const exampleOrg = `; example.org test file 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. @@ -285,3 +344,11 @@ example.org. IN NS b.iana-servers.net. *.example.org. IN A 127.0.0.53 foo.example.org. IN A 127.0.0.54 ` + +const doubleWildcard = `; example.org test file with wildcard at apex +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. +*.example.org. IN A 127.0.0.53 +*.intern.example.org. IN A 127.0.1.52 +foo.example.org. IN A 127.0.0.54 +`