aboutsummaryrefslogtreecommitdiff
path: root/device (follow)
Commit message (Collapse)AuthorAgeFilesLines
* device: remove QueueInboundElement leak with stopped peersJosh Bleecher Snyder2021-01-071-0/+2
| | | | | | | | | | | | | | | This is particularly problematic on mobile, where there is a fixed number of elements. If most of them leak, it'll impact performance; if all of them leak, the device will permanently deadlock. I have a test that detects element leaks, which is how I found this one. There are some remaining leaks that I have not yet tracked down, but this is the most prominent by far. I will commit the test when it passes reliably. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: simplify UAPI helper methodsJosh Bleecher Snyder2021-01-071-12/+5
| | | | | | | | | | | | | bufio is not required. strings.Builder is cheaper than bytes.Buffer for constructing strings. io.Writer is more flexible than io.StringWriter, and just as cheap (when used with io.WriteString). Run gofmt. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: fix alignment of peer stats memberJason A. Donenfeld2021-01-071-1/+2
| | | | | | | | This was shifted by 2 bytes when making persistent keepalive into a u32. Fix it by placing it after the aligned region. Fixes: e739ff7 ("device: fix persistent_keepalive_interval data races") Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: add UAPI helper methodsJason A. Donenfeld2021-01-071-2/+21
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: add missing colon to error lineJason A. Donenfeld2021-01-072-3/+3
| | | | | | | People are actually hitting this condition, so make it uniform. Also, change a printf into a println, to match the other conventions. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: fix error shadowing before log printBrad Fitzpatrick2021-01-071-4/+4
| | | | Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* device: fix data race in peer.timersActiveJosh Bleecher Snyder2021-01-073-3/+6
| | | | | | | | | Found by the race detector and existing tests. To avoid introducing a lock into this hot path, calculate and cache whether any peers exist. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: fix races from changing private_keyJosh Bleecher Snyder2021-01-075-11/+32
| | | | | | | | | | Access keypair.sendNonce atomically. Eliminate one unnecessary initialization to zero. Mutate handshake.lastSentHandshake with the mutex held. Co-authored-by: David Anderson <danderson@tailscale.com> Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: always name *Queue*Element variables elemJosh Bleecher Snyder2021-01-073-26/+26
| | | | | | | | They're called elem in most places. Rename a few local variables to make it consistent. This makes it easier to grep the code for things like elem.Drop. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: use channel close to shut down and drain outbound channelJosh Bleecher Snyder2021-01-072-55/+34
| | | | | | | | | This is a similar treatment to the handling of the encryption channel found a few commits ago: Use the closing of the channel to manage goroutine lifetime and shutdown. It is considerably simpler because there is only a single writer. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: fix persistent_keepalive_interval data racesJosh Bleecher Snyder2021-01-075-9/+22
| | | | | Co-authored-by: David Anderson <danderson@tailscale.com> Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: use channel close to shut down and drain encryption channelJosh Bleecher Snyder2021-01-073-98/+170
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* device: simplify copying counter to nonceJosh Bleecher Snyder2021-01-071-12/+2
| | | | | | | | | | | | | | | | | | Since we already have it packed into a uint64 in a known byte order, write it back out again the same byte order instead of copying byte by byte. This should also generate more efficient code, because the compiler can do a single uint64 write, instead of eight bounds checks and eight byte writes. Due to a missed optimization, it actually generates a mishmash of smaller writes: 1 byte, 4 bytes, 2 bytes, 1 byte. This is https://golang.org/issue/41663. The code is still better than before, and will get better yet once that compiler bug gets fixed. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: add a helper to generate uapi configsJosh Bleecher Snyder2021-01-071-28/+45
| | | | | | | | This makes it easier to work with configs in tests. It'll see heavier use over upcoming commits; this commit only adds the infrastructure. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: use defer to simplify peer.NewTimerJosh Bleecher Snyder2021-01-071-2/+1
| | | | | | This also makes the lifetime of modifyingLock more prominent. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: accept any io.Reader in device.IpcSetOperationJosh Bleecher Snyder2021-01-071-2/+2
| | | | | | | | | | Any io.Reader will do, and there are no performance concerns here. This is technically backwards incompatible, but it is very unlikely to break any existing code. It is compatible with the existing uses in wireguard-{windows,android,apple} and also will allow us to slightly simplify it if desired. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: increase timeout in testsJosh Bleecher Snyder2021-01-071-2/+2
| | | | | | | | | When running many concurrent test processing using https://godoc.org/golang.org/x/tools/cmd/stress the processing sometimes cannot complete a ping in under 300ms. Increase the timeout to 5s to reduce the rate of false positives. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: prevent spurious errors while closing a deviceJosh Bleecher Snyder2021-01-071-0/+5
| | | | | | | | | | | | | | When closing a device, packets that are in flight can make it to SendBuffer, which then returns an error. Those errors add noise but no light; they do not reflect an actual problem. Adding the synchronization required to prevent this from occurring is currently expensive and error-prone. Instead, quietly drop such packets instead of returning an error. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: remove starting waitgroupsJosh Bleecher Snyder2021-01-075-29/+1
| | | | | | | | | | | | | | | In each case, the starting waitgroup did nothing but ensure that the goroutine has launched. Nothing downstream depends on the order in which goroutines launch, and if the Go runtime scheduler is so broken that goroutines don't get launched reasonably promptly, we have much deeper problems. Given all that, simplify the code. Passed a race-enabled stress test 25,000 times without failure. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: make test setup more robustJosh Bleecher Snyder2021-01-071-28/+64
| | | | | | | | | | | | | | | | | | | | | | | | | Picking two free ports to use for a test is difficult. The free port we selected might no longer be free when we reach for it a second time. On my machine, this failure mode led to failures approximately once per thousand test runs. Since failures are rare, and threading through and checking for all possible errors is complicated, fix this with a big hammer: Retry if either device fails to come up. Also, if you accidentally pick the same port twice, delightful confusion ensues. The handshake failures manifest as crypto errors, which look scary. Again, fix with retries. To make these retries easier to implement, use testing.T.Cleanup instead of defer to close devices. This requires Go 1.14. Update go.mod accordingly. Go 1.13 is no longer supported anyway. With these fixes, 'go test -race' ran 100,000 times without failure. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: avoid copying lock in testsJosh Bleecher Snyder2020-12-081-1/+1
| | | | | | | | This doesn't cause any practical problems as it is, but vet (rightly) flags this code as copying a mutex. It is easy to fix, so do so. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: clear pointers when returning elems to poolsJosh Bleecher Snyder2020-12-083-1/+24
| | | | Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: use labeled for loop instead of gotoJosh Bleecher Snyder2020-12-081-4/+4
| | | | | | Minor code cleanup; no functional changes. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* version: bump snapshot0.0.20201118Jason A. Donenfeld2020-11-181-1/+1
|
* device: add write queue mutex for peerHaichao Liu2020-11-183-1/+11
| | | | | | | 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: format a few thingsJason A. Donenfeld2020-11-062-2/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* replay: minor API changes to more idiomatic GoRiobard Zhan2020-10-142-2/+2
| | | | | Signed-off-by: Riobard Zhan <me@riobard.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: remove global for roaming escape hatchJason A. Donenfeld2020-10-142-2/+18
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: get free port when testingSina Siadat2020-07-311-5/+23
| | | | | Signed-off-by: Sina Siadat <siadat@gmail.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: remove bindsocketshim.goDavid Crawshaw2020-07-141-36/+0
| | | | | | | | Both wireguard-windows and wireguard-android access Bind directly for these methods now. Signed-off-by: David Crawshaw <crawshaw@tailscale.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: remove some unnecessary unsafeBrad Fitzpatrick2020-07-151-2/+3
| | | | Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* device: use RTMGRP_IPV4_ROUTE to specify multicast groups maskTobias Klauser2020-07-131-1/+1
| | | | | | | | | Use the RTMGRP_IPV4_ROUTE const from x/sys/unix instead of using the corresponding RTNLGRP_IPV4_ROUTE const to create the multicast groups mask. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: wait for routines to stop before removing peersDmytro Shynkevych2020-07-041-1/+1
| | | | | | | | | | | | | | | 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>
* device: export Bind and remove socketfd shims for androidDavid Crawshaw2020-06-222-24/+6
| | | | Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
* device: do not include sticky sockets on androidJason A. Donenfeld2020-06-072-1/+3
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* conn: unbreak boundif on androidJason A. Donenfeld2020-06-072-44/+24
| | | | | | Another thing never tested ever. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* conn: fix windows situation with boundifJason A. Donenfeld2020-06-071-4/+4
| | | | | | This was evidently never tested before committing. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* replay: account for fqcodel reorderingJason A. Donenfeld2020-05-191-1/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: rework padding calculation and don't shadow paddedSizeJason A. Donenfeld2020-05-181-15/+17
| | | | | Reported-by: Jayakumar S <jayakumar82.s@gmail.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: update header comments and modulesJason A. Donenfeld2020-05-0235-35/+35
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: use atomic access for unlocked keypair.nextJason A. Donenfeld2020-05-024-11/+23
| | | | | | | | | Go's GC semantics might not always guarantee the safety of this, and the race detector gets upset too, so instead we wrap this all in atomic accessors. Reported-by: David Anderson <danderson@tailscale.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: add debug logs describing handshake rejectionAvery Pennarun2020-05-021-4/+8
| | | | | | | Useful in testing when bad network stacks repeat or batch large numbers of packets. Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
* device: return generic error from Ipc{Get,Set}Operation.David Anderson2020-05-021-4/+15
| | | | | | | This makes uapi.go's public API conform to Go style in terms of error types. Signed-off-by: David Anderson <danderson@tailscale.com>
* device: give handshake state a typeDavid Crawshaw2020-05-021-17/+38
| | | | | | And unexport handshake constants. Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
* tuntest: split out testing packageDavid Crawshaw2020-05-021-141/+5
| | | | | | This code is useful to other packages writing tests. Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
* conn: introduce new package that splits out the Bind and Endpoint typesDavid Crawshaw2020-05-0214-1294/+419
| | | | | | | | | | The sticky socket code stays in the device package for now, as it reaches deeply into the peer list. This is the first step in an effort to split some code out of the very busy device package. Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
* device: add test to ensure Peer fields are safe for atomic access on 32-bitDavid Anderson2020-05-022-1/+48
| | | | | | | | | Adds a test that will fail consistently on 32-bit platforms if the struct ever changes again to violate the rules. This is likely not needed because unaligned access crashes reliably, but this will reliably fail even if tests accidentally pass due to lucky alignment. Signed-Off-By: David Anderson <danderson@tailscale.com>
* version: bump snapshot0.0.20200320Jason A. Donenfeld2020-03-201-1/+1
|
* noise: unify zero checking of ecdhJason A. Donenfeld2020-03-173-63/+49
|
* global: use RTMGRP_* consts from x/sys/unixTobias Klauser2020-03-171-1/+1
| | | | | | | | Update the golang.org/x/sys/unix dependency and use the newly introduced RTMGRP_* consts instead of using the corresponding RTNLGRP_* const to create a mask. Signed-off-by: Tobias Klauser <tklauser@distanz.ch>