Browse Source

types/dnstype: introduce new package for Resolver

So the type can be used in net/dns without introducing a tailcfg
dependency.

For #2596

Signed-off-by: David Crawshaw <[email protected]>
David Crawshaw 4 years ago
parent
commit
360223fccb

+ 1 - 0
cmd/tailscale/depaware.txt

@@ -51,6 +51,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
    W    tailscale.com/tsconst                                        from tailscale.com/net/interfaces
      💣 tailscale.com/tstime/mono                                    from tailscale.com/tstime/rate
         tailscale.com/tstime/rate                                    from tailscale.com/wgengine/filter
+        tailscale.com/types/dnstype                                  from tailscale.com/tailcfg
         tailscale.com/types/empty                                    from tailscale.com/ipn
         tailscale.com/types/ipproto                                  from tailscale.com/net/flowtrack+
         tailscale.com/types/key                                      from tailscale.com/derp+

+ 1 - 0
cmd/tailscaled/depaware.txt

@@ -139,6 +139,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         tailscale.com/tstime                                         from tailscale.com/wgengine/magicsock
      💣 tailscale.com/tstime/mono                                    from tailscale.com/net/tstun+
         tailscale.com/tstime/rate                                    from tailscale.com/wgengine/filter
+        tailscale.com/types/dnstype                                  from tailscale.com/ipn/ipnlocal+
         tailscale.com/types/empty                                    from tailscale.com/control/controlclient+
         tailscale.com/types/flagtype                                 from tailscale.com/cmd/tailscaled
         tailscale.com/types/ipproto                                  from tailscale.com/net/flowtrack+

+ 3 - 2
ipn/ipnlocal/local.go

