]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
device: use int64 instead of atomic.Value for time stamp
authorJason A. Donenfeld <Jason@zx2c4.com>
Fri, 29 Jan 2021 17:54:19 +0000 (18:54 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Fri, 29 Jan 2021 17:57:03 +0000 (18:57 +0100)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
device/alignment_test.go [moved from device/peer_test.go with 63% similarity]
device/device.go

similarity index 63%
rename from device/peer_test.go
rename to device/alignment_test.go
index 0020423ed59b11841ea50096feefa36a94517451..5587cbe1317671679c141e7d6337b6d7427b3f66 100644 (file)
@@ -41,3 +41,27 @@ func TestPeerAlignment(t *testing.T) {
        checkAlignment(t, "Peer.stats", unsafe.Offsetof(p.stats))
        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))
+}
index fd888558506f49fabf3c462dd15176460b720151..bac361ec4ad2d71048141d90dde6db2c8ec4056f 100644 (file)
@@ -62,7 +62,7 @@ type Device struct {
        cookieChecker CookieChecker
 
        rate struct {
-               underLoadUntil atomic.Value
+               underLoadUntil int64
                limiter        ratelimiter.Ratelimiter
        }
 
@@ -245,20 +245,15 @@ func (device *Device) Down() {
 }
 
 func (device *Device) IsUnderLoad() bool {
-
        // check if currently under load
-
        now := time.Now()
        underLoad := len(device.queue.handshake.c) >= UnderLoadQueueSize
        if underLoad {
-               device.rate.underLoadUntil.Store(now.Add(UnderLoadAfterTime))
+               atomic.StoreInt64(&device.rate.underLoadUntil, now.Add(UnderLoadAfterTime).UnixNano())
                return true
        }
-
        // check if recently under load
-
-       until := device.rate.underLoadUntil.Load().(time.Time)
-       return until.After(now)
+       return atomic.LoadInt64(&device.rate.underLoadUntil) > now.UnixNano()
 }
 
 func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
@@ -327,14 +322,9 @@ func NewDevice(tunDevice tun.Device, logger *Logger) *Device {
                mtu = DefaultMTU
        }
        device.tun.mtu = int32(mtu)
-
        device.peers.keyMap = make(map[NoisePublicKey]*Peer)
-
        device.rate.limiter.Init()
-       device.rate.underLoadUntil.Store(time.Time{})
-
        device.indexTable.Init()
-
        device.PopulatePools()
 
        // create queues