From 85457cf50dd45a4b3cbf9425007831ee07d34916 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Tue, 23 Jan 2018 10:35:10 +0000 Subject: [PATCH] plugin/secondary: fix a bunch of things and tests (#1406) Fix the error handling. Log when we have an error during any of the transfer state. And if there isn't an error transfer the zones. Also fix the tests in test/ so we, at least, check the initial transfer. Update the docs to show more about how errors are handled. Ref #1400 --- plugin/file/secondary.go | 29 ++++----- plugin/secondary/README.md | 4 ++ test/secondary_net_test.go | 126 ------------------------------------- test/secondary_test.go | 49 +++++++++++++-- 4 files changed, 62 insertions(+), 146 deletions(-) delete mode 100644 test/secondary_net_test.go diff --git a/plugin/file/secondary.go b/plugin/file/secondary.go index a37d62442..83887c9ed 100644 --- a/plugin/file/secondary.go +++ b/plugin/file/secondary.go @@ -118,19 +118,6 @@ Restart: retry := time.Second * time.Duration(z.Apex.SOA.Retry) expire := time.Second * time.Duration(z.Apex.SOA.Expire) - if refresh < time.Hour { - refresh = time.Hour - } - if retry < time.Hour { - retry = time.Hour - } - if refresh > 24*time.Hour { - refresh = 24 * time.Hour - } - if retry > 12*time.Hour { - retry = 12 * time.Hour - } - refreshTicker := time.NewTicker(refresh) retryTicker := time.NewTicker(retry) expireTicker := time.NewTicker(expire) @@ -151,7 +138,12 @@ Restart: time.Sleep(jitter(2000)) // 2s randomize ok, err := z.shouldTransfer() - if err != nil && ok { + if err != nil { + log.Printf("[WARNING] Failed retry check %s", err) + continue + } + + if ok { if err := z.TransferIn(); err != nil { // transfer failed, leave retryActive true break @@ -169,8 +161,13 @@ Restart: time.Sleep(jitter(5000)) // 5s randomize ok, err := z.shouldTransfer() - retryActive = err != nil - if err != nil && ok { + if err != nil { + log.Printf("[WARNING] Failed refresh check %s", err) + retryActive = true + continue + } + + if ok { if err := z.TransferIn(); err != nil { // transfer failed retryActive = true diff --git a/plugin/secondary/README.md b/plugin/secondary/README.md index 62e078b73..b49e676e0 100644 --- a/plugin/secondary/README.md +++ b/plugin/secondary/README.md @@ -35,6 +35,10 @@ secondary [zones...] { normal authoritative serving you don't need *or* want to use this. **ADDRESS** can be an IP address, and IP:port or a string pointing to a file that is structured as /etc/resolv.conf. +When a zone is due to be refreshed (Refresh timer fires) a random jitter of 5 seconds is +applied, before fetching. In the case of retry this will be 2 seconds. If there are any errors +during the transfer the transfer fails; this will be logged. + ## Examples Transfer `example.org` from 10.0.1.1, and if that fails try 10.1.2.1. diff --git a/test/secondary_net_test.go b/test/secondary_net_test.go deleted file mode 100644 index 451195442..000000000 --- a/test/secondary_net_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// +build net - -package test - -import ( - "testing" - - "github.com/miekg/dns" -) - -func TestSecondaryZoneTransfer(t *testing.T) { - /* - Test will only work when there is a CoreDNS running on part 32054 - with example.com and willing to transfer - coredns -conf Corefile -dns.port 32054 - Corefile: - example.com { - file example.com { - transfer to 127.0.0.1:32053 - } - } - example.com: - example.com. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2017042730 7200 3600 1209600 3600 - - example.com. 65118 IN NS a.iana-servers.net. - example.com. 65118 IN NS b.iana-servers.net. - cname.example.com. 434334 IN CNAME a.miek.nl. - */ - - corefile := `example.com:32053 { - secondary { - transfer from 127.0.0.1:32054 - } - } - ` - - sec, err := CoreDNSServer(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - - defer sec.Stop() - - m := new(dns.Msg) - m.SetQuestion("cname.example.com.", dns.TypeCNAME) - - r, err := dns.Exchange(m, "127.0.0.1:32053") - if err != nil { - t.Fatalf("Expected to receive reply, but didn't: %s", err) - } - - if len(r.Answer) == 0 { - t.Fatalf("Expected answer section") - } - - if r.Answer[0].(*dns.CNAME).Target != "a.miek.nl." { - t.Fatalf("Expected target of %s, got %s", "a.miek.nl.", r.Answer[0].(*dns.CNAME).Target) - } - - m = new(dns.Msg) - m.SetQuestion("example.com.", dns.TypeSOA) - r, err = dns.Exchange(m, "127.0.0.1:32053") - if err != nil { - t.Fatalf("Expected to receive reply, but didn't: %s", err) - } - if len(r.Answer) == 0 { - t.Fatalf("Expected answer section") - } - if r.Answer[0].(*dns.SOA).Serial != 2017042730 { - t.Fatalf("Expected serial of %d, got %d", 2017042730, r.Answer[0].(*dns.SOA).Serial) - } -} - -func TestSecondaryZoneTransferUpstream(t *testing.T) { - /* - Test will only work when there is a CoreDNS running on part 32054 - with example.com and willing to transfer - coredns -conf Corefile -dns.port 32054 - Corefile: - example.com { - file example.com { - transfer to 127.0.0.1:32053 - } - } - example.com: - example.com. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2017042730 7200 3600 1209600 3600 - - example.com. 65118 IN NS a.iana-servers.net. - example.com. 65118 IN NS b.iana-servers.net. - cname.example.com. 434334 IN CNAME a.miek.nl. - */ - - corefile := `example.com:32053 { - secondary { - transfer from 127.0.0.1:32054 - upstream 8.8.8.8 - } - } - ` - - sec, err := CoreDNSServer(corefile) - if err != nil { - t.Fatalf("Could not get CoreDNS serving instance: %s", err) - } - - defer sec.Stop() - - m := new(dns.Msg) - m.SetQuestion("cname.example.com.", dns.TypeA) - - r, err := dns.Exchange(m, "127.0.0.1:32053") - if err != nil { - t.Fatalf("Expected to receive reply, but didn't: %s", err) - } - - if len(r.Answer) != 2 { - t.Fatalf("Expected answer section, with 2 records, got %d", len(r.Answer)) - } - - if r.Answer[0].(*dns.CNAME).Target != "a.miek.nl." { - t.Fatalf("Expected target of %s, got %s", "a.miek.nl.", r.Answer[0].(*dns.CNAME).Target) - } - if r.Answer[1].Header().Name != "a.miek.nl." { - t.Fatalf("Expected name of %s, got %s", "a.miek.nl.", r.Answer[1].Header().Name) - } -} diff --git a/test/secondary_test.go b/test/secondary_test.go index 370d523c9..4b38a6208 100644 --- a/test/secondary_test.go +++ b/test/secondary_test.go @@ -1,8 +1,6 @@ package test import ( - "io/ioutil" - "log" "testing" "github.com/coredns/coredns/plugin/proxy" @@ -27,8 +25,6 @@ func TestEmptySecondaryZone(t *testing.T) { } defer i.Stop() - log.SetOutput(ioutil.Discard) - p := proxy.NewLookup([]string{udp}) state := request.Request{W: &test.ResponseWriter{}, Req: new(dns.Msg)} @@ -40,3 +36,48 @@ func TestEmptySecondaryZone(t *testing.T) { t.Fatalf("Expected reply to be a SERVFAIL, got %d", resp.Rcode) } } + +func TestSecondaryZoneTransfer(t *testing.T) { + name, rm, err := test.TempFile(".", exampleOrg) + if err != nil { + t.Fatalf("failed to create zone: %s", err) + } + defer rm() + + corefile := `example.org:0 { + file ` + name + ` { + transfer to * + } +} +` + + i, _, tcp, err := CoreDNSServerAndPorts(corefile) + if err != nil { + t.Fatalf("Could not get CoreDNS serving instance: %s", err) + } + defer i.Stop() + + corefile = `example.org:0 { + secondary { + transfer from ` + tcp + ` + } +} +` + i1, udp, _, err := CoreDNSServerAndPorts(corefile) + if err != nil { + t.Fatalf("Could not get CoreDNS serving instance: %s", err) + } + defer i1.Stop() + + m := new(dns.Msg) + m.SetQuestion("example.org.", dns.TypeSOA) + + r, err := dns.Exchange(m, udp) + if err != nil { + t.Fatalf("Expected to receive reply, but didn't: %s", err) + } + + if len(r.Answer) == 0 { + t.Fatalf("Expected answer section") + } +}