net/netcheck: preserve live home DERP through packet loss

During a short period of packet loss, a TCP connection to the home DERP
may be maintained. If no other regions emerge as winners, such as when
all regions but one are avoided/disallowed as candidates, ensure that
the current home region, if still active, is not dropped as the
preferred region until it has failed two keepalives.

Relatedly apply avoid and no measure no home to ICMP and HTTP checks as
intended.

Updates tailscale/corp#12894
Updates tailscale/corp#29491

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2025-06-11 15:57:55 -07:00
committed by James Tucker
parent 3ed76ceed3
commit b0f7b23efe
5 changed files with 65 additions and 17 deletions

View File

@@ -36,9 +36,13 @@ const (
frameHeaderLen = 1 + 4 // frameType byte + 4 byte length
keyLen = 32
maxInfoLen = 1 << 20
keepAlive = 60 * time.Second
)
// KeepAlive is the minimum frequency at which the DERP server sends
// keep alive frames. The server adds some jitter, so this timing is not
// exact, but 2x this value can be considered a missed keep alive.
const KeepAlive = 60 * time.Second
// ProtocolVersion is bumped whenever there's a wire-incompatible change.
// - version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit
// - version 2: received packets have src addrs in frameRecvPacket at beginning

View File

@@ -1789,7 +1789,7 @@ func (c *sclient) sendLoop(ctx context.Context) error {
defer c.onSendLoopDone()
jitter := rand.N(5 * time.Second)
keepAliveTick, keepAliveTickChannel := c.s.clock.NewTicker(keepAlive + jitter)
keepAliveTick, keepAliveTickChannel := c.s.clock.NewTicker(KeepAlive + jitter)
defer keepAliveTick.Stop()
var werr error // last write error