mirror of
https://github.com/tailscale/tailscale.git
synced 2025-03-28 03:52:35 +00:00
wgengine: use mono.Time
Migrate wgengine to mono.Time for performance-sensitive call sites. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
parent
8a3d52e882
commit
f6e833748b
@ -36,6 +36,7 @@ import (
|
|||||||
"tailscale.com/net/tshttpproxy"
|
"tailscale.com/net/tshttpproxy"
|
||||||
"tailscale.com/net/tstun"
|
"tailscale.com/net/tstun"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/tstime/mono"
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -83,7 +84,7 @@ type userspaceEngine struct {
|
|||||||
wgLogger *wglog.Logger //a wireguard-go logging wrapper
|
wgLogger *wglog.Logger //a wireguard-go logging wrapper
|
||||||
reqCh chan struct{}
|
reqCh chan struct{}
|
||||||
waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool
|
waitCh chan struct{} // chan is closed when first Close call completes; contrast with closing bool
|
||||||
timeNow func() time.Time
|
timeNow func() mono.Time
|
||||||
tundev *tstun.Wrapper
|
tundev *tstun.Wrapper
|
||||||
wgdev *device.Device
|
wgdev *device.Device
|
||||||
router router.Router
|
router router.Router
|
||||||
@ -111,12 +112,12 @@ type userspaceEngine struct {
|
|||||||
lastEngineSigFull deephash.Sum // of full wireguard config
|
lastEngineSigFull deephash.Sum // of full wireguard config
|
||||||
lastEngineSigTrim deephash.Sum // of trimmed wireguard config
|
lastEngineSigTrim deephash.Sum // of trimmed wireguard config
|
||||||
lastDNSConfig *dns.Config
|
lastDNSConfig *dns.Config
|
||||||
recvActivityAt map[tailcfg.DiscoKey]time.Time
|
recvActivityAt map[tailcfg.DiscoKey]mono.Time
|
||||||
trimmedDisco map[tailcfg.DiscoKey]bool // set of disco keys of peers currently excluded from wireguard config
|
trimmedDisco map[tailcfg.DiscoKey]bool // set of disco keys of peers currently excluded from wireguard config
|
||||||
sentActivityAt map[netaddr.IP]*int64 // value is atomic int64 of unixtime
|
sentActivityAt map[netaddr.IP]*mono.Time // value is accessed atomically
|
||||||
destIPActivityFuncs map[netaddr.IP]func()
|
destIPActivityFuncs map[netaddr.IP]func()
|
||||||
statusBufioReader *bufio.Reader // reusable for UAPI
|
statusBufioReader *bufio.Reader // reusable for UAPI
|
||||||
lastStatusPollTime time.Time // last time we polled the engine status
|
lastStatusPollTime mono.Time // last time we polled the engine status
|
||||||
|
|
||||||
mu sync.Mutex // guards following; see lock order comment below
|
mu sync.Mutex // guards following; see lock order comment below
|
||||||
netMap *netmap.NetworkMap // or nil
|
netMap *netmap.NetworkMap // or nil
|
||||||
@ -238,7 +239,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
closePool.add(tsTUNDev)
|
closePool.add(tsTUNDev)
|
||||||
|
|
||||||
e := &userspaceEngine{
|
e := &userspaceEngine{
|
||||||
timeNow: time.Now,
|
timeNow: mono.Now,
|
||||||
logf: logf,
|
logf: logf,
|
||||||
reqCh: make(chan struct{}, 1),
|
reqCh: make(chan struct{}, 1),
|
||||||
waitCh: make(chan struct{}),
|
waitCh: make(chan struct{}),
|
||||||
@ -566,7 +567,7 @@ func (e *userspaceEngine) noteReceiveActivity(dk tailcfg.DiscoKey) {
|
|||||||
// had a packet sent to or received from it since t.
|
// had a packet sent to or received from it since t.
|
||||||
//
|
//
|
||||||
// e.wgLock must be held.
|
// e.wgLock must be held.
|
||||||
func (e *userspaceEngine) isActiveSince(dk tailcfg.DiscoKey, ip netaddr.IP, t time.Time) bool {
|
func (e *userspaceEngine) isActiveSince(dk tailcfg.DiscoKey, ip netaddr.IP, t mono.Time) bool {
|
||||||
if e.recvActivityAt[dk].After(t) {
|
if e.recvActivityAt[dk].After(t) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -574,8 +575,7 @@ func (e *userspaceEngine) isActiveSince(dk tailcfg.DiscoKey, ip netaddr.IP, t ti
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
unixTime := atomic.LoadInt64(timePtr)
|
return timePtr.LoadAtomic().After(t)
|
||||||
return unixTime >= t.Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// discoChanged are the set of peers whose disco keys have changed, implying they've restarted.
|
// discoChanged are the set of peers whose disco keys have changed, implying they've restarted.
|
||||||
@ -687,7 +687,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Publ
|
|||||||
func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey, trackIPs []netaddr.IP) {
|
func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey, trackIPs []netaddr.IP) {
|
||||||
// Generate the new map of which discokeys we want to track
|
// Generate the new map of which discokeys we want to track
|
||||||
// receive times for.
|
// receive times for.
|
||||||
mr := map[tailcfg.DiscoKey]time.Time{} // TODO: only recreate this if set of keys changed
|
mr := map[tailcfg.DiscoKey]mono.Time{} // TODO: only recreate this if set of keys changed
|
||||||
for _, dk := range trackDisco {
|
for _, dk := range trackDisco {
|
||||||
// Preserve old times in the new map, but also
|
// Preserve old times in the new map, but also
|
||||||
// populate map entries for new trackDisco values with
|
// populate map entries for new trackDisco values with
|
||||||
@ -699,25 +699,29 @@ func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey
|
|||||||
e.recvActivityAt = mr
|
e.recvActivityAt = mr
|
||||||
|
|
||||||
oldTime := e.sentActivityAt
|
oldTime := e.sentActivityAt
|
||||||
e.sentActivityAt = make(map[netaddr.IP]*int64, len(oldTime))
|
e.sentActivityAt = make(map[netaddr.IP]*mono.Time, len(oldTime))
|
||||||
oldFunc := e.destIPActivityFuncs
|
oldFunc := e.destIPActivityFuncs
|
||||||
e.destIPActivityFuncs = make(map[netaddr.IP]func(), len(oldFunc))
|
e.destIPActivityFuncs = make(map[netaddr.IP]func(), len(oldFunc))
|
||||||
|
|
||||||
updateFn := func(timePtr *int64) func() {
|
updateFn := func(timePtr *mono.Time) func() {
|
||||||
return func() {
|
return func() {
|
||||||
now := e.timeNow().Unix()
|
now := e.timeNow()
|
||||||
old := atomic.LoadInt64(timePtr)
|
old := timePtr.LoadAtomic()
|
||||||
|
|
||||||
// How long's it been since we last sent a packet?
|
// How long's it been since we last sent a packet?
|
||||||
// For our first packet, old is Unix epoch time 0 (1970).
|
elapsed := now.Sub(old)
|
||||||
elapsedSec := now - old
|
if old == 0 {
|
||||||
|
// For our first packet, old is 0, which has indeterminate meaning.
|
||||||
|
// Set elapsed to a big number (four score and seven years).
|
||||||
|
elapsed = 762642 * time.Hour
|
||||||
|
}
|
||||||
|
|
||||||
if elapsedSec >= int64(packetSendTimeUpdateFrequency/time.Second) {
|
if elapsed >= packetSendTimeUpdateFrequency {
|
||||||
atomic.StoreInt64(timePtr, now)
|
timePtr.StoreAtomic(now)
|
||||||
}
|
}
|
||||||
// On a big jump, assume we might no longer be in the wireguard
|
// On a big jump, assume we might no longer be in the wireguard
|
||||||
// config and go check.
|
// config and go check.
|
||||||
if elapsedSec >= int64(packetSendRecheckWireguardThreshold/time.Second) {
|
if elapsed >= packetSendRecheckWireguardThreshold {
|
||||||
e.wgLock.Lock()
|
e.wgLock.Lock()
|
||||||
defer e.wgLock.Unlock()
|
defer e.wgLock.Unlock()
|
||||||
e.maybeReconfigWireguardLocked(nil)
|
e.maybeReconfigWireguardLocked(nil)
|
||||||
@ -728,7 +732,7 @@ func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey
|
|||||||
for _, ip := range trackIPs {
|
for _, ip := range trackIPs {
|
||||||
timePtr := oldTime[ip]
|
timePtr := oldTime[ip]
|
||||||
if timePtr == nil {
|
if timePtr == nil {
|
||||||
timePtr = new(int64)
|
timePtr = new(mono.Time)
|
||||||
}
|
}
|
||||||
e.sentActivityAt[ip] = timePtr
|
e.sentActivityAt[ip] = timePtr
|
||||||
|
|
||||||
|
@ -9,20 +9,20 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/tstun"
|
"tailscale.com/net/tstun"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/tstime/mono"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
"tailscale.com/wgengine/wgcfg"
|
"tailscale.com/wgengine/wgcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNoteReceiveActivity(t *testing.T) {
|
func TestNoteReceiveActivity(t *testing.T) {
|
||||||
now := time.Unix(1, 0)
|
now := mono.Time(123456)
|
||||||
var logBuf bytes.Buffer
|
var logBuf bytes.Buffer
|
||||||
|
|
||||||
confc := make(chan bool, 1)
|
confc := make(chan bool, 1)
|
||||||
@ -35,8 +35,8 @@ func TestNoteReceiveActivity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
e := &userspaceEngine{
|
e := &userspaceEngine{
|
||||||
timeNow: func() time.Time { return now },
|
timeNow: func() mono.Time { return now },
|
||||||
recvActivityAt: map[tailcfg.DiscoKey]time.Time{},
|
recvActivityAt: map[tailcfg.DiscoKey]mono.Time{},
|
||||||
logf: func(format string, a ...interface{}) {
|
logf: func(format string, a ...interface{}) {
|
||||||
fmt.Fprintf(&logBuf, format, a...)
|
fmt.Fprintf(&logBuf, format, a...)
|
||||||
},
|
},
|
||||||
@ -58,7 +58,7 @@ func TestNoteReceiveActivity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now track it, but don't mark it trimmed, so shouldn't update.
|
// Now track it, but don't mark it trimmed, so shouldn't update.
|
||||||
ra[dk] = time.Time{}
|
ra[dk] = 0
|
||||||
e.noteReceiveActivity(dk)
|
e.noteReceiveActivity(dk)
|
||||||
if len(ra) != 1 {
|
if len(ra) != 1 {
|
||||||
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
t.Fatalf("unexpected growth in map: now has %d keys; want 1", len(ra))
|
||||||
@ -114,8 +114,8 @@ func TestUserspaceEngineReconfig(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wantRecvAt := map[tailcfg.DiscoKey]time.Time{
|
wantRecvAt := map[tailcfg.DiscoKey]mono.Time{
|
||||||
dkFromHex(discoHex): time.Time{},
|
dkFromHex(discoHex): 0,
|
||||||
}
|
}
|
||||||
if got := ue.recvActivityAt; !reflect.DeepEqual(got, wantRecvAt) {
|
if got := ue.recvActivityAt; !reflect.DeepEqual(got, wantRecvAt) {
|
||||||
t.Errorf("wrong recvActivityAt\n got: %v\nwant: %v\n", got, wantRecvAt)
|
t.Errorf("wrong recvActivityAt\n got: %v\nwant: %v\n", got, wantRecvAt)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user