wgengine/netlog: merge connstats into package (#17557)
Merge the connstats package into the netlog package and unexport all of its declarations. Remove the buildfeatures.HasConnStats and use HasNetLog instead. Updates tailscale/corp#33352 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
@@ -768,7 +768,6 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/net/bakedroots from tailscale.com/net/tlsdial+
|
tailscale.com/net/bakedroots from tailscale.com/net/tlsdial+
|
||||||
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/connstats from tailscale.com/wgengine/netlog
|
|
||||||
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
||||||
tailscale.com/net/dns/resolvconffile from tailscale.com/cmd/k8s-operator+
|
tailscale.com/net/dns/resolvconffile from tailscale.com/cmd/k8s-operator+
|
||||||
@@ -787,7 +786,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
💣 tailscale.com/net/netns from tailscale.com/derp/derphttp+
|
💣 tailscale.com/net/netns from tailscale.com/derp/derphttp+
|
||||||
tailscale.com/net/netutil from tailscale.com/client/local+
|
tailscale.com/net/netutil from tailscale.com/client/local+
|
||||||
tailscale.com/net/netx from tailscale.com/control/controlclient+
|
tailscale.com/net/netx from tailscale.com/control/controlclient+
|
||||||
tailscale.com/net/packet from tailscale.com/net/connstats+
|
tailscale.com/net/packet from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
||||||
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
tailscale.com/net/portmapper from tailscale.com/feature/portmapper
|
||||||
@@ -835,7 +834,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
||||||
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
||||||
tailscale.com/types/netlogtype from tailscale.com/net/connstats+
|
tailscale.com/types/netlogtype from tailscale.com/wgengine/netlog
|
||||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||||
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/types/opt from tailscale.com/client/tailscale+
|
tailscale.com/types/opt from tailscale.com/client/tailscale+
|
||||||
|
|||||||
@@ -330,7 +330,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/net/bakedroots from tailscale.com/net/tlsdial+
|
tailscale.com/net/bakedroots from tailscale.com/net/tlsdial+
|
||||||
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock+
|
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock+
|
||||||
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/connstats from tailscale.com/wgengine/netlog
|
|
||||||
tailscale.com/net/dns from tailscale.com/cmd/tailscaled+
|
tailscale.com/net/dns from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
||||||
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
||||||
@@ -349,7 +348,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
W 💣 tailscale.com/net/netstat from tailscale.com/portlist
|
W 💣 tailscale.com/net/netstat from tailscale.com/portlist
|
||||||
tailscale.com/net/netutil from tailscale.com/client/local+
|
tailscale.com/net/netutil from tailscale.com/client/local+
|
||||||
tailscale.com/net/netx from tailscale.com/control/controlclient+
|
tailscale.com/net/netx from tailscale.com/control/controlclient+
|
||||||
tailscale.com/net/packet from tailscale.com/net/connstats+
|
tailscale.com/net/packet from tailscale.com/feature/capture+
|
||||||
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
tailscale.com/net/packet/checksum from tailscale.com/net/tstun
|
||||||
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
tailscale.com/net/ping from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/portmapper from tailscale.com/feature/portmapper+
|
tailscale.com/net/portmapper from tailscale.com/feature/portmapper+
|
||||||
@@ -402,7 +401,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/types/logid from tailscale.com/cmd/tailscaled+
|
tailscale.com/types/logid from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
||||||
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
||||||
tailscale.com/types/netlogtype from tailscale.com/net/connstats+
|
tailscale.com/types/netlogtype from tailscale.com/wgengine/netlog
|
||||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||||
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
||||||
|
|||||||
@@ -174,7 +174,6 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
tailscale.com/net/bakedroots from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/bakedroots from tailscale.com/ipn/ipnlocal+
|
||||||
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/connstats from tailscale.com/wgengine/netlog
|
|
||||||
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
||||||
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
||||||
@@ -240,7 +239,7 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
|
|||||||
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
||||||
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
||||||
tailscale.com/types/netlogtype from tailscale.com/net/connstats+
|
tailscale.com/types/netlogtype from tailscale.com/wgengine/netlog
|
||||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||||
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/types/opt from tailscale.com/cmd/tsidp+
|
tailscale.com/types/opt from tailscale.com/cmd/tsidp+
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
// Code generated by gen.go; DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build ts_omit_connstats
|
|
||||||
|
|
||||||
package buildfeatures
|
|
||||||
|
|
||||||
// HasConnStats is whether the binary was built with support for modular feature "Track per-packet connection statistics".
|
|
||||||
// Specifically, it's whether the binary was NOT built with the "ts_omit_connstats" build tag.
|
|
||||||
// It's a const so it can be used for dead code elimination.
|
|
||||||
const HasConnStats = false
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
// Code generated by gen.go; DO NOT EDIT.
|
|
||||||
|
|
||||||
//go:build !ts_omit_connstats
|
|
||||||
|
|
||||||
package buildfeatures
|
|
||||||
|
|
||||||
// HasConnStats is whether the binary was built with support for modular feature "Track per-packet connection statistics".
|
|
||||||
// Specifically, it's whether the binary was NOT built with the "ts_omit_connstats" build tag.
|
|
||||||
// It's a const so it can be used for dead code elimination.
|
|
||||||
const HasConnStats = true
|
|
||||||
@@ -134,11 +134,7 @@ var Features = map[FeatureTag]FeatureMeta{
|
|||||||
Deps: []FeatureTag{"c2n"},
|
Deps: []FeatureTag{"c2n"},
|
||||||
},
|
},
|
||||||
"completion": {Sym: "Completion", Desc: "CLI shell completion"},
|
"completion": {Sym: "Completion", Desc: "CLI shell completion"},
|
||||||
"connstats": {
|
"cloud": {Sym: "Cloud", Desc: "detect cloud environment to learn instances IPs and DNS servers"},
|
||||||
Sym: "ConnStats",
|
|
||||||
Desc: "Track per-packet connection statistics",
|
|
||||||
},
|
|
||||||
"cloud": {Sym: "Cloud", Desc: "detect cloud environment to learn instances IPs and DNS servers"},
|
|
||||||
"dbus": {
|
"dbus": {
|
||||||
Sym: "DBus",
|
Sym: "DBus",
|
||||||
Desc: "Linux DBus support",
|
Desc: "Linux DBus support",
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
//go:build ts_omit_connstats
|
|
||||||
|
|
||||||
package connstats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/netip"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Statistics struct{}
|
|
||||||
|
|
||||||
func NewStatistics(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, virtual, physical any)) *Statistics {
|
|
||||||
return &Statistics{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Statistics) UpdateTxVirtual(b []byte) {}
|
|
||||||
func (s *Statistics) UpdateRxVirtual(b []byte) {}
|
|
||||||
func (s *Statistics) UpdateTxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {}
|
|
||||||
func (s *Statistics) UpdateRxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {}
|
|
||||||
func (s *Statistics) Shutdown(context.Context) error { return nil }
|
|
||||||
+4
-4
@@ -976,7 +976,7 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
|
|||||||
panic(fmt.Sprintf("short copy: %d != %d", n, len(data)-res.dataOffset))
|
panic(fmt.Sprintf("short copy: %d != %d", n, len(data)-res.dataOffset))
|
||||||
}
|
}
|
||||||
sizes[buffsPos] = n
|
sizes[buffsPos] = n
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
if update := t.connCounter.Load(); update != nil {
|
if update := t.connCounter.Load(); update != nil {
|
||||||
updateConnCounter(update, p.Buffer(), false)
|
updateConnCounter(update, p.Buffer(), false)
|
||||||
}
|
}
|
||||||
@@ -1105,7 +1105,7 @@ func (t *Wrapper) injectedRead(res tunInjectedRead, outBuffs [][]byte, sizes []i
|
|||||||
n, err = tun.GSOSplit(pkt, gsoOptions, outBuffs, sizes, offset)
|
n, err = tun.GSOSplit(pkt, gsoOptions, outBuffs, sizes, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
if update := t.connCounter.Load(); update != nil {
|
if update := t.connCounter.Load(); update != nil {
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
updateConnCounter(update, outBuffs[i][offset:offset+sizes[i]], false)
|
updateConnCounter(update, outBuffs[i][offset:offset+sizes[i]], false)
|
||||||
@@ -1275,7 +1275,7 @@ func (t *Wrapper) Write(buffs [][]byte, offset int) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Wrapper) tdevWrite(buffs [][]byte, offset int) (int, error) {
|
func (t *Wrapper) tdevWrite(buffs [][]byte, offset int) (int, error) {
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
if update := t.connCounter.Load(); update != nil {
|
if update := t.connCounter.Load(); update != nil {
|
||||||
for i := range buffs {
|
for i := range buffs {
|
||||||
updateConnCounter(update, buffs[i][offset:], true)
|
updateConnCounter(update, buffs[i][offset:], true)
|
||||||
@@ -1501,7 +1501,7 @@ func (t *Wrapper) Unwrap() tun.Device {
|
|||||||
// SetConnectionCounter specifies a per-connection statistics aggregator.
|
// SetConnectionCounter specifies a per-connection statistics aggregator.
|
||||||
// Nil may be specified to disable statistics gathering.
|
// Nil may be specified to disable statistics gathering.
|
||||||
func (t *Wrapper) SetConnectionCounter(fn netlogfunc.ConnectionCounter) {
|
func (t *Wrapper) SetConnectionCounter(fn netlogfunc.ConnectionCounter) {
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
t.connCounter.Store(fn)
|
t.connCounter.Store(fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ func TestFilter(t *testing.T) {
|
|||||||
tunStats := stats.Clone()
|
tunStats := stats.Clone()
|
||||||
stats.Reset()
|
stats.Reset()
|
||||||
if len(tunStats) > 0 {
|
if len(tunStats) > 0 {
|
||||||
t.Errorf("connstats.Statistics.Extract = %v, want {}", tunStats)
|
t.Errorf("netlogtype.CountsByConnection = %v, want {}", tunStats)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tt.dir == in {
|
if tt.dir == in {
|
||||||
|
|||||||
+1
-2
@@ -170,7 +170,6 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
tailscale.com/net/bakedroots from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/bakedroots from tailscale.com/ipn/ipnlocal+
|
||||||
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
💣 tailscale.com/net/batching from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/captivedetection from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/connstats from tailscale.com/wgengine/netlog
|
|
||||||
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
tailscale.com/net/dns from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
tailscale.com/net/dns/publicdns from tailscale.com/net/dns+
|
||||||
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
tailscale.com/net/dns/resolvconffile from tailscale.com/net/dns+
|
||||||
@@ -235,7 +234,7 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
|
|||||||
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
tailscale.com/types/logid from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
||||||
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
tailscale.com/types/netlogfunc from tailscale.com/net/tstun+
|
||||||
tailscale.com/types/netlogtype from tailscale.com/net/connstats+
|
tailscale.com/types/netlogtype from tailscale.com/wgengine/netlog
|
||||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||||
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
||||||
|
|||||||
@@ -1861,7 +1861,7 @@ func (c *Conn) receiveIP(b []byte, ipp netip.AddrPort, cache *epAddrEndpointCach
|
|||||||
now := mono.Now()
|
now := mono.Now()
|
||||||
ep.lastRecvUDPAny.StoreAtomic(now)
|
ep.lastRecvUDPAny.StoreAtomic(now)
|
||||||
connNoted := ep.noteRecvActivity(src, now)
|
connNoted := ep.noteRecvActivity(src, now)
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
if update := c.connCounter.Load(); update != nil {
|
if update := c.connCounter.Load(); update != nil {
|
||||||
update(0, netip.AddrPortFrom(ep.nodeAddr, 0), ipp, 1, geneveInclusivePacketLen, true)
|
update(0, netip.AddrPortFrom(ep.nodeAddr, 0), ipp, 1, geneveInclusivePacketLen, true)
|
||||||
}
|
}
|
||||||
@@ -3748,7 +3748,7 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
|
|||||||
// SetConnectionCounter specifies a per-connection statistics aggregator.
|
// SetConnectionCounter specifies a per-connection statistics aggregator.
|
||||||
// Nil may be specified to disable statistics gathering.
|
// Nil may be specified to disable statistics gathering.
|
||||||
func (c *Conn) SetConnectionCounter(fn netlogfunc.ConnectionCounter) {
|
func (c *Conn) SetConnectionCounter(fn netlogfunc.ConnectionCounter) {
|
||||||
if buildfeatures.HasConnStats {
|
if buildfeatures.HasNetLog {
|
||||||
c.connCounter.Store(fn)
|
c.connCounter.Store(fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import (
|
|||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/net/connstats"
|
|
||||||
"tailscale.com/net/netmon"
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
@@ -56,7 +55,7 @@ type Logger struct {
|
|||||||
mu sync.Mutex // protects all fields below
|
mu sync.Mutex // protects all fields below
|
||||||
|
|
||||||
logger *logtail.Logger
|
logger *logtail.Logger
|
||||||
stats *connstats.Statistics
|
stats *statistics
|
||||||
tun Device
|
tun Device
|
||||||
sock Device
|
sock Device
|
||||||
|
|
||||||
@@ -132,7 +131,7 @@ func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID lo
|
|||||||
// can upload to the Tailscale log service, so stay below this limit.
|
// can upload to the Tailscale log service, so stay below this limit.
|
||||||
const maxLogSize = 256 << 10
|
const maxLogSize = 256 << 10
|
||||||
const maxConns = (maxLogSize - netlogtype.MaxMessageJSONSize) / netlogtype.MaxConnectionCountsJSONSize
|
const maxConns = (maxLogSize - netlogtype.MaxMessageJSONSize) / netlogtype.MaxConnectionCountsJSONSize
|
||||||
nl.stats = connstats.NewStatistics(pollPeriod, maxConns, func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
nl.stats = newStatistics(pollPeriod, maxConns, func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
||||||
nl.mu.Lock()
|
nl.mu.Lock()
|
||||||
addrs := nl.addrs
|
addrs := nl.addrs
|
||||||
prefixes := nl.prefixes
|
prefixes := nl.prefixes
|
||||||
@@ -151,7 +150,7 @@ func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID lo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func recordStatistics(logger *logtail.Logger, nodeID tailcfg.StableNodeID, start, end time.Time, connstats, sockStats map[netlogtype.Connection]netlogtype.Counts, addrs map[netip.Addr]bool, prefixes map[netip.Prefix]bool, logExitFlowEnabled bool) {
|
func recordStatistics(logger *logtail.Logger, nodeID tailcfg.StableNodeID, start, end time.Time, connStats, sockStats map[netlogtype.Connection]netlogtype.Counts, addrs map[netip.Addr]bool, prefixes map[netip.Prefix]bool, logExitFlowEnabled bool) {
|
||||||
m := netlogtype.Message{NodeID: nodeID, Start: start.UTC(), End: end.UTC()}
|
m := netlogtype.Message{NodeID: nodeID, Start: start.UTC(), End: end.UTC()}
|
||||||
|
|
||||||
classifyAddr := func(a netip.Addr) (isTailscale, withinRoute bool) {
|
classifyAddr := func(a netip.Addr) (isTailscale, withinRoute bool) {
|
||||||
@@ -170,7 +169,7 @@ func recordStatistics(logger *logtail.Logger, nodeID tailcfg.StableNodeID, start
|
|||||||
}
|
}
|
||||||
|
|
||||||
exitTraffic := make(map[netlogtype.Connection]netlogtype.Counts)
|
exitTraffic := make(map[netlogtype.Connection]netlogtype.Counts)
|
||||||
for conn, cnts := range connstats {
|
for conn, cnts := range connStats {
|
||||||
srcIsTailscaleIP, srcWithinSubnet := classifyAddr(conn.Src.Addr())
|
srcIsTailscaleIP, srcWithinSubnet := classifyAddr(conn.Src.Addr())
|
||||||
dstIsTailscaleIP, dstWithinSubnet := classifyAddr(conn.Dst.Addr())
|
dstIsTailscaleIP, dstWithinSubnet := classifyAddr(conn.Dst.Addr())
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
//go:build !ts_omit_connstats
|
//go:build !ts_omit_netlog && !ts_omit_logtail
|
||||||
|
|
||||||
// Package connstats maintains statistics about connections
|
package netlog
|
||||||
// flowing through a TUN device (which operate at the IP layer).
|
|
||||||
package connstats
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -20,10 +18,10 @@ import (
|
|||||||
"tailscale.com/types/netlogtype"
|
"tailscale.com/types/netlogtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Statistics maintains counters for every connection.
|
// statistics maintains counters for every connection.
|
||||||
// All methods are safe for concurrent use.
|
// All methods are safe for concurrent use.
|
||||||
// The zero value is ready for use.
|
// The zero value is ready for use.
|
||||||
type Statistics struct {
|
type statistics struct {
|
||||||
maxConns int // immutable once set
|
maxConns int // immutable once set
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -42,13 +40,13 @@ type connCnts struct {
|
|||||||
physical map[netlogtype.Connection]netlogtype.Counts
|
physical map[netlogtype.Connection]netlogtype.Counts
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStatistics creates a data structure for tracking connection statistics
|
// newStatistics creates a data structure for tracking connection statistics
|
||||||
// that periodically dumps the virtual and physical connection counts
|
// that periodically dumps the virtual and physical connection counts
|
||||||
// depending on whether the maxPeriod or maxConns is exceeded.
|
// depending on whether the maxPeriod or maxConns is exceeded.
|
||||||
// The dump function is called from a single goroutine.
|
// The dump function is called from a single goroutine.
|
||||||
// Shutdown must be called to cleanup resources.
|
// Shutdown must be called to cleanup resources.
|
||||||
func NewStatistics(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts)) *Statistics {
|
func newStatistics(maxPeriod time.Duration, maxConns int, dump func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts)) *statistics {
|
||||||
s := &Statistics{maxConns: maxConns}
|
s := &statistics{maxConns: maxConns}
|
||||||
s.connCntsCh = make(chan connCnts, 256)
|
s.connCntsCh = make(chan connCnts, 256)
|
||||||
s.shutdownCtx, s.shutdown = context.WithCancel(context.Background())
|
s.shutdownCtx, s.shutdown = context.WithCancel(context.Background())
|
||||||
s.group.Go(func() error {
|
s.group.Go(func() error {
|
||||||
@@ -85,7 +83,7 @@ func NewStatistics(maxPeriod time.Duration, maxConns int, dump func(start, end t
|
|||||||
// UpdateTxVirtual updates the counters for a transmitted IP packet
|
// UpdateTxVirtual updates the counters for a transmitted IP packet
|
||||||
// The source and destination of the packet directly correspond with
|
// The source and destination of the packet directly correspond with
|
||||||
// the source and destination in netlogtype.Connection.
|
// the source and destination in netlogtype.Connection.
|
||||||
func (s *Statistics) UpdateTxVirtual(b []byte) {
|
func (s *statistics) UpdateTxVirtual(b []byte) {
|
||||||
var p packet.Parsed
|
var p packet.Parsed
|
||||||
p.Decode(b)
|
p.Decode(b)
|
||||||
s.UpdateVirtual(p.IPProto, p.Src, p.Dst, 1, len(b), false)
|
s.UpdateVirtual(p.IPProto, p.Src, p.Dst, 1, len(b), false)
|
||||||
@@ -94,7 +92,7 @@ func (s *Statistics) UpdateTxVirtual(b []byte) {
|
|||||||
// UpdateRxVirtual updates the counters for a received IP packet.
|
// UpdateRxVirtual updates the counters for a received IP packet.
|
||||||
// The source and destination of the packet are inverted with respect to
|
// The source and destination of the packet are inverted with respect to
|
||||||
// the source and destination in netlogtype.Connection.
|
// the source and destination in netlogtype.Connection.
|
||||||
func (s *Statistics) UpdateRxVirtual(b []byte) {
|
func (s *statistics) UpdateRxVirtual(b []byte) {
|
||||||
var p packet.Parsed
|
var p packet.Parsed
|
||||||
p.Decode(b)
|
p.Decode(b)
|
||||||
s.UpdateVirtual(p.IPProto, p.Dst, p.Src, 1, len(b), true)
|
s.UpdateVirtual(p.IPProto, p.Dst, p.Src, 1, len(b), true)
|
||||||
@@ -105,7 +103,7 @@ var (
|
|||||||
tailscaleServiceIPv6 = tsaddr.TailscaleServiceIPv6()
|
tailscaleServiceIPv6 = tsaddr.TailscaleServiceIPv6()
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Statistics) UpdateVirtual(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, receive bool) {
|
func (s *statistics) UpdateVirtual(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, receive bool) {
|
||||||
// Network logging is defined as traffic between two Tailscale nodes.
|
// Network logging is defined as traffic between two Tailscale nodes.
|
||||||
// Traffic with the internal Tailscale service is not with another node
|
// Traffic with the internal Tailscale service is not with another node
|
||||||
// and should not be logged. It also happens to be a high volume
|
// and should not be logged. It also happens to be a high volume
|
||||||
@@ -137,7 +135,7 @@ func (s *Statistics) UpdateVirtual(proto ipproto.Proto, src, dst netip.AddrPort,
|
|||||||
// The src is always a Tailscale IP address, representing some remote peer.
|
// The src is always a Tailscale IP address, representing some remote peer.
|
||||||
// The dst is a remote IP address and port that corresponds
|
// The dst is a remote IP address and port that corresponds
|
||||||
// with some physical peer backing the Tailscale IP address.
|
// with some physical peer backing the Tailscale IP address.
|
||||||
func (s *Statistics) UpdateTxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {
|
func (s *statistics) UpdateTxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {
|
||||||
s.UpdatePhysical(0, netip.AddrPortFrom(src, 0), dst, packets, bytes, false)
|
s.UpdatePhysical(0, netip.AddrPortFrom(src, 0), dst, packets, bytes, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +143,11 @@ func (s *Statistics) UpdateTxPhysical(src netip.Addr, dst netip.AddrPort, packet
|
|||||||
// The src is always a Tailscale IP address, representing some remote peer.
|
// The src is always a Tailscale IP address, representing some remote peer.
|
||||||
// The dst is a remote IP address and port that corresponds
|
// The dst is a remote IP address and port that corresponds
|
||||||
// with some physical peer backing the Tailscale IP address.
|
// with some physical peer backing the Tailscale IP address.
|
||||||
func (s *Statistics) UpdateRxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {
|
func (s *statistics) UpdateRxPhysical(src netip.Addr, dst netip.AddrPort, packets, bytes int) {
|
||||||
s.UpdatePhysical(0, netip.AddrPortFrom(src, 0), dst, packets, bytes, true)
|
s.UpdatePhysical(0, netip.AddrPortFrom(src, 0), dst, packets, bytes, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Statistics) UpdatePhysical(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, receive bool) {
|
func (s *statistics) UpdatePhysical(proto ipproto.Proto, src, dst netip.AddrPort, packets, bytes int, receive bool) {
|
||||||
conn := netlogtype.Connection{Proto: proto, Src: src, Dst: dst}
|
conn := netlogtype.Connection{Proto: proto, Src: src, Dst: dst}
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
@@ -170,7 +168,7 @@ func (s *Statistics) UpdatePhysical(proto ipproto.Proto, src, dst netip.AddrPort
|
|||||||
|
|
||||||
// preInsertConn updates the maps to handle insertion of a new connection.
|
// preInsertConn updates the maps to handle insertion of a new connection.
|
||||||
// It reports false if insertion is not allowed (i.e., after shutdown).
|
// It reports false if insertion is not allowed (i.e., after shutdown).
|
||||||
func (s *Statistics) preInsertConn() bool {
|
func (s *statistics) preInsertConn() bool {
|
||||||
// Check whether insertion of a new connection will exceed maxConns.
|
// Check whether insertion of a new connection will exceed maxConns.
|
||||||
if len(s.virtual)+len(s.physical) == s.maxConns && s.maxConns > 0 {
|
if len(s.virtual)+len(s.physical) == s.maxConns && s.maxConns > 0 {
|
||||||
// Extract the current statistics and send it to the serializer.
|
// Extract the current statistics and send it to the serializer.
|
||||||
@@ -192,13 +190,13 @@ func (s *Statistics) preInsertConn() bool {
|
|||||||
return s.shutdownCtx.Err() == nil
|
return s.shutdownCtx.Err() == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Statistics) extract() connCnts {
|
func (s *statistics) extract() connCnts {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
return s.extractLocked()
|
return s.extractLocked()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Statistics) extractLocked() connCnts {
|
func (s *statistics) extractLocked() connCnts {
|
||||||
if len(s.virtual)+len(s.physical) == 0 {
|
if len(s.virtual)+len(s.physical) == 0 {
|
||||||
return connCnts{}
|
return connCnts{}
|
||||||
}
|
}
|
||||||
@@ -210,7 +208,7 @@ func (s *Statistics) extractLocked() connCnts {
|
|||||||
|
|
||||||
// TestExtract synchronously extracts the current network statistics map
|
// TestExtract synchronously extracts the current network statistics map
|
||||||
// and resets the counters. This should only be used for testing purposes.
|
// and resets the counters. This should only be used for testing purposes.
|
||||||
func (s *Statistics) TestExtract() (virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
func (s *statistics) TestExtract() (virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
||||||
cc := s.extract()
|
cc := s.extract()
|
||||||
return cc.virtual, cc.physical
|
return cc.virtual, cc.physical
|
||||||
}
|
}
|
||||||
@@ -218,7 +216,7 @@ func (s *Statistics) TestExtract() (virtual, physical map[netlogtype.Connection]
|
|||||||
// Shutdown performs a final flush of statistics.
|
// Shutdown performs a final flush of statistics.
|
||||||
// Statistics for any subsequent calls to Update will be dropped.
|
// Statistics for any subsequent calls to Update will be dropped.
|
||||||
// It is safe to call Shutdown concurrently and repeatedly.
|
// It is safe to call Shutdown concurrently and repeatedly.
|
||||||
func (s *Statistics) Shutdown(context.Context) error {
|
func (s *statistics) Shutdown(context.Context) error {
|
||||||
s.shutdown()
|
s.shutdown()
|
||||||
return s.group.Wait()
|
return s.group.Wait()
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
package connstats
|
package netlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -54,7 +54,7 @@ func TestInterval(t *testing.T) {
|
|||||||
const maxConns = 2048
|
const maxConns = 2048
|
||||||
|
|
||||||
gotDump := make(chan struct{}, 1)
|
gotDump := make(chan struct{}, 1)
|
||||||
stats := NewStatistics(maxPeriod, maxConns, func(_, _ time.Time, _, _ map[netlogtype.Connection]netlogtype.Counts) {
|
stats := newStatistics(maxPeriod, maxConns, func(_, _ time.Time, _, _ map[netlogtype.Connection]netlogtype.Counts) {
|
||||||
select {
|
select {
|
||||||
case gotDump <- struct{}{}:
|
case gotDump <- struct{}{}:
|
||||||
default:
|
default:
|
||||||
@@ -86,7 +86,7 @@ func TestConcurrent(t *testing.T) {
|
|||||||
const maxPeriod = 10 * time.Millisecond
|
const maxPeriod = 10 * time.Millisecond
|
||||||
const maxConns = 10
|
const maxConns = 10
|
||||||
virtualAggregate := make(map[netlogtype.Connection]netlogtype.Counts)
|
virtualAggregate := make(map[netlogtype.Connection]netlogtype.Counts)
|
||||||
stats := NewStatistics(maxPeriod, maxConns, func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
stats := newStatistics(maxPeriod, maxConns, func(start, end time.Time, virtual, physical map[netlogtype.Connection]netlogtype.Counts) {
|
||||||
c.Assert(start.IsZero(), qt.IsFalse)
|
c.Assert(start.IsZero(), qt.IsFalse)
|
||||||
c.Assert(end.IsZero(), qt.IsFalse)
|
c.Assert(end.IsZero(), qt.IsFalse)
|
||||||
c.Assert(end.Before(start), qt.IsFalse)
|
c.Assert(end.Before(start), qt.IsFalse)
|
||||||
@@ -170,7 +170,7 @@ func Benchmark(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for range b.N {
|
for range b.N {
|
||||||
s := NewStatistics(0, 0, nil)
|
s := newStatistics(0, 0, nil)
|
||||||
for j := 0; j < 1e3; j++ {
|
for j := 0; j < 1e3; j++ {
|
||||||
s.UpdateTxVirtual(p)
|
s.UpdateTxVirtual(p)
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ func Benchmark(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for range b.N {
|
for range b.N {
|
||||||
s := NewStatistics(0, 0, nil)
|
s := newStatistics(0, 0, nil)
|
||||||
for j := 0; j < 1e3; j++ {
|
for j := 0; j < 1e3; j++ {
|
||||||
binary.BigEndian.PutUint32(p[20:], uint32(j)) // unique port combination
|
binary.BigEndian.PutUint32(p[20:], uint32(j)) // unique port combination
|
||||||
s.UpdateTxVirtual(p)
|
s.UpdateTxVirtual(p)
|
||||||
@@ -193,7 +193,7 @@ func Benchmark(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for range b.N {
|
for range b.N {
|
||||||
s := NewStatistics(0, 0, nil)
|
s := newStatistics(0, 0, nil)
|
||||||
var group sync.WaitGroup
|
var group sync.WaitGroup
|
||||||
for j := 0; j < runtime.NumCPU(); j++ {
|
for j := 0; j < runtime.NumCPU(); j++ {
|
||||||
group.Add(1)
|
group.Add(1)
|
||||||
@@ -215,7 +215,7 @@ func Benchmark(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for range b.N {
|
for range b.N {
|
||||||
s := NewStatistics(0, 0, nil)
|
s := newStatistics(0, 0, nil)
|
||||||
var group sync.WaitGroup
|
var group sync.WaitGroup
|
||||||
for j := 0; j < runtime.NumCPU(); j++ {
|
for j := 0; j < runtime.NumCPU(); j++ {
|
||||||
group.Add(1)
|
group.Add(1)
|
||||||
Reference in New Issue
Block a user