From 11ce5b7e57bbf67ed89f404e9e5b3a8ac14c7723 Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Fri, 13 Jan 2023 14:29:41 -0500 Subject: [PATCH] ipn/ipnlocal, wgengine/magicsock: check Expired bool on Node; print error in Ping Change-Id: Ic5f533f175a6e1bb73d4957d8c3f970add42e82e Signed-off-by: Andrew Dunham --- ipn/ipnlocal/local.go | 3 +++ wgengine/magicsock/magicsock.go | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 64c48bff8..76c551cb8 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -2275,6 +2275,9 @@ func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netip.Addr) (peer *ta if !ok { return nil, "", fmt.Errorf("no peer found with Tailscale IP %v", ip) } + if peer.Expired { + return nil, "", errors.New("peer's node key has expired") + } base := peerAPIBase(nm, peer) if base == "" { return nil, "", fmt.Errorf("no PeerAPI base found for peer %v (%v)", peer.ID, ip) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index ee219b7c4..1685150e8 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -3647,6 +3647,8 @@ type endpoint struct { // See #540 for background. heartbeatDisabled bool pathFinderRunning bool + + expired bool // whether the node has expired } type pendingCLIPing struct { @@ -3899,6 +3901,12 @@ func (de *endpoint) cliPing(res *ipnstate.PingResult, cb func(*ipnstate.PingResu de.mu.Lock() defer de.mu.Unlock() + if de.expired { + res.Err = errExpired.Error() + cb(res) + return + } + de.pendingCLIPings = append(de.pendingCLIPings, pendingCLIPing{res, cb}) now := mono.Now() @@ -3920,12 +3928,21 @@ func (de *endpoint) cliPing(res *ipnstate.PingResult, cb func(*ipnstate.PingResu de.noteActiveLocked() } +var ( + errExpired = errors.New("peer's node key has expired") + errNoUDPOrDERP = errors.New("no UDP or DERP addr") +) + func (de *endpoint) send(buffs [][]byte) error { if fn := de.sendFunc.Load(); fn != nil { return fn(buffs) } de.mu.Lock() + if de.expired { + de.mu.Unlock() + return errExpired + } // if heartbeat disabled, kick off pathfinder if de.heartbeatDisabled { @@ -3943,7 +3960,7 @@ func (de *endpoint) send(buffs [][]byte) error { de.mu.Unlock() if !udpAddr.IsValid() && !derpAddr.IsValid() { - return errors.New("no UDP or DERP addr") + return errNoUDPOrDERP } var err error if udpAddr.IsValid() { @@ -4112,6 +4129,7 @@ func (de *endpoint) updateFromNode(n *tailcfg.Node, heartbeatDisabled bool) { defer de.mu.Unlock() de.heartbeatDisabled = heartbeatDisabled + de.expired = n.Expired if de.discoKey != n.DiscoKey { de.c.logf("[v1] magicsock: disco: node %s changed from discokey %s to %s", de.publicKey.ShortString(), de.discoKey, n.DiscoKey)