wgengine/magicsock,control/controlclient: do not overwrite discokey with old key (#18606)
When a client starts up without being able to connect to control, it sends its discoKey to other nodes it wants to communicate with over TSMP. This disco key will be a newer key than the one control knows about. If the client that can connect to control gets a full netmap, ensure that the disco key for the node not connected to control is not overwritten with the stale key control knows about. This is implemented through keeping track of mapSession and use that for the discokey injection if it is available. This ensures that we are not constantly resetting the wireguard connection when getting the wrong keys from control. This is implemented as: - If the key is received via TSMP: - Set lastSeen for the peer to now() - Set online for the peer to false - When processing new keys, only accept keys where either: - Peer is online - lastSeen is newer than existing last seen If mapSession is not available, as in we are not yet connected to control, punt down the disco key injection to magicsock. Ideally, we will want to have mapSession be long lived at some point in the near future so we only need to inject keys in one location and then also use that for testing and loading the cache, but that is a yak for another PR. Updates #12639 Signed-off-by: Claus Lensbøl <claus@tailscale.com>main
parent
ca9aa20255
commit
85bb5f84a5
@ -0,0 +1,30 @@ |
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package events contains type used as eventbus topics in tailscaled.
|
||||
package events |
||||
|
||||
import ( |
||||
"net/netip" |
||||
|
||||
"tailscale.com/types/key" |
||||
) |
||||
|
||||
// DiscoKeyAdvertisement is an event sent on the [eventbus.Bus] when a disco
|
||||
// key has been received over TSMP.
|
||||
//
|
||||
// Its publisher is [tstun.Wrapper]; its main subscriber is
|
||||
// [controlclient.Direct], that injects the received key into the netmap as if
|
||||
// it was a netmap update from control.
|
||||
type DiscoKeyAdvertisement struct { |
||||
Src netip.Addr // Src field is populated by the IP header of the packet, not from the payload itself.
|
||||
Key key.DiscoPublic |
||||
} |
||||
|
||||
// PeerDiscoKeyUpdate is an event sent on the [eventbus.Bus] when
|
||||
// [controlclient.Direct] deems that it cannot handle the key update.
|
||||
//
|
||||
// Its publisher is [controlclient.Direct]; its main subscriber is
|
||||
// [wgengine.userspaceengine], that injects the received key into its
|
||||
// [magicsock.Conn] in order to set up the key directly.
|
||||
type PeerDiscoKeyUpdate DiscoKeyAdvertisement |
||||
Loading…
Reference in new issue