summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--net/netns/netns_darwin.go6
-rw-r--r--version/prop.go14
2 files changed, 18 insertions, 2 deletions
diff --git a/net/netns/netns_darwin.go b/net/netns/netns_darwin.go
index ac5e89d76..794b9b864 100644
--- a/net/netns/netns_darwin.go
+++ b/net/netns/netns_darwin.go
@@ -21,6 +21,7 @@ import (
"tailscale.com/net/netmon"
"tailscale.com/net/tsaddr"
"tailscale.com/types/logger"
+ "tailscale.com/version"
)
func control(logf logger.Logf, netMon *netmon.Monitor) func(network, address string, c syscall.RawConn) error {
@@ -38,8 +39,9 @@ var errInterfaceStateInvalid = errors.New("interface state invalid")
// It's intentionally the same signature as net.Dialer.Control
// and net.ListenConfig.Control.
func controlLogf(logf logger.Logf, netMon *netmon.Monitor, network, address string, c syscall.RawConn) error {
- if isLocalhost(address) {
- // Don't bind to an interface for localhost connections.
+ // Don't bind to an interface for localhost connections for tailscaled. We must still bind for
+ // the network extension variants.
+ if version.IsMacOSTailscaled() && isLocalhost(address) {
return nil
}
diff --git a/version/prop.go b/version/prop.go
index 9327e6fe6..a3d15b1d5 100644
--- a/version/prop.go
+++ b/version/prop.go
@@ -147,6 +147,20 @@ func IsAppleTV() bool {
})
}
+var isMacOSTailscaled lazy.SyncValue[bool]
+
+// IsMacOSTailscaled reports whether this binary is the tailscaled daemon running on macos
+func IsMacOSTailscaled() bool {
+ // This rules out iOS and tvOS
+ if runtime.GOOS != "darwin" {
+ return false
+ }
+ return isMacOSTailscaled.Get(func() bool {
+ // A darwin client that is not sandboxed macOS is tailscaled
+ return !IsSandboxedMacOS()
+ })
+}
+
var isWindowsGUI lazy.SyncValue[bool]
// IsWindowsGUI reports whether the current process is the Windows GUI.