mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-14 23:17:29 +00:00
ipn/ipnlocal,wgengine{/magicsock}: replace SetNetworkMap with eventbus (#16299)
Same with UpdateNetmapDelta. Updates tailscale/corp#27502 Updates #15160 Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
@@ -1946,10 +1946,6 @@ var _ controlclient.NetmapDeltaUpdater = (*LocalBackend)(nil)
|
||||
|
||||
// UpdateNetmapDelta implements controlclient.NetmapDeltaUpdater.
|
||||
func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) {
|
||||
if !b.MagicConn().UpdateNetmapDelta(muts) {
|
||||
return false
|
||||
}
|
||||
|
||||
var notify *ipn.Notify // non-nil if we need to send a Notify
|
||||
defer func() {
|
||||
if notify != nil {
|
||||
|
@@ -5,6 +5,7 @@ package ipnlocal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
memro "go4.org/mem"
|
||||
"go4.org/netipx"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"tailscale.com/appc"
|
||||
@@ -77,6 +79,12 @@ func inRemove(ip netip.Addr) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func makeNodeKeyFromID(nodeID tailcfg.NodeID) key.NodePublic {
|
||||
raw := make([]byte, 32)
|
||||
binary.BigEndian.PutUint64(raw[24:], uint64(nodeID))
|
||||
return key.NodePublicFromRaw32(memro.B(raw))
|
||||
}
|
||||
|
||||
func TestShrinkDefaultRoute(t *testing.T) {
|
||||
tests := []struct {
|
||||
route string
|
||||
@@ -794,6 +802,7 @@ func TestStatusPeerCapabilities(t *testing.T) {
|
||||
(&tailcfg.Node{
|
||||
ID: 1,
|
||||
StableID: "foo",
|
||||
Key: makeNodeKeyFromID(1),
|
||||
IsWireGuardOnly: true,
|
||||
Hostinfo: (&tailcfg.Hostinfo{}).View(),
|
||||
Capabilities: []tailcfg.NodeCapability{tailcfg.CapabilitySSH},
|
||||
@@ -804,6 +813,7 @@ func TestStatusPeerCapabilities(t *testing.T) {
|
||||
(&tailcfg.Node{
|
||||
ID: 2,
|
||||
StableID: "bar",
|
||||
Key: makeNodeKeyFromID(2),
|
||||
Hostinfo: (&tailcfg.Hostinfo{}).View(),
|
||||
Capabilities: []tailcfg.NodeCapability{tailcfg.CapabilityAdmin},
|
||||
CapMap: (tailcfg.NodeCapMap)(map[tailcfg.NodeCapability][]tailcfg.RawMessage{
|
||||
@@ -830,12 +840,14 @@ func TestStatusPeerCapabilities(t *testing.T) {
|
||||
(&tailcfg.Node{
|
||||
ID: 1,
|
||||
StableID: "foo",
|
||||
Key: makeNodeKeyFromID(1),
|
||||
IsWireGuardOnly: true,
|
||||
Hostinfo: (&tailcfg.Hostinfo{}).View(),
|
||||
}).View(),
|
||||
(&tailcfg.Node{
|
||||
ID: 2,
|
||||
StableID: "bar",
|
||||
Key: makeNodeKeyFromID(2),
|
||||
Hostinfo: (&tailcfg.Hostinfo{}).View(),
|
||||
}).View(),
|
||||
},
|
||||
@@ -927,7 +939,11 @@ func TestUpdateNetmapDelta(t *testing.T) {
|
||||
|
||||
nm := &netmap.NetworkMap{}
|
||||
for i := range 5 {
|
||||
nm.Peers = append(nm.Peers, (&tailcfg.Node{ID: (tailcfg.NodeID(i) + 1)}).View())
|
||||
id := tailcfg.NodeID(i + 1)
|
||||
nm.Peers = append(nm.Peers, (&tailcfg.Node{
|
||||
ID: id,
|
||||
Key: makeNodeKeyFromID(id),
|
||||
}).View())
|
||||
}
|
||||
b.currentNode().SetNetMap(nm)
|
||||
|
||||
@@ -963,18 +979,22 @@ func TestUpdateNetmapDelta(t *testing.T) {
|
||||
wants := []*tailcfg.Node{
|
||||
{
|
||||
ID: 1,
|
||||
Key: makeNodeKeyFromID(1),
|
||||
HomeDERP: 1,
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Key: makeNodeKeyFromID(2),
|
||||
Online: ptr.To(true),
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Key: makeNodeKeyFromID(3),
|
||||
Online: ptr.To(false),
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Key: makeNodeKeyFromID(4),
|
||||
LastSeen: ptr.To(someTime),
|
||||
},
|
||||
}
|
||||
@@ -998,12 +1018,14 @@ func TestWhoIs(t *testing.T) {
|
||||
SelfNode: (&tailcfg.Node{
|
||||
ID: 1,
|
||||
User: 10,
|
||||
Key: makeNodeKeyFromID(1),
|
||||
Addresses: []netip.Prefix{netip.MustParsePrefix("100.101.102.103/32")},
|
||||
}).View(),
|
||||
Peers: []tailcfg.NodeView{
|
||||
(&tailcfg.Node{
|
||||
ID: 2,
|
||||
User: 20,
|
||||
Key: makeNodeKeyFromID(2),
|
||||
Addresses: []netip.Prefix{netip.MustParsePrefix("100.200.200.200/32")},
|
||||
}).View(),
|
||||
},
|
||||
@@ -1593,6 +1615,7 @@ func dnsResponse(domain, address string) []byte {
|
||||
}
|
||||
|
||||
func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
zeroValHostinfoView := new(tailcfg.Hostinfo).View()
|
||||
pfx := netip.MustParsePrefix
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -1669,14 +1692,18 @@ func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
}).View(),
|
||||
Peers: []tailcfg.NodeView{
|
||||
(&tailcfg.Node{
|
||||
ID: 201,
|
||||
Name: "a.tailnet",
|
||||
Key: makeNodeKeyFromID(201),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100.0.0.201/32"),
|
||||
pfx("100::201/128"),
|
||||
},
|
||||
}).View(),
|
||||
(&tailcfg.Node{
|
||||
ID: 202,
|
||||
Name: "b.tailnet",
|
||||
Key: makeNodeKeyFromID(202),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100::202/128"),
|
||||
},
|
||||
@@ -1702,18 +1729,24 @@ func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
}).View(),
|
||||
Peers: []tailcfg.NodeView{
|
||||
(&tailcfg.Node{
|
||||
ID: 123,
|
||||
Name: "a.tailnet",
|
||||
StableID: tailcfg.StableNodeID("123"),
|
||||
Key: makeNodeKeyFromID(123),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("127.0.0.1/32"),
|
||||
pfx("100::201/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
(&tailcfg.Node{
|
||||
ID: 202,
|
||||
Name: "b.tailnet",
|
||||
Key: makeNodeKeyFromID(202),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100::202/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
},
|
||||
},
|
||||
@@ -1734,18 +1767,24 @@ func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
}).View(),
|
||||
Peers: []tailcfg.NodeView{
|
||||
(&tailcfg.Node{
|
||||
ID: 123,
|
||||
Name: "a.tailnet",
|
||||
StableID: tailcfg.StableNodeID("123"),
|
||||
Key: makeNodeKeyFromID(123),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("127.0.0.1/32"),
|
||||
pfx("100::201/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
(&tailcfg.Node{
|
||||
ID: 202,
|
||||
Name: "b.tailnet",
|
||||
Key: makeNodeKeyFromID(202),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100::202/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
},
|
||||
},
|
||||
@@ -1768,18 +1807,24 @@ func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
}).View(),
|
||||
Peers: []tailcfg.NodeView{
|
||||
(&tailcfg.Node{
|
||||
ID: 123,
|
||||
Name: "a.tailnet",
|
||||
StableID: tailcfg.StableNodeID("123"),
|
||||
Key: makeNodeKeyFromID(123),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100.64.5.6/32"),
|
||||
pfx("100::201/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
(&tailcfg.Node{
|
||||
ID: 202,
|
||||
Name: "b.tailnet",
|
||||
Key: makeNodeKeyFromID(202),
|
||||
Addresses: []netip.Prefix{
|
||||
pfx("100::202/128"),
|
||||
},
|
||||
Hostinfo: zeroValHostinfoView,
|
||||
}).View(),
|
||||
},
|
||||
},
|
||||
@@ -1827,7 +1872,6 @@ func TestSetExitNodeIDPolicy(t *testing.T) {
|
||||
b.currentNode().SetNetMap(test.nm)
|
||||
b.pm = pm
|
||||
b.lastSuggestedExitNode = test.lastSuggestedExitNode
|
||||
|
||||
prefs := b.pm.prefs.AsStruct()
|
||||
if changed := applySysPolicy(prefs, test.lastSuggestedExitNode, false) || setExitNodeID(prefs, test.nm); changed != test.prefsChanged {
|
||||
t.Errorf("wanted prefs changed %v, got prefs changed %v", test.prefsChanged, changed)
|
||||
@@ -3218,6 +3262,7 @@ type peerOptFunc func(*tailcfg.Node)
|
||||
func makePeer(id tailcfg.NodeID, opts ...peerOptFunc) tailcfg.NodeView {
|
||||
node := &tailcfg.Node{
|
||||
ID: id,
|
||||
Key: makeNodeKeyFromID(id),
|
||||
StableID: tailcfg.StableNodeID(fmt.Sprintf("stable%d", id)),
|
||||
Name: fmt.Sprintf("peer%d", id),
|
||||
HomeDERP: int(id),
|
||||
|
@@ -72,9 +72,10 @@ type nodeBackend struct {
|
||||
filterAtomic atomic.Pointer[filter.Filter]
|
||||
|
||||
// initialized once and immutable
|
||||
eventClient *eventbus.Client
|
||||
filterUpdates *eventbus.Publisher[magicsock.FilterUpdate]
|
||||
nodeUpdates *eventbus.Publisher[magicsock.NodeAddrsHostInfoUpdate]
|
||||
eventClient *eventbus.Client
|
||||
filterPub *eventbus.Publisher[magicsock.FilterUpdate]
|
||||
nodeViewsPub *eventbus.Publisher[magicsock.NodeViewsUpdate]
|
||||
nodeMutsPub *eventbus.Publisher[magicsock.NodeMutationsUpdate]
|
||||
|
||||
// TODO(nickkhyl): maybe use sync.RWMutex?
|
||||
mu sync.Mutex // protects the following fields
|
||||
@@ -113,9 +114,10 @@ func newNodeBackend(ctx context.Context, bus *eventbus.Bus) *nodeBackend {
|
||||
// Default filter blocks everything and logs nothing.
|
||||
noneFilter := filter.NewAllowNone(logger.Discard, &netipx.IPSet{})
|
||||
nb.filterAtomic.Store(noneFilter)
|
||||
nb.filterUpdates = eventbus.Publish[magicsock.FilterUpdate](nb.eventClient)
|
||||
nb.nodeUpdates = eventbus.Publish[magicsock.NodeAddrsHostInfoUpdate](nb.eventClient)
|
||||
nb.filterUpdates.Publish(magicsock.FilterUpdate{Filter: nb.filterAtomic.Load()})
|
||||
nb.filterPub = eventbus.Publish[magicsock.FilterUpdate](nb.eventClient)
|
||||
nb.nodeViewsPub = eventbus.Publish[magicsock.NodeViewsUpdate](nb.eventClient)
|
||||
nb.nodeMutsPub = eventbus.Publish[magicsock.NodeMutationsUpdate](nb.eventClient)
|
||||
nb.filterPub.Publish(magicsock.FilterUpdate{Filter: nb.filterAtomic.Load()})
|
||||
return nb
|
||||
}
|
||||
|
||||
@@ -379,6 +381,12 @@ func (nb *nodeBackend) SetNetMap(nm *netmap.NetworkMap) {
|
||||
nb.netMap = nm
|
||||
nb.updateNodeByAddrLocked()
|
||||
nb.updatePeersLocked()
|
||||
nv := magicsock.NodeViewsUpdate{}
|
||||
if nm != nil {
|
||||
nv.SelfNode = nm.SelfNode
|
||||
nv.Peers = nm.Peers
|
||||
}
|
||||
nb.nodeViewsPub.Publish(nv)
|
||||
}
|
||||
|
||||
func (nb *nodeBackend) updateNodeByAddrLocked() {
|
||||
@@ -429,16 +437,9 @@ func (nb *nodeBackend) updatePeersLocked() {
|
||||
nb.peers[k] = tailcfg.NodeView{}
|
||||
}
|
||||
|
||||
changed := magicsock.NodeAddrsHostInfoUpdate{
|
||||
Complete: true,
|
||||
}
|
||||
// Second pass, add everything wanted.
|
||||
for _, p := range nm.Peers {
|
||||
mak.Set(&nb.peers, p.ID(), p)
|
||||
mak.Set(&changed.NodesByID, p.ID(), magicsock.NodeAddrsHostInfo{
|
||||
Addresses: p.Addresses(),
|
||||
Hostinfo: p.Hostinfo(),
|
||||
})
|
||||
}
|
||||
|
||||
// Third pass, remove deleted things.
|
||||
@@ -447,7 +448,6 @@ func (nb *nodeBackend) updatePeersLocked() {
|
||||
delete(nb.peers, k)
|
||||
}
|
||||
}
|
||||
nb.nodeUpdates.Publish(changed)
|
||||
}
|
||||
|
||||
func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bool) {
|
||||
@@ -462,8 +462,8 @@ func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
// call (e.g. its endpoints + online status both change)
|
||||
var mutableNodes map[tailcfg.NodeID]*tailcfg.Node
|
||||
|
||||
changed := magicsock.NodeAddrsHostInfoUpdate{
|
||||
Complete: false,
|
||||
update := magicsock.NodeMutationsUpdate{
|
||||
Mutations: make([]netmap.NodeMutation, 0, len(muts)),
|
||||
}
|
||||
for _, m := range muts {
|
||||
n, ok := mutableNodes[m.NodeIDBeingMutated()]
|
||||
@@ -475,18 +475,14 @@ func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
}
|
||||
n = nv.AsStruct()
|
||||
mak.Set(&mutableNodes, nv.ID(), n)
|
||||
update.Mutations = append(update.Mutations, m)
|
||||
}
|
||||
m.Apply(n)
|
||||
}
|
||||
for nid, n := range mutableNodes {
|
||||
nv := n.View()
|
||||
nb.peers[nid] = nv
|
||||
mak.Set(&changed.NodesByID, nid, magicsock.NodeAddrsHostInfo{
|
||||
Addresses: nv.Addresses(),
|
||||
Hostinfo: nv.Hostinfo(),
|
||||
})
|
||||
nb.peers[nid] = n.View()
|
||||
}
|
||||
nb.nodeUpdates.Publish(changed)
|
||||
nb.nodeMutsPub.Publish(update)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -508,7 +504,7 @@ func (nb *nodeBackend) filter() *filter.Filter {
|
||||
|
||||
func (nb *nodeBackend) setFilter(f *filter.Filter) {
|
||||
nb.filterAtomic.Store(f)
|
||||
nb.filterUpdates.Publish(magicsock.FilterUpdate{Filter: f})
|
||||
nb.filterPub.Publish(magicsock.FilterUpdate{Filter: f})
|
||||
}
|
||||
|
||||
func (nb *nodeBackend) dnsConfigForNetmap(prefs ipn.PrefsView, selfExpired bool, logf logger.Logf, versionOS string) *dns.Config {
|
||||
|
@@ -918,6 +918,7 @@ func newTestBackend(t *testing.T) *LocalBackend {
|
||||
ID: 152,
|
||||
ComputedName: "some-peer",
|
||||
User: tailcfg.UserID(1),
|
||||
Key: makeNodeKeyFromID(152),
|
||||
Addresses: []netip.Prefix{
|
||||
netip.MustParsePrefix("100.150.151.152/32"),
|
||||
},
|
||||
@@ -927,6 +928,7 @@ func newTestBackend(t *testing.T) *LocalBackend {
|
||||
ComputedName: "some-tagged-peer",
|
||||
Tags: []string{"tag:server", "tag:test"},
|
||||
User: tailcfg.UserID(1),
|
||||
Key: makeNodeKeyFromID(153),
|
||||
Addresses: []netip.Prefix{
|
||||
netip.MustParsePrefix("100.150.151.153/32"),
|
||||
},
|
||||
|
Reference in New Issue
Block a user