diff options
author | 2017-08-10 05:30:18 -0700 | |
---|---|---|
committer | 2017-08-10 05:30:18 -0700 | |
commit | 3654361be26d79e9b4a25581deb0168228022585 (patch) | |
tree | 3a04da77ef4626cd4be9fb0460df0b5a98f78921 /middleware | |
parent | 28447234b164a990c7007158422cbad42d1ff855 (diff) | |
download | coredns-3654361be26d79e9b4a25581deb0168228022585.tar.gz coredns-3654361be26d79e9b4a25581deb0168228022585.tar.zst coredns-3654361be26d79e9b4a25581deb0168228022585.zip |
core: small cleanup (#877)
Add some docs about normalize.Host and normalize.Name. They are used
correctly in the middleware even though they are somewhat confusing,
esp when you copy from ServerBlockKeys in your middleware.
Diffstat (limited to 'middleware')
-rw-r--r-- | middleware/auto/setup.go | 139 | ||||
-rw-r--r-- | middleware/dnssec/setup.go | 52 | ||||
-rw-r--r-- | middleware/etcd/setup.go | 112 | ||||
-rw-r--r-- | middleware/file/setup.go | 116 | ||||
-rw-r--r-- | middleware/hosts/setup.go | 64 | ||||
-rw-r--r-- | middleware/normalize.go | 5 | ||||
-rw-r--r-- | middleware/reverse/setup.go | 171 |
7 files changed, 322 insertions, 337 deletions
diff --git a/middleware/auto/setup.go b/middleware/auto/setup.go index 6bda11238..98eefca4a 100644 --- a/middleware/auto/setup.go +++ b/middleware/auto/setup.go @@ -81,91 +81,88 @@ func autoParse(c *caddy.Controller) (Auto, error) { config := dnsserver.GetConfig(c) for c.Next() { - if c.Val() == "auto" { - // auto [ZONES...] - a.Zones.origins = make([]string, len(c.ServerBlockKeys)) - copy(a.Zones.origins, c.ServerBlockKeys) - - args := c.RemainingArgs() - if len(args) > 0 { - a.Zones.origins = args - } - for i := range a.Zones.origins { - a.Zones.origins[i] = middleware.Host(a.Zones.origins[i]).Normalize() - } + // auto [ZONES...] + a.Zones.origins = make([]string, len(c.ServerBlockKeys)) + copy(a.Zones.origins, c.ServerBlockKeys) - for c.NextBlock() { - switch c.Val() { - case "directory": // directory DIR [REGEXP [TEMPLATE] [DURATION]] - if !c.NextArg() { - return a, c.ArgErr() - } - a.loader.directory = c.Val() - if !path.IsAbs(a.loader.directory) && config.Root != "" { - a.loader.directory = path.Join(config.Root, a.loader.directory) - } - _, err := os.Stat(a.loader.directory) - if err != nil { - if os.IsNotExist(err) { - log.Printf("[WARNING] Directory does not exist: %s", a.loader.directory) - } else { - return a, c.Errf("Unable to access root path '%s': %v", a.loader.directory, err) - } - } + args := c.RemainingArgs() + if len(args) > 0 { + a.Zones.origins = args + } + for i := range a.Zones.origins { + a.Zones.origins[i] = middleware.Host(a.Zones.origins[i]).Normalize() + } - // regexp - if c.NextArg() { - a.loader.re, err = regexp.Compile(c.Val()) - if err != nil { - return a, err - } - if a.loader.re.NumSubexp() == 0 { - return a, c.Errf("Need at least one sub expression") - } + for c.NextBlock() { + switch c.Val() { + case "directory": // directory DIR [REGEXP [TEMPLATE] [DURATION]] + if !c.NextArg() { + return a, c.ArgErr() + } + a.loader.directory = c.Val() + if !path.IsAbs(a.loader.directory) && config.Root != "" { + a.loader.directory = path.Join(config.Root, a.loader.directory) + } + _, err := os.Stat(a.loader.directory) + if err != nil { + if os.IsNotExist(err) { + log.Printf("[WARNING] Directory does not exist: %s", a.loader.directory) + } else { + return a, c.Errf("Unable to access root path '%s': %v", a.loader.directory, err) } + } - // template - if c.NextArg() { - a.loader.template = rewriteToExpand(c.Val()) + // regexp + if c.NextArg() { + a.loader.re, err = regexp.Compile(c.Val()) + if err != nil { + return a, err } - - // duration - if c.NextArg() { - i, err := strconv.Atoi(c.Val()) - if err != nil { - return a, err - } - if i < 1 { - i = 1 - } - a.loader.duration = time.Duration(i) * time.Second + if a.loader.re.NumSubexp() == 0 { + return a, c.Errf("Need at least one sub expression") } + } - case "no_reload": - a.loader.noReload = true + // template + if c.NextArg() { + a.loader.template = rewriteToExpand(c.Val()) + } - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return a, c.ArgErr() - } - ups, err := dnsutil.ParseHostPortOrFile(args...) + // duration + if c.NextArg() { + i, err := strconv.Atoi(c.Val()) if err != nil { return a, err } - a.loader.proxy = proxy.NewLookup(ups) - - default: - t, _, e := file.TransferParse(c, false) - if e != nil { - return a, e - } - if t != nil { - a.loader.transferTo = append(a.loader.transferTo, t...) + if i < 1 { + i = 1 } + a.loader.duration = time.Duration(i) * time.Second } - } + case "no_reload": + a.loader.noReload = true + + case "upstream": + args := c.RemainingArgs() + if len(args) == 0 { + return a, c.ArgErr() + } + ups, err := dnsutil.ParseHostPortOrFile(args...) + if err != nil { + return a, err + } + a.loader.proxy = proxy.NewLookup(ups) + + default: + t, _, e := file.TransferParse(c, false) + if e != nil { + return a, e + } + if t != nil { + a.loader.transferTo = append(a.loader.transferTo, t...) + } + } } } return a, nil diff --git a/middleware/dnssec/setup.go b/middleware/dnssec/setup.go index 6935c4aaa..28dff4432 100644 --- a/middleware/dnssec/setup.go +++ b/middleware/dnssec/setup.go @@ -42,36 +42,34 @@ func dnssecParse(c *caddy.Controller) ([]string, []*DNSKEY, int, error) { capacity := defaultCap for c.Next() { - if c.Val() == "dnssec" { - // dnssec [zones...] - zones = make([]string, len(c.ServerBlockKeys)) - copy(zones, c.ServerBlockKeys) - args := c.RemainingArgs() - if len(args) > 0 { - zones = args - } + // dnssec [zones...] + zones = make([]string, len(c.ServerBlockKeys)) + copy(zones, c.ServerBlockKeys) + args := c.RemainingArgs() + if len(args) > 0 { + zones = args + } - for c.NextBlock() { - switch c.Val() { - case "key": - k, e := keyParse(c) - if e != nil { - return nil, nil, 0, e - } - keys = append(keys, k...) - case "cache_capacity": - if !c.NextArg() { - return nil, nil, 0, c.ArgErr() - } - value := c.Val() - cacheCap, err := strconv.Atoi(value) - if err != nil { - return nil, nil, 0, err - } - capacity = cacheCap + for c.NextBlock() { + switch c.Val() { + case "key": + k, e := keyParse(c) + if e != nil { + return nil, nil, 0, e } - + keys = append(keys, k...) + case "cache_capacity": + if !c.NextArg() { + return nil, nil, 0, c.ArgErr() + } + value := c.Val() + cacheCap, err := strconv.Atoi(value) + if err != nil { + return nil, nil, 0, err + } + capacity = cacheCap } + } } for i := range zones { diff --git a/middleware/etcd/setup.go b/middleware/etcd/setup.go index bedc154f8..331227c34 100644 --- a/middleware/etcd/setup.go +++ b/middleware/etcd/setup.go @@ -60,71 +60,69 @@ func etcdParse(c *caddy.Controller) (*Etcd, bool, error) { stubzones = false ) for c.Next() { - if c.Val() == "etcd" { - etc.Zones = c.RemainingArgs() - if len(etc.Zones) == 0 { - etc.Zones = make([]string, len(c.ServerBlockKeys)) - copy(etc.Zones, c.ServerBlockKeys) - } - for i, str := range etc.Zones { - etc.Zones[i] = middleware.Host(str).Normalize() - } + etc.Zones = c.RemainingArgs() + if len(etc.Zones) == 0 { + etc.Zones = make([]string, len(c.ServerBlockKeys)) + copy(etc.Zones, c.ServerBlockKeys) + } + for i, str := range etc.Zones { + etc.Zones[i] = middleware.Host(str).Normalize() + } - if c.NextBlock() { - for { - switch c.Val() { - case "stubzones": - stubzones = true - case "debug": - etc.Debugging = true - case "path": - if !c.NextArg() { - return &Etcd{}, false, c.ArgErr() - } - etc.PathPrefix = c.Val() - case "endpoint": - args := c.RemainingArgs() - if len(args) == 0 { - return &Etcd{}, false, c.ArgErr() - } - endpoints = args - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return &Etcd{}, false, c.ArgErr() - } - ups, err := dnsutil.ParseHostPortOrFile(args...) - if err != nil { - return &Etcd{}, false, err - } - etc.Proxy = proxy.NewLookup(ups) - case "tls": // cert key cacertfile - args := c.RemainingArgs() - tlsConfig, err = mwtls.NewTLSConfigFromArgs(args...) - if err != nil { - return &Etcd{}, false, err - } - default: - if c.Val() != "}" { - return &Etcd{}, false, c.Errf("unknown property '%s'", c.Val()) - } + if c.NextBlock() { + for { + switch c.Val() { + case "stubzones": + stubzones = true + case "debug": + etc.Debugging = true + case "path": + if !c.NextArg() { + return &Etcd{}, false, c.ArgErr() } - - if !c.Next() { - break + etc.PathPrefix = c.Val() + case "endpoint": + args := c.RemainingArgs() + if len(args) == 0 { + return &Etcd{}, false, c.ArgErr() + } + endpoints = args + case "upstream": + args := c.RemainingArgs() + if len(args) == 0 { + return &Etcd{}, false, c.ArgErr() + } + ups, err := dnsutil.ParseHostPortOrFile(args...) + if err != nil { + return &Etcd{}, false, err + } + etc.Proxy = proxy.NewLookup(ups) + case "tls": // cert key cacertfile + args := c.RemainingArgs() + tlsConfig, err = mwtls.NewTLSConfigFromArgs(args...) + if err != nil { + return &Etcd{}, false, err + } + default: + if c.Val() != "}" { + return &Etcd{}, false, c.Errf("unknown property '%s'", c.Val()) } } + if !c.Next() { + break + } } - client, err := newEtcdClient(endpoints, tlsConfig) - if err != nil { - return &Etcd{}, false, err - } - etc.Client = client - etc.endpoints = endpoints - return &etc, stubzones, nil } + client, err := newEtcdClient(endpoints, tlsConfig) + if err != nil { + return &Etcd{}, false, err + } + etc.Client = client + etc.endpoints = endpoints + + return &etc, stubzones, nil } return &Etcd{}, false, nil } diff --git a/middleware/file/setup.go b/middleware/file/setup.go index ef59223fe..62b561a35 100644 --- a/middleware/file/setup.go +++ b/middleware/file/setup.go @@ -55,76 +55,74 @@ func fileParse(c *caddy.Controller) (Zones, error) { config := dnsserver.GetConfig(c) for c.Next() { - if c.Val() == "file" { - // file db.file [zones...] - if !c.NextArg() { - return Zones{}, c.ArgErr() - } - fileName := c.Val() + // file db.file [zones...] + if !c.NextArg() { + return Zones{}, c.ArgErr() + } + fileName := c.Val() - origins = make([]string, len(c.ServerBlockKeys)) - copy(origins, c.ServerBlockKeys) - args := c.RemainingArgs() - if len(args) > 0 { - origins = args - } + origins = make([]string, len(c.ServerBlockKeys)) + copy(origins, c.ServerBlockKeys) + args := c.RemainingArgs() + if len(args) > 0 { + origins = args + } - if !path.IsAbs(fileName) && config.Root != "" { - fileName = path.Join(config.Root, fileName) - } + if !path.IsAbs(fileName) && config.Root != "" { + fileName = path.Join(config.Root, fileName) + } + + reader, err := os.Open(fileName) + if err != nil { + // bail out + return Zones{}, err + } - reader, err := os.Open(fileName) - if err != nil { - // bail out + for i := range origins { + origins[i] = middleware.Host(origins[i]).Normalize() + zone, err := Parse(reader, origins[i], fileName, 0) + if err == nil { + z[origins[i]] = zone + } else { return Zones{}, err } + names = append(names, origins[i]) + } - for i := range origins { - origins[i] = middleware.Host(origins[i]).Normalize() - zone, err := Parse(reader, origins[i], fileName, 0) - if err == nil { - z[origins[i]] = zone - } else { - return Zones{}, err + noReload := false + prxy := proxy.Proxy{} + t := []string{} + var e error + + for c.NextBlock() { + switch c.Val() { + case "transfer": + t, _, e = TransferParse(c, false) + if e != nil { + return Zones{}, e } - names = append(names, origins[i]) - } - noReload := false - prxy := proxy.Proxy{} - t := []string{} - var e error - - for c.NextBlock() { - switch c.Val() { - case "transfer": - t, _, e = TransferParse(c, false) - if e != nil { - return Zones{}, e - } - - case "no_reload": - noReload = true - - case "upstream": - args := c.RemainingArgs() - if len(args) == 0 { - return Zones{}, c.ArgErr() - } - ups, err := dnsutil.ParseHostPortOrFile(args...) - if err != nil { - return Zones{}, err - } - prxy = proxy.NewLookup(ups) + case "no_reload": + noReload = true + + case "upstream": + args := c.RemainingArgs() + if len(args) == 0 { + return Zones{}, c.ArgErr() } + ups, err := dnsutil.ParseHostPortOrFile(args...) + if err != nil { + return Zones{}, err + } + prxy = proxy.NewLookup(ups) + } - for _, origin := range origins { - if t != nil { - z[origin].TransferTo = append(z[origin].TransferTo, t...) - } - z[origin].NoReload = noReload - z[origin].Proxy = prxy + for _, origin := range origins { + if t != nil { + z[origin].TransferTo = append(z[origin].TransferTo, t...) } + z[origin].NoReload = noReload + z[origin].Proxy = prxy } } } diff --git a/middleware/hosts/setup.go b/middleware/hosts/setup.go index aec739fcc..d024d449e 100644 --- a/middleware/hosts/setup.go +++ b/middleware/hosts/setup.go @@ -41,46 +41,44 @@ func hostsParse(c *caddy.Controller) (Hosts, error) { config := dnsserver.GetConfig(c) for c.Next() { - if c.Val() == "hosts" { // hosts [FILE] [ZONES...] - args := c.RemainingArgs() - if len(args) >= 1 { - h.path = args[0] - args = args[1:] + args := c.RemainingArgs() + if len(args) >= 1 { + h.path = args[0] + args = args[1:] - if !path.IsAbs(h.path) && config.Root != "" { - h.path = path.Join(config.Root, h.path) - } - _, err := os.Stat(h.path) - if err != nil { - if os.IsNotExist(err) { - log.Printf("[WARNING] File does not exist: %s", h.path) - } else { - return h, c.Errf("unable to access hosts file '%s': %v", h.path, err) - } + if !path.IsAbs(h.path) && config.Root != "" { + h.path = path.Join(config.Root, h.path) + } + _, err := os.Stat(h.path) + if err != nil { + if os.IsNotExist(err) { + log.Printf("[WARNING] File does not exist: %s", h.path) + } else { + return h, c.Errf("unable to access hosts file '%s': %v", h.path, err) } } + } - origins := make([]string, len(c.ServerBlockKeys)) - copy(origins, c.ServerBlockKeys) - if len(args) > 0 { - origins = args - } + origins := make([]string, len(c.ServerBlockKeys)) + copy(origins, c.ServerBlockKeys) + if len(args) > 0 { + origins = args + } - for i := range origins { - origins[i] = middleware.Host(origins[i]).Normalize() - } - h.Origins = origins + for i := range origins { + origins[i] = middleware.Host(origins[i]).Normalize() + } + h.Origins = origins - for c.NextBlock() { - switch c.Val() { - case "fallthrough": - args := c.RemainingArgs() - if len(args) == 0 { - h.Fallthrough = true - continue - } - return h, c.ArgErr() + for c.NextBlock() { + switch c.Val() { + case "fallthrough": + args := c.RemainingArgs() + if len(args) == 0 { + h.Fallthrough = true + continue } + return h, c.ArgErr() } } } diff --git a/middleware/normalize.go b/middleware/normalize.go index 18fe58f61..92cc57937 100644 --- a/middleware/normalize.go +++ b/middleware/normalize.go @@ -30,7 +30,8 @@ func (z Zones) Matches(qname string) string { return zone } -// Normalize fully qualifies all zones in z. +// Normalize fully qualifies all zones in z. The zones in Z must be domain names, without +// a port or protocol prefix. func (z Zones) Normalize() { for i := range z { z[i] = Name(z[i]).Normalize() @@ -54,7 +55,7 @@ func (n Name) Normalize() string { return strings.ToLower(dns.Fqdn(string(n))) } type ( // Host represents a host from the Corefile, may contain port. - Host string // Host represents a host from the Corefile, may contain port. + Host string ) // Normalize will return the host portion of host, stripping diff --git a/middleware/reverse/setup.go b/middleware/reverse/setup.go index ee426f852..8d8cc6548 100644 --- a/middleware/reverse/setup.go +++ b/middleware/reverse/setup.go @@ -34,116 +34,111 @@ func setupReverse(c *caddy.Controller) error { } func reverseParse(c *caddy.Controller) (nets networks, fall bool, err error) { - - // normalize zones, validation is almost done by dnsserver - // TODO(miek): need sane helpers for these. zones := make([]string, len(c.ServerBlockKeys)) wildcard := false + // We copy from the serverblock, these contains Hosts. for i, str := range c.ServerBlockKeys { zones[i] = middleware.Host(str).Normalize() } for c.Next() { - if c.Val() == "reverse" { - - var cidrs []*net.IPNet + var cidrs []*net.IPNet - // parse all networks - for _, cidr := range c.RemainingArgs() { - if cidr == "{" { - break - } - _, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - return nil, false, c.Errf("network needs to be CIDR formatted: %q\n", cidr) - } - cidrs = append(cidrs, ipnet) + // parse all networks + for _, cidr := range c.RemainingArgs() { + if cidr == "{" { + break } - if len(cidrs) == 0 { - return nil, false, c.ArgErr() + _, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + return nil, false, c.Errf("network needs to be CIDR formatted: %q\n", cidr) } + cidrs = append(cidrs, ipnet) + } + if len(cidrs) == 0 { + return nil, false, c.ArgErr() + } - // set defaults - var ( - template = "ip-" + templateNameIP + ".{zone[1]}" - ttl = 60 - ) - for c.NextBlock() { - switch c.Val() { - case "hostname": - if !c.NextArg() { - return nil, false, c.ArgErr() - } - template = c.Val() - - case "ttl": - if !c.NextArg() { - return nil, false, c.ArgErr() - } - ttl, err = strconv.Atoi(c.Val()) - if err != nil { - return nil, false, err - } - - case "wildcard": - wildcard = true - - case "fallthrough": - fall = true - - default: + // set defaults + var ( + template = "ip-" + templateNameIP + ".{zone[1]}" + ttl = 60 + ) + for c.NextBlock() { + switch c.Val() { + case "hostname": + if !c.NextArg() { return nil, false, c.ArgErr() } - } - - // prepare template - // replace {zone[index]} by the listen zone/domain of this config block - for i, zone := range zones { - // TODO: we should be smarter about actually replacing this. This works, but silently allows "zone[-1]" - // for instance. - template = strings.Replace(template, "{zone["+strconv.Itoa(i+1)+"]}", zone, 1) - } - if !strings.HasSuffix(template, ".") { - template += "." - } + template = c.Val() - // extract zone from template - templateZone := strings.SplitAfterN(template, ".", 2) - if len(templateZone) != 2 || templateZone[1] == "" { - return nil, false, c.Errf("cannot find domain in template '%v'", template) - } - - // Create for each configured network in this stanza - for _, ipnet := range cidrs { - // precompile regex for hostname to ip matching - regexIP := regexMatchV4 - if ipnet.IP.To4() == nil { - regexIP = regexMatchV6 - } - prefix := "^" - if wildcard { - prefix += ".*" + case "ttl": + if !c.NextArg() { + return nil, false, c.ArgErr() } - regex, err := regexp.Compile( - prefix + strings.Replace( // inject ip regex into template - regexp.QuoteMeta(template), // escape dots - regexp.QuoteMeta(templateNameIP), - regexIP, - 1) + "$") + ttl, err = strconv.Atoi(c.Val()) if err != nil { return nil, false, err } - nets = append(nets, network{ - IPnet: ipnet, - Zone: templateZone[1], - Template: template, - RegexMatchIP: regex, - TTL: uint32(ttl), - }) + case "wildcard": + wildcard = true + + case "fallthrough": + fall = true + + default: + return nil, false, c.ArgErr() } } + + // prepare template + // replace {zone[index]} by the listen zone/domain of this config block + for i, zone := range zones { + // TODO: we should be smarter about actually replacing this. This works, but silently allows "zone[-1]" + // for instance. + template = strings.Replace(template, "{zone["+strconv.Itoa(i+1)+"]}", zone, 1) + } + if !strings.HasSuffix(template, ".") { + template += "." + } + + // extract zone from template + templateZone := strings.SplitAfterN(template, ".", 2) + if len(templateZone) != 2 || templateZone[1] == "" { + return nil, false, c.Errf("cannot find domain in template '%v'", template) + } + + // Create for each configured network in this stanza + for _, ipnet := range cidrs { + // precompile regex for hostname to ip matching + regexIP := regexMatchV4 + if ipnet.IP.To4() == nil { + regexIP = regexMatchV6 + } + prefix := "^" + if wildcard { + prefix += ".*" + } + regex, err := regexp.Compile( + prefix + strings.Replace( // inject ip regex into template + regexp.QuoteMeta(template), // escape dots + regexp.QuoteMeta(templateNameIP), + regexIP, + 1) + "$") + if err != nil { + return nil, false, err + } + + nets = append(nets, network{ + IPnet: ipnet, + Zone: templateZone[1], + Template: template, + RegexMatchIP: regex, + TTL: uint32(ttl), + }) + } } // sort by cidr |