From ac9912345b4da5034ea93f5f245ea2ce04815bd5 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Wed, 18 Apr 2018 20:29:48 +0200 Subject: [PATCH] Fixed read from closed channel A premature waitgroup .Done resulted in reading from closed channel. This caused a nil-pointer deref & crash. Added additional debugging when closing routines. --- peer.go | 2 +- receive.go | 10 +++++++--- send.go | 14 +++++++++++--- timers.go | 10 +++++++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/peer.go b/peer.go index 8acdfbc..f10bfbb 100644 --- a/peer.go +++ b/peer.go @@ -246,8 +246,8 @@ func (peer *Peer) Stop() { // stop & wait for ongoing peer routines - peer.routines.stop.Broadcast() peer.routines.starting.Wait() + peer.routines.stop.Broadcast() peer.routines.stopping.Wait() // stop timers diff --git a/receive.go b/receive.go index 96ba08d..1045cee 100644 --- a/receive.go +++ b/receive.go @@ -500,8 +500,8 @@ func (peer *Peer) RoutineSequentialReceiver() { logError := device.log.Error logDebug := device.log.Debug - func() { - defer peer.routines.stopping.Done() + defer func() { + peer.routines.stopping.Done() logDebug.Println(peer.String(), ": Routine, Sequential Receiver, Stopped") }() @@ -516,7 +516,11 @@ func (peer *Peer) RoutineSequentialReceiver() { case <-peer.routines.stop.Wait(): return - case elem := <-peer.queue.inbound: + case elem, ok := <-peer.queue.inbound: + + if !ok { + return + } // wait for decryption diff --git a/send.go b/send.go index 5a59f6e..df8efdb 100644 --- a/send.go +++ b/send.go @@ -320,13 +320,16 @@ func (device *Device) RoutineEncryption() { */ func (peer *Peer) RoutineSequentialSender() { - defer peer.routines.stopping.Done() - device := peer.device logDebug := device.log.Debug logDebug.Println("Routine, sequential sender, started for", peer.String()) + defer func() { + peer.routines.stopping.Done() + logDebug.Println(peer.String(), ": Routine, Sequential sender, Stopped") + }() + peer.routines.starting.Done() for { @@ -337,7 +340,12 @@ func (peer *Peer) RoutineSequentialSender() { "Routine, sequential sender, stopped for", peer.String()) return - case elem := <-peer.queue.outbound: + case elem, ok := <-peer.queue.outbound: + + if !ok { + return + } + elem.mutex.Lock() if elem.IsDropped() { continue diff --git a/timers.go b/timers.go index e118c38..8725570 100644 --- a/timers.go +++ b/timers.go @@ -183,13 +183,15 @@ func (peer *Peer) sendNewHandshake() error { func (peer *Peer) RoutineTimerHandler() { - defer peer.routines.stopping.Done() - device := peer.device logInfo := device.log.Info logDebug := device.log.Debug - logDebug.Println("Routine, timer handler, started for peer", peer.String()) + + defer func() { + logDebug.Println(peer.String(), ": Routine, Timer handler, Stopped") + peer.routines.stopping.Done() + }() // reset all timers @@ -205,6 +207,8 @@ func (peer *Peer) RoutineTimerHandler() { peer.timer.keepalivePersistent.Reset(duration) } + logDebug.Println("Routine, timer handler, started for peer", peer.String()) + // signal synchronised setup complete peer.routines.starting.Done()