Improved timer state machine

This commit is contained in:
Mathias Hall-Andersen
2017-07-08 23:51:26 +02:00
parent 5c1ccbddf0
commit 4ad62aaa6a
10 changed files with 418 additions and 222 deletions

View File

@@ -20,25 +20,36 @@ type Peer struct {
txBytes uint64
rxBytes uint64
time struct {
mutex sync.RWMutex
lastSend time.Time // last send message
lastHandshake time.Time // last completed handshake
nextKeepalive time.Time
}
signal struct {
newKeyPair chan struct{} // (size 1) : a new key pair was generated
handshakeBegin chan struct{} // (size 1) : request that a new handshake be started ("queue handshake")
handshakeCompleted chan struct{} // (size 1) : handshake completed
flushNonceQueue chan struct{} // (size 1) : empty queued packets
messageSend chan struct{} // (size 1) : a message was send to the peer
messageReceived chan struct{} // (size 1) : an authenticated message was received
stop chan struct{} // (size 0) : close to stop all goroutines for peer
}
timer struct {
sendKeepalive *time.Timer
handshakeTimeout *time.Timer
/* Both keep-alive timers acts as one (see timers.go)
* They are kept seperate to simplify the implementation.
*/
keepalivePersistent *time.Timer // set for persistent keepalives
keepaliveAcknowledgement *time.Timer // set upon recieving messages
zeroAllKeys *time.Timer // zero all key material after RejectAfterTime*3
}
queue struct {
nonce chan *QueueOutboundElement // nonce / pre-handshake queue
outbound chan *QueueOutboundElement // sequential ordering of work
inbound chan *QueueInboundElement // sequential ordering of work
}
flags struct {
keepaliveWaiting int32
}
mac MACStatePeer
}
@@ -51,7 +62,12 @@ func (device *Device) NewPeer(pk NoisePublicKey) *Peer {
peer.mac.Init(pk)
peer.device = device
peer.timer.sendKeepalive = stoppedTimer()
peer.timer.keepalivePersistent = NewStoppedTimer()
peer.timer.keepaliveAcknowledgement = NewStoppedTimer()
peer.timer.zeroAllKeys = NewStoppedTimer()
peer.flags.keepaliveWaiting = AtomicFalse
// assign id for debugging
@@ -82,7 +98,7 @@ func (device *Device) NewPeer(pk NoisePublicKey) *Peer {
peer.queue.outbound = make(chan *QueueOutboundElement, QueueOutboundSize)
peer.queue.inbound = make(chan *QueueInboundElement, QueueInboundSize)
// prepare signaling
// prepare signaling & routines
peer.signal.stop = make(chan struct{})
peer.signal.newKeyPair = make(chan struct{}, 1)
@@ -90,9 +106,8 @@ func (device *Device) NewPeer(pk NoisePublicKey) *Peer {
peer.signal.handshakeCompleted = make(chan struct{}, 1)
peer.signal.flushNonceQueue = make(chan struct{}, 1)
// outbound pipeline
go peer.RoutineNonce()
go peer.RoutineTimerHandler()
go peer.RoutineHandshakeInitiator()
go peer.RoutineSequentialSender()
go peer.RoutineSequentialReceiver()