]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Fix data races in timers
authorJason A. Donenfeld <Jason@zx2c4.com>
Sun, 20 May 2018 04:50:07 +0000 (06:50 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Sun, 20 May 2018 04:50:07 +0000 (06:50 +0200)
peer.go
receive.go
send.go
timers.go

diff --git a/peer.go b/peer.go
index 4d3ac2b68f364106fbd1ad86424f3fe8c0ecae27..172676a443abcb4b58c1209c89ae9ab429d1af1a 100644 (file)
--- a/peer.go
+++ b/peer.go
@@ -40,9 +40,9 @@ type Peer struct {
                newHandshake            *Timer
                zeroKeyMaterial         *Timer
                persistentKeepalive     *Timer
-               handshakeAttempts       uint
-               needAnotherKeepalive    bool
-               sentLastMinuteHandshake bool
+               handshakeAttempts       uint32
+               needAnotherKeepalive    AtomicBool
+               sentLastMinuteHandshake AtomicBool
        }
 
        signals struct {
index 29fe5e98e40868b5e9c5b5cc29f44ead3bab9f93..56e65e7dc7f02f7ce58ad34f47517d3b032a2915 100644 (file)
@@ -105,12 +105,12 @@ func (device *Device) addToHandshakeQueue(
  * NOTE: Not thread safe, but called by sequential receiver!
  */
 func (peer *Peer) keepKeyFreshReceiving() {
-       if peer.timers.sentLastMinuteHandshake {
+       if peer.timers.sentLastMinuteHandshake.Get() {
                return
        }
        keypair := peer.keypairs.Current()
        if keypair != nil && keypair.isInitiator && time.Now().Sub(keypair.created) > (RejectAfterTime-KeepaliveTimeout-RekeyTimeout) {
-               peer.timers.sentLastMinuteHandshake = true
+               peer.timers.sentLastMinuteHandshake.Set(true)
                peer.SendHandshakeInitiation(false)
        }
 }
diff --git a/send.go b/send.go
index d57e11b4ea3388f80093a40741cad85c08cccc70..299274d60f73c3b34db1936072719a348e114e0c 100644 (file)
--- a/send.go
+++ b/send.go
@@ -124,7 +124,7 @@ func (peer *Peer) SendKeepalive() bool {
 
 func (peer *Peer) SendHandshakeInitiation(isRetry bool) error {
        if !isRetry {
-               peer.timers.handshakeAttempts = 0
+               atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
        }
 
        peer.handshake.mutex.RLock()
index 526db137f425833b3911a80e84b6675ca9bd4720..f455f821a4438882adee8aef58c9eb33542de2a2 100644 (file)
--- a/timers.go
+++ b/timers.go
@@ -78,7 +78,7 @@ func (peer *Peer) timersActive() bool {
 }
 
 func expiredRetransmitHandshake(peer *Peer) {
-       if peer.timers.handshakeAttempts > MaxTimerHandshakes {
+       if atomic.LoadUint32(&peer.timers.handshakeAttempts) > MaxTimerHandshakes {
                peer.device.log.Debug.Printf("%s: Handshake did not complete after %d attempts, giving up\n", peer, MaxTimerHandshakes+2)
 
                if peer.timersActive() {
@@ -97,8 +97,8 @@ func expiredRetransmitHandshake(peer *Peer) {
                        peer.timers.zeroKeyMaterial.Mod(RejectAfterTime * 3)
                }
        } else {
-               peer.timers.handshakeAttempts++
-               peer.device.log.Debug.Printf("%s: Handshake did not complete after %d seconds, retrying (try %d)\n", peer, int(RekeyTimeout.Seconds()), peer.timers.handshakeAttempts+1)
+               atomic.AddUint32(&peer.timers.handshakeAttempts, 1)
+               peer.device.log.Debug.Printf("%s: Handshake did not complete after %d seconds, retrying (try %d)\n", peer, int(RekeyTimeout.Seconds()), atomic.LoadUint32(&peer.timers.handshakeAttempts)+1)
 
                /* We clear the endpoint address src address, in case this is the cause of trouble. */
                peer.mutex.Lock()
@@ -113,8 +113,8 @@ func expiredRetransmitHandshake(peer *Peer) {
 
 func expiredSendKeepalive(peer *Peer) {
        peer.SendKeepalive()
-       if peer.timers.needAnotherKeepalive {
-               peer.timers.needAnotherKeepalive = false
+       if peer.timers.needAnotherKeepalive.Get() {
+               peer.timers.needAnotherKeepalive.Set(false)
                if peer.timersActive() {
                        peer.timers.sendKeepalive.Mod(KeepaliveTimeout)
                }
@@ -157,7 +157,7 @@ func (peer *Peer) timersDataReceived() {
                if !peer.timers.sendKeepalive.IsPending() {
                        peer.timers.sendKeepalive.Mod(KeepaliveTimeout)
                } else {
-                       peer.timers.needAnotherKeepalive = true
+                       peer.timers.needAnotherKeepalive.Set(true)
                }
        }
 }
@@ -188,8 +188,8 @@ func (peer *Peer) timersHandshakeComplete() {
        if peer.timersActive() {
                peer.timers.retransmitHandshake.Del()
        }
-       peer.timers.handshakeAttempts = 0
-       peer.timers.sentLastMinuteHandshake = false
+       atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
+       peer.timers.sentLastMinuteHandshake.Set(false)
        atomic.StoreInt64(&peer.stats.lastHandshakeNano, time.Now().UnixNano())
 }
 
@@ -213,9 +213,9 @@ func (peer *Peer) timersInit() {
        peer.timers.newHandshake = peer.NewTimer(expiredNewHandshake)
        peer.timers.zeroKeyMaterial = peer.NewTimer(expiredZeroKeyMaterial)
        peer.timers.persistentKeepalive = peer.NewTimer(expiredPersistentKeepalive)
-       peer.timers.handshakeAttempts = 0
-       peer.timers.sentLastMinuteHandshake = false
-       peer.timers.needAnotherKeepalive = false
+       atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
+       peer.timers.sentLastMinuteHandshake.Set(false)
+       peer.timers.needAnotherKeepalive.Set(false)
 }
 
 func (peer *Peer) timersStop() {