From fe50cd0c48442637918b07a44e77d84951125306 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 25 Jun 2020 11:04:52 -0700 Subject: [PATCH] ipn, wgengine: plumb NetworkMap down to magicsock Now we can have magicsock make decisions based on tailcfg.Debug settings sent by the server. Signed-off-by: Brad Fitzpatrick --- ipn/local.go | 1 + wgengine/magicsock/magicsock.go | 21 +++++++++++++++++++++ wgengine/userspace.go | 5 +++++ wgengine/watchdog.go | 4 ++++ wgengine/wgengine.go | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/ipn/local.go b/ipn/local.go index b682f261a..a940ca4ce 100644 --- a/ipn/local.go +++ b/ipn/local.go @@ -230,6 +230,7 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) { if changed { b.updateFilter(st.NetMap) b.updateDNSMap(st.NetMap) + b.e.SetNetworkMap(st.NetMap) } if disableDERP { b.e.SetDERPMap(nil) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 5aba3bbbd..792dc00ab 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -30,6 +30,7 @@ import ( "github.com/tailscale/wireguard-go/wgcfg" "golang.org/x/time/rate" "inet.af/netaddr" + "tailscale.com/control/controlclient" "tailscale.com/derp" "tailscale.com/derp/derphttp" "tailscale.com/ipn/ipnstate" @@ -107,6 +108,7 @@ type Conn struct { netInfoLast *tailcfg.NetInfo derpMap *tailcfg.DERPMap // nil (or zero regions/nodes) means DERP is disabled + netMap *controlclient.NetworkMap privateKey key.Private myDerp int // nearest DERP region ID; 0 means none/unknown derpStarted chan struct{} // closed on first connection to DERP; for tests @@ -1347,6 +1349,25 @@ func (c *Conn) SetDERPMap(dm *tailcfg.DERPMap) { go c.ReSTUN("derp-map-update") } +// SetNetworkMap is called when the control client gets a new network +// map from the control server. +// +// It should not use the DERPMap field of NetworkMap; that's +// conditionally sent to SetDERPMap instead. +func (c *Conn) SetNetworkMap(nm *controlclient.NetworkMap) { + c.mu.Lock() + defer c.mu.Unlock() + + if reflect.DeepEqual(nm, c.netMap) { + return + } + c.logf("magicsock: got updated network map") + + c.netMap = nm + // TODO: look at Debug fields + // TODO: look at DiscoKey fields to reset AddrSet states when node restarts +} + func (c *Conn) wantDerpLocked() bool { return c.derpMap != nil } // c.mu must be held. diff --git a/wgengine/userspace.go b/wgengine/userspace.go index c3b8b93f5..985605a0d 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -25,6 +25,7 @@ import ( "github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/wgcfg" "go4.org/mem" + "tailscale.com/control/controlclient" "tailscale.com/ipn/ipnstate" "tailscale.com/net/interfaces" "tailscale.com/tailcfg" @@ -830,6 +831,10 @@ func (e *userspaceEngine) SetDERPMap(dm *tailcfg.DERPMap) { e.magicConn.SetDERPMap(dm) } +func (e *userspaceEngine) SetNetworkMap(nm *controlclient.NetworkMap) { + e.magicConn.SetNetworkMap(nm) +} + func (e *userspaceEngine) SetDiscoPrivateKey(k key.Private) { e.magicConn.SetDiscoPrivateKey(k) } diff --git a/wgengine/watchdog.go b/wgengine/watchdog.go index 06e07a134..4e39d83bf 100644 --- a/wgengine/watchdog.go +++ b/wgengine/watchdog.go @@ -11,6 +11,7 @@ import ( "time" "github.com/tailscale/wireguard-go/wgcfg" + "tailscale.com/control/controlclient" "tailscale.com/ipn/ipnstate" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -97,6 +98,9 @@ func (e *watchdogEngine) LinkChange(isExpensive bool) { func (e *watchdogEngine) SetDERPMap(m *tailcfg.DERPMap) { e.watchdog("SetDERPMap", func() { e.wrap.SetDERPMap(m) }) } +func (e *watchdogEngine) SetNetworkMap(nm *controlclient.NetworkMap) { + e.watchdog("SetNetworkMap", func() { e.wrap.SetNetworkMap(nm) }) +} func (e *watchdogEngine) SetDiscoPrivateKey(k key.Private) { e.watchdog("SetDiscoPrivateKey", func() { e.wrap.SetDiscoPrivateKey(k) }) } diff --git a/wgengine/wgengine.go b/wgengine/wgengine.go index b245a77f1..8a1aaa833 100644 --- a/wgengine/wgengine.go +++ b/wgengine/wgengine.go @@ -9,6 +9,7 @@ import ( "time" "github.com/tailscale/wireguard-go/wgcfg" + "tailscale.com/control/controlclient" "tailscale.com/ipn/ipnstate" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -105,6 +106,13 @@ type Engine interface { // is configured. SetDERPMap(*tailcfg.DERPMap) + // SetNetworkMap informs the engine of the latest network map + // from the server. The network map's DERPMap field should be + // ignored as as it might be disabled; get it from SetDERPMap + // instead. + // The network map should only be read from. + SetNetworkMap(*controlclient.NetworkMap) + // SetNetInfoCallback sets the function to call when a // new NetInfo summary is available. SetNetInfoCallback(NetInfoCallback)