diff --git a/net/interfaces/interfaces.go b/net/interfaces/interfaces.go index f2988af34..d04b75177 100644 --- a/net/interfaces/interfaces.go +++ b/net/interfaces/interfaces.go @@ -500,7 +500,8 @@ func isPrivateIP(ip netaddr.IP) bool { } func isGlobalV6(ip netaddr.IP) bool { - return v6Global1.Contains(ip) + return v6Global1.Contains(ip) || + (tsaddr.IsULA(ip) && !tsaddr.TailscaleULARange().Contains(ip)) } func mustCIDR(s string) netaddr.IPPrefix { diff --git a/net/interfaces/interfaces_test.go b/net/interfaces/interfaces_test.go index ab0ee3734..fb7b213c2 100644 --- a/net/interfaces/interfaces_test.go +++ b/net/interfaces/interfaces_test.go @@ -7,6 +7,8 @@ package interfaces import ( "encoding/json" "testing" + + "inet.af/netaddr" ) func TestGetState(t *testing.T) { @@ -43,3 +45,24 @@ func TestLikelyHomeRouterIP(t *testing.T) { } t.Logf("myIP = %v; gw = %v", my, gw) } + +func TestIsGlobalV6(t *testing.T) { + tests := []struct { + name string + ip string + want bool + }{ + {"first ULA", "fc00::1", true}, + {"Tailscale", "fd7a:115c:a1e0::1", false}, + {"Cloud Run", "fddf:3978:feb1:d745::1", true}, + {"zeros", "0000:0000:0000:0000:0000:0000:0000:0000", false}, + {"Link Local", "fe80::1", false}, + {"Global", "2602::1", true}, + } + + for _, test := range tests { + if got := isGlobalV6(netaddr.MustParseIP(test.ip)); got != test.want { + t.Errorf("isGlobalV6(%s) = %v, want %v", test.name, got, test.want) + } + } +}