diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-01-07 15:56:52 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-01-07 17:08:41 +0100 |
commit | 29b04775856b62213d7bc01937641e2db081d707 (patch) | |
tree | 6044865a29772209154acd59ba7f66274a623403 | |
parent | 85b495057977e12df378778366a03b508c43f00f (diff) |
device: receive: drain decryption queue before exiting RoutineDecryption
It's possible for RoutineSequentialReceiver to try to lock an elem after
RoutineDecryption has exited. Before this meant we didn't then unlock
the elem, so the whole program deadlocked.
As well, it looks like the flush code (which is now potentially
unnecessary?) wasn't properly dropping the buffers for the
not-already-dropped case.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | device/device.go | 5 | ||||
-rw-r--r-- | device/receive.go | 15 |
2 files changed, 18 insertions, 2 deletions
diff --git a/device/device.go b/device/device.go index 3172224..d37fe6f 100644 --- a/device/device.go +++ b/device/device.go @@ -371,7 +371,10 @@ func (device *Device) FlushPacketQueues() { select { case elem, ok := <-device.queue.decryption: if ok { - elem.Drop() + if !elem.IsDropped() { + elem.Drop() + device.PutMessageBuffer(elem.buffer) + } } case <-device.queue.handshake: default: diff --git a/device/receive.go b/device/receive.go index 4b6f278..0bd22bf 100644 --- a/device/receive.go +++ b/device/receive.go @@ -251,7 +251,20 @@ func (device *Device) RoutineDecryption() { for { select { case <-device.signals.stop: - return + for { + select { + case elem, ok := <-device.queue.decryption: + if ok { + if !elem.IsDropped() { + elem.Drop() + device.PutMessageBuffer(elem.buffer) + } + elem.Unlock() + } + default: + return + } + } case elem, ok := <-device.queue.decryption: |