diff --git a/libtailscale/net.go b/libtailscale/net.go index 17986e0c00..5fc2d9f4aa 100644 --- a/libtailscale/net.go +++ b/libtailscale/net.go @@ -80,36 +80,27 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) (err error) b.logger.Logf("updateTUN: changed") defer b.logger.Logf("updateTUN: finished") - // Close previous tunnel(s). - // This is necessary for ChromeOS, native Android devices - // seem to handle seamless handover between tunnels correctly. - // - // TODO(eliasnaur): If seamless handover becomes a desirable feature, skip - // the closing on ChromeOS. - b.logger.Logf("updateTUN: closing old TUNs") - b.CloseTUNs() - b.logger.Logf("updateTUN: closed old TUNs") - - // Since the previous tunnel(s) are closed, the [multiTUN] device is - // not operational until a new underlying tunnel is created and added, - // which may never happen in case of an error or an empty [router.Config]. - // - // Therefore, to prevent deadlocks where a [multiTUN.Write] would - // block waiting for a new tunnel to be added, we bring the multiTUN - // device down on exit unless a new [tun.Device] is created and added - // successfully. See tailscale/tailscale#18679. - // - // TODO(nickkhyl): revisit and simplify the [multiTUN] implementation? - hasTunnel := false - defer func() { - if !hasTunnel && b.devices.Down() { + if disableTUN := len(rcfg.LocalAddrs) == 0; disableTUN { + b.logger.Logf("updateTUN: closing old TUNs") + b.CloseTUNs() + b.logger.Logf("updateTUN: closed old TUNs") + + // Since the previous tunnel(s) are closed, the [multiTUN] device is + // not operational until a new underlying tunnel is created and added, + // which may never happen in case of an error or an empty [router.Config]. + // + // Therefore, to prevent deadlocks where a [multiTUN.Write] would + // block waiting for a new tunnel to be added, we bring the multiTUN + // device down on exit unless a new [tun.Device] is created and added + // successfully. See tailscale/tailscale#18679. + // + // TODO(nickkhyl): revisit and simplify the [multiTUN] implementation? + if b.devices.Down() { b.logger.Logf("updateTUN: tunnel brought down: %v", err) } - }() - - if len(rcfg.LocalAddrs) == 0 { return nil } + builder := vpnService.service.NewBuilder() b.logger.Logf("updateTUN: got new builder") @@ -244,7 +235,6 @@ func (b *backend) updateTUN(rcfg *router.Config, dcfg *dns.OSConfig) (err error) b.logger.Logf("updateTUN: created TUN device") b.devices.add(tunDev) - hasTunnel = true b.logger.Logf("updateTUN: added TUN device") if b.devices.Up() {