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") + } +}