Просмотр исходного кода

wgengine: take in dns.Config, split out to resolver.Config and dns.OSConfig.

Stepping stone towards having the DNS package handle the config splitting.

Signed-off-by: David Anderson <[email protected]>
David Anderson 5 лет назад
Родитель
Сommit
6ad44f9fdf

+ 27 - 21
ipn/ipnlocal/local.go

@@ -1442,35 +1442,41 @@ func (b *LocalBackend) authReconfig() {
 
 	rcfg := routerConfig(cfg, uc)
 
-	// If CorpDNS is false, rcfg.DNS remains the zero value.
+	var dcfg dns.Config
+
+	// If CorpDNS is false, dcfg remains the zero value.
 	if uc.CorpDNS {
 		proxied := nm.DNS.Proxied
 		if proxied && len(nm.DNS.Nameservers) == 0 {
 			b.logf("[unexpected] dns proxied but no nameservers")
 			proxied = false
 		}
-		rcfg.DNS = dns.OSConfig{
-			Nameservers: nm.DNS.Nameservers,
-			Domains:     nm.DNS.Domains,
-			Proxied:     proxied,
-		}
-	}
-
-	nameToIP := make(map[string][]netaddr.IP)
-	set := func(name string, addrs []netaddr.IPPrefix) {
-		if len(addrs) == 0 || name == "" {
-			return
+		for _, ip := range nm.DNS.Nameservers {
+			dcfg.DefaultResolvers = append(dcfg.DefaultResolvers, netaddr.IPPort{
+				IP:   ip,
+				Port: 53,
+			})
+		}
+		dcfg.SearchDomains = nm.DNS.Domains
+		dcfg.AuthoritativeSuffixes = magicDNSRootDomains(nm)
+		set := func(name string, addrs []netaddr.IPPrefix) {
+			if len(addrs) == 0 || name == "" {
+				return
+			}
+			var ips []netaddr.IP
+			for _, addr := range addrs {
+				ips = append(ips, addr.IP)
+			}
+			dcfg.Hosts[name] = ips
 		}
-		for _, addr := range addrs {
-			nameToIP[name] = append(nameToIP[name], addr.IP)
+		dcfg.Hosts = map[string][]netaddr.IP{}
+		set(nm.Name, nm.Addresses)
+		for _, peer := range nm.Peers {
+			set(peer.Name, peer.Addresses)
 		}
 	}
-	for _, peer := range nm.Peers {
-		set(peer.Name, peer.Addresses)
-	}
-	set(nm.Name, nm.Addresses)
 
-	err = b.e.Reconfig(cfg, rcfg, nameToIP, magicDNSRootDomains(nm))
+	err = b.e.Reconfig(cfg, rcfg, &dcfg)
 	if err == wgengine.ErrNoChanges {
 		return
 	}
@@ -1725,7 +1731,7 @@ func (b *LocalBackend) enterState(newState ipn.State) {
 		b.blockEngineUpdates(true)
 		fallthrough
 	case ipn.Stopped:
-		err := b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, nil, nil)
+		err := b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{})
 		if err != nil {
 			b.logf("Reconfig(down): %v", err)
 		}
@@ -1817,7 +1823,7 @@ func (b *LocalBackend) stateMachine() {
 // a status update that predates the "I've shut down" update.
 func (b *LocalBackend) stopEngineAndWait() {
 	b.logf("stopEngineAndWait...")
-	b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, nil, nil)
+	b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{})
 	b.requestEngineStatusAndWait()
 	b.logf("stopEngineAndWait: done.")
 }

+ 0 - 7
net/dns/config.go

@@ -42,18 +42,11 @@ type OSConfig struct {
 	Nameservers []netaddr.IP
 	// Domains are the search domains to use.
 	Domains []string
-	// Proxied indicates whether DNS requests are proxied through a dns.Resolver.
-	// This enables MagicDNS.
-	Proxied bool
 }
 
 // Equal determines whether its argument and receiver
 // represent equivalent DNS configurations (then DNS reconfig is a no-op).
 func (lhs OSConfig) Equal(rhs OSConfig) bool {
-	if lhs.Proxied != rhs.Proxied {
-		return false
-	}
-
 	if len(lhs.Nameservers) != len(rhs.Nameservers) {
 		return false
 	}

+ 1 - 0
wgengine/router/router.go

@@ -58,6 +58,7 @@ type Config struct {
 	// this node has chosen to use.
 	Routes []netaddr.IPPrefix
 
+	// Set internally by wgengine, must not be set elsewhere.
 	DNS dns.OSConfig
 
 	// Linux-only things below, ignored on other platforms.

+ 24 - 14
wgengine/userspace.go

@@ -29,6 +29,7 @@ import (
 	"tailscale.com/health"
 	"tailscale.com/internal/deepprint"
 	"tailscale.com/ipn/ipnstate"
+	"tailscale.com/net/dns"
 	"tailscale.com/net/dns/resolver"
 	"tailscale.com/net/flowtrack"
 	"tailscale.com/net/interfaces"
@@ -912,10 +913,13 @@ func genLocalAddrFunc(addrs []netaddr.IPPrefix) func(netaddr.IP) bool {
 	return func(t netaddr.IP) bool { return m[t] }
 }
 
-func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, hosts map[string][]netaddr.IP, localDomains []string) error {
+func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *dns.Config) error {
 	if routerCfg == nil {
 		panic("routerCfg must not be nil")
 	}
+	if dnsCfg == nil {
+		panic("dnsCfg must not be nil")
+	}
 
 	e.isLocalAddr.Store(genLocalAddrFunc(routerCfg.LocalAddrs))
 
@@ -932,7 +936,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
 	e.mu.Unlock()
 
 	engineChanged := deepprint.UpdateHash(&e.lastEngineSigFull, cfg)
-	routerChanged := deepprint.UpdateHash(&e.lastRouterSig, routerCfg, hosts, localDomains)
+	routerChanged := deepprint.UpdateHash(&e.lastRouterSig, routerCfg, dnsCfg)
 	if !engineChanged && !routerChanged {
 		return ErrNoChanges
 	}
@@ -979,22 +983,28 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
 
 	if routerChanged {
 		resolverCfg := resolver.Config{
-			Hosts:        hosts,
-			LocalDomains: localDomains,
+			Hosts:        dnsCfg.Hosts,
+			LocalDomains: dnsCfg.AuthoritativeSuffixes,
 			Routes:       map[string][]netaddr.IPPort{},
 		}
-		if routerCfg.DNS.Proxied {
-			ips := routerCfg.DNS.Nameservers
-			upstreams := make([]netaddr.IPPort, len(ips))
-			for i, ip := range ips {
-				upstreams[i] = netaddr.IPPort{
-					IP:   ip,
-					Port: 53,
-				}
-			}
-			resolverCfg.Routes["."] = upstreams
+		// We must proxy through quad-100 if MagicDNS hosts are in
+		// use, or there are any per-domain routes.
+		mustProxy := len(dnsCfg.Hosts) > 0 || len(dnsCfg.Routes) > 0
+		routerCfg.DNS = dns.OSConfig{
+			Domains: dnsCfg.SearchDomains,
+		}
+		if mustProxy {
 			routerCfg.DNS.Nameservers = []netaddr.IP{tsaddr.TailscaleServiceIP()}
+			resolverCfg.Routes["."] = dnsCfg.DefaultResolvers
+			for suffix, resolvers := range dnsCfg.Routes {
+				resolverCfg.Routes[suffix] = resolvers
+			}
+		} else {
+			for _, resolver := range dnsCfg.DefaultResolvers {
+				routerCfg.DNS.Nameservers = append(routerCfg.DNS.Nameservers, resolver.IP)
+			}
 		}
+		routerCfg.DNS.Domains = dnsCfg.SearchDomains
 		e.resolver.SetConfig(resolverCfg) // TODO: check error and propagate to health pkg
 		e.logf("wgengine: Reconfig: configuring router")
 		err := e.router.Set(routerCfg)

+ 2 - 1
wgengine/userspace_test.go

@@ -13,6 +13,7 @@ import (
 
 	"go4.org/mem"
 	"inet.af/netaddr"
+	"tailscale.com/net/dns"
 	"tailscale.com/net/tstun"
 	"tailscale.com/tailcfg"
 	"tailscale.com/types/key"
@@ -108,7 +109,7 @@ func TestUserspaceEngineReconfig(t *testing.T) {
 			},
 		}
 
-		err = e.Reconfig(cfg, routerCfg, nil, nil)
+		err = e.Reconfig(cfg, routerCfg, &dns.Config{})
 		if err != nil {
 			t.Fatal(err)
 		}

+ 3 - 2
wgengine/watchdog.go

@@ -14,6 +14,7 @@ import (
 
 	"inet.af/netaddr"
 	"tailscale.com/ipn/ipnstate"
+	"tailscale.com/net/dns"
 	"tailscale.com/net/tstun"
 	"tailscale.com/tailcfg"
 	"tailscale.com/types/netmap"
@@ -73,8 +74,8 @@ func (e *watchdogEngine) watchdog(name string, fn func()) {
 	})
 }
 
-func (e *watchdogEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, hosts map[string][]netaddr.IP, localDomains []string) error {
-	return e.watchdogErr("Reconfig", func() error { return e.wrap.Reconfig(cfg, routerCfg, hosts, localDomains) })
+func (e *watchdogEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *dns.Config) error {
+	return e.watchdogErr("Reconfig", func() error { return e.wrap.Reconfig(cfg, routerCfg, dnsCfg) })
 }
 func (e *watchdogEngine) GetLinkMonitor() *monitor.Mon {
 	return e.wrap.GetLinkMonitor()

+ 2 - 1
wgengine/wgengine.go

@@ -9,6 +9,7 @@ import (
 
 	"inet.af/netaddr"
 	"tailscale.com/ipn/ipnstate"
+	"tailscale.com/net/dns"
 	"tailscale.com/tailcfg"
 	"tailscale.com/types/netmap"
 	"tailscale.com/wgengine/filter"
@@ -56,7 +57,7 @@ type Engine interface {
 	// sends an updated network map.
 	//
 	// The returned error is ErrNoChanges if no changes were made.
-	Reconfig(*wgcfg.Config, *router.Config, map[string][]netaddr.IP, []string) error
+	Reconfig(*wgcfg.Config, *router.Config, *dns.Config) error
 
 	// GetFilter returns the current packet filter, if any.
 	GetFilter() *filter.Filter