derp: make RunConnectionLoop funcs take Messages, support PeerPresentFlags

PeerPresentFlags was added in 5ffb2668ef but wasn't plumbed through to
the RunConnectionLoop. Rather than add yet another parameter (as
IP:port was added earlier), pass in the raw PeerPresentMessage and
PeerGoneMessage struct values, which are the same things, plus two
fields: PeerGoneReasonType for gone and the PeerPresentFlags from
5ffb2668ef.

Updates tailscale/corp#17816

Change-Id: Ib19d9f95353651ada90656071fc3656cf58b7987
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2024-06-25 08:04:12 -07:00
committed by Brad Fitzpatrick
parent 7eb8a77ac8
commit 3485e4bf5a
4 changed files with 26 additions and 28 deletions

View File

@@ -5,7 +5,6 @@ package derphttp
import (
"context"
"net/netip"
"sync"
"time"
@@ -35,9 +34,14 @@ var testHookWatchLookConnectResult func(connectError error, wasSelfConnect bool)
// To force RunWatchConnectionLoop to return quickly, its ctx needs to be
// closed, and c itself needs to be closed.
//
// It is a fatal error to call this on an already-started Client withoutq having
// It is a fatal error to call this on an already-started Client without having
// initialized Client.WatchConnectionChanges to true.
func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key.NodePublic, infoLogf logger.Logf, add func(key.NodePublic, netip.AddrPort), remove func(key.NodePublic)) {
//
// If the DERP connection breaks and reconnects, remove will be called for all
// previously seen peers, with Reason type PeerGoneReasonSynthetic. Those
// clients are likely still connected and their add message will appear after
// reconnect.
func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key.NodePublic, infoLogf logger.Logf, add func(derp.PeerPresentMessage), remove func(derp.PeerGoneMessage)) {
if !c.WatchConnectionChanges {
if c.isStarted() {
panic("invalid use of RunWatchConnectionLoop on already-started Client without setting Client.RunWatchConnectionLoop")
@@ -62,7 +66,7 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key
}
logf("reconnected; clearing %d forwarding mappings", len(present))
for k := range present {
remove(k)
remove(derp.PeerGoneMessage{Peer: k, Reason: derp.PeerGoneReasonMeshConnBroke})
}
present = map[key.NodePublic]bool{}
}
@@ -84,13 +88,7 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key
})
defer timer.Stop()
updatePeer := func(k key.NodePublic, ipPort netip.AddrPort, isPresent bool) {
if isPresent {
add(k, ipPort)
} else {
remove(k)
}
updatePeer := func(k key.NodePublic, isPresent bool) {
mu.Lock()
defer mu.Unlock()
if isPresent {
@@ -148,7 +146,8 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key
}
switch m := m.(type) {
case derp.PeerPresentMessage:
updatePeer(m.Key, m.IPPort, true)
add(m)
updatePeer(m.Key, true)
case derp.PeerGoneMessage:
switch m.Reason {
case derp.PeerGoneReasonDisconnected:
@@ -160,7 +159,8 @@ func (c *Client) RunWatchConnectionLoop(ctx context.Context, ignoreServerKey key
logf("Recv: peer %s not at server %s for unknown reason %v",
key.NodePublic(m.Peer).ShortString(), c.ServerPublicKey().ShortString(), m.Reason)
}
updatePeer(key.NodePublic(m.Peer), netip.AddrPort{}, false)
remove(m)
updatePeer(m.Peer, false)
default:
continue
}