Fix data races in timers

This commit is contained in:
Jason A. Donenfeld 2018-05-20 06:50:07 +02:00
parent 18f43705ec
commit acb5481246
4 changed files with 17 additions and 17 deletions

View file

@ -40,9 +40,9 @@ type Peer struct {
newHandshake *Timer newHandshake *Timer
zeroKeyMaterial *Timer zeroKeyMaterial *Timer
persistentKeepalive *Timer persistentKeepalive *Timer
handshakeAttempts uint handshakeAttempts uint32
needAnotherKeepalive bool needAnotherKeepalive AtomicBool
sentLastMinuteHandshake bool sentLastMinuteHandshake AtomicBool
} }
signals struct { signals struct {

View file

@ -105,12 +105,12 @@ func (device *Device) addToHandshakeQueue(
* NOTE: Not thread safe, but called by sequential receiver! * NOTE: Not thread safe, but called by sequential receiver!
*/ */
func (peer *Peer) keepKeyFreshReceiving() { func (peer *Peer) keepKeyFreshReceiving() {
if peer.timers.sentLastMinuteHandshake { if peer.timers.sentLastMinuteHandshake.Get() {
return return
} }
keypair := peer.keypairs.Current() keypair := peer.keypairs.Current()
if keypair != nil && keypair.isInitiator && time.Now().Sub(keypair.created) > (RejectAfterTime-KeepaliveTimeout-RekeyTimeout) { 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) peer.SendHandshakeInitiation(false)
} }
} }

View file

@ -124,7 +124,7 @@ func (peer *Peer) SendKeepalive() bool {
func (peer *Peer) SendHandshakeInitiation(isRetry bool) error { func (peer *Peer) SendHandshakeInitiation(isRetry bool) error {
if !isRetry { if !isRetry {
peer.timers.handshakeAttempts = 0 atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
} }
peer.handshake.mutex.RLock() peer.handshake.mutex.RLock()

View file

@ -78,7 +78,7 @@ func (peer *Peer) timersActive() bool {
} }
func expiredRetransmitHandshake(peer *Peer) { 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) peer.device.log.Debug.Printf("%s: Handshake did not complete after %d attempts, giving up\n", peer, MaxTimerHandshakes+2)
if peer.timersActive() { if peer.timersActive() {
@ -97,8 +97,8 @@ func expiredRetransmitHandshake(peer *Peer) {
peer.timers.zeroKeyMaterial.Mod(RejectAfterTime * 3) peer.timers.zeroKeyMaterial.Mod(RejectAfterTime * 3)
} }
} else { } else {
peer.timers.handshakeAttempts++ 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()), 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. */ /* We clear the endpoint address src address, in case this is the cause of trouble. */
peer.mutex.Lock() peer.mutex.Lock()
@ -113,8 +113,8 @@ func expiredRetransmitHandshake(peer *Peer) {
func expiredSendKeepalive(peer *Peer) { func expiredSendKeepalive(peer *Peer) {
peer.SendKeepalive() peer.SendKeepalive()
if peer.timers.needAnotherKeepalive { if peer.timers.needAnotherKeepalive.Get() {
peer.timers.needAnotherKeepalive = false peer.timers.needAnotherKeepalive.Set(false)
if peer.timersActive() { if peer.timersActive() {
peer.timers.sendKeepalive.Mod(KeepaliveTimeout) peer.timers.sendKeepalive.Mod(KeepaliveTimeout)
} }
@ -157,7 +157,7 @@ func (peer *Peer) timersDataReceived() {
if !peer.timers.sendKeepalive.IsPending() { if !peer.timers.sendKeepalive.IsPending() {
peer.timers.sendKeepalive.Mod(KeepaliveTimeout) peer.timers.sendKeepalive.Mod(KeepaliveTimeout)
} else { } else {
peer.timers.needAnotherKeepalive = true peer.timers.needAnotherKeepalive.Set(true)
} }
} }
} }
@ -188,8 +188,8 @@ func (peer *Peer) timersHandshakeComplete() {
if peer.timersActive() { if peer.timersActive() {
peer.timers.retransmitHandshake.Del() peer.timers.retransmitHandshake.Del()
} }
peer.timers.handshakeAttempts = 0 atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
peer.timers.sentLastMinuteHandshake = false peer.timers.sentLastMinuteHandshake.Set(false)
atomic.StoreInt64(&peer.stats.lastHandshakeNano, time.Now().UnixNano()) atomic.StoreInt64(&peer.stats.lastHandshakeNano, time.Now().UnixNano())
} }
@ -213,9 +213,9 @@ func (peer *Peer) timersInit() {
peer.timers.newHandshake = peer.NewTimer(expiredNewHandshake) peer.timers.newHandshake = peer.NewTimer(expiredNewHandshake)
peer.timers.zeroKeyMaterial = peer.NewTimer(expiredZeroKeyMaterial) peer.timers.zeroKeyMaterial = peer.NewTimer(expiredZeroKeyMaterial)
peer.timers.persistentKeepalive = peer.NewTimer(expiredPersistentKeepalive) peer.timers.persistentKeepalive = peer.NewTimer(expiredPersistentKeepalive)
peer.timers.handshakeAttempts = 0 atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
peer.timers.sentLastMinuteHandshake = false peer.timers.sentLastMinuteHandshake.Set(false)
peer.timers.needAnotherKeepalive = false peer.timers.needAnotherKeepalive.Set(false)
} }
func (peer *Peer) timersStop() { func (peer *Peer) timersStop() {