aboutsummaryrefslogtreecommitdiff
path: root/tun (unfollow)
Commit message (Collapse)AuthorFilesLines
2021-02-08device: separate timersInit from timersStartJosh Bleecher Snyder2-5/+7
timersInit sets up the timers. It need only be done once per peer. timersStart does the work to prepare the timers for a newly running peer. It needs to be done every time a peer starts. Separate the two and call them in the appropriate places. This prevents data races on the peer's timers fields when starting and stopping peers. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: don't track device interface state in RoutineTUNEventReaderJosh Bleecher Snyder1-7/+4
We already track this state elsewhere. No need to duplicate. The cost of calling changeState is negligible. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: improve MTU change handlingJosh Bleecher Snyder1-8/+15
The old code silently accepted negative MTUs. It also set MTUs above the maximum. It also had hard to follow deeply nested conditionals. Add more paranoid handling, and make the code more straight-line. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: remove device.state.stopping from RoutineTUNEventReaderJosh Bleecher Snyder2-2/+1
The TUN event reader does three things: Change MTU, device up, and device down. Changing the MTU after the device is closed does no harm. Device up and device down don't make sense after the device is closed, but we can check that condition before proceeding with changeState. There's thus no reason to block device.Close on RoutineTUNEventReader exiting. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: overhaul device state managementJosh Bleecher Snyder8-139/+188
This commit simplifies device state management. It creates a single unified state variable and documents its semantics. It also makes state changes more atomic. As an example of the sort of bug that occurred due to non-atomic state changes, the following sequence of events used to occur approximately every 2.5 million test runs: * RoutineTUNEventReader received an EventDown event. * It called device.Down, which called device.setUpDown. * That set device.state.changing, but did not yet attempt to lock device.state.Mutex. * Test completion called device.Close. * device.Close locked device.state.Mutex. * device.Close blocked on a call to device.state.stopping.Wait. * device.setUpDown then attempted to lock device.state.Mutex and blocked. Deadlock results. setUpDown cannot progress because device.state.Mutex is locked. Until setUpDown returns, RoutineTUNEventReader cannot call device.state.stopping.Done. Until device.state.stopping.Done gets called, device.state.stopping.Wait is blocked. As long as device.state.stopping.Wait is blocked, device.state.Mutex cannot be unlocked. This commit fixes that deadlock by holding device.state.mu when checking that the device is not closed. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: remove unnecessary zeroing in peer.SendKeepaliveJosh Bleecher Snyder1-1/+0
elem.packet is always already nil. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: remove device.state.stopping from RoutineHandshakeJosh Bleecher Snyder2-5/+1
It is no longer necessary. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-02-08device: remove device.state.stopping from RoutineDecryptionJosh Bleecher Snyder2-5/+3
It is no longer necessary, as of 454de6f3e64abd2a7bf9201579cd92eea5280996 (device: use channel close to shut down and drain decryption channel). Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>