]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
Fixed read from closed channel
authorMathias Hall-Andersen <mathias@hall-andersen.dk>
Wed, 18 Apr 2018 18:29:48 +0000 (20:29 +0200)
committerMathias Hall-Andersen <mathias@hall-andersen.dk>
Wed, 18 Apr 2018 18:29:48 +0000 (20:29 +0200)
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
receive.go
send.go
timers.go

diff --git a/peer.go b/peer.go
index 8acdfbc02924a01e950c56459488b0e6b6db4556..f10bfbb7e1d0ec6978702bc0f9223e18b7a3bc5b 100644 (file)
--- 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
index 96ba08da2f011069c99427b91095d5db4b0100b5..1045cee64b02b1320c546290bd0a40e3cda41021 100644 (file)
@@ -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 5a59f6e4fb81c66bf558e7d96db8c4b3b2253b1f..df8efdbe71912395fc041266db0c1eda8245ce7e 100644 (file)
--- 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
index e118c387349f4cd33245a670372ad85b525a959b..87255708d79a496b4b8e3e8c72de16a80a327c42 100644 (file)
--- 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()