Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions net/dns/manager_darwin.go
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we drop the network extension, we're going to start informing the OS of the magicDNS server by modifying /etc/resolvers

Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (c *darwinConfigurator) SetDNS(cfg OSConfig) error {
// Add a dummy file to /etc/resolver with a "search ..." directive if we have
// search suffixes to add.
if len(cfg.SearchDomains) > 0 {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't currently use search domains.

const searchFile = "search.tailscale" // fake DNS suffix+TLD to put our search
const searchFile = "search.coder" // fake DNS suffix+TLD to put our search
mak.Set(&keep, searchFile, true)
var sbuf bytes.Buffer
sbuf.WriteString(macResolverFileHeader)
Expand Down Expand Up @@ -86,7 +86,7 @@ func (c *darwinConfigurator) GetBaseConfig() (OSConfig, error) {
return OSConfig{}, ErrGetBaseConfigNotSupported
}

const macResolverFileHeader = "# Added by tailscaled\n"
const macResolverFileHeader = "# Added by Coder Desktop\n"

// removeResolverFiles deletes all files in /etc/resolver for which the shouldDelete
// func returns true.
Expand Down
14 changes: 6 additions & 8 deletions net/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
// which HTTP proxy the system should use.
var LoginEndpointForProxyDetermination = "https://controlplane.tailscale.com/"

// Tailscale returns the current machine's Tailscale interface, if any.
// Tailscale returns the current machine's Coder interface, if any.
// If none is found, all zero values are returned.
// A non-nil error is only returned on a problem listing the system interfaces.
func Tailscale() ([]netip.Addr, *net.Interface, error) {
Expand Down Expand Up @@ -58,12 +58,10 @@ func Tailscale() ([]netip.Addr, *net.Interface, error) {
}

// maybeTailscaleInterfaceName reports whether s is an interface
// name that might be used by Tailscale.
// name that might be used by Coder.
func maybeTailscaleInterfaceName(s string) bool {
return s == "Tailscale" ||
strings.HasPrefix(s, "wg") ||
strings.HasPrefix(s, "ts") ||
strings.HasPrefix(s, "tailscale") ||
return s == "Coder" ||
strings.HasPrefix(s, "coder") ||
strings.HasPrefix(s, "utun")
}

Expand Down Expand Up @@ -496,8 +494,8 @@ func isTailscaleInterface(name string, ips []netip.Prefix) bool {
// macOS NetworkExtensions and utun devices.
return true
}
return name == "Tailscale" || // as it is on Windows
strings.HasPrefix(name, "tailscale") // TODO: use --tun flag value, etc; see TODO in method doc
return name == "Coder" || // as it is on Windows
strings.HasPrefix(name, "coder") // TODO: use --tun flag value, etc; see TODO in method doc
}

// getPAC, if non-nil, returns the current PAC file URL.
Expand Down
5 changes: 5 additions & 0 deletions net/netmon/netmon_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ func (m *darwinRouteMon) skipRouteMessage(msg *route.RouteMessage) bool {
// dst = fe80::b476:66ff:fe30:c8f6%15
return true
}
if msg.Type == unix.RTM_GET {
// Skip RTM_GET messages, which are used to query the routing table
// See nets_darwin.go
return true
}
return false
}

Expand Down
20 changes: 10 additions & 10 deletions net/netns/netns_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ func controlLogf(logf logger.Logf, netMon *netmon.Monitor, network, address stri
return nil
}

return bindConnToInterface(c, network, address, idx, logf)
// Verify that we didn't just choose the Coder interface.
_, tsif, err2 := interfaces.Tailscale()
if err2 == nil && tsif != nil && tsif.Index == idx {
return fmt.Errorf("netns_darwin: refusing bind to Coder interface %q (index %d) for address %q", tsif.Name, tsif.Index, address)
}

// Let the OS decide
return nil
}

func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string) (int, error) {
Expand Down Expand Up @@ -98,7 +105,8 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string)
// If the address doesn't parse, use the default index.
addr, err := netip.ParseAddr(host)
if err != nil {
logf("[unexpected] netns: error parsing address %q: %v", host, err)
// Log removed to prevent noise when the address is `:0`
// logf("[unexpected] netns: error parsing address %q: %v", host, err)
return defaultIdx()
}

Expand All @@ -108,14 +116,6 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string)
return defaultIdx()
}

// Verify that we didn't just choose the Tailscale interface;
// if so, we fall back to binding from the default.
_, tsif, err2 := interfaces.Tailscale()
if err2 == nil && tsif != nil && tsif.Index == idx {
logf("[unexpected] netns: interfaceIndexFor returned Tailscale interface")
return defaultIdx()
}

