From c2202cc27c568b522a458b29b876efa7b883de65 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 21 Jul 2021 10:43:53 -0700 Subject: [PATCH] net/tstun: use mono.Time There's a call to Now once per packet. Move to mono.Now. Though the current implementation provides high precision, we document it to be coarse, to preserve the ability to switch to a coarse monotonic time later. Signed-off-by: Josh Bleecher Snyder --- cmd/tailscaled/depaware.txt | 1 + net/tstun/wrap.go | 13 +++++++------ net/tstun/wrap_test.go | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index d7b9557ca..1b13159ff 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -130,6 +130,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/tailcfg from tailscale.com/control/controlclient+ W tailscale.com/tsconst from tailscale.com/net/interfaces tailscale.com/tstime from tailscale.com/wgengine/magicsock + 💣 tailscale.com/tstime/mono from tailscale.com/net/tstun tailscale.com/types/empty from tailscale.com/control/controlclient+ tailscale.com/types/flagtype from tailscale.com/cmd/tailscaled tailscale.com/types/ipproto from tailscale.com/net/flowtrack+ diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go index 431f33850..63d8b065a 100644 --- a/net/tstun/wrap.go +++ b/net/tstun/wrap.go @@ -18,6 +18,7 @@ import ( "golang.zx2c4.com/wireguard/tun" "inet.af/netaddr" "tailscale.com/net/packet" + "tailscale.com/tstime/mono" "tailscale.com/types/ipproto" "tailscale.com/types/logger" "tailscale.com/wgengine/filter" @@ -64,7 +65,7 @@ type Wrapper struct { closeOnce sync.Once - lastActivityAtomic int64 // unix seconds of last send or receive + lastActivityAtomic mono.Time // time of last send or receive destIPActivity atomic.Value // of map[netaddr.IP]func() @@ -165,6 +166,7 @@ func Wrap(logf logger.Logf, tdev tun.Device) *Wrapper { go tun.pumpEvents() // The buffer starts out consumed. tun.bufferConsumed <- struct{}{} + tun.noteActivity() return tun } @@ -364,16 +366,15 @@ func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response { // noteActivity records that there was a read or write at the current time. func (t *Wrapper) noteActivity() { - atomic.StoreInt64(&t.lastActivityAtomic, time.Now().Unix()) + t.lastActivityAtomic.StoreAtomic(mono.Now()) } // IdleDuration reports how long it's been since the last read or write to this device. // -// Its value is only accurate to roughly second granularity. -// If there's never been activity, the duration is since 1970. +// Its value should only be presumed accurate to roughly 10ms granularity. +// If there's never been activity, the duration is since the wrapper was created. func (t *Wrapper) IdleDuration() time.Duration { - sec := atomic.LoadInt64(&t.lastActivityAtomic) - return time.Since(time.Unix(sec, 0)) + return mono.Since(t.lastActivityAtomic.LoadAtomic()) } func (t *Wrapper) Read(buf []byte, offset int) (int, error) { diff --git a/net/tstun/wrap_test.go b/net/tstun/wrap_test.go index 1875e897b..e3230c0e2 100644 --- a/net/tstun/wrap_test.go +++ b/net/tstun/wrap_test.go @@ -10,13 +10,13 @@ import ( "fmt" "strconv" "strings" - "sync/atomic" "testing" "unsafe" "golang.zx2c4.com/wireguard/tun/tuntest" "inet.af/netaddr" "tailscale.com/net/packet" + "tailscale.com/tstime/mono" "tailscale.com/types/ipproto" "tailscale.com/types/logger" "tailscale.com/wgengine/filter" @@ -335,9 +335,9 @@ func TestFilter(t *testing.T) { // data was actually filtered. // If it stays zero, nothing made it through // to the wrapped TUN. - atomic.StoreInt64(&tun.lastActivityAtomic, 0) + tun.lastActivityAtomic.StoreAtomic(0) _, err = tun.Write(tt.data, 0) - filtered = atomic.LoadInt64(&tun.lastActivityAtomic) == 0 + filtered = tun.lastActivityAtomic.LoadAtomic() == 0 } else { chtun.Outbound <- tt.data n, err = tun.Read(buf[:], 0) @@ -416,7 +416,7 @@ func TestAtomic64Alignment(t *testing.T) { } c := new(Wrapper) - atomic.StoreInt64(&c.lastActivityAtomic, 123) + c.lastActivityAtomic.StoreAtomic(mono.Now()) } func TestPeerAPIBypass(t *testing.T) {