Compare commits

...

1 Commits

Author SHA1 Message Date
julianknodt
4f1e783ad8 wgengine: log connection metrics
Adds counter for connection types, which aren't currently bubbled up anywhere but can be easily
in the future.

Signed-off-by: julianknodt <julianknodt@gmail.com>
2021-08-20 12:04:28 -07:00
3 changed files with 27 additions and 0 deletions

View File

@@ -190,6 +190,9 @@ type Conn struct {
// havePrivateKey is whether privateKey is non-zero.
havePrivateKey syncs.AtomicBool
// DERPCount is the number of DERP connections created.
DERPCount uint32
// port is the preferred port from opts.Port; 0 means auto.
port syncs.AtomicUint32
@@ -350,6 +353,7 @@ func (c *Conn) addDerpPeerRoute(peer key.Public, derpID int, dc *derphttp.Client
if c.derpRoute == nil {
c.derpRoute = make(map[key.Public]derpRoute)
}
atomic.AddUint32(&c.DERPCount, 1)
r := derpRoute{derpID, dc}
c.derpRoute[peer] = r
}

View File

@@ -9,6 +9,7 @@ import (
"os"
"runtime"
"strconv"
"sync/atomic"
"time"
"tailscale.com/ipn/ipnstate"
@@ -122,6 +123,9 @@ func (e *userspaceEngine) trackOpenPostFilterOut(pp *packet.Parsed, t *tstun.Wra
}
}
// Accepted a flow, log the flow kind
atomic.AddUint32(&e.connMetrics.direct, 1)
timer := time.AfterFunc(tcpTimeoutBeforeDebug, func() {
e.onOpenTimeout(flow)
})
@@ -153,6 +157,7 @@ func (e *userspaceEngine) onOpenTimeout(flow flowtrack.Tuple) {
e.mu.Unlock()
if !problem.IsZero() {
atomic.AddUint32(&e.connMetrics.unreachable, 1)
e.logf("open-conn-track: timeout opening %v; peer reported problem: %v", flow, problem)
}
@@ -160,14 +165,17 @@ func (e *userspaceEngine) onOpenTimeout(flow flowtrack.Tuple) {
n, err := e.peerForIP(flow.Dst.IP())
if err != nil {
e.logf("open-conn-track: timeout opening %v; peerForIP: %v", flow, err)
atomic.AddUint32(&e.connMetrics.unreachable, 1)
return
}
if n == nil {
e.logf("open-conn-track: timeout opening %v; no associated peer node", flow)
atomic.AddUint32(&e.connMetrics.unreachable, 1)
return
}
if n.DiscoKey.IsZero() {
e.logf("open-conn-track: timeout opening %v; peer node %v running pre-0.100", flow, n.Key.ShortString())
atomic.AddUint32(&e.connMetrics.unreachable, 1)
return
}
if n.DERP == "" {

View File

@@ -119,6 +119,8 @@ type userspaceEngine struct {
statusBufioReader *bufio.Reader // reusable for UAPI
lastStatusPollTime mono.Time // last time we polled the engine status
connMetrics metrics // counts for success/failure/kinds of connections.
mu sync.Mutex // guards following; see lock order comment below
netMap *netmap.NetworkMap // or nil
closing bool // Close was called (even if we're still closing)
@@ -133,6 +135,19 @@ type userspaceEngine struct {
// Lock ordering: magicsock.Conn.mu, wgLock, then mu.
}
type metrics struct {
// offline is the number of flows magicsock attempted to connect to which are offline.
offline uint32
// relayed is the number of flows magicsock connected thru over DERP.
relayed uint32
// direct is the number of flows connected to directly.
direct uint32
// unreachable is the number of flows which were expected to be online but could not be
// connected to. This is expected to be small, as there is only a brief window where flows are
// offline but have not yet notified control.
unreachable uint32
}
// InternalsGetter is implemented by Engines that can export their internals.
type InternalsGetter interface {
GetInternals() (_ *tstun.Wrapper, _ *magicsock.Conn, ok bool)