wgengine/magicsock: add client flag and envknob to disable heartbeat (#5638)

Baby steps towards turning off heartbeat pings entirely as per #540.
This doesn't change any current magicsock functionality and requires additional
changes to send/disco paths before the flag can be turned on.

Updates #540

Change-Id: Idc9a72748e74145b068d67e6dd4a4ffe3932efd0
Signed-off-by: Jenny Zhang <jz@tailscale.com>

Signed-off-by: Jenny Zhang <jz@tailscale.com>
This commit is contained in:
phirework
2022-09-16 23:48:46 -04:00
committed by GitHub
parent 65c24b6334
commit 5c42990c2f
4 changed files with 24 additions and 5 deletions

View File

@@ -2356,6 +2356,8 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) {
}
c.netMap = nm
heartbeatDisabled := debugEnableSilentDisco() || (c.netMap != nil && c.netMap.Debug != nil && c.netMap.Debug.EnableSilentDisco)
// Try a pass of just upserting nodes and creating missing
// endpoints. If the set of nodes is the same, this is an
// efficient alloc-free update. If the set of nodes is different,
@@ -2364,16 +2366,18 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) {
for _, n := range nm.Peers {
if ep, ok := c.peerMap.endpointForNodeKey(n.Key); ok {
oldDiscoKey := ep.discoKey
ep.heartbeatDisabled = heartbeatDisabled
ep.updateFromNode(n)
c.peerMap.upsertEndpoint(ep, oldDiscoKey) // maybe update discokey mappings in peerMap
continue
}
ep := &endpoint{
c: c,
publicKey: n.Key,
sentPing: map[stun.TxID]sentPing{},
endpointState: map[netip.AddrPort]*endpointState{},
c: c,
publicKey: n.Key,
sentPing: map[stun.TxID]sentPing{},
endpointState: map[netip.AddrPort]*endpointState{},
heartbeatDisabled: heartbeatDisabled,
}
if !n.DiscoKey.IsZero() {
ep.discoKey = n.DiscoKey
@@ -3307,6 +3311,8 @@ type endpoint struct {
isCallMeMaybeEP map[netip.AddrPort]bool
pendingCLIPings []pendingCLIPing // any outstanding "tailscale ping" commands running
heartbeatDisabled bool // heartBeatTimer disabled for silent disco. See issue #540.
}
type pendingCLIPing struct {
@@ -3502,6 +3508,11 @@ func (de *endpoint) heartbeat() {
de.heartBeatTimer = nil
if de.heartbeatDisabled {
// If control override to disable heartBeatTimer set, return early.
return
}
if !de.canP2P() {
// Cannot form p2p connections, no heartbeating necessary.
return
@@ -3560,7 +3571,7 @@ func (de *endpoint) wantFullPingLocked(now mono.Time) bool {
func (de *endpoint) noteActiveLocked() {
de.lastSend = mono.Now()
if de.heartBeatTimer == nil && de.canP2P() {
if de.heartBeatTimer == nil && de.canP2P() && !de.heartbeatDisabled {
de.heartBeatTimer = time.AfterFunc(heartbeatInterval, de.heartbeat)
}
}