Cleanup ParseHostOrFile (#2100)

Create plugin/pkg/transport that holds the transport related functions.
This needed to be a new pkg to prevent cyclic import errors.

This cleans up a bunch of duplicated code in core/dnsserver that also
tried to parse a transport (now all done in transport.Parse).

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2018-09-19 07:29:37 +01:00
committed by GitHub
parent 2f1223c36a
commit c349446a23
24 changed files with 182 additions and 221 deletions

View File

@@ -5,15 +5,21 @@ import (
"net"
"os"
"github.com/coredns/coredns/plugin/pkg/transport"
"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.
// ParseHostPortOrFile parses the strings in s, each string can either be a
// address, [scheme://]address:port or a filename. The address part is checked
// and in case of filename a resolv.conf like file is (assumed) and parsed and
// the nameservers found are returned.
func ParseHostPortOrFile(s ...string) ([]string, error) {
var servers []string
for _, host := range s {
for _, h := range s {
trans, host := transport.Parse(h)
addr, _, err := net.SplitHostPort(host)
if err != nil {
// Parse didn't work, it is not a addr:port combo
@@ -26,13 +32,23 @@ func ParseHostPortOrFile(s ...string) ([]string, error) {
}
return servers, fmt.Errorf("not an IP address or file: %q", host)
}
ss := net.JoinHostPort(host, "53")
var ss string
switch trans {
case transport.DNS:
ss = net.JoinHostPort(host, "53")
case transport.TLS:
ss = transport.TLS + "://" + net.JoinHostPort(host, transport.TLSPort)
case transport.GRPC:
ss = transport.GRPC + "://" + net.JoinHostPort(host, transport.GRPCPort)
case transport.HTTPS:
ss = transport.HTTPS + "://" + net.JoinHostPort(host, transport.HTTPSPort)
}
servers = append(servers, ss)
continue
}
if net.ParseIP(addr) == nil {
// No an IP address.
// Not an IP address.
ss, err := tryFile(host)
if err == nil {
servers = append(servers, ss...)
@@ -40,7 +56,7 @@ func ParseHostPortOrFile(s ...string) ([]string, error) {
}
return servers, fmt.Errorf("not an IP address or file: %q", host)
}
servers = append(servers, host)
servers = append(servers, h)
}
return servers, nil
}

View File

@@ -0,0 +1,49 @@
package transport
import (
"strings"
)
// Parse returns the transport defined in s and a string where the
// transport prefix is removed (if there was any). If no transport is defined
// we default to TransportDNS
func Parse(s string) (transport string, addr string) {
switch {
case strings.HasPrefix(s, TLS+"://"):
s = s[len(TLS+"://"):]
return TLS, s
case strings.HasPrefix(s, DNS+"://"):
s = s[len(DNS+"://"):]
return DNS, s
case strings.HasPrefix(s, GRPC+"://"):
s = s[len(GRPC+"://"):]
return GRPC, s
case strings.HasPrefix(s, HTTPS+"://"):
s = s[len(HTTPS+"://"):]
return HTTPS, s
}
return DNS, s
}
// Supported transports.
const (
DNS = "dns"
TLS = "tls"
GRPC = "grpc"
HTTPS = "https"
)
// Port numbers for the various protocols
const (
// TLSPort is the default port for DNS-over-TLS.
TLSPort = "853"
// GRPCPort is the default port for DNS-over-gRPC.
GRPCPort = "443"
// HTTPSPort is the default port for DNS-over-HTTPS.
HTTPSPort = "443"
)

View File

@@ -0,0 +1,21 @@
package transport
import "testing"
func TestParse(t *testing.T) {
for i, test := range []struct {
input string
expected string
}{
{"dns://.:53", DNS},
{"2003::1/64.:53", DNS},
{"grpc://example.org:1443 ", GRPC},
{"tls://example.org ", TLS},
{"https://example.org ", HTTPS},
} {
actual, _ := Parse(test.input)
if actual != test.expected {
t.Errorf("Test %d: Expected %s but got %s", i, test.expected, actual)
}
}
}