diff options
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/etcd/README.md | 5 | ||||
-rw-r--r-- | plugin/kubernetes/README.md | 9 | ||||
-rw-r--r-- | plugin/kubernetes/setup_reverse_test.go | 2 | ||||
-rw-r--r-- | plugin/normalize.go | 40 | ||||
-rw-r--r-- | plugin/normalize_test.go | 30 | ||||
-rw-r--r-- | plugin/pkg/dnsutil/reverse.go | 2 |
6 files changed, 58 insertions, 30 deletions
diff --git a/plugin/etcd/README.md b/plugin/etcd/README.md index 8b8680f25..f8e3353ca 100644 --- a/plugin/etcd/README.md +++ b/plugin/etcd/README.md @@ -84,11 +84,10 @@ when resolving external pointing CNAMEs. Reverse zones are supported. You need to make CoreDNS aware of the fact that you are also authoritative for the reverse. For instance if you want to add the reverse for 10.0.0.0/24, you'll -need to add the zone `0.0.10.in-addr.arpa` to the list of zones. (The fun starts with IPv6 reverse zones -in the ip6.arpa domain.) Showing a snippet of a Corefile: +need to add the zone `0.0.10.in-addr.arpa` to the list of zones. Showing a snippet of a Corefile: ~~~ -etcd skydns.local 0.0.10.in-addr.arpa { +etcd skydns.local 10.0.0.0/24 { stubzones ... ~~~ diff --git a/plugin/kubernetes/README.md b/plugin/kubernetes/README.md index f7887f74d..42fc54543 100644 --- a/plugin/kubernetes/README.md +++ b/plugin/kubernetes/README.md @@ -76,13 +76,12 @@ kubernetes [ZONES...] { ## Examples -Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. -Also handle all `PTR` requests for `10.0.0.0/16` . Verify the existence of pods when answering pod -requests. Resolve upstream records against `10.102.3.10`. Note we show the entire server block -here: +Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Also handle all +`in-addr.arpa` `PTR` requests for `10.0.0.0/17` . Verify the existence of pods when answering pod +requests. Resolve upstream records against `10.102.3.10`. Note we show the entire server block here: ~~~ txt -10.0.0.0/16 cluster.local { +10.0.0.0/17 cluster.local { kubernetes { pods verified upstream 10.102.3.10:53 diff --git a/plugin/kubernetes/setup_reverse_test.go b/plugin/kubernetes/setup_reverse_test.go index ed51a7410..626874e6d 100644 --- a/plugin/kubernetes/setup_reverse_test.go +++ b/plugin/kubernetes/setup_reverse_test.go @@ -12,7 +12,7 @@ func TestKubernetesParseReverseZone(t *testing.T) { expectedZones []string // expected count of defined zones. }{ {`kubernetes coredns.local 10.0.0.0/16`, []string{"coredns.local.", "0.10.in-addr.arpa."}}, - {`kubernetes coredns.local 10.0.0.0/17`, []string{"coredns.local.", "10.0.0.0/17."}}, + {`kubernetes coredns.local 10.0.0.0/17`, []string{"coredns.local.", "0.10.in-addr.arpa."}}, } for i, tc := range tests { diff --git a/plugin/normalize.go b/plugin/normalize.go index 75b9c53c8..f8cbcf7a0 100644 --- a/plugin/normalize.go +++ b/plugin/normalize.go @@ -75,13 +75,14 @@ func (h Host) Normalize() string { // The error can be ignore here, because this function is called after the corefile // has already been vetted. - host, _, _ := SplitHostPort(s) + 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) { +// String the string s should *not* be prefixed with any protocols, i.e. dns://. The returned ipnet is the +// *net.IPNet that is used when the zone is a reverse and a netmask is given. +func SplitHostPort(s string) (host, port string, ipnet *net.IPNet, 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. @@ -89,7 +90,7 @@ func SplitHostPort(s string) (host, port string, err error) { colon := strings.LastIndex(s, ":") if colon == len(s)-1 { - return "", "", fmt.Errorf("expecting data after last colon: %q", s) + return "", "", nil, fmt.Errorf("expecting data after last colon: %q", s) } if colon != -1 { if p, err := strconv.Atoi(s[colon+1:]); err == nil { @@ -100,33 +101,34 @@ func SplitHostPort(s string) (host, port string, err error) { // TODO(miek): this should take escaping into account. if len(host) > 255 { - return "", "", fmt.Errorf("specified zone is too long: %d > 255", len(host)) + return "", "", nil, 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) + return "", "", nil, 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) + // Check if it parses as a reverse zone, if so we use that. Must be fully specified IP and mask. + ip, n, err := net.ParseCIDR(host) + ones, bits := 0, 0 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 - } + ones, bits = n.Mask.Size() + // Get the first lower octet boundary to see what encompassing zone we should be authoritative for. + mod := (bits - ones) % 8 + nearest := (bits - ones) + mod + offset, end := 0, false + for i := 0; i < nearest/8; i++ { + offset, end = dns.NextLabel(rev, offset) + if end { + break } - host = rev[offset:] } + host = rev[offset:] } } - return host, port, nil + return host, port, n, nil } // Duplicated from core/dnsserver/address.go ! diff --git a/plugin/normalize_test.go b/plugin/normalize_test.go index 3eb9c5231..e81d32629 100644 --- a/plugin/normalize_test.go +++ b/plugin/normalize_test.go @@ -70,7 +70,7 @@ func TestNameNormalize(t *testing.T) { func TestHostNormalize(t *testing.T) { hosts := []string{".:53", ".", "example.org:53", "example.org.", "example.org.:53", "example.org.", - "10.0.0.0/8:53", "10.in-addr.arpa.", "10.0.0.0/9", "10.0.0.0/9.", + "10.0.0.0/8:53", "10.in-addr.arpa.", "10.0.0.0/9", "10.in-addr.arpa.", "dns://example.org", "example.org."} for i := 0; i < len(hosts); i += 2 { @@ -82,3 +82,31 @@ func TestHostNormalize(t *testing.T) { } } } + +func TestSplitHostPortReverse(t *testing.T) { + tests := map[string]int{ + "example.org.": 0, + "10.0.0.0/9": 32 - 9, + "10.0.0.0/8": 32 - 8, + "10.0.0.0/17": 32 - 17, + "10.0.0.0/0": 32 - 0, + "10.0.0.0/64": 0, + "10.0.0.0": 0, + "10.0.0": 0, + "2003::1/65": 128 - 65, + } + for in, expect := range tests { + _, _, n, err := SplitHostPort(in) + if err != nil { + t.Errorf("Expected no error, got %q for %s", in, err) + } + if n == nil { + continue + } + ones, bits := n.Mask.Size() + got := bits - ones + if got != expect { + t.Errorf("Expected %d, got %d for %s", expect, got, in) + } + } +} diff --git a/plugin/pkg/dnsutil/reverse.go b/plugin/pkg/dnsutil/reverse.go index daf9cc600..f92cf18b5 100644 --- a/plugin/pkg/dnsutil/reverse.go +++ b/plugin/pkg/dnsutil/reverse.go @@ -9,7 +9,7 @@ import ( // into an IP address. This works for ipv4 or ipv6. // // 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion -// failes the empty string is returned. +// fails the empty string is returned. func ExtractAddressFromReverse(reverseName string) string { search := "" |