aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugin/secondary/setup.go21
-rw-r--r--test/secondary_test.go84
2 files changed, 104 insertions, 1 deletions
diff --git a/plugin/secondary/setup.go b/plugin/secondary/setup.go
index c09147276..9dcd9099b 100644
--- a/plugin/secondary/setup.go
+++ b/plugin/secondary/setup.go
@@ -1,14 +1,19 @@
package secondary
import (
+ "time"
+
"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/file"
+ clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/plugin/pkg/parse"
"github.com/coredns/coredns/plugin/pkg/upstream"
)
+var log = clog.NewWithPlugin("secondary")
+
func init() { plugin.Register("secondary", setup) }
func setup(c *caddy.Controller) error {
@@ -24,7 +29,21 @@ func setup(c *caddy.Controller) error {
c.OnStartup(func() error {
z.StartupOnce.Do(func() {
go func() {
- z.TransferIn()
+ dur := time.Millisecond * 250
+ step := time.Duration(2)
+ max := time.Second * 10
+ for {
+ err := z.TransferIn()
+ if err == nil {
+ break
+ }
+ log.Warningf("All '%s' masters failed to transfer, retrying in %s: %s", n, dur.String(), err)
+ time.Sleep(dur)
+ dur = step * dur
+ if dur > max {
+ dur = max
+ }
+ }
z.Update()
}()
})
diff --git a/test/secondary_test.go b/test/secondary_test.go
index c6b311be9..c60aa0355 100644
--- a/test/secondary_test.go
+++ b/test/secondary_test.go
@@ -132,3 +132,87 @@ func TestIxfrResponse(t *testing.T) {
t.Fatalf("Serial should be %d, got %d", 2015082541, soa.Serial)
}
}
+
+func TestRetryInitialTransfer(t *testing.T) {
+ // Start up a secondary that expects to transfer from a master that doesn't exist yet
+ corefile := `example.org:0 {
+ secondary {
+ transfer from 127.0.0.1:5399
+ }
+ }`
+
+ i, udp, _, err := CoreDNSServerAndPorts(corefile)
+ if err != nil {
+ t.Fatalf("Could not get CoreDNS serving instance: %s", err)
+ }
+ defer i.Stop()
+
+ m := new(dns.Msg)
+ m.SetQuestion("www.example.org.", dns.TypeA)
+ resp, err := dns.Exchange(m, udp)
+ if err != nil {
+ t.Fatal("Expected to receive reply, but didn't")
+ }
+ // Expect that the query will fail
+ if resp.Rcode != dns.RcodeServerFailure {
+ t.Fatalf("Expected reply to be a SERVFAIL, got %d", resp.Rcode)
+ }
+
+ // Now spin up the master server
+ name, rm, err := test.TempFile(".", `$ORIGIN example.org.
+@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
+ 2017042745 ; serial
+ 7200 ; refresh (2 hours)
+ 3600 ; retry (1 hour)
+ 1209600 ; expire (2 weeks)
+ 3600 ; minimum (1 hour)
+)
+
+ 3600 IN NS a.iana-servers.net.
+ 3600 IN NS b.iana-servers.net.
+
+www IN A 127.0.0.1
+www IN AAAA ::1
+`)
+ if err != nil {
+ t.Fatalf("Failed to create zone: %s", err)
+ }
+ defer rm()
+
+ corefileMaster := `example.org:5399 {
+ file ` + name + `
+ transfer {
+ to *
+ }
+ }`
+
+ master, _, _, err := CoreDNSServerAndPorts(corefileMaster)
+ if err != nil {
+ t.Fatalf("Could not start CoreDNS master: %s", err)
+ }
+ defer master.Stop()
+
+ retry := time.Tick(time.Millisecond * 100)
+ timeout := time.Tick(time.Second * 5)
+
+ for {
+ select {
+ case <-retry:
+ m = new(dns.Msg)
+ m.SetQuestion("www.example.org.", dns.TypeA)
+ resp, err = dns.Exchange(m, udp)
+ if err != nil {
+ continue
+ }
+ // Expect the query to succeed
+ if resp.Rcode != dns.RcodeSuccess {
+ continue
+ }
+ return
+ case <-timeout:
+ t.Fatal("Timed out trying for successful response.")
+ return
+ }
+ }
+
+}