@@ -38,6 +38,7 @@ import (
 	"tailscale.com/paths"
 	"tailscale.com/portlist"
 	"tailscale.com/tailcfg"
+	"tailscale.com/types/dnstype"
 	"tailscale.com/types/empty"
 	"tailscale.com/types/key"
 	"tailscale.com/types/logger"
@@ -1820,7 +1821,7 @@ func (b *LocalBackend) authReconfig() {
 	}
 
 	if uc.CorpDNS {
-		addDefault := func(resolvers []tailcfg.DNSResolver) {
+		addDefault := func(resolvers []dnstype.Resolver) {
 			for _, resolver := range resolvers {
 				res, err := parseResolver(resolver)
 				if err != nil {
@@ -1896,7 +1897,7 @@ func (b *LocalBackend) authReconfig() {
 	b.initPeerAPIListener()
 }
 
-func parseResolver(cfg tailcfg.DNSResolver) (netaddr.IPPort, error) {
+func parseResolver(cfg dnstype.Resolver) (netaddr.IPPort, error) {
 	ip, err := netaddr.ParseIP(cfg.Addr)
 	if err != nil {
 		return netaddr.IPPort{}, fmt.Errorf("[unexpected] non-IP resolver %q", cfg.Addr)

+ 5 - 21
tailcfg/tailcfg.go

@@ -4,7 +4,7 @@
 
 package tailcfg
 
-//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode --clonefunc=true --output=tailcfg_clone.go
+//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode --clonefunc=true --output=tailcfg_clone.go
 
 import (
 	"encoding/hex"
@@ -16,6 +16,7 @@ import (
 
 	"go4.org/mem"
 	"inet.af/netaddr"
+	"tailscale.com/types/dnstype"
 	"tailscale.com/types/key"
 	"tailscale.com/types/opt"
 	"tailscale.com/types/structs"
@@ -832,38 +833,21 @@ var FilterAllowAll = []FilterRule{
 	},
 }
 
-// DNSResolver is the configuration for one DNS resolver.
-type DNSResolver struct {
-	// Addr is the address of the DNS resolver, one of:
-	//  - A plain IP address for a "classic" UDP+TCP DNS resolver
-	//  - [TODO] "tls://resolver.com" for DNS over TCP+TLS
-	//  - [TODO] "https://resolver.com/query-tmpl" for DNS over HTTPS
-	Addr string `json:",omitempty"`
-
-	// BootstrapResolution is an optional suggested resolution for the
-	// DoT/DoH resolver, if the resolver URL does not reference an IP
-	// address directly.
-	// BootstrapResolution may be empty, in which case clients should
-	// look up the DoT/DoH server using their local "classic" DNS
-	// resolver.
-	BootstrapResolution []netaddr.IP `json:",omitempty"`
-}
-
 // DNSConfig is the DNS configuration.
 type DNSConfig struct {
 	// Resolvers are the DNS resolvers to use, in order of preference.
-	Resolvers []DNSResolver `json:",omitempty"`
+	Resolvers []dnstype.Resolver `json:",omitempty"`
 	// Routes maps DNS name suffixes to a set of DNS resolvers to
 	// use. It is used to implement "split DNS" and other advanced DNS
 	// routing overlays.
 	// Map keys must be fully-qualified DNS name suffixes, with a
 	// trailing dot but no leading dot.
-	Routes map[string][]DNSResolver `json:",omitempty"`
+	Routes map[string][]dnstype.Resolver `json:",omitempty"`
 	// FallbackResolvers is like Resolvers, but is only used if a
 	// split DNS configuration is requested in a configuration that
 	// doesn't work yet without explicit default resolvers.
 	// https://github.com/tailscale/tailscale/issues/1743
-	FallbackResolvers []DNSResolver `json:",omitempty"`
+	FallbackResolvers []dnstype.Resolver `json:",omitempty"`
 	// Domains are the search domains to use.
 	// Search domains must be FQDNs, but *without* the trailing dot.
 	Domains []string `json:",omitempty"`

+ 20 - 47
tailcfg/tailcfg_clone.go

@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode; DO NOT EDIT.
+// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode; DO NOT EDIT.
 
 package tailcfg
 
 import (
 	"inet.af/netaddr"
+	"tailscale.com/types/dnstype"
 	"tailscale.com/types/opt"
 	"tailscale.com/types/structs"
 	"time"
@@ -26,7 +27,7 @@ func (src *User) Clone() *User {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _UserNeedsRegeneration = User(struct {
 	ID            UserID
 	LoginName     string
@@ -63,7 +64,7 @@ func (src *Node) Clone() *Node {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _NodeNeedsRegeneration = Node(struct {
 	ID                      NodeID
 	StableID                StableNodeID
@@ -107,7 +108,7 @@ func (src *Hostinfo) Clone() *Hostinfo {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _HostinfoNeedsRegeneration = Hostinfo(struct {
 	IPNVersion    string
 	FrontendLogID string
@@ -144,7 +145,7 @@ func (src *NetInfo) Clone() *NetInfo {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _NetInfoNeedsRegeneration = NetInfo(struct {
 	MappingVariesByDestIP opt.Bool
 	HairPinning           opt.Bool
@@ -171,7 +172,7 @@ func (src *Login) Clone() *Login {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _LoginNeedsRegeneration = Login(struct {
 	_             structs.Incomparable
 	ID            LoginID
@@ -190,17 +191,17 @@ func (src *DNSConfig) Clone() *DNSConfig {
 	}
 	dst := new(DNSConfig)
 	*dst = *src
-	dst.Resolvers = make([]DNSResolver, len(src.Resolvers))
+	dst.Resolvers = make([]dnstype.Resolver, len(src.Resolvers))
 	for i := range dst.Resolvers {
 		dst.Resolvers[i] = *src.Resolvers[i].Clone()
 	}
 	if dst.Routes != nil {
-		dst.Routes = map[string][]DNSResolver{}
+		dst.Routes = map[string][]dnstype.Resolver{}
 		for k := range src.Routes {
-			dst.Routes[k] = append([]DNSResolver{}, src.Routes[k]...)
+			dst.Routes[k] = append([]dnstype.Resolver{}, src.Routes[k]...)
 		}
 	}
-	dst.FallbackResolvers = make([]DNSResolver, len(src.FallbackResolvers))
+	dst.FallbackResolvers = make([]dnstype.Resolver, len(src.FallbackResolvers))
 	for i := range dst.FallbackResolvers {
 		dst.FallbackResolvers[i] = *src.FallbackResolvers[i].Clone()
 	}
@@ -212,11 +213,11 @@ func (src *DNSConfig) Clone() *DNSConfig {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _DNSConfigNeedsRegeneration = DNSConfig(struct {
-	Resolvers         []DNSResolver
-	Routes            map[string][]DNSResolver
-	FallbackResolvers []DNSResolver
+	Resolvers         []dnstype.Resolver
+	Routes            map[string][]dnstype.Resolver
+	FallbackResolvers []dnstype.Resolver
 	Domains           []string
 	Proxied           bool
 	Nameservers       []netaddr.IP
@@ -225,25 +226,6 @@ var _DNSConfigNeedsRegeneration = DNSConfig(struct {
 	ExtraRecords      []DNSRecord
 }{})
 
-// Clone makes a deep copy of DNSResolver.
-// The result aliases no memory with the original.
-func (src *DNSResolver) Clone() *DNSResolver {
-	if src == nil {
-		return nil
-	}
-	dst := new(DNSResolver)
-	*dst = *src
-	dst.BootstrapResolution = append(src.BootstrapResolution[:0:0], src.BootstrapResolution...)
-	return dst
-}
-
-// A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
-var _DNSResolverNeedsRegeneration = DNSResolver(struct {
-	Addr                string
-	BootstrapResolution []netaddr.IP
-}{})
-
 // Clone makes a deep copy of RegisterResponse.
 // The result aliases no memory with the original.
 func (src *RegisterResponse) Clone() *RegisterResponse {
@@ -257,7 +239,7 @@ func (src *RegisterResponse) Clone() *RegisterResponse {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _RegisterResponseNeedsRegeneration = RegisterResponse(struct {
 	User              User
 	Login             Login
@@ -282,7 +264,7 @@ func (src *DERPRegion) Clone() *DERPRegion {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _DERPRegionNeedsRegeneration = DERPRegion(struct {
 	RegionID   int
 	RegionCode string
@@ -309,7 +291,7 @@ func (src *DERPMap) Clone() *DERPMap {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _DERPMapNeedsRegeneration = DERPMap(struct {
 	Regions            map[int]*DERPRegion
 	OmitDefaultRegions bool
@@ -327,7 +309,7 @@ func (src *DERPNode) Clone() *DERPNode {
 }
 
 // A compilation failure here means this code must be regenerated, with command:
-//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
+//   tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode
 var _DERPNodeNeedsRegeneration = DERPNode(struct {
 	Name             string
 	RegionID         int
@@ -344,7 +326,7 @@ var _DERPNodeNeedsRegeneration = DERPNode(struct {
 
 // Clone duplicates src into dst and reports whether it succeeded.
 // To succeed, <src, dst> must be of types <*T, *T> or <*T, **T>,
-// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode.
+// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,DERPRegion,DERPMap,DERPNode.
 func Clone(dst, src interface{}) bool {
 	switch src := src.(type) {
 	case *User:
@@ -401,15 +383,6 @@ func Clone(dst, src interface{}) bool {
 			*dst = src.Clone()
 			return true
 		}
-	case *DNSResolver:
-		switch dst := dst.(type) {
-		case *DNSResolver:
-			*dst = *src.Clone()
-			return true
-		case **DNSResolver:
-			*dst = src.Clone()
-			return true
-		}
 	case *RegisterResponse:
 		switch dst := dst.(type) {
 		case *RegisterResponse:

+ 27 - 0
types/dnstype/dnstype.go

@@ -0,0 +1,27 @@
+// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package dnstype defines types for working with DNS.
+package dnstype
+
+//go:generate go run tailscale.com/cmd/cloner --type=Resolver --clonefunc=true --output=dnstype_clone.go
+
+import "inet.af/netaddr"
+
+// Resolver is the configuration for one DNS resolver.
+type Resolver struct {
+	// Addr is the address of the DNS resolver, one of:
+	//  - A plain IP address for a "classic" UDP+TCP DNS resolver
+	//  - [TODO] "tls://resolver.com" for DNS over TCP+TLS
+	//  - [TODO] "https://resolver.com/query-tmpl" for DNS over HTTPS
+	Addr string `json:",omitempty"`
+
+	// BootstrapResolution is an optional suggested resolution for the
+	// DoT/DoH resolver, if the resolver URL does not reference an IP
+	// address directly.
+	// BootstrapResolution may be empty, in which case clients should
+	// look up the DoT/DoH server using their local "classic" DNS
+	// resolver.
+	BootstrapResolution []netaddr.IP `json:",omitempty"`
+}

+ 48 - 0
types/dnstype/dnstype_clone.go

@@ -0,0 +1,48 @@
+// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by tailscale.com/cmd/cloner -type Resolver; DO NOT EDIT.
+
+package dnstype
+
+import (
+	"inet.af/netaddr"
+)
+
+// Clone makes a deep copy of Resolver.
+// The result aliases no memory with the original.
+func (src *Resolver) Clone() *Resolver {
+	if src == nil {
+		return nil
+	}
+	dst := new(Resolver)
+	*dst = *src
+	dst.BootstrapResolution = append(src.BootstrapResolution[:0:0], src.BootstrapResolution...)
+	return dst
+}
+
+// A compilation failure here means this code must be regenerated, with command:
+//   tailscale.com/cmd/cloner -type Resolver
+var _ResolverNeedsRegeneration = Resolver(struct {
+	Addr                string
+	BootstrapResolution []netaddr.IP
+}{})
+
+// Clone duplicates src into dst and reports whether it succeeded.
+// To succeed, <src, dst> must be of types <*T, *T> or <*T, **T>,
+// where T is one of Resolver.
+func Clone(dst, src interface{}) bool {
+	switch src := src.(type) {
+	case *Resolver:
+		switch dst := dst.(type) {
+		case *Resolver:
+			*dst = *src.Clone()
+			return true
+		case **Resolver:
+			*dst = src.Clone()
+			return true
+		}
+	}
+	return false
+}

+ 2 - 1
util/deephash/deephash_test.go

@@ -15,6 +15,7 @@ import (
 
 	"inet.af/netaddr"
 	"tailscale.com/tailcfg"
+	"tailscale.com/types/dnstype"
 	"tailscale.com/types/ipproto"
 	"tailscale.com/util/dnsname"
 	"tailscale.com/version"
@@ -189,7 +190,7 @@ func getVal() []interface{} {
 				},
 			},
 			DNSConfig: &tailcfg.DNSConfig{
-				Resolvers: []tailcfg.DNSResolver{
+				Resolvers: []dnstype.Resolver{
 					{Addr: "10.0.0.1"},
 				},
 			},