mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-22 12:58:37 +00:00
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"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/peterbourgon/ff/v2/ffcli"
|
"github.com/peterbourgon/ff/v2/ffcli"
|
||||||
"github.com/toqueteos/webbrowser"
|
"github.com/toqueteos/webbrowser"
|
||||||
@ -23,7 +22,6 @@ import (
|
|||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/tstime/mono"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
if statusArgs.json {
|
if statusArgs.json {
|
||||||
if statusArgs.active {
|
if statusArgs.active {
|
||||||
for peer, ps := range st.Peer {
|
for peer, ps := range st.Peer {
|
||||||
if !peerActive(ps) {
|
if !ps.Active {
|
||||||
delete(st.Peer, peer)
|
delete(st.Peer, peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +129,6 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
f := func(format string, a ...interface{}) { fmt.Fprintf(&buf, format, a...) }
|
f := func(format string, a ...interface{}) { fmt.Fprintf(&buf, format, a...) }
|
||||||
printPS := func(ps *ipnstate.PeerStatus) {
|
printPS := func(ps *ipnstate.PeerStatus) {
|
||||||
active := peerActive(ps)
|
|
||||||
f("%-15s %-20s %-12s %-7s ",
|
f("%-15s %-20s %-12s %-7s ",
|
||||||
firstIPString(ps.TailscaleIPs),
|
firstIPString(ps.TailscaleIPs),
|
||||||
dnsOrQuoteHostname(st, ps),
|
dnsOrQuoteHostname(st, ps),
|
||||||
@ -140,7 +137,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
)
|
)
|
||||||
relay := ps.Relay
|
relay := ps.Relay
|
||||||
anyTraffic := ps.TxBytes != 0 || ps.RxBytes != 0
|
anyTraffic := ps.TxBytes != 0 || ps.RxBytes != 0
|
||||||
if !active {
|
if !ps.Active {
|
||||||
if ps.ExitNode {
|
if ps.ExitNode {
|
||||||
f("idle; exit node")
|
f("idle; exit node")
|
||||||
} else if anyTraffic {
|
} else if anyTraffic {
|
||||||
@ -179,8 +176,7 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
ipnstate.SortPeers(peers)
|
ipnstate.SortPeers(peers)
|
||||||
for _, ps := range peers {
|
for _, ps := range peers {
|
||||||
active := peerActive(ps)
|
if statusArgs.active && !ps.Active {
|
||||||
if statusArgs.active && !active {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
printPS(ps)
|
printPS(ps)
|
||||||
@ -190,13 +186,6 @@ func runStatus(ctx context.Context, args []string) error {
|
|||||||
return nil
|
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 {
|
func dnsOrQuoteHostname(st *ipnstate.Status, ps *ipnstate.PeerStatus) string {
|
||||||
baseName := dnsname.TrimSuffix(ps.DNSName, st.MagicDNSSuffix)
|
baseName := dnsname.TrimSuffix(ps.DNSName, st.MagicDNSSuffix)
|
||||||
if baseName != "" {
|
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/syncs from tailscale.com/net/interfaces+
|
||||||
tailscale.com/tailcfg from tailscale.com/cmd/tailscale/cli+
|
tailscale.com/tailcfg from tailscale.com/cmd/tailscale/cli+
|
||||||
W tailscale.com/tsconst from tailscale.com/net/interfaces
|
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/tstime/rate from tailscale.com/wgengine/filter
|
||||||
tailscale.com/types/empty from tailscale.com/ipn
|
tailscale.com/types/empty from tailscale.com/ipn
|
||||||
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/tstime/mono"
|
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
@ -91,12 +90,19 @@ type PeerStatus struct {
|
|||||||
RxBytes int64
|
RxBytes int64
|
||||||
TxBytes int64
|
TxBytes int64
|
||||||
Created time.Time // time registered with tailcontrol
|
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
|
LastSeen time.Time // last seen to tailcontrol
|
||||||
LastHandshake time.Time // with local wireguard
|
LastHandshake time.Time // with local wireguard
|
||||||
KeepAlive bool
|
KeepAlive bool
|
||||||
ExitNode bool // true if this is the currently selected exit node.
|
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
|
PeerAPIURL []string
|
||||||
Capabilities []string `json:",omitempty"`
|
Capabilities []string `json:",omitempty"`
|
||||||
|
|
||||||
@ -278,6 +284,9 @@ func (sb *StatusBuilder) AddPeer(peer key.Public, st *PeerStatus) {
|
|||||||
if st.ShareeNode {
|
if st.ShareeNode {
|
||||||
e.ShareeNode = true
|
e.ShareeNode = true
|
||||||
}
|
}
|
||||||
|
if st.Active {
|
||||||
|
e.Active = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusUpdater interface {
|
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("<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")
|
f("</thead>\n<tbody>\n")
|
||||||
|
|
||||||
now := mono.Now()
|
now := time.Now()
|
||||||
|
|
||||||
var peers []*PeerStatus
|
var peers []*PeerStatus
|
||||||
for _, peer := range st.Peers() {
|
for _, peer := range st.Peers() {
|
||||||
@ -378,9 +387,7 @@ table tbody tr:nth-child(even) td { background-color: #f5f5f5; }
|
|||||||
)
|
)
|
||||||
f("<td>")
|
f("<td>")
|
||||||
|
|
||||||
// TODO: let server report this active bool instead
|
if ps.Active {
|
||||||
active := !ps.LastWrite.IsZero() && mono.Since(ps.LastWrite) < 2*time.Minute
|
|
||||||
if active {
|
|
||||||
if ps.Relay != "" && ps.CurAddr == "" {
|
if ps.Relay != "" && ps.CurAddr == "" {
|
||||||
f("relay <b>%s</b>", html.EscapeString(ps.Relay))
|
f("relay <b>%s</b>", html.EscapeString(ps.Relay))
|
||||||
} else if ps.CurAddr != "" {
|
} 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))
|
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.
|
// MarshalJSON formats t for JSON as if it were a time.Time.
|
||||||
// We format Time this way for backwards-compatibility.
|
// We format Time this way for backwards-compatibility.
|
||||||
// This is best-effort only. Time does not survive a MarshalJSON/UnmarshalJSON round trip unchanged.
|
// 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.
|
// 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.
|
// Even in the best of circumstances, it may vary by a few milliseconds.
|
||||||
func (t Time) MarshalJSON() ([]byte, error) {
|
func (t Time) MarshalJSON() ([]byte, error) {
|
||||||
var tt time.Time
|
tt := t.WallTime()
|
||||||
if !t.IsZero() {
|
|
||||||
tt = baseWall.Add(t.Sub(baseMono)).Truncate(0)
|
|
||||||
}
|
|
||||||
return tt.MarshalJSON()
|
return tt.MarshalJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ func (as *addrSet) populatePeerStatus(ps *ipnstate.PeerStatus) {
|
|||||||
as.mu.Lock()
|
as.mu.Lock()
|
||||||
defer as.mu.Unlock()
|
defer as.mu.Unlock()
|
||||||
|
|
||||||
ps.LastWrite = as.lastSend
|
ps.LastWrite = as.lastSend.WallTime()
|
||||||
for i, ua := range as.ipPorts {
|
for i, ua := range as.ipPorts {
|
||||||
if ua.IP() == derpMagicIPAddr {
|
if ua.IP() == derpMagicIPAddr {
|
||||||
continue
|
continue
|
||||||
|
@ -3836,9 +3836,10 @@ func (de *discoEndpoint) populatePeerStatus(ps *ipnstate.PeerStatus) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ps.LastWrite = de.lastSend
|
|
||||||
|
|
||||||
now := mono.Now()
|
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() {
|
if udpAddr, derpAddr := de.addrForSendLocked(now); !udpAddr.IsZero() && derpAddr.IsZero() {
|
||||||
ps.CurAddr = udpAddr.String()
|
ps.CurAddr = udpAddr.String()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user