mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
ipn/ipnlocal: prefer to use one CGNAT route on the Mac
Together with 06aa141632
this minimizes
the number of NEPacketTunnelNetworkSettings updates that we have to do,
and thus avoids Chrome interrupting outstanding requests due to
(perceived) network changes.
Updates #3102
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This commit is contained in:
parent
3f4fd64311
commit
ec649e707f
@ -2175,7 +2175,6 @@ func (b *LocalBackend) authReconfig() {
|
|||||||
nm := b.netMap
|
nm := b.netMap
|
||||||
hasPAC := b.prevIfState.HasPAC()
|
hasPAC := b.prevIfState.HasPAC()
|
||||||
disableSubnetsIfPAC := nm != nil && nm.Debug != nil && nm.Debug.DisableSubnetsIfPAC.EqualBool(true)
|
disableSubnetsIfPAC := nm != nil && nm.Debug != nil && nm.Debug.DisableSubnetsIfPAC.EqualBool(true)
|
||||||
oneCGNATRoute := nm != nil && nm.Debug != nil && nm.Debug.OneCGNATRoute.EqualBool(true)
|
|
||||||
b.mu.Unlock()
|
b.mu.Unlock()
|
||||||
|
|
||||||
if blocked {
|
if blocked {
|
||||||
@ -2220,6 +2219,7 @@ func (b *LocalBackend) authReconfig() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oneCGNATRoute := shouldUseOneCGNATRoute(nm, b.logf, version.OS())
|
||||||
rcfg := b.routerConfig(cfg, prefs, oneCGNATRoute)
|
rcfg := b.routerConfig(cfg, prefs, oneCGNATRoute)
|
||||||
dcfg := dnsConfigForNetmap(nm, prefs, b.logf, version.OS())
|
dcfg := dnsConfigForNetmap(nm, prefs, b.logf, version.OS())
|
||||||
|
|
||||||
@ -2232,6 +2232,38 @@ func (b *LocalBackend) authReconfig() {
|
|||||||
b.initPeerAPIListener()
|
b.initPeerAPIListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shouldUseOneCGNATRoute reports whether we should prefer to make one big
|
||||||
|
// CGNAT /10 route rather than a /32 per peer.
|
||||||
|
//
|
||||||
|
// The versionOS is a Tailscale-style version ("iOS", "macOS") and not
|
||||||
|
// a runtime.GOOS.
|
||||||
|
func shouldUseOneCGNATRoute(nm *netmap.NetworkMap, logf logger.Logf, versionOS string) bool {
|
||||||
|
// Explicit enabling or disabling always take precedence.
|
||||||
|
if nm.Debug != nil {
|
||||||
|
if v, ok := nm.Debug.OneCGNATRoute.Get(); ok {
|
||||||
|
logf("[v1] shouldUseOneCGNATRoute: explicit=%v", v)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also prefer to do this on the Mac, so that we don't need to constantly
|
||||||
|
// update the network extension configuration (which is disruptive to
|
||||||
|
// Chrome, see https://github.com/tailscale/tailscale/issues/3102). Only
|
||||||
|
// use fine-grained routes if another interfaces is also using the CGNAT
|
||||||
|
// IP range.
|
||||||
|
if versionOS == "macOS" {
|
||||||
|
hasCGNATInterface, err := interfaces.HasCGNATInterface()
|
||||||
|
if err != nil {
|
||||||
|
logf("shouldUseOneCGNATRoute: Could not determine if any interfaces use CGNAT: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
logf("[v1] shouldUseOneCGNATRoute: macOS automatic=%v", !hasCGNATInterface)
|
||||||
|
if !hasCGNATInterface {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// dnsConfigForNetmap returns a *dns.Config for the given netmap,
|
// dnsConfigForNetmap returns a *dns.Config for the given netmap,
|
||||||
// prefs, client OS version, and cloud hosting environment.
|
// prefs, client OS version, and cloud hosting environment.
|
||||||
//
|
//
|
||||||
|
@ -720,3 +720,25 @@ func DefaultRouteInterface() (string, error) {
|
|||||||
func DefaultRoute() (DefaultRouteDetails, error) {
|
func DefaultRoute() (DefaultRouteDetails, error) {
|
||||||
return defaultRoute()
|
return defaultRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasCGNATInterface reports whether there are any non-Tailscale interfaces that
|
||||||
|
// use a CGNAT IP range.
|
||||||
|
func HasCGNATInterface() (bool, error) {
|
||||||
|
hasCGNATInterface := false
|
||||||
|
cgnatRange := tsaddr.CGNATRange()
|
||||||
|
err := ForeachInterface(func(i Interface, pfxs []netaddr.IPPrefix) {
|
||||||
|
if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, pfx := range pfxs {
|
||||||
|
if cgnatRange.Overlaps(pfx) {
|
||||||
|
hasCGNATInterface = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return hasCGNATInterface, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user