diff --git a/hscontrol/grpcv1.go b/hscontrol/grpcv1.go index 8b516c3e..38cc6ff6 100644 --- a/hscontrol/grpcv1.go +++ b/hscontrol/grpcv1.go @@ -544,6 +544,7 @@ func nodesToProto(polMan policy.PolicyManager, isLikelyConnected *xsync.MapOf[ty // currently connected nodes. if val, ok := isLikelyConnected.Load(node.ID); ok && val { resp.Online = true + resp.LastSeen = timestamppb.New(time.Now()) } var tags []string diff --git a/hscontrol/mapper/mapper.go b/hscontrol/mapper/mapper.go index d7deb0a5..455271fa 100644 --- a/hscontrol/mapper/mapper.go +++ b/hscontrol/mapper/mapper.go @@ -504,7 +504,7 @@ func (m *Mapper) ListPeers(nodeID types.NodeID, peerIDs ...types.NodeID) (types. for _, peer := range peers { online := m.notif.IsLikelyConnected(peer.ID) - peer.IsOnline = &online + peer.IsOnline = online } return peers, nil @@ -520,7 +520,7 @@ func (m *Mapper) ListNodes(nodeIDs ...types.NodeID) (types.Nodes, error) { for _, node := range nodes { online := m.notif.IsLikelyConnected(node.ID) - node.IsOnline = &online + node.IsOnline = online } return nodes, nil diff --git a/hscontrol/mapper/mapper_test.go b/hscontrol/mapper/mapper_test.go index dfce60bb..61403786 100644 --- a/hscontrol/mapper/mapper_test.go +++ b/hscontrol/mapper/mapper_test.go @@ -17,6 +17,7 @@ import ( "tailscale.com/tailcfg" "tailscale.com/types/dnstype" "tailscale.com/types/key" + "tailscale.com/types/ptr" ) var iap = func(ipStr string) *netip.Addr { @@ -184,6 +185,7 @@ func Test_fullMapResponse(t *testing.T) { }), Created: created, Tags: []string{}, + Online: ptr.To(false), LastSeen: &lastSeen, MachineAuthorized: true, @@ -239,6 +241,7 @@ func Test_fullMapResponse(t *testing.T) { Hostinfo: hiview(tailcfg.Hostinfo{}), Created: created, Tags: []string{}, + Online: ptr.To(false), LastSeen: &lastSeen, MachineAuthorized: true, diff --git a/hscontrol/mapper/tail.go b/hscontrol/mapper/tail.go index eae70e96..03cb901f 100644 --- a/hscontrol/mapper/tail.go +++ b/hscontrol/mapper/tail.go @@ -9,6 +9,7 @@ import ( "github.com/samber/lo" "tailscale.com/net/tsaddr" "tailscale.com/tailcfg" + "tailscale.com/types/ptr" ) func tailNodes( @@ -107,7 +108,7 @@ func tailNode( Hostinfo: node.Hostinfo.View(), Created: node.CreatedAt.UTC(), - Online: node.IsOnline, + Online: ptr.To(node.IsOnline), Tags: tags, @@ -125,7 +126,10 @@ func tailNode( tNode.CapMap[tailcfg.NodeAttrRandomizeClientPort] = []tailcfg.RawMessage{} } - if node.IsOnline == nil || !*node.IsOnline { + if node.IsOnline { + // If the node is online, return the current time. + tNode.LastSeen = ptr.To(time.Now()) + } else { // LastSeen is only set when node is // not connected to the control server. tNode.LastSeen = node.LastSeen diff --git a/hscontrol/mapper/tail_test.go b/hscontrol/mapper/tail_test.go index cacc4930..e0b35467 100644 --- a/hscontrol/mapper/tail_test.go +++ b/hscontrol/mapper/tail_test.go @@ -15,6 +15,7 @@ import ( "tailscale.com/net/tsaddr" "tailscale.com/tailcfg" "tailscale.com/types/key" + "tailscale.com/types/ptr" ) func TestTailNode(t *testing.T) { @@ -73,6 +74,7 @@ func TestTailNode(t *testing.T) { Tags: []string{}, MachineAuthorized: true, + Online: ptr.To(false), CapMap: tailcfg.NodeCapMap{ tailcfg.CapabilityFileSharing: []tailcfg.RawMessage{}, tailcfg.CapabilityAdmin: []tailcfg.RawMessage{}, @@ -158,6 +160,7 @@ func TestTailNode(t *testing.T) { Tags: []string{}, + Online: ptr.To(false), LastSeen: &lastSeen, MachineAuthorized: true, @@ -186,6 +189,7 @@ func TestTailNode(t *testing.T) { Hostinfo: hiview(tailcfg.Hostinfo{}), Tags: []string{}, MachineAuthorized: true, + Online: ptr.To(false), CapMap: tailcfg.NodeCapMap{ tailcfg.CapabilityFileSharing: []tailcfg.RawMessage{}, diff --git a/hscontrol/types/node.go b/hscontrol/types/node.go index da185563..22c9b474 100644 --- a/hscontrol/types/node.go +++ b/hscontrol/types/node.go @@ -110,7 +110,7 @@ type Node struct { UpdatedAt time.Time DeletedAt *time.Time - IsOnline *bool `gorm:"-"` + IsOnline bool `gorm:"-"` } type Nodes []*Node @@ -512,7 +512,7 @@ func (node *Node) ApplyPeerChange(change *tailcfg.PeerChange) { } if change.Online != nil { - node.IsOnline = change.Online + node.IsOnline = *change.Online } if change.Endpoints != nil {