return idx, err
}

Expand Down
35 changes: 12 additions & 23 deletions net/tsaddr/tsaddr.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,48 +73,37 @@ const (
CoderServiceIPv6String = "fd60:627a:a42b::53"
)

// These are all unfortunately Coder IP ranges, not Tailscale IP ranges.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dean suggested not renaming to minimize the diff.


// IsTailscaleIP reports whether ip is an IP address in a range that
// Tailscale assigns from.
// Coder assigns from.
func IsTailscaleIP(ip netip.Addr) bool {
if ip.Is4() {
return CGNATRange().Contains(ip) && !ChromeOSVMRange().Contains(ip)
}
return TailscaleULARange().Contains(ip)
}

// TailscaleULARange returns the IPv6 Unique Local Address range that
// is the superset range that Tailscale assigns out of.
// is the superset range that Coder assigns out of.
func TailscaleULARange() netip.Prefix {
tsUlaRange.Do(func() { mustPrefix(&tsUlaRange.v, "fd7a:115c:a1e0::/48") })
tsUlaRange.Do(func() { mustPrefix(&tsUlaRange.v, "fd60:627a:a42b::/48") })
return tsUlaRange.v
}
Comment on lines 86 to 89
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to address:

newRoutes := make(map[netip.Prefix]bool)
for _, route := range cfg.Routes {
if runtime.GOOS != "darwin" && route == tsaddr.TailscaleULARange() {
// Because we added the interface address as a /48 above,
// the kernel already created the Tailscale ULA route
// implicitly. We mustn't try to add/delete it ourselves.
continue
}
newRoutes[route] = true


// TailscaleViaRange returns the IPv6 Unique Local Address subset range
// TailscaleULARange that's used for IPv4 tunneling via IPv6.
// Unused by Coder
func TailscaleViaRange() netip.Prefix {
// Mnemonic: "b1a" sounds like "via".
tsViaRange.Do(func() { mustPrefix(&tsViaRange.v, "fd7a:115c:a1e0:b1a::/64") })
tsViaRange.Do(func() { mustPrefix(&tsViaRange.v, "fd60:627a:a42b::/128") })
return tsViaRange.v
}

// Tailscale4To6Range returns the subset of TailscaleULARange used for
// auto-translated Tailscale ipv4 addresses.
// Unused by Coder
func Tailscale4To6Range() netip.Prefix {
// This IP range has no significance, beyond being a subset of
// TailscaleULARange. The bits from /48 to /104 were picked at
// random.
ula4To6Range.Do(func() { mustPrefix(&ula4To6Range.v, "fd7a:115c:a1e0:ab12:4843:cd96:6200::/104") })
// This needs to be a /104 prefix, so it can fit IPv4 addresses
ula4To6Range.Do(func() { mustPrefix(&ula4To6Range.v, "fd60:627a:a42b::/104") })
return ula4To6Range.v
}

// TailscaleEphemeral6Range returns the subset of TailscaleULARange
// used for ephemeral IPv6-only Tailscale nodes.
// Unused by Coder
func TailscaleEphemeral6Range() netip.Prefix {
// This IP range has no significance, beyond being a subset of
// TailscaleULARange. The bits from /48 to /64 were picked at
// random, with the only criterion being to not be the conflict
// with the Tailscale4To6Range above.
ulaEph6Range.Do(func() { mustPrefix(&ulaEph6Range.v, "fd7a:115c:a1e0:efe3::/64") })
ulaEph6Range.Do(func() { mustPrefix(&ulaEph6Range.v, "fd60:627a:a42b::/128") })
return ulaEph6Range.v
}

Expand Down
3 changes: 2 additions & 1 deletion wgengine/magicsock/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"tailscale.com/disco"
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/stun"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
"tailscale.com/tstime/mono"
"tailscale.com/types/key"
Expand Down Expand Up @@ -1064,7 +1065,7 @@ func (de *endpoint) handleCallMeMaybe(m *disco.CallMeMaybe) {
}
var newEPs []netip.AddrPort
for _, ep := range m.MyNumber {
if ep.Addr().Is6() && ep.Addr().IsLinkLocalUnicast() {
if (ep.Addr().Is6() && ep.Addr().IsLinkLocalUnicast()) || tsaddr.IsTailscaleIP(ep.Addr()) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so we don't discover Coder tailnet IPs as peer endpoints.

// We send these out, but ignore them for now.
// TODO: teach the ping code to ping on all interfaces
// for these.
Expand Down
Loading