Update dependencies
This commit is contained in:
180
vendor/tailscale.com/control/controlclient/map.go
generated
vendored
180
vendor/tailscale.com/control/controlclient/map.go
generated
vendored
@@ -7,14 +7,12 @@ import (
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -31,6 +29,7 @@ import (
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/mak"
|
||||
"tailscale.com/util/set"
|
||||
"tailscale.com/util/slicesx"
|
||||
"tailscale.com/wgengine/filter"
|
||||
)
|
||||
|
||||
@@ -75,11 +74,10 @@ type mapSession struct {
|
||||
lastPrintMap time.Time
|
||||
lastNode tailcfg.NodeView
|
||||
lastCapSet set.Set[tailcfg.NodeCapability]
|
||||
peers map[tailcfg.NodeID]*tailcfg.NodeView // pointer to view (oddly). same pointers as sortedPeers.
|
||||
sortedPeers []*tailcfg.NodeView // same pointers as peers, but sorted by Node.ID
|
||||
peers map[tailcfg.NodeID]tailcfg.NodeView
|
||||
lastDNSConfig *tailcfg.DNSConfig
|
||||
lastDERPMap *tailcfg.DERPMap
|
||||
lastUserProfile map[tailcfg.UserID]tailcfg.UserProfile
|
||||
lastUserProfile map[tailcfg.UserID]tailcfg.UserProfileView
|
||||
lastPacketFilterRules views.Slice[tailcfg.FilterRule] // concatenation of all namedPacketFilters
|
||||
namedPacketFilters map[string]views.Slice[tailcfg.FilterRule]
|
||||
lastParsedPacketFilter []filter.Match
|
||||
@@ -91,7 +89,6 @@ type mapSession struct {
|
||||
lastPopBrowserURL string
|
||||
lastTKAInfo *tailcfg.TKAInfo
|
||||
lastNetmapSummary string // from NetworkMap.VeryConcise
|
||||
lastMaxExpiry time.Duration
|
||||
}
|
||||
|
||||
// newMapSession returns a mostly unconfigured new mapSession.
|
||||
@@ -106,7 +103,7 @@ func newMapSession(privateNodeKey key.NodePrivate, nu NetmapUpdater, controlKnob
|
||||
privateNodeKey: privateNodeKey,
|
||||
publicNodeKey: privateNodeKey.Public(),
|
||||
lastDNSConfig: new(tailcfg.DNSConfig),
|
||||
lastUserProfile: map[tailcfg.UserID]tailcfg.UserProfile{},
|
||||
lastUserProfile: map[tailcfg.UserID]tailcfg.UserProfileView{},
|
||||
|
||||
// Non-nil no-op defaults, to be optionally overridden by the caller.
|
||||
logf: logger.Discard,
|
||||
@@ -167,6 +164,7 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
|
||||
|
||||
// For responses that mutate the self node, check for updated nodeAttrs.
|
||||
if resp.Node != nil {
|
||||
upgradeNode(resp.Node)
|
||||
if DevKnob.StripCaps() {
|
||||
resp.Node.Capabilities = nil
|
||||
resp.Node.CapMap = nil
|
||||
@@ -182,6 +180,13 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
|
||||
ms.controlKnobs.UpdateFromNodeAttributes(resp.Node.CapMap)
|
||||
}
|
||||
|
||||
for _, p := range resp.Peers {
|
||||
upgradeNode(p)
|
||||
}
|
||||
for _, p := range resp.PeersChanged {
|
||||
upgradeNode(p)
|
||||
}
|
||||
|
||||
// Call Node.InitDisplayNames on any changed nodes.
|
||||
initDisplayNames(cmp.Or(resp.Node.View(), ms.lastNode), resp)
|
||||
|
||||
@@ -217,6 +222,33 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
|
||||
return nil
|
||||
}
|
||||
|
||||
// upgradeNode upgrades Node fields from the server into the modern forms
|
||||
// not using deprecated fields.
|
||||
func upgradeNode(n *tailcfg.Node) {
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
if n.LegacyDERPString != "" {
|
||||
if n.HomeDERP == 0 {
|
||||
ip, portStr, err := net.SplitHostPort(n.LegacyDERPString)
|
||||
if ip == tailcfg.DerpMagicIP && err == nil {
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err == nil {
|
||||
n.HomeDERP = port
|
||||
}
|
||||
}
|
||||
}
|
||||
n.LegacyDERPString = ""
|
||||
}
|
||||
if DevKnob.StripHomeDERP() {
|
||||
n.HomeDERP = 0
|
||||
}
|
||||
|
||||
if n.AllowedIPs == nil {
|
||||
n.AllowedIPs = slices.Clone(n.Addresses)
|
||||
}
|
||||
}
|
||||
|
||||
func (ms *mapSession) tryHandleIncrementally(res *tailcfg.MapResponse) bool {
|
||||
if ms.controlKnobs != nil && ms.controlKnobs.DisableDeltaUpdates.Load() {
|
||||
return false
|
||||
@@ -260,13 +292,22 @@ func (ms *mapSession) updateStateFromResponse(resp *tailcfg.MapResponse) {
|
||||
}
|
||||
|
||||
for _, up := range resp.UserProfiles {
|
||||
ms.lastUserProfile[up.ID] = up
|
||||
ms.lastUserProfile[up.ID] = up.View()
|
||||
}
|
||||
// TODO(bradfitz): clean up old user profiles? maybe not worth it.
|
||||
|
||||
if dm := resp.DERPMap; dm != nil {
|
||||
ms.vlogf("netmap: new map contains DERP map")
|
||||
|
||||
// Guard against the control server accidentally sending
|
||||
// a nil region definition, which at least Headscale was
|
||||
// observed to send.
|
||||
for rid, r := range dm.Regions {
|
||||
if r == nil {
|
||||
delete(dm.Regions, rid)
|
||||
}
|
||||
}
|
||||
|
||||
// Zero-valued fields in a DERPMap mean that we're not changing
|
||||
// anything and are using the previous value(s).
|
||||
if ldm := ms.lastDERPMap; ldm != nil {
|
||||
@@ -345,9 +386,6 @@ func (ms *mapSession) updateStateFromResponse(resp *tailcfg.MapResponse) {
|
||||
if resp.TKAInfo != nil {
|
||||
ms.lastTKAInfo = resp.TKAInfo
|
||||
}
|
||||
if resp.MaxKeyDuration > 0 {
|
||||
ms.lastMaxExpiry = resp.MaxKeyDuration
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -366,16 +404,11 @@ var (
|
||||
patchifiedPeerEqual = clientmetric.NewCounter("controlclient_patchified_peer_equal")
|
||||
)
|
||||
|
||||
// updatePeersStateFromResponseres updates ms.peers and ms.sortedPeers from res. It takes ownership of res.
|
||||
// updatePeersStateFromResponseres updates ms.peers from resp.
|
||||
// It takes ownership of resp.
|
||||
func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (stats updateStats) {
|
||||
defer func() {
|
||||
if stats.removed > 0 || stats.added > 0 {
|
||||
ms.rebuildSorted()
|
||||
}
|
||||
}()
|
||||
|
||||
if ms.peers == nil {
|
||||
ms.peers = make(map[tailcfg.NodeID]*tailcfg.NodeView)
|
||||
ms.peers = make(map[tailcfg.NodeID]tailcfg.NodeView)
|
||||
}
|
||||
|
||||
if len(resp.Peers) > 0 {
|
||||
@@ -384,12 +417,12 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
keep := make(map[tailcfg.NodeID]bool, len(resp.Peers))
|
||||
for _, n := range resp.Peers {
|
||||
keep[n.ID] = true
|
||||
if vp, ok := ms.peers[n.ID]; ok {
|
||||
lenBefore := len(ms.peers)
|
||||
ms.peers[n.ID] = n.View()
|
||||
if len(ms.peers) == lenBefore {
|
||||
stats.changed++
|
||||
*vp = n.View()
|
||||
} else {
|
||||
stats.added++
|
||||
ms.peers[n.ID] = ptr.To(n.View())
|
||||
}
|
||||
}
|
||||
for id := range ms.peers {
|
||||
@@ -410,12 +443,12 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
}
|
||||
|
||||
for _, n := range resp.PeersChanged {
|
||||
if vp, ok := ms.peers[n.ID]; ok {
|
||||
lenBefore := len(ms.peers)
|
||||
ms.peers[n.ID] = n.View()
|
||||
if len(ms.peers) == lenBefore {
|
||||
stats.changed++
|
||||
*vp = n.View()
|
||||
} else {
|
||||
stats.added++
|
||||
ms.peers[n.ID] = ptr.To(n.View())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +460,7 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
} else {
|
||||
mut.LastSeen = nil
|
||||
}
|
||||
*vp = mut.View()
|
||||
ms.peers[nodeID] = mut.View()
|
||||
stats.changed++
|
||||
}
|
||||
}
|
||||
@@ -436,7 +469,7 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
if vp, ok := ms.peers[nodeID]; ok {
|
||||
mut := vp.AsStruct()
|
||||
mut.Online = ptr.To(online)
|
||||
*vp = mut.View()
|
||||
ms.peers[nodeID] = mut.View()
|
||||
stats.changed++
|
||||
}
|
||||
}
|
||||
@@ -449,7 +482,7 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
stats.changed++
|
||||
mut := vp.AsStruct()
|
||||
if pc.DERPRegion != 0 {
|
||||
mut.DERP = fmt.Sprintf("%s:%v", tailcfg.DerpMagicIP, pc.DERPRegion)
|
||||
mut.HomeDERP = pc.DERPRegion
|
||||
patchDERPRegion.Add(1)
|
||||
}
|
||||
if pc.Cap != 0 {
|
||||
@@ -488,31 +521,12 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
mut.CapMap = v
|
||||
patchCapMap.Add(1)
|
||||
}
|
||||
*vp = mut.View()
|
||||
ms.peers[pc.NodeID] = mut.View()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// rebuildSorted rebuilds ms.sortedPeers from ms.peers. It should be called
|
||||
// after any additions or removals from peers.
|
||||
func (ms *mapSession) rebuildSorted() {
|
||||
if ms.sortedPeers == nil {
|
||||
ms.sortedPeers = make([]*tailcfg.NodeView, 0, len(ms.peers))
|
||||
} else {
|
||||
if len(ms.sortedPeers) > len(ms.peers) {
|
||||
clear(ms.sortedPeers[len(ms.peers):])
|
||||
}
|
||||
ms.sortedPeers = ms.sortedPeers[:0]
|
||||
}
|
||||
for _, p := range ms.peers {
|
||||
ms.sortedPeers = append(ms.sortedPeers, p)
|
||||
}
|
||||
sort.Slice(ms.sortedPeers, func(i, j int) bool {
|
||||
return ms.sortedPeers[i].ID() < ms.sortedPeers[j].ID()
|
||||
})
|
||||
}
|
||||
|
||||
func (ms *mapSession) addUserProfile(nm *netmap.NetworkMap, userID tailcfg.UserID) {
|
||||
if userID == 0 {
|
||||
return
|
||||
@@ -576,7 +590,7 @@ func (ms *mapSession) patchifyPeer(n *tailcfg.Node) (_ *tailcfg.PeerChange, ok b
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return peerChangeDiff(*was, n)
|
||||
return peerChangeDiff(was, n)
|
||||
}
|
||||
|
||||
// peerChangeDiff returns the difference from 'was' to 'n', if possible.
|
||||
@@ -656,17 +670,13 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
if !views.SliceEqual(was.Endpoints(), views.SliceOf(n.Endpoints)) {
|
||||
pc().Endpoints = slices.Clone(n.Endpoints)
|
||||
}
|
||||
case "DERP":
|
||||
if was.DERP() != n.DERP {
|
||||
ip, portStr, err := net.SplitHostPort(n.DERP)
|
||||
if err != nil || ip != "127.3.3.40" {
|
||||
return nil, false
|
||||
}
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil || port < 1 || port > 65535 {
|
||||
return nil, false
|
||||
}
|
||||
pc().DERPRegion = port
|
||||
case "LegacyDERPString":
|
||||
if was.LegacyDERPString() != "" || n.LegacyDERPString != "" {
|
||||
panic("unexpected; caller should've already called upgradeNode")
|
||||
}
|
||||
case "HomeDERP":
|
||||
if was.HomeDERP() != n.HomeDERP {
|
||||
pc().DERPRegion = n.HomeDERP
|
||||
}
|
||||
case "Hostinfo":
|
||||
if !was.Hostinfo().Valid() && !n.Hostinfo.Valid() {
|
||||
@@ -688,21 +698,23 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
}
|
||||
case "CapMap":
|
||||
if len(n.CapMap) != was.CapMap().Len() {
|
||||
// If they have different lengths, they're different.
|
||||
if n.CapMap == nil {
|
||||
pc().CapMap = make(tailcfg.NodeCapMap)
|
||||
} else {
|
||||
pc().CapMap = maps.Clone(n.CapMap)
|
||||
}
|
||||
break
|
||||
}
|
||||
was.CapMap().Range(func(k tailcfg.NodeCapability, v views.Slice[tailcfg.RawMessage]) bool {
|
||||
nv, ok := n.CapMap[k]
|
||||
if !ok || !views.SliceEqual(v, views.SliceOf(nv)) {
|
||||
pc().CapMap = maps.Clone(n.CapMap)
|
||||
return false
|
||||
} else {
|
||||
// If they have the same length, check that all their keys
|
||||
// have the same values.
|
||||
for k, v := range was.CapMap().All() {
|
||||
nv, ok := n.CapMap[k]
|
||||
if !ok || !views.SliceEqual(v, views.SliceOf(nv)) {
|
||||
pc().CapMap = maps.Clone(n.CapMap)
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
case "Tags":
|
||||
if !views.SliceEqual(was.Tags(), views.SliceOf(n.Tags)) {
|
||||
return nil, false
|
||||
@@ -712,13 +724,11 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
return nil, false
|
||||
}
|
||||
case "Online":
|
||||
wasOnline := was.Online()
|
||||
if n.Online != nil && wasOnline != nil && *n.Online != *wasOnline {
|
||||
if wasOnline, ok := was.Online().GetOk(); ok && n.Online != nil && *n.Online != wasOnline {
|
||||
pc().Online = ptr.To(*n.Online)
|
||||
}
|
||||
case "LastSeen":
|
||||
wasSeen := was.LastSeen()
|
||||
if n.LastSeen != nil && wasSeen != nil && !wasSeen.Equal(*n.LastSeen) {
|
||||
if wasSeen, ok := was.LastSeen().GetOk(); ok && n.LastSeen != nil && !wasSeen.Equal(*n.LastSeen) {
|
||||
pc().LastSeen = ptr.To(*n.LastSeen)
|
||||
}
|
||||
case "MachineAuthorized":
|
||||
@@ -743,18 +753,18 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
}
|
||||
case "SelfNodeV4MasqAddrForThisPeer":
|
||||
va, vb := was.SelfNodeV4MasqAddrForThisPeer(), n.SelfNodeV4MasqAddrForThisPeer
|
||||
if va == nil && vb == nil {
|
||||
if !va.Valid() && vb == nil {
|
||||
continue
|
||||
}
|
||||
if va == nil || vb == nil || *va != *vb {
|
||||
if va, ok := va.GetOk(); !ok || vb == nil || va != *vb {
|
||||
return nil, false
|
||||
}
|
||||
case "SelfNodeV6MasqAddrForThisPeer":
|
||||
va, vb := was.SelfNodeV6MasqAddrForThisPeer(), n.SelfNodeV6MasqAddrForThisPeer
|
||||
if va == nil && vb == nil {
|
||||
if !va.Valid() && vb == nil {
|
||||
continue
|
||||
}
|
||||
if va == nil || vb == nil || *va != *vb {
|
||||
if va, ok := va.GetOk(); !ok || vb == nil || va != *vb {
|
||||
return nil, false
|
||||
}
|
||||
case "ExitNodeDNSResolvers":
|
||||
@@ -778,21 +788,26 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
return ret, true
|
||||
}
|
||||
|
||||
func (ms *mapSession) sortedPeers() []tailcfg.NodeView {
|
||||
ret := slicesx.MapValues(ms.peers)
|
||||
slices.SortFunc(ret, func(a, b tailcfg.NodeView) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
// netmap returns a fully populated NetworkMap from the last state seen from
|
||||
// a call to updateStateFromResponse, filling in omitted
|
||||
// information from prior MapResponse values.
|
||||
func (ms *mapSession) netmap() *netmap.NetworkMap {
|
||||
peerViews := make([]tailcfg.NodeView, len(ms.sortedPeers))
|
||||
for i, vp := range ms.sortedPeers {
|
||||
peerViews[i] = *vp
|
||||
}
|
||||
peerViews := ms.sortedPeers()
|
||||
|
||||
nm := &netmap.NetworkMap{
|
||||
NodeKey: ms.publicNodeKey,
|
||||
PrivateKey: ms.privateNodeKey,
|
||||
MachineKey: ms.machinePubKey,
|
||||
Peers: peerViews,
|
||||
UserProfiles: make(map[tailcfg.UserID]tailcfg.UserProfile),
|
||||
UserProfiles: make(map[tailcfg.UserID]tailcfg.UserProfileView),
|
||||
Domain: ms.lastDomain,
|
||||
DomainAuditLogID: ms.lastDomainAuditLogID,
|
||||
DNS: *ms.lastDNSConfig,
|
||||
@@ -803,7 +818,6 @@ func (ms *mapSession) netmap() *netmap.NetworkMap {
|
||||
DERPMap: ms.lastDERPMap,
|
||||
ControlHealth: ms.lastHealth,
|
||||
TKAEnabled: ms.lastTKAInfo != nil && !ms.lastTKAInfo.Disabled,
|
||||
MaxKeyDuration: ms.lastMaxExpiry,
|
||||
}
|
||||
|
||||
if ms.lastTKAInfo != nil && ms.lastTKAInfo.Head != "" {
|
||||
|
||||
Reference in New Issue
Block a user