mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-12 13:48:01 +00:00
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:
@@ -263,6 +263,11 @@ type Conn struct {
|
||||
// logging.
|
||||
noV4, noV6 syncs.AtomicBool
|
||||
|
||||
// noV4Send is whether IPv4 UDP is known to be unable to transmit
|
||||
// at all. This could happen if the socket is in an invalid state
|
||||
// (as can happen on darwin after a network link status change).
|
||||
noV4Send syncs.AtomicBool
|
||||
|
||||
// networkUp is whether the network is up (some interface is up
|
||||
// with IPv4 or IPv6). It's used to suppress log spam and prevent
|
||||
// new connection that'll fail.
|
||||
@@ -603,6 +608,10 @@ func (c *Conn) updateEndpoints(why string) {
|
||||
c.muCond.Broadcast()
|
||||
}()
|
||||
c.logf("[v1] magicsock: starting endpoint update (%s)", why)
|
||||
if c.noV4Send.Get() {
|
||||
c.logf("magicsock: last netcheck reported send error. Rebinding.")
|
||||
c.Rebind()
|
||||
}
|
||||
|
||||
endpoints, err := c.determineEndpoints(c.connCtx)
|
||||
if err != nil {
|
||||
@@ -697,6 +706,7 @@ func (c *Conn) updateNetInfo(ctx context.Context) (*netcheck.Report, error) {
|
||||
|
||||
c.noV4.Set(!report.IPv4)
|
||||
c.noV6.Set(!report.IPv6)
|
||||
c.noV4Send.Set(!report.IPv4CanSend)
|
||||
|
||||
ni := &tailcfg.NetInfo{
|
||||
DERPLatency: map[string]float64{},
|
||||
|
@@ -1143,7 +1143,8 @@ func (e *userspaceEngine) GetLinkMonitor() *monitor.Mon {
|
||||
}
|
||||
|
||||
// LinkChange signals a network change event. It's currently
|
||||
// (2021-03-03) only called on Android.
|
||||
// (2021-03-03) only called on Android. On other platforms, linkMon
|
||||
// generates link change events for us.
|
||||
func (e *userspaceEngine) LinkChange(_ bool) {
|
||||
e.linkMon.InjectEvent()
|
||||
}
|
||||
|
Reference in New Issue
Block a user