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
This commit is contained in:
Miek Gieben
2017-09-14 09:36:06 +01:00
committed by GitHub
parent b984aa4559
commit d8714e64e4
354 changed files with 974 additions and 969 deletions

View File

@@ -0,0 +1,15 @@
package dnsutil
import "github.com/miekg/dns"
// DuplicateCNAME returns true if r already exists in records.
func DuplicateCNAME(r *dns.CNAME, records []dns.RR) bool {
for _, rec := range records {
if v, ok := rec.(*dns.CNAME); ok {
if v.Target == r.Target {
return true
}
}
}
return false
}

View File

@@ -0,0 +1,55 @@
package dnsutil
import (
"testing"
"github.com/miekg/dns"
)
func TestDuplicateCNAME(t *testing.T) {
tests := []struct {
cname string
records []string
expected bool
}{
{
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
[]string{
"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534",
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
},
true,
},
{
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
[]string{
"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534",
},
false,
},
{
"1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.",
[]string{},
false,
},
}
for i, test := range tests {
cnameRR, err := dns.NewRR(test.cname)
if err != nil {
t.Fatalf("Test %d, cname ('%s') error (%s)!", i, test.cname, err)
}
cname := cnameRR.(*dns.CNAME)
records := []dns.RR{}
for j, r := range test.records {
rr, err := dns.NewRR(r)
if err != nil {
t.Fatalf("Test %d, record %d ('%s') error (%s)!", i, j, r, err)
}
records = append(records, rr)
}
got := DuplicateCNAME(cname, records)
if got != test.expected {
t.Errorf("Test %d, expected '%v', got '%v' for CNAME ('%s') and RECORDS (%v)", i, test.expected, got, test.cname, test.records)
}
}
}

View File

@@ -0,0 +1,12 @@
package dnsutil
import "github.com/miekg/dns"
// Dedup de-duplicates a message.
func Dedup(m *dns.Msg) *dns.Msg {
// TODO(miek): expensive!
m.Answer = dns.Dedup(m.Answer, nil)
m.Ns = dns.Dedup(m.Ns, nil)
m.Extra = dns.Dedup(m.Extra, nil)
return m
}

View File

@@ -0,0 +1,2 @@
// Package dnsutil contains DNS related helper functions.
package dnsutil

View File

@@ -0,0 +1,82 @@
package dnsutil
import (
"fmt"
"net"
"os"
"github.com/miekg/dns"
)
// ParseHostPortOrFile parses the strings in s, each string can either be a address,
// address:port or a filename. The address part is checked and the filename case a
// resolv.conf like file is parsed and the nameserver found are returned.
func ParseHostPortOrFile(s ...string) ([]string, error) {
var servers []string
for _, host := range s {
addr, _, err := net.SplitHostPort(host)
if err != nil {
// Parse didn't work, it is not a addr:port combo
if net.ParseIP(host) == nil {
// Not an IP address.
ss, err := tryFile(host)
if err == nil {
servers = append(servers, ss...)
continue
}
return servers, fmt.Errorf("not an IP address or file: %q", host)
}
ss := net.JoinHostPort(host, "53")
servers = append(servers, ss)
continue
}
if net.ParseIP(addr) == nil {
// No an IP address.
ss, err := tryFile(host)
if err == nil {
servers = append(servers, ss...)
continue
}
return servers, fmt.Errorf("not an IP address or file: %q", host)
}
servers = append(servers, host)
}
return servers, nil
}
// Try to open this is a file first.
func tryFile(s string) ([]string, error) {
c, err := dns.ClientConfigFromFile(s)
if err == os.ErrNotExist {
return nil, fmt.Errorf("failed to open file %q: %q", s, err)
} else if err != nil {
return nil, err
}
servers := []string{}
for _, s := range c.Servers {
servers = append(servers, net.JoinHostPort(s, c.Port))
}
return servers, nil
}
// ParseHostPort will check if the host part is a valid IP address, if the
// IP address is valid, but no port is found, defaultPort is added.
func ParseHostPort(s, defaultPort string) (string, error) {
addr, port, err := net.SplitHostPort(s)
if port == "" {
port = defaultPort
}
if err != nil {
if net.ParseIP(s) == nil {
return "", fmt.Errorf("must specify an IP address: `%s'", s)
}
return net.JoinHostPort(s, port), nil
}
if net.ParseIP(addr) == nil {
return "", fmt.Errorf("must specify an IP address: `%s'", addr)
}
return net.JoinHostPort(addr, port), nil
}

