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>
This commit is contained in:
Jason A. Donenfeld 2021-01-07 15:56:52 +01:00
parent 85b4950579
commit 29b0477585
2 changed files with 18 additions and 2 deletions

View file

@ -371,7 +371,10 @@ func (device *Device) FlushPacketQueues() {
select { select {
case elem, ok := <-device.queue.decryption: case elem, ok := <-device.queue.decryption:
if ok { if ok {
if !elem.IsDropped() {
elem.Drop() elem.Drop()
device.PutMessageBuffer(elem.buffer)
}
} }
case <-device.queue.handshake: case <-device.queue.handshake:
default: default:

View file

@ -251,7 +251,20 @@ func (device *Device) RoutineDecryption() {
for { for {
select { select {
case <-device.signals.stop: case <-device.signals.stop:
for {
select {
case elem, ok := <-device.queue.decryption:
if ok {
if !elem.IsDropped() {
elem.Drop()
device.PutMessageBuffer(elem.buffer)
}
elem.Unlock()
}
default:
return return
}
}
case elem, ok := <-device.queue.decryption: case elem, ok := <-device.queue.decryption: