diff --git a/middleware/auto/auto.go b/middleware/auto/auto.go index ec04a8766..fabf492e1 100644 --- a/middleware/auto/auto.go +++ b/middleware/auto/auto.go @@ -34,7 +34,7 @@ type ( // In the future this should be something like ZoneMeta that contains all this stuff. transferTo []string noReload bool - Proxy proxy.Proxy // Proxy for looking up names during the resolution process + proxy proxy.Proxy // Proxy for looking up names during the resolution process duration time.Duration } diff --git a/middleware/auto/setup.go b/middleware/auto/setup.go index 2d397a079..ddb5670f0 100644 --- a/middleware/auto/setup.go +++ b/middleware/auto/setup.go @@ -155,7 +155,7 @@ func autoParse(c *caddy.Controller) (Auto, error) { args[i] = h + ":53" } } - a.loader.Proxy = proxy.New(args) + a.loader.proxy = proxy.New(args) default: t, _, e := file.TransferParse(c, false) diff --git a/middleware/auto/walk.go b/middleware/auto/walk.go index 3f7ebb19f..25e2af44f 100644 --- a/middleware/auto/walk.go +++ b/middleware/auto/walk.go @@ -51,6 +51,7 @@ func (a Auto) Walk() error { } zo.NoReload = a.loader.noReload + zo.Proxy = a.loader.proxy zo.TransferTo = a.loader.transferTo a.Zones.Add(zo, origin) diff --git a/middleware/file/cname_test.go b/middleware/file/cname_test.go index 2388aef33..bb678f7ff 100644 --- a/middleware/file/cname_test.go +++ b/middleware/file/cname_test.go @@ -93,7 +93,7 @@ func TestLookupCNAMEExternal(t *testing.T) { if err != nil { t.Fatalf("Expected no error when reading zone, got %q", err) } - zone.Proxy = proxy.New([]string{"8.8.8.8:53"}) // TODO(point to local instance) + zone.Proxy = proxy.New([]string{"8.8.8.8:53"}) // TODO(miek): point to local instance fm := File{Next: test.ErrorHandler(), Zones: Zones{Z: map[string]*Zone{name: zone}, Names: []string{name}}} ctx := context.TODO() diff --git a/middleware/file/file.go b/middleware/file/file.go index 3f16a956e..6a171740f 100644 --- a/middleware/file/file.go +++ b/middleware/file/file.go @@ -84,7 +84,7 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i return xfr.ServeDNS(ctx, w, r) } - answer, ns, extra, result := z.Lookup(qname, state.QType(), state.Do()) + answer, ns, extra, result := z.Lookup(state, qname) m := new(dns.Msg) m.SetReply(r) diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go index 50c99afb0..4afd6262e 100644 --- a/middleware/file/lookup.go +++ b/middleware/file/lookup.go @@ -25,7 +25,11 @@ const ( // Lookup looks up qname and qtype in the zone. When do is true DNSSEC records are included. // Three sets of records are returned, one for the answer, one for authority and one for the additional section. -func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) { +func (z *Zone) Lookup(state request.Request, qname string) ([]dns.RR, []dns.RR, []dns.RR, Result) { + + qtype := state.QType() + do := state.Do() + if !z.NoReload { z.reloadMu.RLock() } @@ -121,7 +125,7 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, // DNAME...? if rrs := elem.Types(dns.TypeCNAME); len(rrs) > 0 && qtype != dns.TypeCNAME { - return z.searchCNAME(elem, rrs, qtype, do) + return z.searchCNAME(state, elem, rrs) } rrs := elem.Types(qtype, qname) @@ -153,7 +157,7 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, auth := []dns.RR{} if rrs := wildElem.Types(dns.TypeCNAME, qname); len(rrs) > 0 { - return z.searchCNAME(wildElem, rrs, qtype, do) + return z.searchCNAME(state, wildElem, rrs) } rrs := wildElem.Types(qtype, qname) @@ -252,7 +256,11 @@ func (z *Zone) ns(do bool) []dns.RR { return z.Apex.NS } -func (z *Zone) searchCNAME(elem *tree.Elem, rrs []dns.RR, qtype uint16, do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) { +func (z *Zone) searchCNAME(state request.Request, elem *tree.Elem, rrs []dns.RR) ([]dns.RR, []dns.RR, []dns.RR, Result) { + + qtype := state.QType() + do := state.Do() + if do { sigs := elem.Types(dns.TypeRRSIG) sigs = signatureForSubType(sigs, dns.TypeCNAME) @@ -263,14 +271,10 @@ func (z *Zone) searchCNAME(elem *tree.Elem, rrs []dns.RR, qtype uint16, do bool) targetName := rrs[0].(*dns.CNAME).Target elem, _ = z.Tree.Search(targetName) - println(targetName) if elem == nil { if !dns.IsSubDomain(z.origin, targetName) { - println(targetName, "is not a child of", z.origin) + rrs = append(rrs, z.externalLookup(state, targetName, qtype)...) } - st := request.Request{} - z.Proxy.Lookup(st, targetName, qtype) - return rrs, nil, nil, Success } @@ -292,7 +296,9 @@ Redo: elem, _ = z.Tree.Search(targetName) if elem == nil { if !dns.IsSubDomain(z.origin, targetName) { - println(targetName, "is not a child of", z.origin) + if !dns.IsSubDomain(z.origin, targetName) { + rrs = append(rrs, z.externalLookup(state, targetName, qtype)...) + } } return rrs, nil, nil, Success } @@ -331,6 +337,15 @@ func cnameForType(targets []dns.RR, origQtype uint16) []dns.RR { return ret } +func (z *Zone) externalLookup(state request.Request, target string, qtype uint16) []dns.RR { + m, e := z.Proxy.Lookup(state, target, qtype) + if e != nil || m == nil { + // TODO(miek): debugMsg for this as well? Log? + return nil + } + return m.Answer +} + // signatureForSubType range through the signature and return the correct ones for the subtype. func signatureForSubType(rrs []dns.RR, subtype uint16) []dns.RR { sigs := []dns.RR{} diff --git a/middleware/file/reload_test.go b/middleware/file/reload_test.go index c46dc3e20..caa81b536 100644 --- a/middleware/file/reload_test.go +++ b/middleware/file/reload_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/miekg/coredns/middleware/test" + "github.com/miekg/coredns/request" "github.com/miekg/dns" ) @@ -31,11 +32,17 @@ func TestZoneReload(t *testing.T) { z.Reload() - if _, _, _, res := z.Lookup("miek.nl.", dns.TypeSOA, false); res != Success { + r := new(dns.Msg) + r.SetQuestion("miek.nl", dns.TypeSOA) + state := request.Request{W: &test.ResponseWriter{}, Req: r} + if _, _, _, res := z.Lookup(state, "miek.nl."); res != Success { t.Fatalf("failed to lookup, got %d", res) } - if _, _, _, res := z.Lookup("miek.nl.", dns.TypeNS, false); res != Success { + r = new(dns.Msg) + r.SetQuestion("miek.nl", dns.TypeNS) + state = request.Request{W: &test.ResponseWriter{}, Req: r} + if _, _, _, res := z.Lookup(state, "miek.nl."); res != Success { t.Fatalf("failed to lookup, got %d", res) }