package dnsserver import ( "fmt" "net" "strings" "github.com/coredns/coredns/plugin" "github.com/miekg/dns" ) type zoneAddr struct { Zone string Port string Transport string // dns, tls or grpc IPNet *net.IPNet // if reverse zone this hold the IPNet } // String return the string representation of z. func (z zoneAddr) String() string { return z.Transport + "://" + z.Zone + ":" + z.Port } // Transport returns the protocol of the string s func Transport(s string) string { switch { case strings.HasPrefix(s, TransportTLS+"://"): return TransportTLS case strings.HasPrefix(s, TransportDNS+"://"): return TransportDNS case strings.HasPrefix(s, TransportGRPC+"://"): return TransportGRPC } return TransportDNS } // normalizeZone parses an zone string into a structured format with separate // host, and port portions, as well as the original input string. func normalizeZone(str string) (zoneAddr, error) { var err error // Default to DNS if there isn't a transport protocol prefix. trans := TransportDNS switch { case strings.HasPrefix(str, TransportTLS+"://"): trans = TransportTLS str = str[len(TransportTLS+"://"):] case strings.HasPrefix(str, TransportDNS+"://"): trans = TransportDNS str = str[len(TransportDNS+"://"):] case strings.HasPrefix(str, TransportGRPC+"://"): trans = TransportGRPC str = str[len(TransportGRPC+"://"):] } host, port, ipnet, err := plugin.SplitHostPort(str) if err != nil { return zoneAddr{}, err } if port == "" { if trans == TransportDNS { port = Port } if trans == TransportTLS { port = TLSPort } if trans == TransportGRPC { port = GRPCPort } } return zoneAddr{Zone: dns.Fqdn(host), Port: port, Transport: trans, IPNet: ipnet}, nil } // SplitProtocolHostPort - split a full formed address like "dns://[::1}:53" into parts func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) { parts := strings.Split(address, "://") switch len(parts) { case 1: ip, port, err := net.SplitHostPort(parts[0]) return "", ip, port, err case 2: ip, port, err := net.SplitHostPort(parts[1]) return parts[0], ip, port, err default: return "", "", "", fmt.Errorf("provided value is not in an address format : %s", address) } } // Supported transports. const ( TransportDNS = "dns" TransportTLS = "tls" TransportGRPC = "grpc" )