diff options
author | 2017-09-14 09:36:06 +0100 | |
---|---|---|
committer | 2017-09-14 09:36:06 +0100 | |
commit | d8714e64e400ef873c2adc4d929a07d7890727b9 (patch) | |
tree | c9fa4c157e6af12eb1517654f8d23ca5d5619513 /plugin/normalize.go | |
parent | b984aa45595dc95253b91191afe7d3ee29e71b48 (diff) | |
download | coredns-d8714e64e400ef873c2adc4d929a07d7890727b9.tar.gz coredns-d8714e64e400ef873c2adc4d929a07d7890727b9.tar.zst coredns-d8714e64e400ef873c2adc4d929a07d7890727b9.zip |
Remove the word middleware (#1067)
* Rename middleware to plugin
first pass; mostly used 'sed', few spots where I manually changed
text.
This still builds a coredns binary.
* fmt error
* Rename AddMiddleware to AddPlugin
* Readd AddMiddleware to remain backwards compat
Diffstat (limited to 'plugin/normalize.go')
-rw-r--r-- | plugin/normalize.go | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/plugin/normalize.go b/plugin/normalize.go new file mode 100644 index 000000000..75b9c53c8 --- /dev/null +++ b/plugin/normalize.go @@ -0,0 +1,137 @@ +package plugin + +import ( + "fmt" + "net" + "strconv" + "strings" + + "github.com/miekg/dns" +) + +// See core/dnsserver/address.go - we should unify these two impls. + +// Zones respresents a lists of zone names. +type Zones []string + +// Matches checks is qname is a subdomain of any of the zones in z. The match +// will return the most specific zones that matches other. The empty string +// signals a not found condition. +func (z Zones) Matches(qname string) string { + zone := "" + for _, zname := range z { + if dns.IsSubDomain(zname, qname) { + // We want the *longest* matching zone, otherwise we may end up in a parent + if len(zname) > len(zone) { + zone = zname + } + } + } + return zone +} + +// 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() + } +} + +// Name represents a domain name. +type Name string + +// Matches checks to see if other is a subdomain (or the same domain) of n. +// This method assures that names can be easily and consistently matched. +func (n Name) Matches(child string) bool { + if dns.Name(n) == dns.Name(child) { + return true + } + return dns.IsSubDomain(string(n), child) +} + +// Normalize lowercases and makes n fully qualified. +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 +) + +// Normalize will return the host portion of host, stripping +// of any port or transport. The host will also be fully qualified and lowercased. +func (h Host) Normalize() string { + + s := string(h) + + switch { + case strings.HasPrefix(s, TransportTLS+"://"): + s = s[len(TransportTLS+"://"):] + case strings.HasPrefix(s, TransportDNS+"://"): + s = s[len(TransportDNS+"://"):] + case strings.HasPrefix(s, TransportGRPC+"://"): + s = s[len(TransportGRPC+"://"):] + } + + // The error can be ignore here, because this function is called after the corefile + // has already been vetted. + host, _, _ := SplitHostPort(s) + return Name(host).Normalize() +} + +// SplitHostPort splits s up in a host and port portion, taking reverse address notation into account. +// String the string s should *not* be prefixed with any protocols, i.e. dns:// +func SplitHostPort(s string) (host, port string, err error) { + // If there is: :[0-9]+ on the end we assume this is the port. This works for (ascii) domain + // names and our reverse syntax, which always needs a /mask *before* the port. + // So from the back, find first colon, and then check if its a number. + host = s + + colon := strings.LastIndex(s, ":") + if colon == len(s)-1 { + return "", "", fmt.Errorf("expecting data after last colon: %q", s) + } + if colon != -1 { + if p, err := strconv.Atoi(s[colon+1:]); err == nil { + port = strconv.Itoa(p) + host = s[:colon] + } + } + + // TODO(miek): this should take escaping into account. + if len(host) > 255 { + return "", "", fmt.Errorf("specified zone is too long: %d > 255", len(host)) + } + + _, d := dns.IsDomainName(host) + if !d { + return "", "", fmt.Errorf("zone is not a valid domain name: %s", host) + } + + // Check if it parses as a reverse zone, if so we use that. Must be fully + // specified IP and mask and mask % 8 = 0. + ip, net, err := net.ParseCIDR(host) + if err == nil { + if rev, e := dns.ReverseAddr(ip.String()); e == nil { + ones, bits := net.Mask.Size() + if (bits-ones)%8 == 0 { + offset, end := 0, false + for i := 0; i < (bits-ones)/8; i++ { + offset, end = dns.NextLabel(rev, offset) + if end { + break + } + } + host = rev[offset:] + } + } + } + return host, port, nil +} + +// Duplicated from core/dnsserver/address.go ! +const ( + TransportDNS = "dns" + TransportTLS = "tls" + TransportGRPC = "grpc" +) |