wgengine/magicsock: add DERP homeless debug mode for testing

In DERP homeless mode, a DERP home connection is not sought or
maintained and the local node is not reachable.

Updates #3363
Updates tailscale/corp#396

Change-Id: Ibc30488ac2e3cfe4810733b96c2c9f10a51b8331
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2023-11-15 15:10:45 -08:00
committed by Brad Fitzpatrick
parent 2ff54f9d12
commit 3bd382f369
6 changed files with 53 additions and 15 deletions

View File

@@ -144,6 +144,10 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
health.SetMagicSockDERPHome(0)
return false
}
if c.homeless {
c.myDerp = 0
return false
}
if derpNum == c.myDerp {
// No change.
return true

View File

@@ -270,6 +270,7 @@ type Conn struct {
privateKey key.NodePrivate // WireGuard private key for this node
everHadKey bool // whether we ever had a non-zero private key
myDerp int // nearest DERP region ID; 0 means none/unknown
homeless bool // if true, don't try to find & stay conneted to a DERP home (myDerp will stay 0)
derpStarted chan struct{} // closed on first connection to DERP; for tests & cleaner Close
activeDerp map[int]activeDerp // DERP regionID -> connection to a node in that region
prevDerp map[int]*syncs.WaitGroupChan
@@ -2202,7 +2203,7 @@ func (c *Conn) goroutinesRunningLocked() bool {
}
func (c *Conn) shouldDoPeriodicReSTUNLocked() bool {
if c.networkDown() {
if c.networkDown() || c.homeless {
return false
}
if len(c.peerSet) == 0 || c.privateKey.IsZero() {
@@ -2686,6 +2687,24 @@ func (c *Conn) SetStatistics(stats *connstats.Statistics) {
c.stats.Store(stats)
}
// SetHomeless sets whether magicsock should idle harder and not have a DERP
// home connection active and not search for its nearest DERP home. In this
// homeless mode, the node is unreachable by others.
func (c *Conn) SetHomeless(v bool) {
c.mu.Lock()
defer c.mu.Unlock()
c.homeless = v
if v && c.myDerp != 0 {
oldHome := c.myDerp
c.myDerp = 0
c.closeDerpLocked(oldHome, "set-homeless")
}
if !v {
go c.updateEndpoints("set-homeless-disabled")
}
}
const (
// sessionActiveTimeout is how long since the last activity we
// try to keep an established endpoint peering alive.