mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-18 21:52:41 +00:00
wgengine, magicsock, tstun: don't regularly STUN when idle (mobile only for now)
If there's been 5 minutes of inactivity, stop doing STUN lookups. That means NAT mappings will expire, but they can resume later when there's activity again. We'll do this for all platforms later. Updates tailscale/corp#320 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
fe50cd0c48
commit
23e74a0f7a
@@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/tailscale/wireguard-go/device"
|
||||
"github.com/tailscale/wireguard-go/tun"
|
||||
@@ -57,6 +58,8 @@ type TUN struct {
|
||||
// tdev is the underlying TUN device.
|
||||
tdev tun.Device
|
||||
|
||||
lastActivityAtomic int64 // unix seconds of last send or receive
|
||||
|
||||
// buffer stores the oldest unconsumed packet from tdev.
|
||||
// It is made a static buffer in order to avoid allocations.
|
||||
buffer [maxBufferSize]byte
|
||||
@@ -234,6 +237,20 @@ func (t *TUN) filterOut(buf []byte) filter.Response {
|
||||
return filter.Accept
|
||||
}
|
||||
|
||||
// noteActivity records that there was a read or write at the current time.
|
||||
func (t *TUN) noteActivity() {
|
||||
atomic.StoreInt64(&t.lastActivityAtomic, time.Now().Unix())
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (t *TUN) IdleDuration() time.Duration {
|
||||
sec := atomic.LoadInt64(&t.lastActivityAtomic)
|
||||
return time.Since(time.Unix(sec, 0))
|
||||
}
|
||||
|
||||
func (t *TUN) Read(buf []byte, offset int) (int, error) {
|
||||
var n int
|
||||
|
||||
@@ -251,7 +268,8 @@ func (t *TUN) Read(buf []byte, offset int) (int, error) {
|
||||
t.bufferConsumed <- struct{}{}
|
||||
} else {
|
||||
// If the packet is not from t.buffer, then it is an injected packet.
|
||||
// In this case, we return eary to bypass filtering
|
||||
// In this case, we return early to bypass filtering
|
||||
t.noteActivity()
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
@@ -264,6 +282,7 @@ func (t *TUN) Read(buf []byte, offset int) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
t.noteActivity()
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@@ -306,6 +325,7 @@ func (t *TUN) Write(buf []byte, offset int) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
t.noteActivity()
|
||||
return t.tdev.Write(buf, offset)
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,9 @@ package tstun
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tailscale/wireguard-go/tun/tuntest"
|
||||
"tailscale.com/types/logger"
|
||||
@@ -353,3 +355,13 @@ func BenchmarkRead(b *testing.B) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAtomic64Alignment(t *testing.T) {
|
||||
off := unsafe.Offsetof(TUN{}.lastActivityAtomic)
|
||||
if off%8 != 0 {
|
||||
t.Errorf("offset %v not 8-byte aligned", off)
|
||||
}
|
||||
|
||||
c := new(TUN)
|
||||
atomic.StoreInt64(&c.lastActivityAtomic, 123)
|
||||
}
|
||||
|
Reference in New Issue
Block a user