View File

@@ -0,0 +1,85 @@
package dnsutil
import (
"io/ioutil"
"os"
"testing"
)
func TestParseHostPortOrFile(t *testing.T) {
tests := []struct {
in string
expected string
shouldErr bool
}{
{
"8.8.8.8",
"8.8.8.8:53",
false,
},
{
"8.8.8.8:153",
"8.8.8.8:153",
false,
},
{
"/etc/resolv.conf:53",
"",
true,
},
{
"resolv.conf",
"127.0.0.1:53",
false,
},
}
err := ioutil.WriteFile("resolv.conf", []byte("nameserver 127.0.0.1\n"), 0600)
if err != nil {
t.Fatalf("Failed to write test resolv.conf")
}
defer os.Remove("resolv.conf")
for i, tc := range tests {
got, err := ParseHostPortOrFile(tc.in)
if err == nil && tc.shouldErr {
t.Errorf("Test %d, expected error, got nil", i)
continue
}
if err != nil && tc.shouldErr {
continue
}
if got[0] != tc.expected {
t.Errorf("Test %d, expected %q, got %q", i, tc.expected, got[0])
}
}
}
func TestParseHostPort(t *testing.T) {
tests := []struct {
in string
expected string
shouldErr bool
}{
{"8.8.8.8:53", "8.8.8.8:53", false},
{"a.a.a.a:153", "", true},
{"8.8.8.8", "8.8.8.8:53", false},
{"8.8.8.8:", "8.8.8.8:53", false},
{"8.8.8.8::53", "", true},
{"resolv.conf", "", true},
}
for i, tc := range tests {
got, err := ParseHostPort(tc.in, "53")
if err == nil && tc.shouldErr {
t.Errorf("Test %d, expected error, got nil", i)
continue
}
if err != nil && !tc.shouldErr {
t.Errorf("Test %d, expected no error, got %q", i, err)
}
if got != tc.expected {
t.Errorf("Test %d, expected %q, got %q", i, tc.expected, got)
}
}
}

View File

@@ -0,0 +1,19 @@
package dnsutil
import (
"strings"
"github.com/miekg/dns"
)
// Join joins labels to form a fully qualified domain name. If the last label is
// the root label it is ignored. Not other syntax checks are performed.
func Join(labels []string) string {
ll := len(labels)
if labels[ll-1] == "." {
s := strings.Join(labels[:ll-1], ".")
return dns.Fqdn(s)
}
s := strings.Join(labels, ".")
return dns.Fqdn(s)
}

View File

@@ -0,0 +1,20 @@
package dnsutil
import "testing"
func TestJoin(t *testing.T) {
tests := []struct {
in []string
out string
}{
{[]string{"bla", "bliep", "example", "org"}, "bla.bliep.example.org."},
{[]string{"example", "."}, "example."},
{[]string{"."}, "."},
}
for i, tc := range tests {
if x := Join(tc.in); x != tc.out {
t.Errorf("Test %d, expected %s, got %s", i, tc.out, x)
}
}
}

View File

