]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
device: add write queue mutex for peer
authorHaichao Liu <liuhaichao@bytedance.com>
Wed, 18 Nov 2020 12:53:22 +0000 (20:53 +0800)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 18 Nov 2020 13:22:15 +0000 (14:22 +0100)
fix panic: send on closed channel when remove peer

Signed-off-by: Haichao Liu <liuhaichao@bytedance.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
device/peer.go
device/receive.go
device/send.go

index ef6c0103f6191f82d7fb5df785c8b4e2b3e3c5af..78204bbd5c3ec5f55c518066a24479dc61aa7945 100644 (file)
@@ -58,6 +58,7 @@ type Peer struct {
        }
 
        queue struct {
+               sync.RWMutex
                nonce                           chan *QueueOutboundElement // nonce / pre-handshake queue
                outbound                        chan *QueueOutboundElement // sequential ordering of work
                inbound                         chan *QueueInboundElement  // sequential ordering of work
@@ -195,10 +196,11 @@ func (peer *Peer) Start() {
        peer.routines.stopping.Add(PeerRoutineNumber)
 
        // prepare queues
-
+       peer.queue.Lock()
        peer.queue.nonce = make(chan *QueueOutboundElement, QueueOutboundSize)
        peer.queue.outbound = make(chan *QueueOutboundElement, QueueOutboundSize)
        peer.queue.inbound = make(chan *QueueInboundElement, QueueInboundSize)
+       peer.queue.Unlock()
 
        peer.timersInit()
        peer.handshake.lastSentHandshake = time.Now().Add(-(RekeyTimeout + time.Second))
@@ -284,9 +286,11 @@ func (peer *Peer) Stop() {
 
        // close queues
 
+       peer.queue.Lock()
        close(peer.queue.nonce)
        close(peer.queue.outbound)
        close(peer.queue.inbound)
+       peer.queue.Unlock()
 
        peer.ZeroAndFlushAll()
 }
index b53c9c06ea7c4b08595befff7f52a05171f31eeb..e4a94b51a17b9eebe5b589b9eb095e4ca87fc752 100644 (file)
@@ -184,11 +184,13 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind conn.Bind) {
 
                        // add to decryption queues
 
+                       peer.queue.RLock()
                        if peer.isRunning.Get() {
                                if device.addToInboundAndDecryptionQueues(peer.queue.inbound, device.queue.decryption, elem) {
                                        buffer = device.GetMessageBuffer()
                                }
                        }
+                       peer.queue.RUnlock()
 
                        continue
 
index c0bdba38e7dcc95baec90469e76803290b966711..d202b622c06fc843c47bfa88860045d87b107937 100644 (file)
@@ -107,6 +107,8 @@ func addToOutboundAndEncryptionQueues(outboundQueue chan *QueueOutboundElement,
 /* Queues a keepalive if no packets are queued for peer
  */
 func (peer *Peer) SendKeepalive() bool {
+       peer.queue.RLock()
+       defer peer.queue.RUnlock()
        if len(peer.queue.nonce) != 0 || peer.queue.packetInNonceQueueIsAwaitingKey.Get() || !peer.isRunning.Get() {
                return false
        }
@@ -310,6 +312,7 @@ func (device *Device) RoutineReadFromTUN() {
 
                // insert into nonce/pre-handshake queue
 
+               peer.queue.RLock()
                if peer.isRunning.Get() {
                        if peer.queue.packetInNonceQueueIsAwaitingKey.Get() {
                                peer.SendHandshakeInitiation(false)
@@ -317,6 +320,7 @@ func (device *Device) RoutineReadFromTUN() {
                        addToNonceQueue(peer.queue.nonce, elem, device)
                        elem = nil
                }
+               peer.queue.RUnlock()
        }
 }