diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 76c551cb8..170d778c6 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -715,6 +715,10 @@ func peerStatusFromNode(ps *ipnstate.PeerStatus, n *tailcfg.Node) { v := views.IPPrefixSliceOf(n.PrimaryRoutes) ps.PrimaryRoutes = &v } + + if n.Expired { + ps.Expired = true + } } // WhoIs reports the node and user who owns the node with the given IP:port. diff --git a/ipn/ipnstate/ipnstate.go b/ipn/ipnstate/ipnstate.go index 3250fc1dc..7e4f31847 100644 --- a/ipn/ipnstate/ipnstate.go +++ b/ipn/ipnstate/ipnstate.go @@ -246,6 +246,11 @@ type PeerStatus struct { // InEngine means that this peer is tracked by the wireguard engine. // In theory, all of InNetworkMap and InMagicSock and InEngine should all be true. InEngine bool + + // Expired means that this peer's node key has expired, based on either + // information from control or optimisically set on the client if the + // expiration time has passed. + Expired bool `json:",omitempty"` } type StatusBuilder struct { @@ -427,6 +432,9 @@ func (sb *StatusBuilder) AddPeer(peer key.NodePublic, st *PeerStatus) { if st.PeerAPIURL != nil { e.PeerAPIURL = st.PeerAPIURL } + if st.Expired { + e.Expired = true + } } type StatusUpdater interface {