@@ -0,0 +1,68 @@
package dnsutil
import (
"net"
"strings"
)
// ExtractAddressFromReverse turns a standard PTR reverse record name
// 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.
func ExtractAddressFromReverse(reverseName string) string {
search := ""
f := reverse
switch {
case strings.HasSuffix(reverseName, v4arpaSuffix):
search = strings.TrimSuffix(reverseName, v4arpaSuffix)
case strings.HasSuffix(reverseName, v6arpaSuffix):
search = strings.TrimSuffix(reverseName, v6arpaSuffix)
f = reverse6
default:
return ""
}
// Reverse the segments and then combine them.
return f(strings.Split(search, "."))
}
func reverse(slice []string) string {
for i := 0; i < len(slice)/2; i++ {
j := len(slice) - i - 1
slice[i], slice[j] = slice[j], slice[i]
}
ip := net.ParseIP(strings.Join(slice, ".")).To4()
if ip == nil {
return ""
}
return ip.String()
}
// reverse6 reverse the segments and combine them according to RFC3596:
// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2
// is reversed to 2001:db8::567:89ab
func reverse6(slice []string) string {
for i := 0; i < len(slice)/2; i++ {
j := len(slice) - i - 1
slice[i], slice[j] = slice[j], slice[i]
}
slice6 := []string{}
for i := 0; i < len(slice)/4; i++ {
slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], ""))
}
ip := net.ParseIP(strings.Join(slice6, ":")).To16()
if ip == nil {
return ""
}
return ip.String()
}
const (
// v4arpaSuffix is the reverse tree suffix for v4 IP addresses.
v4arpaSuffix = ".in-addr.arpa."
// v6arpaSuffix is the reverse tree suffix for v6 IP addresses.
v6arpaSuffix = ".ip6.arpa."
)

View File

@@ -0,0 +1,51 @@
package dnsutil
import (
"testing"
)
func TestExtractAddressFromReverse(t *testing.T) {
tests := []struct {
reverseName string
expectedAddress string
}{
{
"54.119.58.176.in-addr.arpa.",
"176.58.119.54",
},
{
".58.176.in-addr.arpa.",
"",
},
{
"b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.in-addr.arpa.",
"",
},
{
"b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
"2001:db8::567:89ab",
},
{
"d.0.1.0.0.2.ip6.arpa.",
"",
},
{
"54.119.58.176.ip6.arpa.",
"",
},
{
"NONAME",
"",
},
{
"",
"",
},
}
for i, test := range tests {
got := ExtractAddressFromReverse(test.reverseName)
if got != test.expectedAddress {
t.Errorf("Test %d, expected '%s', got '%s'", i, test.expectedAddress, got)
}
}
}

View File

@@ -0,0 +1,20 @@
package dnsutil
import (
"errors"
"github.com/miekg/dns"
)
// TrimZone removes the zone component from q. It returns the trimmed
// name or an error is zone is longer then qname. The trimmed name will be returned
// without a trailing dot.
func TrimZone(q string, z string) (string, error) {
zl := dns.CountLabel(z)
i, ok := dns.PrevLabel(q, zl)
if ok || i-1 < 0 {
return "", errors.New("trimzone: overshot qname: " + q + "for zone " + z)
}
// This includes the '.', remove on return
return q[:i-1], nil
}

View File

@@ -0,0 +1,39 @@
package dnsutil
import (
"errors"
"testing"
"github.com/miekg/dns"
)
func TestTrimZone(t *testing.T) {
tests := []struct {
qname string
zone string
expected string
err error
}{
{"a.example.org", "example.org", "a", nil},
{"a.b.example.org", "example.org", "a.b", nil},
{"b.", ".", "b", nil},
{"example.org", "example.org", "", errors.New("should err")},
{"org", "example.org", "", errors.New("should err")},
}
for i, tc := range tests {
got, err := TrimZone(dns.Fqdn(tc.qname), dns.Fqdn(tc.zone))
if tc.err != nil && err == nil {
t.Errorf("Test %d, expected error got nil", i)
continue
}
if tc.err == nil && err != nil {
t.Errorf("Test %d, expected no error got %v", i, err)
continue
}
if got != tc.expected {
t.Errorf("Test %d, expected %s, got %s", i, tc.expected, got)
continue
}
}
}