The sync.Locker used with a sync.Cond must be acquired when changing
the associated condition, otherwise there is a window within
sync.Cond.Wait() where a wake-up may be missed.
Fixes: 4846070 ("device: use a waiting sync.Pool instead of a channel")
Reviewed-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This enables a conn.Bind to bring its own encapsulating transport, e.g.
VXLAN/Geneve.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This is already enforced in receive.go, but if these unmarshallers are
to have error return values anyway, make them as explicit as possible.
cherry picked from commit WireGuard/wireguard-go@842888ac5c
Updates tailscale/corp#28879
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
There is a possible deadlock in `device.Close()` when you try to close
the device very soon after its start. The problem is that two different
methods acquire the same locks in different order:
1. device.Close()
- device.ipcMutex.Lock()
- device.state.Lock()
2. device.changeState(deviceState)
- device.state.Lock()
- device.ipcMutex.Lock()
Reproducer:
func TestDevice_deadlock(t *testing.T) {
d := randDevice(t)
d.Close()
}
Problem:
$ go clean -testcache && go test -race -timeout 3s -run TestDevice_deadlock ./device | grep -A 10 sync.runtime_SemacquireMutex
sync.runtime_SemacquireMutex(0xc000117d20?, 0x94?, 0x0?)
/usr/local/opt/go/libexec/src/runtime/sema.go:77 +0x25
sync.(*Mutex).lockSlow(0xc000130518)
/usr/local/opt/go/libexec/src/sync/mutex.go:171 +0x213
sync.(*Mutex).Lock(0xc000130518)
/usr/local/opt/go/libexec/src/sync/mutex.go:90 +0x55
golang.zx2c4.com/wireguard/device.(*Device).Close(0xc000130500)
/Users/martin.basovnik/git/basovnik/wireguard-go/device/device.go:373 +0xb6
golang.zx2c4.com/wireguard/device.TestDevice_deadlock(0x0?)
/Users/martin.basovnik/git/basovnik/wireguard-go/device/device_test.go:480 +0x2c
testing.tRunner(0xc00014c000, 0x131d7b0)
--
sync.runtime_SemacquireMutex(0xc000130564?, 0x60?, 0xc000130548?)
/usr/local/opt/go/libexec/src/runtime/sema.go:77 +0x25
sync.(*Mutex).lockSlow(0xc000130750)
/usr/local/opt/go/libexec/src/sync/mutex.go:171 +0x213
sync.(*Mutex).Lock(0xc000130750)
/usr/local/opt/go/libexec/src/sync/mutex.go:90 +0x55
sync.(*RWMutex).Lock(0xc000130750)
/usr/local/opt/go/libexec/src/sync/rwmutex.go:147 +0x45
golang.zx2c4.com/wireguard/device.(*Device).upLocked(0xc000130500)
/Users/martin.basovnik/git/basovnik/wireguard-go/device/device.go:179 +0x72
golang.zx2c4.com/wireguard/device.(*Device).changeState(0xc000130500, 0x1)
cherry picked from commit WireGuard/wireguard-go@12269c2761
Updates tailscale/corp#28879
Signed-off-by: Martin Basovnik <martin.basovnik@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Only bother updating the rxBytes counter once we've processed a whole
vector, since additions are atomic.
cherry picked from commit WireGuard/wireguard-go@542e565baa
Updates tailscale/corp#28879
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Upstream doesn't use GitHub actions for CI as GitHub is simply a mirror.
Our workflows involve GitHub, so establish some basic CI jobs.
Updates tailscale/corp#28877
Signed-off-by: Jordan Whited <jordan@tailscale.com>
torvalds/linux@e269d79c7d broke virtio_net
TCP & UDP GRO causing GRO writes to return EINVAL. The bug was then
resolved later in
torvalds/linux@89add40066. The offending
commit was pulled into various LTS releases.
Updates tailscale/tailscale#13041
Signed-off-by: Jordan Whited <jordan@tailscale.com>
When generating page-aligned random bytes, random data started at the
beginning of the buffer that will be chopped off. When the page size
differs, the start of the returned slice is different than expected for
the expected checksums, causing the tests to fail.
External implementers of tun.Device may support GSO, and may also be
platform-agnostic, e.g. gVisor.
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Introduce an optional extension point for Endpoint that enables a path
for WireGuard to inform an integration about the peer public key that is
associated with an Endpoint.
The API is expected to return either the same or a new Endpoint in
response to this function. A future version of this patch could
potentially remove the returned Endpoint, but would require larger
integrator changes downstream.
This adds a small per-packet cost that could later be removed with a
larger refactor of the wireguard-go interface and Tailscale magicsock
code, as well as introducing a generic bound for Endpoint in a device &
bind instance.
Updates tailscale/corp#20732
The sync.Locker used with a sync.Cond must be acquired when changing
the associated condition, otherwise there is a window within
sync.Cond.Wait() where a wake-up may be missed.
Fixes: 4846070 ("device: use a waiting sync.Pool instead of a channel")
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Certain device drivers (e.g. vxlan, geneve) do not properly handle
coalesced UDP packets later in the stack, resulting in packet loss.
Signed-off-by: Jordan Whited <jordan@tailscale.com>