aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* device: add Device.ListenPort and Device.SetListenPortjs/sample-apiJosh Bleecher Snyder2020-12-222-9/+24
| | | | | | | | | | | | | | | | | | | This is a sample commit for a possible way to make a Go API that lives alongside UAPI. The general idea is to add Device and Peer methods corresponding to UAPI directives, including a way to look up a peer from a device based on a public key, as in UAPI. The UAPI code then deals with parsing and generating textual input/output, and calls the Go methods to do the work. This commit also contains a bug fix for a racy access of device.net.port I will send an independently commit that fixes those directly in UAPI. This commit is NOT meant to be merged as-is. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
* device: add UAPI helper methodsJason A. Donenfeld2020-12-221-2/+21
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun: make customization of WintunPool and WintunGUID more obviousJason A. Donenfeld2020-12-221-10/+3
| | | | | | | | | | | Persnickety consumers can now do: func init() { tun.WintunPool, _ = wintun.Pool("Flurp") tun.WintunStaticRequestedGUID, _ = windows.GUIDFromString("{5ae2716f-0b3e-4dc4-a8b5-48eba11a6e16}") } Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* conn: do not SO_REUSEADDR on linuxJason A. Donenfeld2020-12-181-19/+0
| | | | | | SO_REUSEADDR does not make sense for unicast UDP sockets. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* device: add missing colon to error lineJason A. Donenfeld2020-12-182-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 Fitzpatrick2020-12-171-4/+4
| | | | Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* device: fix data race in peer.timersActiveJosh Bleecher Snyder2020-12-163-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 Snyder2020-12-165-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 Snyder2020-12-163-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 Snyder2020-12-162-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 Snyder2020-12-155-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 Snyder2020-12-153-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 Snyder2020-12-151-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 Snyder2020-12-151-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 Snyder2020-12-151-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 Snyder2020-12-151-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 Snyder2020-12-151-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 Snyder2020-12-151-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 Snyder2020-12-105-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 Snyder2020-12-102-29/+65
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* wintun: do not load dll in init()Jason A. Donenfeld2020-12-095-14/+21
| | | | | | | This prevents linking to wintun.dll until it's actually needed, which should improve startup time. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun/tuntest: make genICMPv4 allocate lessJosh Bleecher Snyder2020-12-081-8/+7
| | | | | | It doesn't really matter, because it is only used in tests, but it does remove some noise from pprof profiles. 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>
* memmod: fix import loading function usageJason A. Donenfeld2020-11-275-32/+10
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wintun: log when reboot is suggested by WindowsSimon Rozman2020-11-251-1/+5
| | | | | | | Which really shouldn't happen. But it is a useful information for troubleshooting. Signed-off-by: Simon Rozman <simon@rozman.si>
* wintun: keep original error when Wintun session start failsSimon Rozman2020-11-251-1/+1
| | | | Signed-off-by: Simon Rozman <simon@rozman.si>
* version: bump snapshot0.0.20201118Jason A. Donenfeld2020-11-181-1/+1
|
* mod: bumpJason A. Donenfeld2020-11-182-9/+11
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* 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>
* wintun: load from filesystem by defaultJason A. Donenfeld2020-11-113-39/+109
| | | | | | | | We let people loading this from resources opt in via: go build -tags load_wintun_from_rsrc Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* global: switch to using %w instead of %v for ErrorfJason A. Donenfeld2020-11-076-34/+34
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* mod: update depsJason A. Donenfeld2020-11-072-12/+9
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wintun: ring management moved to wintun.dllSimon Rozman2020-11-074-214/+147
| | | | | Signed-off-by: Simon Rozman <simon@rozman.si> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wintun: load wintun.dll from RCDATA resourceSimon Rozman2020-11-0719-2/+1578
| | | | | Signed-off-by: Simon Rozman <simon@rozman.si> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* wintun: migrate to wintun.dll APISimon Rozman2020-11-0725-3711/+169
| | | | | | | | Rather than having every application using Wintun driver reinvent the wheel, the Wintun device/adapter/interface management has been moved from wireguard-go to wintun.dll deployed with Wintun itself. Signed-off-by: Simon Rozman <simon@rozman.si>
* device: format a few thingsJason A. Donenfeld2020-11-062-2/+1
| | | | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun: use SockaddrCtl from golang.org/x/sys/unix on macOSTobias Klauser2020-10-271-29/+6
| | | | | | | | | Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on macOS and might not be supported in future versions. Switch to use unix.Connect with unix.SockaddrCtl instead. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun: use Ioctl{Get,Set}IfreqMTU from golang.org/x/sys/unix on macOSTobias Klauser2020-10-271-35/+10
| | | | | | | | | Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on macOS and might not be supported in future versions. Switch to use unix.Ioctl{Get,Set}IfreqMTU to get and set an interface's MTU. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun: use IoctlCtlInfo from golang.org/x/sys/unix on macOSTobias Klauser2020-10-271-20/+6
| | | | | | | | | Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on macOS and might not be supported in future versions. Switch to use unix.IoctlCtlInfo to get the kernel control info. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun: use GetsockoptString in (*NativeTun).Name on macOSTobias Klauser2020-10-271-14/+6
| | | | | | | | | Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on macOS and might not be supported in future versions. Instead, use the existing unix.GetsockoptString wrapper to get the interface name. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* go.mod: bump golang.org/x/sys to latest versionTobias Klauser2020-10-272-3/+3
| | | | | | | | This adds the fixes for golang/go#41868 which are needed to build wireguard without direct syscalls on macOS. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* tun/wintun/registry: fix Go 1.15 race/checkptr failureBrad Fitzpatrick2020-10-213-4/+4
| | | | | | Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> [Jason: ran go mod tidy.] Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* Makefile: Add test targetFrank Werner2020-10-201-1/+4
| | | | | Signed-off-by: Frank Werner <mail@hb9fxq.ch> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* replay: minor API changes to more idiomatic GoRiobard Zhan2020-10-144-17/+17
| | | | | Signed-off-by: Riobard Zhan <me@riobard.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
* replay: clean up internals and better documentationRiobard Zhan2020-10-142-71/+50
| | | | | 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>
* replay: divide by bits-per-byteJason A. Donenfeld2020-09-071-1/+1
| | | | | | | | Bits / Bytes-per-Word misses the step of also dividing by Bits-per-Byte, which we need in order for this to make sense. Reported-by: Riobard Zhan <me@riobard.com> 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>