aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2016-04-03 07:37:41 +0100
committerGravatar Miek Gieben <miek@miek.nl> 2016-04-03 07:37:41 +0100
commit6ecbdef112b3bf0759a60914d0eb08540c5274ed (patch)
tree67fa5b74cbe50cbd07eaf9d96a50ebe58d6e36e4
parent4a2a95561f4d22b04e155d575b20d803460b9903 (diff)
downloadcoredns-6ecbdef112b3bf0759a60914d0eb08540c5274ed.tar.gz
coredns-6ecbdef112b3bf0759a60914d0eb08540c5274ed.tar.zst
coredns-6ecbdef112b3bf0759a60914d0eb08540c5274ed.zip
Add notifies to master servers
This adds a bunch of supporting code to send notifies to a primary name server.
-rw-r--r--core/setup/file.go4
-rw-r--r--middleware/file/README.md4
-rw-r--r--middleware/file/notify.go37
-rw-r--r--middleware/file/zone.go3
-rw-r--r--middleware/host.go22
5 files changed, 59 insertions, 11 deletions
diff --git a/core/setup/file.go b/core/setup/file.go
index 7128b77aa..aca9f8f9f 100644
--- a/core/setup/file.go
+++ b/core/setup/file.go
@@ -13,6 +13,8 @@ func File(c *Controller) (middleware.Middleware, error) {
if err != nil {
return nil, err
}
+ // Set start function is transfer is specified
+
return func(next middleware.Handler) middleware.Handler {
return file.File{Next: next, Zones: zones}
}, nil
@@ -35,7 +37,7 @@ func fileParse(c *Controller) (file.Zones, error) {
origin = c.Val()
}
// normalize this origin
- origin = middleware.Host(origin).StandardHost()
+ origin = middleware.Host(origin).Standard()
reader, err := os.Open(fileName)
if err != nil {
diff --git a/middleware/file/README.md b/middleware/file/README.md
index bd9a24d1e..407c1119c 100644
--- a/middleware/file/README.md
+++ b/middleware/file/README.md
@@ -17,9 +17,11 @@ file dbfile [zones...]
If you want to round robin A and AAAA responses look at the `loadbalance` middleware.
+TSIG key configuration is TODO; directive format will change.
+
~~~
file dbfile [zones... ] {
- transfer in|out
+ transfer out [address...]
}
~~~
diff --git a/middleware/file/notify.go b/middleware/file/notify.go
index cb61cc050..58cc66e79 100644
--- a/middleware/file/notify.go
+++ b/middleware/file/notify.go
@@ -1,8 +1,39 @@
package file
-// Notify sends notifies to the configured remotes. It will try up to three times
-// before giving up on a specific remote.
-func Notify(remotes []string) error {
+import (
+ "fmt"
+
+ "github.com/miekg/coredns/middleware"
+ "github.com/miekg/dns"
+)
+
+// Notify will send notifies to all configured IP addresses.
+func (z *Zone) Notify() {
+ go notify(z.name, z.Peers)
+}
+
+// notify sends notifies to the configured remotes. It will try up to three times
+// before giving up on a specific remote. We will sequentially loop through the remotes
+// until they all have replied (or have 3 failed attempts).
+func notify(zone string, remotes []string) error {
+ m := new(dns.Msg)
+ m.SetNotify(zone)
+ c := new(dns.Client)
+
+ // TODO(miek): error handling? Run this in a goroutine?
+ for _, remote := range remotes {
+ notifyRemote(c, m, middleware.Addr(remote).Standard())
+ }
return nil
+}
+func notifyRemote(c *dns.Client, m *dns.Msg, s string) error {
+ for i := 0; i < 3; i++ {
+ ret, err := middleware.Exchange(c, m, s)
+ if err == nil && ret.Rcode == dns.RcodeSuccess || ret.Rcode == dns.RcodeNotImplemented {
+ return nil
+ }
+ // timeout? mean don't want it. should stop sending as well
+ }
+ return fmt.Errorf("failed to send notify for zone '%s' to '%s'", m.Question[0].Name, s)
}
diff --git a/middleware/file/zone.go b/middleware/file/zone.go
index 1547a23b4..8c56b6bf9 100644
--- a/middleware/file/zone.go
+++ b/middleware/file/zone.go
@@ -10,7 +10,6 @@ import (
type Transfer struct {
Out bool
In bool
- // more later?
}
type Zone struct {
@@ -18,7 +17,7 @@ type Zone struct {
SIG []dns.RR
name string
*tree.Tree
- Masters []string
+ Peers []string
Transfer *Transfer
}
diff --git a/middleware/host.go b/middleware/host.go
index 17ecedb5f..7b9b9a42a 100644
--- a/middleware/host.go
+++ b/middleware/host.go
@@ -7,12 +7,15 @@ import (
"github.com/miekg/dns"
)
-// Host represents a host from the Caddyfile, may contain port.
-type Host string
+// Host represents a host from the Corefile, may contain port.
+type (
+ Host string
+ Addr string
+)
-// Standard host will return the host portion of host, stripping
+// Standard will return the host portion of host, stripping
// of any port. The host will also be fully qualified and lowercased.
-func (h Host) StandardHost() string {
+func (h Host) Standard() string {
// separate host and port
host, _, err := net.SplitHostPort(string(h))
if err != nil {
@@ -20,3 +23,14 @@ func (h Host) StandardHost() string {
}
return strings.ToLower(dns.Fqdn(host))
}
+
+// Standard will return a normalized address, if not port is specified
+// port 53 is added, otherwise the port will be left as is.
+func (a Addr) Standard() string {
+ // separate host and port
+ addr, port, err := net.SplitHostPort(string(a))
+ if err != nil {
+ addr, port, _ = net.SplitHostPort(string(a) + ":53")
+ }
+ return net.JoinHostPort(addr, port)
+}