All atomic access must be aligned to 64 bits, even on 32-bit
platforms. Go promises that the start of allocated structs is
aligned to 64 bits. So, place the atomically-accessed things
first in the struct so that they benefit from that alignment.
As a side bonus, it cleanly separates fields that are accessed
by atomic ops, and those that should be accessed under mu.
Also 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>
This lets us include the package on those platforms in a
followup commit where we split out a conn package from device.
It also lets us run `go test ./...` when developing on macOS.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
The existing test would occasionally flake out with:
--- FAIL: TestRatelimiter (0.12s)
ratelimiter_test.go:99: Test failed for 127.0.0.1 , on: 7 ( not having refilled enough ) expected: false got: true
FAIL
FAIL golang.zx2c4.com/wireguard/ratelimiter 0.171s
The fake clock also means the tests run much faster, so
testing this package with -count=1000 now takes < 100ms.
While here, several style cleanups. The most significant one
is unembeding the sync.Mutex fields in the rate limiter objects.
Embedded as they were, the lock methods were accessible
outside the ratelimiter package. As they aren't needed externally,
keep them internal to make them easier to reason about.
Passes `go test -race -count=10000 ./ratelimiter`
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
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>
Some devices take ~2 seconds to enumerate on Windows if we try to get
their instance name. The hardware id property, on the other hand,
is available right away.
Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
[zx2c4: inlined this to where it makes sense, reused setupapi const]
On my Chromebook (Linux 4.19.44 in a VM) and on an AWS EC2
machine, select() was sometimes returning EINTR. This is
harmless and just means you should try again. So let's try
again.
This eliminates a problem where the tunnel fails to come up
correctly and the program needs to be restarted.
Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
In some cases, we operate on an already-up interface, or the user brings
up the interface before we start monitoring. For those situations, we
should first check if the interface is already up.
This still technically races between the initial check and the start of
the route loop, but fixing that is a bit ugly and probably not worth it
at the moment.
Reported-by: Theo Buehler <tb@theobuehler.org>