ipn/ipnstate: move tailscale status "active" determination to tailscaled
Fixes #2579 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
0858673f1f
commit
f3c96df162
|
@ -14,7 +14,6 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/peterbourgon/ff/v2/ffcli"
|
||||
"github.com/toqueteos/webbrowser"
|
||||
|
@ -23,7 +22,6 @@ import (
|
|||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/tstime/mono"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -63,7 +61,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||
if statusArgs.json {
|
||||
if statusArgs.active {
|
||||
for peer, ps := range st.Peer {
|
||||
if !peerActive(ps) {
|
||||
if !ps.Active {
|
||||
delete(st.Peer, peer)
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +129,6 @@ func runStatus(ctx context.Context, args []string) error {
|
|||
var buf bytes.Buffer
|
||||
f := func(format string, a ...interface{}) { fmt.Fprintf(&buf, format, a...) }
|
||||
printPS := func(ps *ipnstate.PeerStatus) {
|
||||
active := peerActive(ps)
|
||||
f("%-15s %-20s %-12s %-7s ",
|
||||
firstIPString(ps.TailscaleIPs),
|
||||
dnsOrQuoteHostname(st, ps),
|
||||
|
@ -140,7 +137,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||
)
|
||||
relay := ps.Relay
|
||||
anyTraffic := ps.TxBytes != 0 || ps.RxBytes != 0
|
||||
if !active {
|
||||
if !ps.Active {
|
||||
if ps.ExitNode {
|
||||
f("idle; exit node")
|
||||
} else if anyTraffic {
|
||||
|
@ -179,8 +176,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||
}
|
||||
ipnstate.SortPeers(peers)
|
||||
for _, ps := range peers {
|
||||
active := peerActive(ps)
|
||||
if statusArgs.active && !active {
|
||||
if statusArgs.active && !ps.Active {
|
||||
continue
|
||||
}
|
||||
printPS(ps)
|
||||
|
@ -190,13 +186,6 @@ func runStatus(ctx context.Context, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// peerActive reports whether ps has recent activity.
|
||||
//
|
||||
// TODO: have the server report this bool instead.
|
||||
func peerActive(ps *ipnstate.PeerStatus) bool {
|
||||
return !ps.LastWrite.IsZero() && mono.Since(ps.LastWrite) < 2*time.Minute
|
||||
}
|
||||
|
||||
func dnsOrQuoteHostname(st *ipnstate.Status, ps *ipnstate.PeerStatus) string {
|
||||
baseName := dnsname.TrimSuffix(ps.DNSName, st.MagicDNSSuffix)
|
||||
if baseName != "" {
|
||||
|
|
|
@ -49,7 +49,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
|||
tailscale.com/syncs from tailscale.com/net/interfaces+
|
||||
tailscale.com/tailcfg from tailscale.com/cmd/tailscale/cli+
|
||||
W tailscale.com/tsconst from tailscale.com/net/interfaces
|
||||
💣 tailscale.com/tstime/mono from tailscale.com/cmd/tailscale/cli+
|
||||
💣 tailscale.com/tstime/mono from tailscale.com/tstime/rate
|
||||
tailscale.com/tstime/rate from tailscale.com/wgengine/filter
|
||||
tailscale.com/types/empty from tailscale.com/ipn
|
||||
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstime/mono"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
@ -91,12 +90,19 @@ type PeerStatus struct {
|
|||
RxBytes int64
|
||||
TxBytes int64
|
||||
Created time.Time // time registered with tailcontrol
|
||||
LastWrite mono.Time // time last packet sent
|
||||
LastWrite time.Time // time last packet sent
|
||||
LastSeen time.Time // last seen to tailcontrol
|
||||
LastHandshake time.Time // with local wireguard
|
||||
KeepAlive bool
|
||||
ExitNode bool // true if this is the currently selected exit node.
|
||||
|
||||
// Active is whether the node was recently active. The
|
||||
// definition is somewhat undefined but has historically and
|
||||
// currently means that there was some packet sent to this
|
||||
// peer in the past two minutes. That definition is subject to
|
||||
// change.
|
||||
Active bool
|
||||
|
||||
PeerAPIURL []string
|
||||
Capabilities []string `json:",omitempty"`
|
||||
|
||||
|
@ -278,6 +284,9 @@ func (sb *StatusBuilder) AddPeer(peer key.Public, st *PeerStatus) {
|
|||
if st.ShareeNode {
|
||||
e.ShareeNode = true
|
||||
}
|
||||
if st.Active {
|
||||
e.Active = true
|
||||
}
|
||||
}
|
||||
|
||||
type StatusUpdater interface {
|
||||
|
@ -321,7 +330,7 @@ table tbody tr:nth-child(even) td { background-color: #f5f5f5; }
|
|||
f("<tr><th>Peer</th><th>OS</th><th>Node</th><th>Owner</th><th>Rx</th><th>Tx</th><th>Activity</th><th>Connection</th></tr>\n")
|
||||
f("</thead>\n<tbody>\n")
|
||||
|
||||
now := mono.Now()
|
||||
now := time.Now()
|
||||
|
||||
var peers []*PeerStatus
|
||||
for _, peer := range st.Peers() {
|
||||
|
@ -378,9 +387,7 @@ table tbody tr:nth-child(even) td { background-color: #f5f5f5; }
|
|||
)
|
||||
f("<td>")
|
||||
|
||||
// TODO: let server report this active bool instead
|
||||
active := !ps.LastWrite.IsZero() && mono.Since(ps.LastWrite) < 2*time.Minute
|
||||
if active {
|
||||
if ps.Active {
|
||||
if ps.Relay != "" && ps.CurAddr == "" {
|
||||
f("relay <b>%s</b>", html.EscapeString(ps.Relay))
|
||||
} else if ps.CurAddr != "" {
|
||||
|
|
|
@ -95,16 +95,21 @@ func (t Time) String() string {
|
|||
return fmt.Sprintf("mono.Time(ns=%d, estimated wall=%v)", int64(t), baseWall.Add(t.Sub(baseMono)).Truncate(0))
|
||||
}
|
||||
|
||||
// WallTime returns an approximate wall time that corresponded to t.
|
||||
func (t Time) WallTime() time.Time {
|
||||
if !t.IsZero() {
|
||||
return baseWall.Add(t.Sub(baseMono)).Truncate(0)
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
// MarshalJSON formats t for JSON as if it were a time.Time.
|
||||
// We format Time this way for backwards-compatibility.
|
||||
// This is best-effort only. Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged.
|
||||
// Since t is a monotonic time, it can vary from the actual wall clock by arbitrary amounts.
|
||||
// Even in the best of circumstances, it may vary by a few milliseconds.
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
var tt time.Time
|
||||
if !t.IsZero() {
|
||||
tt = baseWall.Add(t.Sub(baseMono)).Truncate(0)
|
||||
}
|
||||
tt := t.WallTime()
|
||||
return tt.MarshalJSON()
|
||||
}
|
||||
|
||||
|
|
|
@ -538,7 +538,7 @@ func (as *addrSet) populatePeerStatus(ps *ipnstate.PeerStatus) {
|
|||
as.mu.Lock()
|
||||
defer as.mu.Unlock()
|
||||
|
||||
ps.LastWrite = as.lastSend
|
||||
ps.LastWrite = as.lastSend.WallTime()
|
||||
for i, ua := range as.ipPorts {
|
||||
if ua.IP() == derpMagicIPAddr {
|
||||
continue
|
||||
|
|
|
@ -3836,9 +3836,10 @@ func (de *discoEndpoint) populatePeerStatus(ps *ipnstate.PeerStatus) {
|
|||
return
|
||||
}
|
||||
|
||||
ps.LastWrite = de.lastSend
|
||||
|
||||
now := mono.Now()
|
||||
ps.LastWrite = de.lastSend.WallTime()
|
||||
ps.Active = now.Sub(de.lastSend) < sessionActiveTimeout
|
||||
|
||||
if udpAddr, derpAddr := de.addrForSendLocked(now); !udpAddr.IsZero() && derpAddr.IsZero() {
|
||||
ps.CurAddr = udpAddr.String()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue