From acb5481246ea97bff64cc3eba1fa4255fc1ccd72 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 20 May 2018 06:50:07 +0200 Subject: [PATCH] Fix data races in timers --- peer.go | 6 +++--- receive.go | 4 ++-- send.go | 2 +- timers.go | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/peer.go b/peer.go index 4d3ac2b..172676a 100644 --- 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 { diff --git a/receive.go b/receive.go index 29fe5e9..56e65e7 100644 --- a/receive.go +++ b/receive.go @@ -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 d57e11b..299274d 100644 --- 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() diff --git a/timers.go b/timers.go index 526db13..f455f82 100644 --- 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() {