summaryrefslogtreecommitdiffhomepage
path: root/device/keypair.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-05-02 01:30:23 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-05-02 01:56:48 -0600
commit28c4d043048e8bb7167e96df6558a6366306fc17 (patch)
treec98e39cd6ed75e23f54e6d1b72b6f5c70fa9ab8a /device/keypair.go
parentfdba6c183aa8d4c19680f436517624038a6f3be5 (diff)
device: use atomic access for unlocked keypair.next
Go's GC semantics might not always guarantee the safety of this, and the race detector gets upset too, so instead we wrap this all in atomic accessors. Reported-by: David Anderson <danderson@tailscale.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'device/keypair.go')
-rw-r--r--device/keypair.go10
1 files changed, 10 insertions, 0 deletions
diff --git a/device/keypair.go b/device/keypair.go
index 9c78fa9..d70c7f4 100644
--- a/device/keypair.go
+++ b/device/keypair.go
@@ -8,7 +8,9 @@ package device
import (
"crypto/cipher"
"sync"
+ "sync/atomic"
"time"
+ "unsafe"
"golang.zx2c4.com/wireguard/replay"
)
@@ -38,6 +40,14 @@ type Keypairs struct {
next *Keypair
}
+func (kp *Keypairs) storeNext(next *Keypair) {
+ atomic.StorePointer((*unsafe.Pointer)((unsafe.Pointer)(&kp.next)), (unsafe.Pointer)(next))
+}
+
+func (kp *Keypairs) loadNext() *Keypair {
+ return (*Keypair)(atomic.LoadPointer((*unsafe.Pointer)((unsafe.Pointer)(&kp.next))))
+}
+
func (kp *Keypairs) Current() *Keypair {
kp.RLock()
defer kp.RUnlock()