device: use int64 instead of atomic.Value for time stamp

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2021-01-29 18:54:19 +01:00
parent beb25cc4fd
commit de51129e33
2 changed files with 27 additions and 13 deletions

View file

@ -41,3 +41,27 @@ func TestPeerAlignment(t *testing.T) {
checkAlignment(t, "Peer.stats", unsafe.Offsetof(p.stats)) checkAlignment(t, "Peer.stats", unsafe.Offsetof(p.stats))
checkAlignment(t, "Peer.isRunning", unsafe.Offsetof(p.isRunning)) checkAlignment(t, "Peer.isRunning", unsafe.Offsetof(p.isRunning))
} }
// TestDeviceAlignment checks that atomically-accessed fields are
// aligned to 64-bit boundaries, as required by the atomic package.
//
// Unfortunately, violating this rule on 32-bit platforms results in a
// hard segfault at runtime.
func TestDeviceAlignment(t *testing.T) {
var d Device
typ := reflect.TypeOf(&d).Elem()
t.Logf("Device type size: %d, with fields:", typ.Size())
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
t.Logf("\t%30s\toffset=%3v\t(type size=%3d, align=%d)",
field.Name,
field.Offset,
field.Type.Size(),
field.Type.Align(),
)
}
checkAlignment(t, "Device.rate.underLoadUntil", unsafe.Offsetof(d.rate.underLoadUntil))
}

View file

@ -62,7 +62,7 @@ type Device struct {
cookieChecker CookieChecker cookieChecker CookieChecker
rate struct { rate struct {
underLoadUntil atomic.Value underLoadUntil int64
limiter ratelimiter.Ratelimiter limiter ratelimiter.Ratelimiter
} }
@ -245,20 +245,15 @@ func (device *Device) Down() {
} }
func (device *Device) IsUnderLoad() bool { func (device *Device) IsUnderLoad() bool {
// check if currently under load // check if currently under load
now := time.Now() now := time.Now()
underLoad := len(device.queue.handshake.c) >= UnderLoadQueueSize underLoad := len(device.queue.handshake.c) >= UnderLoadQueueSize
if underLoad { if underLoad {
device.rate.underLoadUntil.Store(now.Add(UnderLoadAfterTime)) atomic.StoreInt64(&device.rate.underLoadUntil, now.Add(UnderLoadAfterTime).UnixNano())
return true return true
} }
// check if recently under load // check if recently under load
return atomic.LoadInt64(&device.rate.underLoadUntil) > now.UnixNano()
until := device.rate.underLoadUntil.Load().(time.Time)
return until.After(now)
} }
func (device *Device) SetPrivateKey(sk NoisePrivateKey) error { func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
@ -327,14 +322,9 @@ func NewDevice(tunDevice tun.Device, logger *Logger) *Device {
mtu = DefaultMTU mtu = DefaultMTU
} }
device.tun.mtu = int32(mtu) device.tun.mtu = int32(mtu)
device.peers.keyMap = make(map[NoisePublicKey]*Peer) device.peers.keyMap = make(map[NoisePublicKey]*Peer)
device.rate.limiter.Init() device.rate.limiter.Init()
device.rate.underLoadUntil.Store(time.Time{})
device.indexTable.Init() device.indexTable.Init()
device.PopulatePools() device.PopulatePools()
// create queues // create queues