diff options
author | 2017-08-10 05:30:18 -0700 | |
---|---|---|
committer | 2017-08-10 05:30:18 -0700 | |
commit | 3654361be26d79e9b4a25581deb0168228022585 (patch) | |
tree | 3a04da77ef4626cd4be9fb0460df0b5a98f78921 | |
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.
-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 |