magicsock: if STUN failed to send before, rebind before STUNning again.
On iOS (and possibly other platforms), sometimes our UDP socket would get stuck in a state where it was bound to an invalid interface (or no interface) after a network reconfiguration. We can detect this by actually checking the error codes from sending our STUN packets. If we completely fail to send any STUN packets, we know something is very broken. So on the next STUN attempt, let's rebind the UDP socket to try to correct any problems. This fixes a problem where iOS would sometimes get stuck using DERP instead of direct connections until the backend was restarted. Fixes #2994 Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
This commit is contained in:
@@ -100,11 +100,18 @@ func TestWorksWhenUDPBlocked(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := newReport()
|
||||
r.UPnP = ""
|
||||
r.PMP = ""
|
||||
r.PCP = ""
|
||||
|
||||
want := newReport()
|
||||
|
||||
// The IPv4CanSend flag gets set differently across platforms.
|
||||
// On Windows this test detects false, while on Linux detects true.
|
||||
// That's not relevant to this test, so just accept what we're
|
||||
// given.
|
||||
want.IPv4CanSend = r.IPv4CanSend
|
||||
|
||||
if !reflect.DeepEqual(r, want) {
|
||||
t.Errorf("mismatch\n got: %+v\nwant: %+v\n", r, want)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user