diff --git a/iana.go b/iana.go index ddad1de..b0b0cf1 100644 --- a/iana.go +++ b/iana.go @@ -42,9 +42,16 @@ func getIANAZoneMasters(tld string) ([]string, error) { m := new(dns.Msg) m.SetQuestion(tld, dns.TypeNS) - r, _, err := c.Exchange(m, getRandomInternicRoot()) - if err != nil { - return nil, errors.Wrap(err, "Could not query nameservers") + var ( + err error + r *dns.Msg + ) + + if err = retry(func() error { + r, _, err = c.Exchange(m, getRandomInternicRoot()) + return errors.Wrap(err, "Could not query nameservers") + }); err != nil { + return nil, err } if r.Rcode != dns.RcodeSuccess { diff --git a/opennic.go b/opennic.go index eccccb0..11b3766 100644 --- a/opennic.go +++ b/opennic.go @@ -13,9 +13,16 @@ func getOpenNICTLDs() ([]string, error) { m := new(dns.Msg) m.SetQuestion("tlds.opennic.glue.", dns.TypeTXT) - r, _, err := c.Exchange(m, cfg.OpenNICRoot+":53") - if err != nil { - return nil, errors.Wrap(err, "Could not query nameservers") + var ( + err error + r *dns.Msg + ) + + if err = retry(func() error { + r, _, err = c.Exchange(m, cfg.OpenNICRoot+":53") + return errors.Wrap(err, "Could not query nameservers") + }); err != nil { + return nil, err } if r.Rcode != dns.RcodeSuccess { @@ -42,9 +49,16 @@ func getOpenNICZoneMasters(tld string) ([]string, error) { m := new(dns.Msg) m.SetQuestion(tld+"opennic.glue.", dns.TypeCNAME) - r, _, err := c.Exchange(m, cfg.OpenNICRoot+":53") - if err != nil { - return nil, errors.Wrap(err, "Could not query nameservers") + var ( + err error + r *dns.Msg + ) + + if err = retry(func() error { + r, _, err = c.Exchange(m, cfg.OpenNICRoot+":53") + return errors.Wrap(err, "Could not query nameservers") + }); err != nil { + return nil, err } if r.Rcode != dns.RcodeSuccess { @@ -65,9 +79,11 @@ func getOpenNICZoneMasters(tld string) ([]string, error) { m = new(dns.Msg) m.SetQuestion(master, dns.TypeA) - r, _, err := c.Exchange(m, cfg.OpenNICRoot+":53") - if err != nil { - return nil, errors.Wrap(err, "Could not query nameservers") + if err = retry(func() error { + r, _, err = c.Exchange(m, cfg.OpenNICRoot+":53") + return errors.Wrap(err, "Could not query nameservers") + }); err != nil { + return nil, err } if r.Rcode != dns.RcodeSuccess { diff --git a/retry.go b/retry.go new file mode 100644 index 0000000..384f2a9 --- /dev/null +++ b/retry.go @@ -0,0 +1,26 @@ +package main + +import ( + "math" + "time" +) + +const ( + maxRetries = 5 + retryDelay = 1.2 +) + +func retry(f func() error) error { + var err error + + for i := 1; i <= maxRetries; i++ { + if err = f(); err == nil { + return nil + } + + sleep := time.Duration(math.Pow(retryDelay, float64(i)) * float64(time.Second)) + time.Sleep(sleep) + } + + return err +}