From 3a182d5dd6b9a0f3fed9ae1aaad50786d667f870 Mon Sep 17 00:00:00 2001 From: Melanie Warrick Date: Tue, 7 Jun 2022 12:31:10 -0700 Subject: [PATCH] ipn/ipnstate: add ExitNodeStatus to share the exit node if it is in use, the IP, ID and whether its online. (#4761) - Updates #4619 Signed-off-by: nyghtowl --- ipn/ipnlocal/local.go | 14 ++++++++++++++ ipn/ipnstate/ipnstate.go | 16 ++++++++++++++++ types/netmap/netmap.go | 10 ++++++++++ 3 files changed, 40 insertions(+) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 334f9a407..dd3a1414f 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -425,6 +425,20 @@ func (b *LocalBackend) updateStatus(sb *ipnstate.StatusBuilder, extraLocked func s.CurrentTailnet.MagicDNSSuffix = b.netMap.MagicDNSSuffix() s.CurrentTailnet.MagicDNSEnabled = b.netMap.DNS.Proxied s.CurrentTailnet.Name = b.netMap.Domain + if b.prefs != nil && !b.prefs.ExitNodeID.IsZero() { + if exitPeer, ok := b.netMap.PeerWithStableID(b.prefs.ExitNodeID); ok { + var online = false + if exitPeer.Online != nil { + online = *exitPeer.Online + } + s.ExitNodeStatus = &ipnstate.ExitNodeStatus{ + ID: b.prefs.ExitNodeID, + Online: online, + TailscaleIPs: exitPeer.Addresses, + } + } + + } } }) sb.MutateSelfStatus(func(ss *ipnstate.PeerStatus) { diff --git a/ipn/ipnstate/ipnstate.go b/ipn/ipnstate/ipnstate.go index f0322878d..fb7babdf6 100644 --- a/ipn/ipnstate/ipnstate.go +++ b/ipn/ipnstate/ipnstate.go @@ -38,6 +38,10 @@ type Status struct { TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node Self *PeerStatus + // ExitNodeStatus describes the current exit node. + // If nil, an exit node is not in use. + ExitNodeStatus *ExitNodeStatus `json:"ExitNodeStatus,omitempty"` + // Health contains health check problems. // Empty means everything is good. (or at least that no known // problems are detected) @@ -81,6 +85,18 @@ type TailnetStatus struct { MagicDNSEnabled bool } +// ExitNodeStatus describes the current exit node. +type ExitNodeStatus struct { + // ID is the exit node's ID. + ID tailcfg.StableNodeID + + // Online is whether the exit node is alive. + Online bool + + // TailscaleIPs are the exit node's IP addresses assigned to the node. + TailscaleIPs []netaddr.IPPrefix +} + func (s *Status) Peers() []key.NodePublic { kk := make([]key.NodePublic, 0, len(s.Peer)) for k := range s.Peer { diff --git a/types/netmap/netmap.go b/types/netmap/netmap.go index 9946cb823..8d899ef5d 100644 --- a/types/netmap/netmap.go +++ b/types/netmap/netmap.go @@ -122,6 +122,16 @@ func (nm *NetworkMap) VeryConcise() string { return buf.String() } +// PeerWithStableID finds and returns the peer associated to the inputted StableNodeID. +func (nm *NetworkMap) PeerWithStableID(pid tailcfg.StableNodeID) (_ *tailcfg.Node, ok bool) { + for _, p := range nm.Peers { + if p.StableID == pid { + return p, true + } + } + return nil, false +} + // printConciseHeader prints a concise header line representing nm to buf. // // If this function is changed to access different fields of nm, keep