aboutsummaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorDmytro Shynkevych <dmytro@tailscale.com>2020-06-24 01:35:41 -0400
committerDavid Crawshaw <crawshaw@tailscale.com>2020-07-04 20:29:31 +1000
commit4369db522b3fd7adc28a2a82b89315a6f3edbcc4 (patch)
treee6d62689017864d23334de818b5fa8c8dc380d9b /device
parentdevice: export Bind and remove socketfd shims for android (diff)
downloadwireguard-go-4369db522b3fd7adc28a2a82b89315a6f3edbcc4.tar.xz
wireguard-go-4369db522b3fd7adc28a2a82b89315a6f3edbcc4.zip
device: wait for routines to stop before removing peers
Peers are currently removed after Device's goroutines are signaled to stop, but without waiting for them to actually do so, which is racy. For example, RoutineHandshake may be in Peer.SendKeepalive when the corresponding peer is removed, which closes its nonce channel. This causes a send on a closed channel, as observed in tailscale/tailscale#487. This patch seems to be the correct synchronizing action: Peer's goroutines are receivers and handle channel closure gracefully, so Device's goroutines are the ones that should be fully stopped first. Signed-Off-By: Dmytro Shynkevych <dmytro@tailscale.com>
Diffstat (limited to 'device')
-rw-r--r--device/device.go2
1 files changed, 1 insertions, 1 deletions
diff --git a/device/device.go b/device/device.go
index c64432e..c440679 100644
--- a/device/device.go
+++ b/device/device.go
@@ -383,10 +383,10 @@ func (device *Device) Close() {
device.isUp.Set(false)
close(device.signals.stop)
+ device.state.stopping.Wait()
device.RemoveAllPeers()
- device.state.stopping.Wait()
device.FlushPacketQueues()
device.rate.limiter.Close()