device: separate timersInit from timersStart

timersInit sets up the timers.
It need only be done once per peer.

timersStart does the work to prepare the timers
for a newly running peer. It needs to be done
every time a peer starts.

Separate the two and call them in the appropriate places.
This prevents data races on the peer's timers fields
when starting and stopping peers.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
Josh Bleecher Snyder 2021-02-08 10:01:35 -08:00
parent d840445e9b
commit 15810daa22
2 changed files with 7 additions and 5 deletions

View file

@ -107,6 +107,7 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
device.peers.empty.Set(false) device.peers.empty.Set(false)
// start peer // start peer
peer.timersInit()
if peer.device.isUp() { if peer.device.isUp() {
peer.Start() peer.Start()
} }
@ -183,7 +184,7 @@ func (peer *Peer) Start() {
} }
peer.device.queue.encryption.wg.Add(1) // keep encryption queue open for our writes peer.device.queue.encryption.wg.Add(1) // keep encryption queue open for our writes
peer.timersInit() peer.timersStart()
go peer.RoutineSequentialSender() go peer.RoutineSequentialSender()
go peer.RoutineSequentialReceiver() go peer.RoutineSequentialReceiver()

View file

@ -14,10 +14,8 @@ import (
"time" "time"
) )
/* This Timer structure and related functions should roughly copy the interface of // A Timer manages time-based aspects of the WireGuard protocol.
* the Linux kernel's struct timer_list. // Timer roughly copies the interface of the Linux kernel's struct timer_list.
*/
type Timer struct { type Timer struct {
*time.Timer *time.Timer
modifyingLock sync.RWMutex modifyingLock sync.RWMutex
@ -213,6 +211,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)
}
func (peer *Peer) timersStart() {
atomic.StoreUint32(&peer.timers.handshakeAttempts, 0) atomic.StoreUint32(&peer.timers.handshakeAttempts, 0)
peer.timers.sentLastMinuteHandshake.Set(false) peer.timers.sentLastMinuteHandshake.Set(false)
peer.timers.needAnotherKeepalive.Set(false) peer.timers.needAnotherKeepalive.Set(false)