mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-16 03:31:39 +00:00
wgengine: use key.NodePublic instead of tailcfg.NodeKey.
Updates #3206 Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
parent
72ace0acba
commit
c3d7115e63
@ -114,8 +114,8 @@ type userspaceEngine struct {
|
|||||||
lastEngineSigFull deephash.Sum // of full wireguard config
|
lastEngineSigFull deephash.Sum // of full wireguard config
|
||||||
lastEngineSigTrim deephash.Sum // of trimmed wireguard config
|
lastEngineSigTrim deephash.Sum // of trimmed wireguard config
|
||||||
lastDNSConfig *dns.Config
|
lastDNSConfig *dns.Config
|
||||||
recvActivityAt map[tailcfg.NodeKey]mono.Time
|
recvActivityAt map[key.NodePublic]mono.Time
|
||||||
trimmedNodes map[tailcfg.NodeKey]bool // set of node keys of peers currently excluded from wireguard config
|
trimmedNodes map[key.NodePublic]bool // set of node keys of peers currently excluded from wireguard config
|
||||||
sentActivityAt map[netaddr.IP]*mono.Time // value is accessed atomically
|
sentActivityAt map[netaddr.IP]*mono.Time // value is accessed atomically
|
||||||
destIPActivityFuncs map[netaddr.IP]func()
|
destIPActivityFuncs map[netaddr.IP]func()
|
||||||
statusBufioReader *bufio.Reader // reusable for UAPI
|
statusBufioReader *bufio.Reader // reusable for UAPI
|
||||||
@ -127,7 +127,7 @@ type userspaceEngine struct {
|
|||||||
netMap *netmap.NetworkMap // or nil
|
netMap *netmap.NetworkMap // or nil
|
||||||
closing bool // Close was called (even if we're still closing)
|
closing bool // Close was called (even if we're still closing)
|
||||||
statusCallback StatusCallback
|
statusCallback StatusCallback
|
||||||
peerSequence []tailcfg.NodeKey
|
peerSequence []key.NodePublic
|
||||||
endpoints []tailcfg.Endpoint
|
endpoints []tailcfg.Endpoint
|
||||||
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
|
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
|
||||||
networkMapCallbacks map[*someHandle]NetworkMapCallback
|
networkMapCallbacks map[*someHandle]NetworkMapCallback
|
||||||
@ -554,8 +554,7 @@ func isTrimmablePeer(p *wgcfg.Peer, numPeers int) bool {
|
|||||||
// noteRecvActivity is called by magicsock when a packet has been
|
// noteRecvActivity is called by magicsock when a packet has been
|
||||||
// received for the peer with node key nk. Magicsock calls this no
|
// received for the peer with node key nk. Magicsock calls this no
|
||||||
// more than every 10 seconds for a given peer.
|
// more than every 10 seconds for a given peer.
|
||||||
func (e *userspaceEngine) noteRecvActivity(k key.NodePublic) {
|
func (e *userspaceEngine) noteRecvActivity(nk key.NodePublic) {
|
||||||
nk := k.AsNodeKey()
|
|
||||||
e.wgLock.Lock()
|
e.wgLock.Lock()
|
||||||
defer e.wgLock.Unlock()
|
defer e.wgLock.Unlock()
|
||||||
|
|
||||||
@ -597,7 +596,7 @@ func (e *userspaceEngine) noteRecvActivity(k key.NodePublic) {
|
|||||||
// has had a packet sent to or received from it since t.
|
// has had a packet sent to or received from it since t.
|
||||||
//
|
//
|
||||||
// e.wgLock must be held.
|
// e.wgLock must be held.
|
||||||
func (e *userspaceEngine) isActiveSinceLocked(nk tailcfg.NodeKey, ip netaddr.IP, t mono.Time) bool {
|
func (e *userspaceEngine) isActiveSinceLocked(nk key.NodePublic, ip netaddr.IP, t mono.Time) bool {
|
||||||
if e.recvActivityAt[nk].After(t) {
|
if e.recvActivityAt[nk].After(t) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -614,7 +613,7 @@ func (e *userspaceEngine) isActiveSinceLocked(nk tailcfg.NodeKey, ip netaddr.IP,
|
|||||||
// If discoChanged is nil or empty, this extra removal step isn't done.
|
// If discoChanged is nil or empty, this extra removal step isn't done.
|
||||||
//
|
//
|
||||||
// e.wgLock must be held.
|
// e.wgLock must be held.
|
||||||
func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[tailcfg.NodeKey]bool) error {
|
func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.NodePublic]bool) error {
|
||||||
if hook := e.testMaybeReconfigHook; hook != nil {
|
if hook := e.testMaybeReconfigHook; hook != nil {
|
||||||
hook()
|
hook()
|
||||||
return nil
|
return nil
|
||||||
@ -640,36 +639,35 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[tailcfg.
|
|||||||
// their NodeKey and Tailscale IPs. These are the ones we'll need
|
// their NodeKey and Tailscale IPs. These are the ones we'll need
|
||||||
// to install tracking hooks for to watch their send/receive
|
// to install tracking hooks for to watch their send/receive
|
||||||
// activity.
|
// activity.
|
||||||
trackNodes := make([]tailcfg.NodeKey, 0, len(full.Peers))
|
trackNodes := make([]key.NodePublic, 0, len(full.Peers))
|
||||||
trackIPs := make([]netaddr.IP, 0, len(full.Peers))
|
trackIPs := make([]netaddr.IP, 0, len(full.Peers))
|
||||||
|
|
||||||
trimmedNodes := map[tailcfg.NodeKey]bool{} // TODO: don't re-alloc this map each time
|
trimmedNodes := map[key.NodePublic]bool{} // TODO: don't re-alloc this map each time
|
||||||
|
|
||||||
needRemoveStep := false
|
needRemoveStep := false
|
||||||
for i := range full.Peers {
|
for i := range full.Peers {
|
||||||
p := &full.Peers[i]
|
p := &full.Peers[i]
|
||||||
nk := p.PublicKey
|
nk := p.PublicKey
|
||||||
tnk := nk.AsNodeKey()
|
|
||||||
if !isTrimmablePeer(p, len(full.Peers)) {
|
if !isTrimmablePeer(p, len(full.Peers)) {
|
||||||
min.Peers = append(min.Peers, *p)
|
min.Peers = append(min.Peers, *p)
|
||||||
if discoChanged[tnk] {
|
if discoChanged[nk] {
|
||||||
needRemoveStep = true
|
needRemoveStep = true
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
trackNodes = append(trackNodes, tnk)
|
trackNodes = append(trackNodes, nk)
|
||||||
recentlyActive := false
|
recentlyActive := false
|
||||||
for _, cidr := range p.AllowedIPs {
|
for _, cidr := range p.AllowedIPs {
|
||||||
trackIPs = append(trackIPs, cidr.IP())
|
trackIPs = append(trackIPs, cidr.IP())
|
||||||
recentlyActive = recentlyActive || e.isActiveSinceLocked(tnk, cidr.IP(), activeCutoff)
|
recentlyActive = recentlyActive || e.isActiveSinceLocked(nk, cidr.IP(), activeCutoff)
|
||||||
}
|
}
|
||||||
if recentlyActive {
|
if recentlyActive {
|
||||||
min.Peers = append(min.Peers, *p)
|
min.Peers = append(min.Peers, *p)
|
||||||
if discoChanged[tnk] {
|
if discoChanged[nk] {
|
||||||
needRemoveStep = true
|
needRemoveStep = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trimmedNodes[tnk] = true
|
trimmedNodes[nk] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastNMinPeers = len(min.Peers)
|
e.lastNMinPeers = len(min.Peers)
|
||||||
@ -688,7 +686,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[tailcfg.
|
|||||||
minner.Peers = nil
|
minner.Peers = nil
|
||||||
numRemove := 0
|
numRemove := 0
|
||||||
for _, p := range min.Peers {
|
for _, p := range min.Peers {
|
||||||
if discoChanged[p.PublicKey.AsNodeKey()] {
|
if discoChanged[p.PublicKey] {
|
||||||
numRemove++
|
numRemove++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -716,10 +714,10 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[tailcfg.
|
|||||||
// as given to wireguard-go.
|
// as given to wireguard-go.
|
||||||
//
|
//
|
||||||
// e.wgLock must be held.
|
// e.wgLock must be held.
|
||||||
func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []tailcfg.NodeKey, trackIPs []netaddr.IP) {
|
func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic, trackIPs []netaddr.IP) {
|
||||||
// Generate the new map of which nodekeys we want to track
|
// Generate the new map of which nodekeys we want to track
|
||||||
// receive times for.
|
// receive times for.
|
||||||
mr := map[tailcfg.NodeKey]mono.Time{} // TODO: only recreate this if set of keys changed
|
mr := map[key.NodePublic]mono.Time{} // TODO: only recreate this if set of keys changed
|
||||||
for _, nk := range trackNodes {
|
for _, nk := range trackNodes {
|
||||||
// Preserve old times in the new map, but also
|
// Preserve old times in the new map, but also
|
||||||
// populate map entries for new trackNodes values with
|
// populate map entries for new trackNodes values with
|
||||||
@ -808,7 +806,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
e.peerSequence = e.peerSequence[:0]
|
e.peerSequence = e.peerSequence[:0]
|
||||||
for _, p := range cfg.Peers {
|
for _, p := range cfg.Peers {
|
||||||
e.peerSequence = append(e.peerSequence, p.PublicKey.AsNodeKey())
|
e.peerSequence = append(e.peerSequence, p.PublicKey)
|
||||||
peerSet[p.PublicKey] = struct{}{}
|
peerSet[p.PublicKey] = struct{}{}
|
||||||
}
|
}
|
||||||
e.mu.Unlock()
|
e.mu.Unlock()
|
||||||
@ -841,12 +839,12 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
// If so, we need to update the wireguard-go/device.Device in two phases:
|
// If so, we need to update the wireguard-go/device.Device in two phases:
|
||||||
// once without the node which has restarted, to clear its wireguard session key,
|
// once without the node which has restarted, to clear its wireguard session key,
|
||||||
// and a second time with it.
|
// and a second time with it.
|
||||||
discoChanged := make(map[tailcfg.NodeKey]bool)
|
discoChanged := make(map[key.NodePublic]bool)
|
||||||
{
|
{
|
||||||
prevEP := make(map[tailcfg.NodeKey]key.DiscoPublic)
|
prevEP := make(map[key.NodePublic]key.DiscoPublic)
|
||||||
for i := range e.lastCfgFull.Peers {
|
for i := range e.lastCfgFull.Peers {
|
||||||
if p := &e.lastCfgFull.Peers[i]; !p.DiscoKey.IsZero() {
|
if p := &e.lastCfgFull.Peers[i]; !p.DiscoKey.IsZero() {
|
||||||
prevEP[p.PublicKey.AsNodeKey()] = p.DiscoKey
|
prevEP[p.PublicKey] = p.DiscoKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range cfg.Peers {
|
for i := range cfg.Peers {
|
||||||
@ -854,7 +852,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
if p.DiscoKey.IsZero() {
|
if p.DiscoKey.IsZero() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pub := p.PublicKey.AsNodeKey()
|
pub := p.PublicKey
|
||||||
if old, ok := prevEP[pub]; ok && old != p.DiscoKey {
|
if old, ok := prevEP[pub]; ok && old != p.DiscoKey {
|
||||||
discoChanged[pub] = true
|
discoChanged[pub] = true
|
||||||
e.logf("wgengine: Reconfig: %s changed from %q to %q", pub.ShortString(), old, p.DiscoKey)
|
e.logf("wgengine: Reconfig: %s changed from %q to %q", pub.ShortString(), old, p.DiscoKey)
|
||||||
@ -979,7 +977,7 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
|
|||||||
errc <- err
|
errc <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pp := make(map[tailcfg.NodeKey]ipnstate.PeerStatusLite)
|
pp := make(map[key.NodePublic]ipnstate.PeerStatusLite)
|
||||||
var p ipnstate.PeerStatusLite
|
var p ipnstate.PeerStatusLite
|
||||||
|
|
||||||
var hst1, hst2, n int64
|
var hst1, hst2, n int64
|
||||||
@ -1013,7 +1011,7 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
|
|||||||
return nil, fmt.Errorf("IpcGetOperation: invalid key in line %q", line)
|
return nil, fmt.Errorf("IpcGetOperation: invalid key in line %q", line)
|
||||||
}
|
}
|
||||||
if !p.NodeKey.IsZero() {
|
if !p.NodeKey.IsZero() {
|
||||||
pp[p.NodeKey] = p
|
pp[p.NodeKey.AsNodePublic()] = p
|
||||||
}
|
}
|
||||||
p = ipnstate.PeerStatusLite{NodeKey: pk.AsNodeKey()}
|
p = ipnstate.PeerStatusLite{NodeKey: pk.AsNodeKey()}
|
||||||
case "rx_bytes":
|
case "rx_bytes":
|
||||||
@ -1044,7 +1042,7 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !p.NodeKey.IsZero() {
|
if !p.NodeKey.IsZero() {
|
||||||
pp[p.NodeKey] = p
|
pp[p.NodeKey.AsNodePublic()] = p
|
||||||
}
|
}
|
||||||
if err := <-errc; err != nil {
|
if err := <-errc; err != nil {
|
||||||
return nil, fmt.Errorf("IpcGetOperation: %v", err)
|
return nil, fmt.Errorf("IpcGetOperation: %v", err)
|
||||||
@ -1457,7 +1455,7 @@ func (e *userspaceEngine) peerForIP(ip netaddr.IP) (n *tailcfg.Node, isSelf bool
|
|||||||
|
|
||||||
// TODO(bradfitz): this is O(n peers). Add ART to netaddr?
|
// TODO(bradfitz): this is O(n peers). Add ART to netaddr?
|
||||||
var best netaddr.IPPrefix
|
var best netaddr.IPPrefix
|
||||||
var bestKey tailcfg.NodeKey
|
var bestKey key.NodePublic
|
||||||
for _, p := range e.lastCfgFull.Peers {
|
for _, p := range e.lastCfgFull.Peers {
|
||||||
for _, cidr := range p.AllowedIPs {
|
for _, cidr := range p.AllowedIPs {
|
||||||
if !cidr.Contains(ip) {
|
if !cidr.Contains(ip) {
|
||||||
@ -1465,7 +1463,7 @@ func (e *userspaceEngine) peerForIP(ip netaddr.IP) (n *tailcfg.Node, isSelf bool
|
|||||||
}
|
}
|
||||||
if best.IsZero() || cidr.Bits() > best.Bits() {
|
if best.IsZero() || cidr.Bits() > best.Bits() {
|
||||||
best = cidr
|
best = cidr
|
||||||
bestKey = p.PublicKey.AsNodeKey()
|
bestKey = p.PublicKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1473,7 +1471,7 @@ func (e *userspaceEngine) peerForIP(ip netaddr.IP) (n *tailcfg.Node, isSelf bool
|
|||||||
// call. But TODO(bradfitz): add a lookup map to netmap.NetworkMap.
|
// call. But TODO(bradfitz): add a lookup map to netmap.NetworkMap.
|
||||||
if !bestKey.IsZero() {
|
if !bestKey.IsZero() {
|
||||||
for _, p := range nm.Peers {
|
for _, p := range nm.Peers {
|
||||||
if p.Key == bestKey {
|
if p.Key.AsNodePublic() == bestKey {
|
||||||
return p, false, nil
|
return p, false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,16 +37,15 @@ func TestNoteReceiveActivity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
e := &userspaceEngine{
|
e := &userspaceEngine{
|
||||||
timeNow: func() mono.Time { return now },
|
timeNow: func() mono.Time { return now },
|
||||||
recvActivityAt: map[tailcfg.NodeKey]mono.Time{},
|
recvActivityAt: map[key.NodePublic]mono.Time{},
|
||||||
logf: logBuf.Logf,
|
logf: logBuf.Logf,
|
||||||
tundev: new(tstun.Wrapper),
|
tundev: new(tstun.Wrapper),
|
||||||
testMaybeReconfigHook: func() { confc <- true },
|
testMaybeReconfigHook: func() { confc <- true },
|
||||||
trimmedNodes: map[tailcfg.NodeKey]bool{},
|
trimmedNodes: map[key.NodePublic]bool{},
|
||||||
}
|
}
|
||||||
ra := e.recvActivityAt
|
ra := e.recvActivityAt
|
||||||
|
|
||||||
nk := key.NewNode().Public()
|
nk := key.NewNode().Public()
|
||||||
tnk := nk.AsNodeKey()
|
|
||||||
|
|
||||||
// Activity on an untracked key should do nothing.
|
// Activity on an untracked key should do nothing.
|
||||||
e.noteRecvActivity(nk)
|
e.noteRecvActivity(nk)
|
||||||
@ -58,12 +57,12 @@ func TestNoteReceiveActivity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now track it, but don't mark it trimmed, so shouldn't update.
|
// Now track it, but don't mark it trimmed, so shouldn't update.
|
||||||
ra[tnk] = 0
|
ra[nk] = 0
|
||||||
e.noteRecvActivity(nk)
|
e.noteRecvActivity(nk)
|
||||||
if len(ra) != 1 {
|
if len(ra) != 1 {
|
||||||
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
||||||
}
|
}
|
||||||
if got := ra[tnk]; got != now {
|
if got := ra[nk]; got != now {
|
||||||
t.Fatalf("time in map = %v; want %v", got, now)
|
t.Fatalf("time in map = %v; want %v", got, now)
|
||||||
}
|
}
|
||||||
if gotConf() {
|
if gotConf() {
|
||||||
@ -71,12 +70,12 @@ func TestNoteReceiveActivity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now mark it trimmed and expect an update.
|
// Now mark it trimmed and expect an update.
|
||||||
e.trimmedNodes[tnk] = true
|
e.trimmedNodes[nk] = true
|
||||||
e.noteRecvActivity(nk)
|
e.noteRecvActivity(nk)
|
||||||
if len(ra) != 1 {
|
if len(ra) != 1 {
|
||||||
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
||||||
}
|
}
|
||||||
if got := ra[tnk]; got != now {
|
if got := ra[nk]; got != now {
|
||||||
t.Fatalf("time in map = %v; want %v", got, now)
|
t.Fatalf("time in map = %v; want %v", got, now)
|
||||||
}
|
}
|
||||||
if !gotConf() {
|
if !gotConf() {
|
||||||
@ -101,7 +100,7 @@ func TestUserspaceEngineReconfig(t *testing.T) {
|
|||||||
nm := &netmap.NetworkMap{
|
nm := &netmap.NetworkMap{
|
||||||
Peers: []*tailcfg.Node{
|
Peers: []*tailcfg.Node{
|
||||||
&tailcfg.Node{
|
&tailcfg.Node{
|
||||||
Key: nkFromHex(nodeHex),
|
Key: nkFromHex(nodeHex).AsNodeKey(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -126,14 +125,14 @@ func TestUserspaceEngineReconfig(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wantRecvAt := map[tailcfg.NodeKey]mono.Time{
|
wantRecvAt := map[key.NodePublic]mono.Time{
|
||||||
nkFromHex(nodeHex): 0,
|
nkFromHex(nodeHex): 0,
|
||||||
}
|
}
|
||||||
if got := ue.recvActivityAt; !reflect.DeepEqual(got, wantRecvAt) {
|
if got := ue.recvActivityAt; !reflect.DeepEqual(got, wantRecvAt) {
|
||||||
t.Errorf("wrong recvActivityAt\n got: %v\nwant: %v\n", got, wantRecvAt)
|
t.Errorf("wrong recvActivityAt\n got: %v\nwant: %v\n", got, wantRecvAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
wantTrimmedNodes := map[tailcfg.NodeKey]bool{
|
wantTrimmedNodes := map[key.NodePublic]bool{
|
||||||
nkFromHex(nodeHex): true,
|
nkFromHex(nodeHex): true,
|
||||||
}
|
}
|
||||||
if got := ue.trimmedNodes; !reflect.DeepEqual(got, wantTrimmedNodes) {
|
if got := ue.trimmedNodes; !reflect.DeepEqual(got, wantTrimmedNodes) {
|
||||||
@ -210,7 +209,7 @@ func TestUserspaceEnginePortReconfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nkFromHex(hex string) tailcfg.NodeKey {
|
func nkFromHex(hex string) key.NodePublic {
|
||||||
if len(hex) != 64 {
|
if len(hex) != 64 {
|
||||||
panic(fmt.Sprintf("%q is len %d; want 64", hex, len(hex)))
|
panic(fmt.Sprintf("%q is len %d; want 64", hex, len(hex)))
|
||||||
}
|
}
|
||||||
@ -218,7 +217,7 @@ func nkFromHex(hex string) tailcfg.NodeKey {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("%q is not hex: %v", hex, err))
|
panic(fmt.Sprintf("%q is not hex: %v", hex, err))
|
||||||
}
|
}
|
||||||
return k.AsNodeKey()
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
// an experiment to see if genLocalAddrFunc was worth it. As of Go
|
// an experiment to see if genLocalAddrFunc was worth it. As of Go
|
||||||
|
Loading…
x
Reference in New Issue
Block a user