wireguard-go/device
Josh Bleecher Snyder e1fa1cc556 device: use channel close to shut down and drain encryption channel
The new test introduced in this commit used to deadlock about 1% of the time.

I believe that the deadlock occurs as follows:

* The test completes, calling device.Close.
* device.Close closes device.signals.stop.
* RoutineEncryption stops.
* The deferred function in RoutineEncryption drains device.queue.encryption.
* RoutineEncryption exits.
* A peer's RoutineNonce processes an element queued in peer.queue.nonce.
* RoutineNonce puts that element into the outbound and encryption queues.
* RoutineSequentialSender reads that elements from the outbound queue.
* It waits for that element to get Unlocked by RoutineEncryption.
* RoutineEncryption has already exited, so RoutineSequentialSender blocks forever.
* device.RemoveAllPeers calls peer.Stop on all peers.
* peer.Stop waits for peer.routines.stopping, which blocks forever.

Rather than attempt to add even more ordering to the already complex
centralized shutdown orchestration, this commit moves towards a
data-flow-oriented shutdown.

The device.queue.encryption gets closed when there will be no more writes to it.
All device.queue.encryption readers always read until the channel is closed and then exit.
We thus guarantee that any element that enters the encryption queue also exits it.
This removes the need for central control of the lifetime of RoutineEncryption,
removes the need to drain the encryption queue on shutdown, and simplifies RoutineEncryption.

This commit also fixes a data race. When RoutineSequentialSender
drains its queue on shutdown, it needs to lock the elem before operating on it,
just as the main body does.

The new test in this commit passed 50k iterations with the race detector enabled
and 150k iterations with the race detector disabled, with no failures.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-07 14:49:44 +01:00
..
allowedips.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
allowedips_rand_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
allowedips_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
bind_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
constants.go replay: account for fqcodel reordering 2020-05-19 17:46:35 -06:00
cookie.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
cookie_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
device.go device: use channel close to shut down and drain encryption channel 2021-01-07 14:49:44 +01:00
device_test.go device: use channel close to shut down and drain encryption channel 2021-01-07 14:49:44 +01:00
endpoint_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
indextable.go device: remove some unnecessary unsafe 2020-07-15 06:59:44 +10:00
ip.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
kdf_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
keypair.go replay: minor API changes to more idiomatic Go 2020-10-14 10:46:00 +02:00
logger.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
misc.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
mobilequirks.go device: format a few things 2020-11-06 18:01:27 +01:00
noise-helpers.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
noise-protocol.go replay: minor API changes to more idiomatic Go 2020-10-14 10:46:00 +02:00
noise-types.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
noise_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
peer.go device: prevent spurious errors while closing a device 2021-01-07 14:49:44 +01:00
peer_test.go device: avoid copying lock in tests 2020-12-08 14:25:10 -08:00
pools.go device: clear pointers when returning elems to pools 2020-12-08 14:25:02 -08:00
queueconstants_android.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
queueconstants_default.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
queueconstants_ios.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
receive.go device: simplify copying counter to nonce 2021-01-07 14:49:44 +01:00
send.go device: use channel close to shut down and drain encryption channel 2021-01-07 14:49:44 +01:00
sticky_default.go device: do not include sticky sockets on android 2020-06-07 01:50:20 -06:00
sticky_linux.go device: use RTMGRP_IPV4_ROUTE to specify multicast groups mask 2020-07-13 17:58:10 -06:00
timers.go device: use defer to simplify peer.NewTimer 2021-01-07 14:49:44 +01:00
tun.go device: remove starting waitgroups 2021-01-07 14:49:44 +01:00
tun_test.go global: update header comments and modules 2020-05-02 02:08:26 -06:00
uapi.go device: accept any io.Reader in device.IpcSetOperation 2021-01-07 14:49:44 +01:00
version.go version: bump snapshot 2020-11-18 14:24:17 +01:00