diff --git a/client/tailscale/acl.go b/client/tailscale/acl.go
index 53274c9d0..dd28ef401 100644
--- a/client/tailscale/acl.go
+++ b/client/tailscale/acl.go
@@ -13,8 +13,7 @@
"encoding/json"
"fmt"
"net/http"
-
- "tailscale.com/net/netaddr"
+ "net/netip"
)
// ACLRow defines a rule that grants access by a set of users or groups to a set
@@ -354,7 +353,7 @@ func (c *Client) PreviewACLForUser(ctx context.Context, acl ACL, user string) (r
// Returns ACLPreview on success with matches in a slice. If there are no matches,
// the call is still successful but Matches will be an empty slice.
// Returns error if the provided ACL is invalid.
-func (c *Client) PreviewACLForIPPort(ctx context.Context, acl ACL, ipport netaddr.IPPort) (res *ACLPreview, err error) {
+func (c *Client) PreviewACLForIPPort(ctx context.Context, acl ACL, ipport netip.AddrPort) (res *ACLPreview, err error) {
// Format return errors to be descriptive.
defer func() {
if err != nil {
diff --git a/client/tailscale/localclient.go b/client/tailscale/localclient.go
index da7ce2430..27289b6d0 100644
--- a/client/tailscale/localclient.go
+++ b/client/tailscale/localclient.go
@@ -19,6 +19,7 @@
"net"
"net/http"
"net/http/httptrace"
+ "net/netip"
"net/url"
"os/exec"
"runtime"
@@ -31,7 +32,6 @@
"tailscale.com/client/tailscale/apitype"
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netutil"
"tailscale.com/paths"
"tailscale.com/safesocket"
@@ -665,7 +665,7 @@ func (lc *LocalClient) ExpandSNIName(ctx context.Context, name string) (fqdn str
// Ping sends a ping of the provided type to the provided IP and waits
// for its response.
-func (lc *LocalClient) Ping(ctx context.Context, ip netaddr.IP, pingtype tailcfg.PingType) (*ipnstate.PingResult, error) {
+func (lc *LocalClient) Ping(ctx context.Context, ip netip.Addr, pingtype tailcfg.PingType) (*ipnstate.PingResult, error) {
v := url.Values{}
v.Set("ip", ip.String())
v.Set("type", string(pingtype))
diff --git a/client/tailscale/routes.go b/client/tailscale/routes.go
index 70e10aa1e..067fb2e20 100644
--- a/client/tailscale/routes.go
+++ b/client/tailscale/routes.go
@@ -13,15 +13,14 @@
"encoding/json"
"fmt"
"net/http"
-
- "tailscale.com/net/netaddr"
+ "net/netip"
)
// Routes contains the lists of subnet routes that are currently advertised by a device,
// as well as the subnets that are enabled to be routed by the device.
type Routes struct {
- AdvertisedRoutes []netaddr.IPPrefix `json:"advertisedRoutes"`
- EnabledRoutes []netaddr.IPPrefix `json:"enabledRoutes"`
+ AdvertisedRoutes []netip.Prefix `json:"advertisedRoutes"`
+ EnabledRoutes []netip.Prefix `json:"enabledRoutes"`
}
// Routes retrieves the list of subnet routes that have been enabled for a device.
@@ -56,14 +55,14 @@ func (c *Client) Routes(ctx context.Context, deviceID string) (routes *Routes, e
}
type postRoutesParams struct {
- Routes []netaddr.IPPrefix `json:"routes"`
+ Routes []netip.Prefix `json:"routes"`
}
// SetRoutes updates the list of subnets that are enabled for a device.
// Subnets must be parsable by net/netip.ParsePrefix.
// Subnets do not have to be currently advertised by a device, they may be pre-enabled.
// Returns the updated list of enabled and advertised subnet routes in a *Routes object.
-func (c *Client) SetRoutes(ctx context.Context, deviceID string, subnets []netaddr.IPPrefix) (routes *Routes, err error) {
+func (c *Client) SetRoutes(ctx context.Context, deviceID string, subnets []netip.Prefix) (routes *Routes, err error) {
defer func() {
if err != nil {
err = fmt.Errorf("tailscale.SetRoutes: %w", err)
diff --git a/cmd/tailscale/cli/cli_test.go b/cmd/tailscale/cli/cli_test.go
index 3bb35e178..736f19058 100644
--- a/cmd/tailscale/cli/cli_test.go
+++ b/cmd/tailscale/cli/cli_test.go
@@ -18,7 +18,6 @@
"github.com/google/go-cmp/cmp"
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
"tailscale.com/tstest"
"tailscale.com/types/persist"
"tailscale.com/types/preftype"
@@ -57,7 +56,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
flags []string // argv to be parsed by FlagSet
curPrefs *ipn.Prefs
- curExitNodeIP netaddr.IP
+ curExitNodeIP netip.Addr
curUser string // os.Getenv("USER") on the client side
goos string // empty means "linux"
distro distro.Distro
@@ -153,7 +152,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("10.0.42.0/24"),
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
@@ -169,7 +168,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("10.0.42.0/24"),
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
@@ -185,7 +184,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("10.0.42.0/24"),
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
@@ -213,7 +212,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("1.2.0.0/16"),
},
},
@@ -227,7 +226,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
netip.MustParsePrefix("1.2.0.0/16"),
@@ -262,7 +261,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AdvertiseTags: []string{"tag:foo", "tag:bar"},
Hostname: "myhostname",
ForceDaemon: true,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("10.0.0.0/16"),
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
@@ -287,7 +286,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AdvertiseTags: []string{"tag:foo", "tag:bar"},
Hostname: "myhostname",
ForceDaemon: true,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("10.0.0.0/16"),
},
NetfilterMode: preftype.NetfilterNoDivert,
@@ -345,7 +344,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
netip.MustParsePrefix("1.2.0.0/16"),
@@ -361,7 +360,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
AllowSingleHosts: true,
CorpDNS: true,
NetfilterMode: preftype.NetfilterOn,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
netip.MustParsePrefix("1.2.0.0/16"),
@@ -563,7 +562,7 @@ func TestPrefsFromUpArgs(t *testing.T) {
WantRunning: true,
AllowSingleHosts: true,
CorpDNS: true,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
},
@@ -632,7 +631,7 @@ func TestPrefsFromUpArgs(t *testing.T) {
exitNodeIP: "100.105.106.107",
},
st: &ipnstate.Status{
- TailscaleIPs: []netaddr.IP{netip.MustParseAddr("100.105.106.107")},
+ TailscaleIPs: []netip.Addr{netip.MustParseAddr("100.105.106.107")},
},
wantErr: `cannot use 100.105.106.107 as an exit node as it is a local IP address to this machine; did you mean --advertise-exit-node?`,
},
@@ -672,7 +671,7 @@ func TestPrefsFromUpArgs(t *testing.T) {
want: &ipn.Prefs{
WantRunning: true,
NoSNAT: true,
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("fd7a:115c:a1e0:b1a::bb:10.0.0.0/112"),
},
},
@@ -957,7 +956,7 @@ func TestUpdatePrefs(t *testing.T) {
}
}
-var cmpIP = cmp.Comparer(func(a, b netaddr.IP) bool {
+var cmpIP = cmp.Comparer(func(a, b netip.Addr) bool {
return a == b
})
diff --git a/cmd/tailscale/cli/file.go b/cmd/tailscale/cli/file.go
index 9cbe2534e..4b29ddbc7 100644
--- a/cmd/tailscale/cli/file.go
+++ b/cmd/tailscale/cli/file.go
@@ -27,7 +27,6 @@
"tailscale.com/client/tailscale/apitype"
"tailscale.com/envknob"
"tailscale.com/ipn"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
"tailscale.com/version"
@@ -192,7 +191,7 @@ func getTargetStableID(ctx context.Context, ipStr string) (id tailcfg.StableNode
// fileTargetErrorDetail returns a non-nil error saying why ip is an
// invalid file sharing target.
-func fileTargetErrorDetail(ctx context.Context, ip netaddr.IP) error {
+func fileTargetErrorDetail(ctx context.Context, ip netip.Addr) error {
found := false
if st, err := localClient.Status(ctx); err == nil && st.Self != nil {
for _, peer := range st.Peer {
diff --git a/cmd/tailscale/cli/status.go b/cmd/tailscale/cli/status.go
index 34f83ccd3..830b2f000 100644
--- a/cmd/tailscale/cli/status.go
+++ b/cmd/tailscale/cli/status.go
@@ -13,6 +13,7 @@
"fmt"
"net"
"net/http"
+ "net/netip"
"os"
"strings"
@@ -21,7 +22,6 @@
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)
@@ -260,7 +260,7 @@ func ownerLogin(st *ipnstate.Status, ps *ipnstate.PeerStatus) string {
return u.LoginName
}
-func firstIPString(v []netaddr.IP) string {
+func firstIPString(v []netip.Addr) string {
if len(v) == 0 {
return ""
}
diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go
index 683b90ed9..36dcf4d86 100644
--- a/cmd/tailscale/cli/up.go
+++ b/cmd/tailscale/cli/up.go
@@ -27,7 +27,6 @@
qrcode "github.com/skip2/go-qrcode"
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/safesocket"
"tailscale.com/tailcfg"
@@ -204,7 +203,7 @@ func warnf(format string, args ...any) {
ipv6default = netip.MustParsePrefix("::/0")
)
-func validateViaPrefix(ipp netaddr.IPPrefix) error {
+func validateViaPrefix(ipp netip.Prefix) error {
if !tsaddr.IsViaPrefix(ipp) {
return fmt.Errorf("%v is not a 4-in-6 prefix", ipp)
}
@@ -224,8 +223,8 @@ func validateViaPrefix(ipp netaddr.IPPrefix) error {
return nil
}
-func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]netaddr.IPPrefix, error) {
- routeMap := map[netaddr.IPPrefix]bool{}
+func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]netip.Prefix, error) {
+ routeMap := map[netip.Prefix]bool{}
if advertiseRoutes != "" {
var default4, default6 bool
advroutes := strings.Split(advertiseRoutes, ",")
@@ -259,7 +258,7 @@ func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]
routeMap[netip.MustParsePrefix("0.0.0.0/0")] = true
routeMap[netip.MustParsePrefix("::/0")] = true
}
- routes := make([]netaddr.IPPrefix, 0, len(routeMap))
+ routes := make([]netip.Prefix, 0, len(routeMap))
for r := range routeMap {
routes = append(routes, r)
}
@@ -791,7 +790,7 @@ type upCheckEnv struct {
flagSet *flag.FlagSet
upArgs upArgsT
backendState string
- curExitNodeIP netaddr.IP
+ curExitNodeIP netip.Addr
distro distro.Distro
}
@@ -992,7 +991,7 @@ func fmtFlagValueArg(flagName string, val any) string {
return fmt.Sprintf("--%s=%v", flagName, shellquote.Join(fmt.Sprint(val)))
}
-func hasExitNodeRoutes(rr []netaddr.IPPrefix) bool {
+func hasExitNodeRoutes(rr []netip.Prefix) bool {
var v4, v6 bool
for _, r := range rr {
if r.Bits() == 0 {
@@ -1009,11 +1008,11 @@ func hasExitNodeRoutes(rr []netaddr.IPPrefix) bool {
// withoutExitNodes returns rr unchanged if it has only 1 or 0 /0
// routes. If it has both IPv4 and IPv6 /0 routes, then it returns
// a copy with all /0 routes removed.
-func withoutExitNodes(rr []netaddr.IPPrefix) []netaddr.IPPrefix {
+func withoutExitNodes(rr []netip.Prefix) []netip.Prefix {
if !hasExitNodeRoutes(rr) {
return rr
}
- var out []netaddr.IPPrefix
+ var out []netip.Prefix
for _, r := range rr {
if r.Bits() > 0 {
out = append(out, r)
@@ -1024,7 +1023,7 @@ func withoutExitNodes(rr []netaddr.IPPrefix) []netaddr.IPPrefix {
// exitNodeIP returns the exit node IP from p, using st to map
// it from its ID form to an IP address if needed.
-func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netaddr.IP) {
+func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netip.Addr) {
if p == nil {
return
}
diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt
index 31eb00d46..dfc96ab0a 100644
--- a/cmd/tailscale/depaware.txt
+++ b/cmd/tailscale/depaware.txt
@@ -52,7 +52,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
tailscale.com/net/dnsfallback from tailscale.com/control/controlhttp
tailscale.com/net/flowtrack from tailscale.com/wgengine/filter+
💣 tailscale.com/net/interfaces from tailscale.com/cmd/tailscale/cli+
- tailscale.com/net/netaddr from tailscale.com/client/tailscale+
+ tailscale.com/net/netaddr from tailscale.com/disco+
tailscale.com/net/netcheck from tailscale.com/cmd/tailscale/cli
tailscale.com/net/neterror from tailscale.com/net/netcheck+
tailscale.com/net/netknob from tailscale.com/net/netns
diff --git a/cmd/tailscaled/debug.go b/cmd/tailscaled/debug.go
index e0b963fd8..b269d8e2b 100644
--- a/cmd/tailscaled/debug.go
+++ b/cmd/tailscaled/debug.go
@@ -30,7 +30,6 @@
"tailscale.com/envknob"
"tailscale.com/ipn"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/portmapper"
"tailscale.com/net/tshttpproxy"
"tailscale.com/tailcfg"
@@ -267,7 +266,7 @@ func debugPortmap(ctx context.Context) error {
return err
}
- gatewayAndSelfIP := func() (gw, self netaddr.IP, ok bool) {
+ gatewayAndSelfIP := func() (gw, self netip.Addr, ok bool) {
if v := os.Getenv("TS_DEBUG_GW_SELF"); strings.Contains(v, "/") {
i := strings.Index(v, "/")
gw = netip.MustParseAddr(v[:i])
diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt
index b24546552..e2576892e 100644
--- a/cmd/tailscaled/depaware.txt
+++ b/cmd/tailscaled/depaware.txt
@@ -217,7 +217,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/net/dnsfallback from tailscale.com/control/controlclient+
tailscale.com/net/flowtrack from tailscale.com/net/packet+
💣 tailscale.com/net/interfaces from tailscale.com/control/controlclient+
- tailscale.com/net/netaddr from tailscale.com/client/tailscale+
+ tailscale.com/net/netaddr from tailscale.com/disco+
tailscale.com/net/netcheck from tailscale.com/wgengine/magicsock
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
tailscale.com/net/netknob from tailscale.com/net/netns+
diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go
index fd8c32e86..160ec1677 100644
--- a/cmd/tailscaled/tailscaled.go
+++ b/cmd/tailscaled/tailscaled.go
@@ -21,6 +21,7 @@
"net"
"net/http"
"net/http/pprof"
+ "net/netip"
"os"
"os/signal"
"path/filepath"
@@ -38,7 +39,6 @@
"tailscale.com/logpolicy"
"tailscale.com/logtail"
"tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
"tailscale.com/net/proxymux"
"tailscale.com/net/socks5"
@@ -366,11 +366,11 @@ func run() error {
ns.ProcessSubnets = useNetstack || wrapNetstack
if useNetstack {
- dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
+ dialer.UseNetstackForIP = func(ip netip.Addr) bool {
_, ok := e.PeerForIP(ip)
return ok
}
- dialer.NetstackDialTCP = func(ctx context.Context, dst netaddr.IPPort) (net.Conn, error) {
+ dialer.NetstackDialTCP = func(ctx context.Context, dst netip.AddrPort) (net.Conn, error) {
return ns.DialContextTCP(ctx, dst)
}
}
diff --git a/cmd/tailscaled/tailscaled_windows.go b/cmd/tailscaled/tailscaled_windows.go
index 8910c2855..085c5ca0a 100644
--- a/cmd/tailscaled/tailscaled_windows.go
+++ b/cmd/tailscaled/tailscaled_windows.go
@@ -25,6 +25,7 @@
"encoding/json"
"fmt"
"log"
+ "net/netip"
"os"
"time"
@@ -37,7 +38,6 @@
"tailscale.com/ipn/store"
"tailscale.com/logpolicy"
"tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsdial"
"tailscale.com/net/tstun"
"tailscale.com/safesocket"
@@ -245,7 +245,7 @@ func beFirewallKillswitch() bool {
// is passed in via stdin encoded in json.
dcd := json.NewDecoder(os.Stdin)
for {
- var routes []netaddr.IPPrefix
+ var routes []netip.Prefix
if err := dcd.Decode(&routes); err != nil {
log.Fatalf("parent process died or requested exit, exiting (%v)", err)
}
diff --git a/cmd/tsconnect/wasm/wasm_js.go b/cmd/tsconnect/wasm/wasm_js.go
index 4adc6e654..b28b618c6 100644
--- a/cmd/tsconnect/wasm/wasm_js.go
+++ b/cmd/tsconnect/wasm/wasm_js.go
@@ -19,6 +19,7 @@
"log"
"math/rand"
"net"
+ "net/netip"
"strings"
"syscall/js"
"time"
@@ -29,7 +30,6 @@
"tailscale.com/ipn/ipnlocal"
"tailscale.com/ipn/ipnserver"
"tailscale.com/ipn/store/mem"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
"tailscale.com/net/tsdial"
"tailscale.com/safesocket"
@@ -78,10 +78,10 @@ func newIPN(jsConfig js.Value) map[string]any {
if err := ns.Start(); err != nil {
log.Fatalf("failed to start netstack: %v", err)
}
- dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
+ dialer.UseNetstackForIP = func(ip netip.Addr) bool {
return true
}
- dialer.NetstackDialTCP = func(ctx context.Context, dst netaddr.IPPort) (net.Conn, error) {
+ dialer.NetstackDialTCP = func(ctx context.Context, dst netip.AddrPort) (net.Conn, error) {
return ns.DialContextTCP(ctx, dst)
}
@@ -175,7 +175,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
Self: jsNetMapSelfNode{
jsNetMapNode: jsNetMapNode{
Name: nm.Name,
- Addresses: mapSlice(nm.Addresses, func(a netaddr.IPPrefix) string { return a.Addr().String() }),
+ Addresses: mapSlice(nm.Addresses, func(a netip.Prefix) string { return a.Addr().String() }),
NodeKey: nm.NodeKey.String(),
MachineKey: nm.MachineKey.String(),
},
@@ -185,7 +185,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
return jsNetMapPeerNode{
jsNetMapNode: jsNetMapNode{
Name: p.Name,
- Addresses: mapSlice(p.Addresses, func(a netaddr.IPPrefix) string { return a.Addr().String() }),
+ Addresses: mapSlice(p.Addresses, func(a netip.Prefix) string { return a.Addr().String() }),
MachineKey: p.Machine.String(),
NodeKey: p.Key.String(),
},
diff --git a/cmd/viewer/tests/tests.go b/cmd/viewer/tests/tests.go
index 0d3eb2bfd..b2f704c5f 100644
--- a/cmd/viewer/tests/tests.go
+++ b/cmd/viewer/tests/tests.go
@@ -7,15 +7,14 @@
import (
"fmt"
-
- "tailscale.com/net/netaddr"
+ "net/netip"
)
//go:generate go run tailscale.com/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices
type StructWithoutPtrs struct {
Int int
- Pfx netaddr.IPPrefix
+ Pfx netip.Prefix
}
type Map struct {
@@ -54,6 +53,6 @@ type StructWithSlices struct {
Ints []*int
Slice []string
- Prefixes []netaddr.IPPrefix
+ Prefixes []netip.Prefix
Data []byte
}
diff --git a/cmd/viewer/viewer.go b/cmd/viewer/viewer.go
index c63a16e2b..99c6c21c5 100644
--- a/cmd/viewer/viewer.go
+++ b/cmd/viewer/viewer.go
@@ -177,7 +177,7 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, thi
case "byte":
it.Import("go4.org/mem")
writeTemplate("byteSliceField")
- case "inet.af/netaddr.IPPrefix", "net/netip.Prefix":
+ case "inet.af/netip.Prefix", "net/netip.Prefix":
it.Import("tailscale.com/types/views")
writeTemplate("ipPrefixSliceField")
default:
diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go
index e0e8528f2..39387549a 100644
--- a/control/controlclient/direct.go
+++ b/control/controlclient/direct.go
@@ -16,6 +16,7 @@
"io/ioutil"
"log"
"net/http"
+ "net/netip"
"net/url"
"os"
"reflect"
@@ -36,7 +37,6 @@
"tailscale.com/net/dnscache"
"tailscale.com/net/dnsfallback"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netutil"
"tailscale.com/net/tlsdial"
"tailscale.com/net/tsdial"
@@ -129,7 +129,7 @@ type Options struct {
// Pinger is the LocalBackend.Ping method.
type Pinger interface {
// Ping is a request to do a ping with the peer handling the given IP.
- Ping(ctx context.Context, ip netaddr.IP, pingType tailcfg.PingType) (*ipnstate.PingResult, error)
+ Ping(ctx context.Context, ip netip.Addr, pingType tailcfg.PingType) (*ipnstate.PingResult, error)
}
type Decompressor interface {
@@ -1167,8 +1167,8 @@ func TrimWGConfig() opt.Bool {
// It should not return false positives.
//
// TODO(bradfitz): Change controlclient.Options.SkipIPForwardingCheck into a
-// func([]netaddr.IPPrefix) error signature instead.
-func ipForwardingBroken(routes []netaddr.IPPrefix, state *interfaces.State) bool {
+// func([]netip.Prefix) error signature instead.
+func ipForwardingBroken(routes []netip.Prefix, state *interfaces.State) bool {
warn, err := netutil.CheckIPForwarding(routes, state)
if err != nil {
// Oh well, we tried. This is just for debugging.
diff --git a/control/controlclient/direct_test.go b/control/controlclient/direct_test.go
index eef98e610..54a33c1cf 100644
--- a/control/controlclient/direct_test.go
+++ b/control/controlclient/direct_test.go
@@ -8,12 +8,12 @@
"encoding/json"
"net/http"
"net/http/httptest"
+ "net/netip"
"testing"
"time"
"tailscale.com/hostinfo"
"tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsdial"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
@@ -86,7 +86,7 @@ func TestNewDirect(t *testing.T) {
func fakeEndpoints(ports ...uint16) (ret []tailcfg.Endpoint) {
for _, port := range ports {
ret = append(ret, tailcfg.Endpoint{
- Addr: netaddr.IPPortFrom(netaddr.IP{}, port),
+ Addr: netip.AddrPortFrom(netip.Addr{}, port),
})
}
return
diff --git a/control/controlclient/map.go b/control/controlclient/map.go
index 30e892e63..a96876407 100644
--- a/control/controlclient/map.go
+++ b/control/controlclient/map.go
@@ -7,10 +7,10 @@
import (
"fmt"
"log"
+ "net/netip"
"sort"
"tailscale.com/envknob"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"tailscale.com/types/logger"
@@ -303,7 +303,7 @@ func cloneNodes(v1 []*tailcfg.Node) []*tailcfg.Node {
var debugSelfIPv6Only = envknob.Bool("TS_DEBUG_SELF_V6_ONLY")
-func filterSelfAddresses(in []netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
+func filterSelfAddresses(in []netip.Prefix) (ret []netip.Prefix) {
switch {
default:
return in
diff --git a/derp/derp_client.go b/derp/derp_client.go
index 3d7eef603..f7282f646 100644
--- a/derp/derp_client.go
+++ b/derp/derp_client.go
@@ -18,7 +18,6 @@
"go4.org/mem"
"golang.org/x/time/rate"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
"tailscale.com/types/logger"
)
@@ -598,17 +597,17 @@ func (c *Client) setSendRateLimiter(sm ServerInfoMessage) {
//
// If the client is broken in some previously detectable way, it
// returns an error.
-func (c *Client) LocalAddr() (netaddr.IPPort, error) {
+func (c *Client) LocalAddr() (netip.AddrPort, error) {
readErr, _ := c.readErr.Load().(error)
if readErr != nil {
- return netaddr.IPPort{}, readErr
+ return netip.AddrPort{}, readErr
}
if c.nc == nil {
- return netaddr.IPPort{}, errors.New("nil conn")
+ return netip.AddrPort{}, errors.New("nil conn")
}
a := c.nc.LocalAddr()
if a == nil {
- return netaddr.IPPort{}, errors.New("nil addr")
+ return netip.AddrPort{}, errors.New("nil addr")
}
return netip.ParseAddrPort(a.String())
}
diff --git a/derp/derp_server.go b/derp/derp_server.go
index 593dd1110..337568fc2 100644
--- a/derp/derp_server.go
+++ b/derp/derp_server.go
@@ -41,7 +41,6 @@
"tailscale.com/disco"
"tailscale.com/envknob"
"tailscale.com/metrics"
- "tailscale.com/net/netaddr"
"tailscale.com/syncs"
"tailscale.com/types/key"
"tailscale.com/types/logger"
@@ -163,8 +162,8 @@ type Server struct {
// src.
sentTo map[key.NodePublic]map[key.NodePublic]int64 // src => dst => dst's latest sclient.connNum
- // maps from netaddr.IPPort to a client's public key
- keyOfAddr map[netaddr.IPPort]key.NodePublic
+ // maps from netip.AddrPort to a client's public key
+ keyOfAddr map[netip.AddrPort]key.NodePublic
}
// clientSet represents 1 or more *sclients.
@@ -315,7 +314,7 @@ func NewServer(privateKey key.NodePrivate, logf logger.Logf) *Server {
watchers: map[*sclient]bool{},
sentTo: map[key.NodePublic]map[key.NodePublic]int64{},
avgQueueDuration: new(uint64),
- keyOfAddr: map[netaddr.IPPort]key.NodePublic{},
+ keyOfAddr: map[netip.AddrPort]key.NodePublic{},
}
s.initMetacert()
s.packetsRecvDisco = s.packetsRecvByKind.Get("disco")
@@ -1247,7 +1246,7 @@ type sclient struct {
logf logger.Logf
done <-chan struct{} // closed when connection closes
remoteAddr string // usually ip:port from net.Conn.RemoteAddr().String()
- remoteIPPort netaddr.IPPort // zero if remoteAddr is not ip:port.
+ remoteIPPort netip.AddrPort // zero if remoteAddr is not ip:port.
sendQueue chan pkt // packets queued to this client; never closed
discoSendQueue chan pkt // important packets queued to this client; never closed
sendPongCh chan [8]byte // pong replies to send to the client; never closed
@@ -1760,8 +1759,8 @@ type BytesSentRecv struct {
// parseSSOutput parses the output from the specific call to ss in ServeDebugTraffic.
// Separated out for ease of testing.
-func parseSSOutput(raw string) map[netaddr.IPPort]BytesSentRecv {
- newState := map[netaddr.IPPort]BytesSentRecv{}
+func parseSSOutput(raw string) map[netip.AddrPort]BytesSentRecv {
+ newState := map[netip.AddrPort]BytesSentRecv{}
// parse every 2 lines and get src and dst ips, and kv pairs
lines := strings.Split(raw, "\n")
for i := 0; i < len(lines); i += 2 {
@@ -1794,7 +1793,7 @@ func parseSSOutput(raw string) map[netaddr.IPPort]BytesSentRecv {
}
func (s *Server) ServeDebugTraffic(w http.ResponseWriter, r *http.Request) {
- prevState := map[netaddr.IPPort]BytesSentRecv{}
+ prevState := map[netip.AddrPort]BytesSentRecv{}
enc := json.NewEncoder(w)
for r.Context().Err() == nil {
output, err := exec.Command("ss", "-i", "-H", "-t").Output()
diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go
index 035b35d15..28d990bc4 100644
--- a/derp/derphttp/derphttp_client.go
+++ b/derp/derphttp/derphttp_client.go
@@ -34,7 +34,6 @@
"tailscale.com/derp"
"tailscale.com/envknob"
"tailscale.com/net/dnscache"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
"tailscale.com/net/tlsdial"
"tailscale.com/net/tshttpproxy"
@@ -580,7 +579,7 @@ func (c *Client) dialContext(ctx context.Context, proto, addr string) (net.Conn,
// address (given in s) is valid. An empty value means to dial, but to
// use DNS. The predicate function reports whether the non-empty
// string s contained a valid IP address of the right family.
-func shouldDialProto(s string, pred func(netaddr.IP) bool) bool {
+func shouldDialProto(s string, pred func(netip.Addr) bool) bool {
if s == "" {
return true
}
@@ -652,10 +651,10 @@ type res struct {
}
}()
}
- if shouldDialProto(n.IPv4, netaddr.IP.Is4) {
+ if shouldDialProto(n.IPv4, netip.Addr.Is4) {
startDial(n.IPv4, "tcp4")
}
- if shouldDialProto(n.IPv6, netaddr.IP.Is6) {
+ if shouldDialProto(n.IPv6, netip.Addr.Is6) {
startDial(n.IPv6, "tcp6")
}
if nwait == 0 {
@@ -840,15 +839,15 @@ func (c *Client) SendPing(data [8]byte) error {
// LocalAddr reports c's local TCP address, without any implicit
// connect or reconnect.
-func (c *Client) LocalAddr() (netaddr.IPPort, error) {
+func (c *Client) LocalAddr() (netip.AddrPort, error) {
c.mu.Lock()
closed, client := c.closed, c.client
c.mu.Unlock()
if closed {
- return netaddr.IPPort{}, ErrClientClosed
+ return netip.AddrPort{}, ErrClientClosed
}
if client == nil {
- return netaddr.IPPort{}, errors.New("client not connected")
+ return netip.AddrPort{}, errors.New("client not connected")
}
return client.LocalAddr()
}
diff --git a/disco/disco.go b/disco/disco.go
index 270b169a3..53ce81361 100644
--- a/disco/disco.go
+++ b/disco/disco.go
@@ -24,6 +24,7 @@
"errors"
"fmt"
"net"
+ "net/netip"
"go4.org/mem"
"tailscale.com/net/netaddr"
@@ -172,7 +173,7 @@ type CallMeMaybe struct {
// in this field, but might not yet be in control's endpoints.
// (And in the future, control will stop distributing endpoints
// when clients are suitably new.)
- MyNumber []netaddr.IPPort
+ MyNumber []netip.AddrPort
}
const epLength = 16 + 2 // 16 byte IP address + 2 byte port
@@ -193,11 +194,11 @@ func parseCallMeMaybe(ver uint8, p []byte) (m *CallMeMaybe, err error) {
if len(p)%epLength != 0 || ver != 0 || len(p) == 0 {
return m, nil
}
- m.MyNumber = make([]netaddr.IPPort, 0, len(p)/epLength)
+ m.MyNumber = make([]netip.AddrPort, 0, len(p)/epLength)
for len(p) > 0 {
var a [16]byte
copy(a[:], p)
- m.MyNumber = append(m.MyNumber, netaddr.IPPortFrom(
+ m.MyNumber = append(m.MyNumber, netip.AddrPortFrom(
netaddr.IPFrom16(a),
binary.BigEndian.Uint16(p[16:18])))
p = p[epLength:]
@@ -211,7 +212,7 @@ func parseCallMeMaybe(ver uint8, p []byte) (m *CallMeMaybe, err error) {
// STUN response.
type Pong struct {
TxID [12]byte
- Src netaddr.IPPort // 18 bytes (16+2) on the wire; v4-mapped ipv6 for IPv4
+ Src netip.AddrPort // 18 bytes (16+2) on the wire; v4-mapped ipv6 for IPv4
}
const pongLen = 12 + 16 + 2
@@ -236,7 +237,7 @@ func parsePong(ver uint8, p []byte) (m *Pong, err error) {
srcIP, _ := netaddr.FromStdIP(net.IP(p[:16]))
p = p[16:]
port := binary.BigEndian.Uint16(p)
- m.Src = netaddr.IPPortFrom(srcIP, port)
+ m.Src = netip.AddrPortFrom(srcIP, port)
return m, nil
}
diff --git a/disco/disco_test.go b/disco/disco_test.go
index 354a8e59f..25070d581 100644
--- a/disco/disco_test.go
+++ b/disco/disco_test.go
@@ -12,7 +12,6 @@
"testing"
"go4.org/mem"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
)
@@ -61,7 +60,7 @@ func TestMarshalAndParse(t *testing.T) {
{
name: "call_me_maybe_endpoints",
m: &CallMeMaybe{
- MyNumber: []netaddr.IPPort{
+ MyNumber: []netip.AddrPort{
netip.MustParseAddrPort("1.2.3.4:567"),
netip.MustParseAddrPort("[2001::3456]:789"),
},
@@ -94,7 +93,7 @@ func TestMarshalAndParse(t *testing.T) {
}
}
-func mustIPPort(s string) netaddr.IPPort {
+func mustIPPort(s string) netip.AddrPort {
ipp, err := netip.ParseAddrPort(s)
if err != nil {
panic(err)
diff --git a/ipn/handle.go b/ipn/handle.go
index 2080d5dfa..225f1b6ed 100644
--- a/ipn/handle.go
+++ b/ipn/handle.go
@@ -5,10 +5,10 @@
package ipn
import (
+ "net/netip"
"sync"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
"tailscale.com/types/netmap"
@@ -126,7 +126,7 @@ func (h *Handle) EngineStatus() EngineStatus {
return h.engineStatusCache
}
-func (h *Handle) LocalAddrs() []netaddr.IPPrefix {
+func (h *Handle) LocalAddrs() []netip.Prefix {
h.mu.Lock()
defer h.mu.Unlock()
@@ -134,7 +134,7 @@ func (h *Handle) LocalAddrs() []netaddr.IPPrefix {
if nm != nil {
return nm.Addresses
}
- return []netaddr.IPPrefix{}
+ return []netip.Prefix{}
}
func (h *Handle) NetMap() *netmap.NetworkMap {
diff --git a/ipn/ipnlocal/dnsconfig_test.go b/ipn/ipnlocal/dnsconfig_test.go
index 280162e82..2357f3f97 100644
--- a/ipn/ipnlocal/dnsconfig_test.go
+++ b/ipn/ipnlocal/dnsconfig_test.go
@@ -12,7 +12,6 @@
"tailscale.com/ipn"
"tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/tstest"
"tailscale.com/types/dnstype"
@@ -21,7 +20,7 @@
"tailscale.com/util/dnsname"
)
-func ipps(ippStrs ...string) (ipps []netaddr.IPPrefix) {
+func ipps(ippStrs ...string) (ipps []netip.Prefix) {
for _, s := range ippStrs {
if ip, err := netip.ParseAddr(s); err == nil {
ipps = append(ipps, netip.PrefixFrom(ip, ip.BitLen()))
@@ -32,7 +31,7 @@ func ipps(ippStrs ...string) (ipps []netaddr.IPPrefix) {
return
}
-func ips(ss ...string) (ips []netaddr.IP) {
+func ips(ss ...string) (ips []netip.Addr) {
for _, s := range ss {
ips = append(ips, netip.MustParseAddr(s))
}
@@ -55,7 +54,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
prefs: &ipn.Prefs{},
want: &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
},
},
{
@@ -81,7 +80,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
prefs: &ipn.Prefs{},
want: &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
- Hosts: map[dnsname.FQDN][]netaddr.IP{
+ Hosts: map[dnsname.FQDN][]netip.Addr{
"b.net.": ips("100.102.0.1", "100.102.0.2"),
"myname.net.": ips("100.101.101.101"),
"peera.net.": ips("100.102.0.1", "100.102.0.2"),
@@ -116,7 +115,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
want: &dns.Config{
OnlyIPv6: true,
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
- Hosts: map[dnsname.FQDN][]netaddr.IP{
+ Hosts: map[dnsname.FQDN][]netip.Addr{
"b.net.": ips("fe75::2"),
"myname.net.": ips("fe75::1"),
"peera.net.": ips("fe75::1001"),
@@ -140,7 +139,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
prefs: &ipn.Prefs{},
want: &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
- Hosts: map[dnsname.FQDN][]netaddr.IP{
+ Hosts: map[dnsname.FQDN][]netip.Addr{
"myname.net.": ips("100.101.101.101"),
"foo.com.": ips("1.2.3.4"),
"bar.com.": ips("1::6"),
@@ -160,7 +159,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
CorpDNS: true,
},
want: &dns.Config{
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
"0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.": nil,
"100.100.in-addr.arpa.": nil,
@@ -260,7 +259,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
CorpDNS: true,
},
want: &dns.Config{
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
DefaultResolvers: []*dnstype.Resolver{
{Addr: "8.8.8.8"},
},
@@ -283,7 +282,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
ExitNodeID: "some-id",
},
want: &dns.Config{
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
DefaultResolvers: []*dnstype.Resolver{
{Addr: "8.8.4.4"},
@@ -303,7 +302,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
CorpDNS: true,
},
want: &dns.Config{
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
},
},
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index b9d3de562..ffff19488 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -34,7 +34,6 @@
"tailscale.com/ipn/policy"
"tailscale.com/net/dns"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netutil"
"tailscale.com/net/tsaddr"
"tailscale.com/net/tsdial"
@@ -130,7 +129,7 @@ type LocalBackend struct {
shutdownCalled bool // if Shutdown has been called
filterAtomic atomic.Value // of *filter.Filter
- containsViaIPFuncAtomic atomic.Value // of func(netaddr.IP) bool
+ containsViaIPFuncAtomic atomic.Value // of func(netip.Addr) bool
// The mutex protects the following elements.
mu sync.Mutex
@@ -152,7 +151,7 @@ type LocalBackend struct {
hostinfo *tailcfg.Hostinfo
// netMap is not mutated in-place once set.
netMap *netmap.NetworkMap
- nodeByAddr map[netaddr.IP]*tailcfg.Node
+ nodeByAddr map[netip.Addr]*tailcfg.Node
activeLogin string // last logged LoginName from netMap
engineStatus ipn.EngineStatus
endpoints []tailcfg.Endpoint
@@ -498,13 +497,13 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
if p.LastSeen != nil {
lastSeen = *p.LastSeen
}
- var tailscaleIPs = make([]netaddr.IP, 0, len(p.Addresses))
+ var tailscaleIPs = make([]netip.Addr, 0, len(p.Addresses))
for _, addr := range p.Addresses {
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
tailscaleIPs = append(tailscaleIPs, addr.Addr())
}
}
- exitNodeOption := tsaddr.PrefixesContainsFunc(p.AllowedIPs, func(r netaddr.IPPrefix) bool {
+ exitNodeOption := tsaddr.PrefixesContainsFunc(p.AllowedIPs, func(r netip.Prefix) bool {
return r.Bits() == 0
})
var tags *views.Slice[string]
@@ -542,12 +541,12 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
// WhoIs reports the node and user who owns the node with the given IP:port.
// If the IP address is a Tailscale IP, the provided port may be 0.
// If ok == true, n and u are valid.
-func (b *LocalBackend) WhoIs(ipp netaddr.IPPort) (n *tailcfg.Node, u tailcfg.UserProfile, ok bool) {
+func (b *LocalBackend) WhoIs(ipp netip.AddrPort) (n *tailcfg.Node, u tailcfg.UserProfile, ok bool) {
b.mu.Lock()
defer b.mu.Unlock()
n, ok = b.nodeByAddr[ipp.Addr()]
if !ok {
- var ip netaddr.IP
+ var ip netip.Addr
if ipp.Port() != 0 {
ip, ok = b.e.WhoIsIPPort(ipp)
}
@@ -568,7 +567,7 @@ func (b *LocalBackend) WhoIs(ipp netaddr.IPPort) (n *tailcfg.Node, u tailcfg.Use
// PeerCaps returns the capabilities that remote src IP has to
// ths current node.
-func (b *LocalBackend) PeerCaps(src netaddr.IP) []string {
+func (b *LocalBackend) PeerCaps(src netip.Addr) []string {
b.mu.Lock()
defer b.mu.Unlock()
if b.netMap == nil {
@@ -770,7 +769,7 @@ func (b *LocalBackend) findExitNodeIDLocked(nm *netmap.NetworkMap) (prefsChanged
// Found the node being referenced, upgrade prefs to
// reference it directly for next time.
b.prefs.ExitNodeID = peer.StableID
- b.prefs.ExitNodeIP = netaddr.IP{}
+ b.prefs.ExitNodeIP = netip.Addr{}
return true
}
}
@@ -1123,7 +1122,7 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs *ipn.
// quite hard to debug, so save yourself the trouble.
var (
haveNetmap = netMap != nil
- addrs []netaddr.IPPrefix
+ addrs []netip.Prefix
packetFilter []filter.Match
localNetsB netipx.IPSetBuilder
logNetsB netipx.IPSetBuilder
@@ -1206,7 +1205,7 @@ func (b *LocalBackend) setFilter(f *filter.Filter) {
b.e.SetFilter(f)
}
-var removeFromDefaultRoute = []netaddr.IPPrefix{
+var removeFromDefaultRoute = []netip.Prefix{
// RFC1918 LAN ranges
netip.MustParsePrefix("192.168.0.0/16"),
netip.MustParsePrefix("172.16.0.0/12"),
@@ -1232,7 +1231,7 @@ func (b *LocalBackend) setFilter(f *filter.Filter) {
//
// Given that "internal" routes don't leave the device, we choose to
// trust them more, allowing access to them when an Exit Node is enabled.
-func internalAndExternalInterfaces() (internal, external []netaddr.IPPrefix, err error) {
+func internalAndExternalInterfaces() (internal, external []netip.Prefix, err error) {
il, err := interfaces.GetList()
if err != nil {
return nil, nil, err
@@ -1240,11 +1239,11 @@ func internalAndExternalInterfaces() (internal, external []netaddr.IPPrefix, err
return internalAndExternalInterfacesFrom(il, runtime.GOOS)
}
-func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (internal, external []netaddr.IPPrefix, err error) {
+func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (internal, external []netip.Prefix, err error) {
// We use an IPSetBuilder here to canonicalize the prefixes
// and to remove any duplicate entries.
var internalBuilder, externalBuilder netipx.IPSetBuilder
- if err := il.ForeachInterfaceAddress(func(iface interfaces.Interface, pfx netaddr.IPPrefix) {
+ if err := il.ForeachInterfaceAddress(func(iface interfaces.Interface, pfx netip.Prefix) {
if tsaddr.IsTailscaleIP(pfx.Addr()) {
return
}
@@ -1286,9 +1285,9 @@ func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (interna
return iSet.Prefixes(), eSet.Prefixes(), nil
}
-func interfaceRoutes() (ips *netipx.IPSet, hostIPs []netaddr.IP, err error) {
+func interfaceRoutes() (ips *netipx.IPSet, hostIPs []netip.Addr, err error) {
var b netipx.IPSetBuilder
- if err := interfaces.ForeachInterfaceAddress(func(_ interfaces.Interface, pfx netaddr.IPPrefix) {
+ if err := interfaces.ForeachInterfaceAddress(func(_ interfaces.Interface, pfx netip.Prefix) {
if tsaddr.IsTailscaleIP(pfx.Addr()) {
return
}
@@ -1308,7 +1307,7 @@ func interfaceRoutes() (ips *netipx.IPSet, hostIPs []netaddr.IP, err error) {
// shrinkDefaultRoute returns an IPSet representing the IPs in route,
// minus those in removeFromDefaultRoute and localInterfaceRoutes,
// plus the IPs in hostIPs.
-func shrinkDefaultRoute(route netaddr.IPPrefix, localInterfaceRoutes *netipx.IPSet, hostIPs []netaddr.IP) (*netipx.IPSet, error) {
+func shrinkDefaultRoute(route netip.Prefix, localInterfaceRoutes *netipx.IPSet, hostIPs []netip.Addr) (*netipx.IPSet, error) {
var b netipx.IPSetBuilder
// Add the default route.
b.AddPrefix(route)
@@ -1335,7 +1334,7 @@ func shrinkDefaultRoute(route netaddr.IPPrefix, localInterfaceRoutes *netipx.IPS
// dnsCIDRsEqual determines whether two CIDR lists are equal
// for DNS map construction purposes (that is, only the first entry counts).
-func dnsCIDRsEqual(newAddr, oldAddr []netaddr.IPPrefix) bool {
+func dnsCIDRsEqual(newAddr, oldAddr []netip.Prefix) bool {
if len(newAddr) != len(oldAddr) {
return false
}
@@ -1733,7 +1732,7 @@ func (b *LocalBackend) StartLoginInteractive() {
}
}
-func (b *LocalBackend) Ping(ctx context.Context, ip netaddr.IP, pingType tailcfg.PingType) (*ipnstate.PingResult, error) {
+func (b *LocalBackend) Ping(ctx context.Context, ip netip.Addr, pingType tailcfg.PingType) (*ipnstate.PingResult, error) {
if pingType == tailcfg.PingPeerAPI {
t0 := time.Now()
node, base, err := b.pingPeerAPI(ctx, ip)
@@ -1770,7 +1769,7 @@ func (b *LocalBackend) Ping(ctx context.Context, ip netaddr.IP, pingType tailcfg
}
}
-func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netaddr.IP) (peer *tailcfg.Node, peerBase string, err error) {
+func (b *LocalBackend) pingPeerAPI(ctx context.Context, ip netip.Addr) (peer *tailcfg.Node, peerBase string, err error) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
nm := b.NetMap()
@@ -2069,7 +2068,7 @@ func (b *LocalBackend) setPrefsLockedOnEntry(caller string, newp *ipn.Prefs) {
// GetPeerAPIPort returns the port number for the peerapi server
// running on the provided IP.
-func (b *LocalBackend) GetPeerAPIPort(ip netaddr.IP) (port uint16, ok bool) {
+func (b *LocalBackend) GetPeerAPIPort(ip netip.Addr) (port uint16, ok bool) {
b.mu.Lock()
defer b.mu.Unlock()
for _, pln := range b.peerAPIListeners {
@@ -2087,7 +2086,7 @@ func (b *LocalBackend) GetPeerAPIPort(ip netaddr.IP) (port uint16, ok bool) {
// or IPv6 IP and the peerapi port for that address).
//
// The connection will be closed by ServePeerAPIConnection.
-func (b *LocalBackend) ServePeerAPIConnection(remote, local netaddr.IPPort, c net.Conn) {
+func (b *LocalBackend) ServePeerAPIConnection(remote, local netip.AddrPort, c net.Conn) {
b.mu.Lock()
defer b.mu.Unlock()
for _, pln := range b.peerAPIListeners {
@@ -2289,7 +2288,7 @@ func shouldUseOneCGNATRoute(nm *netmap.NetworkMap, logf logger.Logf, versionOS s
func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Logf, versionOS string) *dns.Config {
dcfg := &dns.Config{
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
- Hosts: map[dnsname.FQDN][]netaddr.IP{},
+ Hosts: map[dnsname.FQDN][]netip.Addr{},
}
// selfV6Only is whether we only have IPv6 addresses ourselves.
@@ -2302,7 +2301,7 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Log
// isn't configured to make MagicDNS resolution truly
// magic. Details in
// https://github.com/tailscale/tailscale/issues/1886.
- set := func(name string, addrs []netaddr.IPPrefix) {
+ set := func(name string, addrs []netip.Prefix) {
if len(addrs) == 0 || name == "" {
return
}
@@ -2311,7 +2310,7 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Log
return // TODO: propagate error?
}
have4 := tsaddr.PrefixesContainsFunc(addrs, tsaddr.PrefixIs4)
- var ips []netaddr.IP
+ var ips []netip.Addr
for _, addr := range addrs {
if selfV6Only {
if addr.Addr().Is6() {
@@ -2629,11 +2628,11 @@ func magicDNSRootDomains(nm *netmap.NetworkMap) []dnsname.FQDN {
// peerRoutes returns the routerConfig.Routes to access peers.
// If there are over cgnatThreshold CGNAT routes, one big CGNAT route
// is used instead.
-func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netaddr.IPPrefix) {
+func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netip.Prefix) {
tsULA := tsaddr.TailscaleULARange()
cgNAT := tsaddr.CGNATRange()
var didULA bool
- var cgNATIPs []netaddr.IPPrefix
+ var cgNATIPs []netip.Prefix
for _, peer := range peers {
for _, aip := range peer.AllowedIPs {
aip = unmapIPPrefix(aip)
@@ -2665,7 +2664,7 @@ func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netaddr.IPPref
return routes
}
-func ipPrefixLess(ri, rj netaddr.IPPrefix) bool {
+func ipPrefixLess(ri, rj netip.Prefix) bool {
if ri.Addr() == rj.Addr() {
return ri.Bits() < rj.Bits()
}
@@ -2736,17 +2735,17 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs *ipn.Prefs, oneCGNA
}
if tsaddr.PrefixesContainsFunc(rs.LocalAddrs, tsaddr.PrefixIs4) {
- rs.Routes = append(rs.Routes, netaddr.IPPrefixFrom(tsaddr.TailscaleServiceIP(), 32))
+ rs.Routes = append(rs.Routes, netip.PrefixFrom(tsaddr.TailscaleServiceIP(), 32))
}
return rs
}
-func unmapIPPrefix(ipp netaddr.IPPrefix) netaddr.IPPrefix {
+func unmapIPPrefix(ipp netip.Prefix) netip.Prefix {
return netip.PrefixFrom(ipp.Addr().Unmap(), ipp.Bits())
}
-func unmapIPPrefixes(ippsList ...[]netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
+func unmapIPPrefixes(ippsList ...[]netip.Prefix) (ret []netip.Prefix) {
for _, ipps := range ippsList {
for _, ipp := range ipps {
ret = append(ret, unmapIPPrefix(ipp))
@@ -2989,8 +2988,8 @@ func (b *LocalBackend) ShouldRunSSH() bool { return b.sshAtomicBool.Get() && can
// ShouldHandleViaIP reports whether whether ip is an IPv6 address in the
// Tailscale ULA's v6 "via" range embedding an IPv4 address to be forwarded to
// by Tailscale.
-func (b *LocalBackend) ShouldHandleViaIP(ip netaddr.IP) bool {
- if f, ok := b.containsViaIPFuncAtomic.Load().(func(netaddr.IP) bool); ok {
+func (b *LocalBackend) ShouldHandleViaIP(ip netip.Addr) bool {
+ if f, ok := b.containsViaIPFuncAtomic.Load().(func(netip.Addr) bool); ok {
return f(ip)
}
return false
@@ -3107,7 +3106,7 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
// Update the nodeByAddr index.
if b.nodeByAddr == nil {
- b.nodeByAddr = map[netaddr.IP]*tailcfg.Node{}
+ b.nodeByAddr = map[netip.Addr]*tailcfg.Node{}
}
// First pass, mark everything unwanted.
for k := range b.nodeByAddr {
@@ -3313,12 +3312,12 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
p6 = s.Port
}
}
- var ipp netaddr.IPPort
+ var ipp netip.AddrPort
switch {
case have4 && p4 != 0:
- ipp = netaddr.IPPortFrom(nodeIP(peer, netaddr.IP.Is4), p4)
+ ipp = netip.AddrPortFrom(nodeIP(peer, netip.Addr.Is4), p4)
case have6 && p6 != 0:
- ipp = netaddr.IPPortFrom(nodeIP(peer, netaddr.IP.Is6), p6)
+ ipp = netip.AddrPortFrom(nodeIP(peer, netip.Addr.Is6), p6)
}
if !ipp.Addr().IsValid() {
return ""
@@ -3326,13 +3325,13 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
return fmt.Sprintf("http://%v", ipp)
}
-func nodeIP(n *tailcfg.Node, pred func(netaddr.IP) bool) netaddr.IP {
+func nodeIP(n *tailcfg.Node, pred func(netip.Addr) bool) netip.Addr {
for _, a := range n.Addresses {
if a.IsSingleIP() && pred(a.Addr()) {
return a.Addr()
}
}
- return netaddr.IP{}
+ return netip.Addr{}
}
func (b *LocalBackend) CheckIPForwarding() error {
diff --git a/ipn/ipnlocal/local_test.go b/ipn/ipnlocal/local_test.go
index 26aaf1589..4d8d25c1c 100644
--- a/ipn/ipnlocal/local_test.go
+++ b/ipn/ipnlocal/local_test.go
@@ -17,7 +17,6 @@
"tailscale.com/ipn"
"tailscale.com/ipn/store/mem"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
@@ -31,13 +30,13 @@ func TestNetworkMapCompare(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- node1 := &tailcfg.Node{Addresses: []netaddr.IPPrefix{prefix1}}
+ node1 := &tailcfg.Node{Addresses: []netip.Prefix{prefix1}}
prefix2, err := netip.ParsePrefix("10.0.0.0/8")
if err != nil {
t.Fatal(err)
}
- node2 := &tailcfg.Node{Addresses: []netaddr.IPPrefix{prefix2}}
+ node2 := &tailcfg.Node{Addresses: []netip.Prefix{prefix2}}
tests := []struct {
name string
@@ -133,7 +132,7 @@ func TestNetworkMapCompare(t *testing.T) {
}
}
-func inRemove(ip netaddr.IP) bool {
+func inRemove(ip netip.Addr) bool {
for _, pfx := range removeFromDefaultRoute {
if pfx.Contains(ip) {
return true
@@ -147,7 +146,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
route string
in []string
out []string
- localIPFn func(netaddr.IP) bool // true if this machine's local IP address should be "in" after shrinking.
+ localIPFn func(netip.Addr) bool // true if this machine's local IP address should be "in" after shrinking.
}{
{
route: "0.0.0.0/0",
@@ -167,7 +166,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
"fe80::",
"2601::1",
},
- localIPFn: func(ip netaddr.IP) bool { return !inRemove(ip) && ip.Is4() },
+ localIPFn: func(ip netip.Addr) bool { return !inRemove(ip) && ip.Is4() },
},
{
route: "::/0",
@@ -177,7 +176,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
"ff00::1",
tsaddr.TailscaleULARange().Addr().String(),
},
- localIPFn: func(ip netaddr.IP) bool { return !inRemove(ip) && ip.Is6() },
+ localIPFn: func(ip netip.Addr) bool { return !inRemove(ip) && ip.Is6() },
},
}
@@ -193,13 +192,13 @@ func TestShrinkDefaultRoute(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- hostIPs := []netaddr.IP{
+ hostIPs := []netip.Addr{
netip.MustParseAddr("127.0.0.1"),
netip.MustParseAddr("192.168.9.39"),
netip.MustParseAddr("fe80::1"),
netip.MustParseAddr("fe80::437d:feff:feca:49a7"),
}
- localAddresses := []netaddr.IP{
+ localAddresses := []netip.Addr{
netip.MustParseAddr("192.168.9.39"),
}
@@ -233,18 +232,18 @@ func TestPeerRoutes(t *testing.T) {
tests := []struct {
name string
peers []wgcfg.Peer
- want []netaddr.IPPrefix
+ want []netip.Prefix
}{
{
name: "small_v4",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("100.101.102.103/32"),
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("100.101.102.103/32"),
},
},
@@ -252,14 +251,14 @@ func TestPeerRoutes(t *testing.T) {
name: "big_v4",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("100.101.102.103/32"),
pp("100.101.102.104/32"),
pp("100.101.102.105/32"),
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("100.64.0.0/10"),
},
},
@@ -267,12 +266,12 @@ func TestPeerRoutes(t *testing.T) {
name: "has_1_v6",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("fd7a:115c:a1e0:ab12:4843:cd96:6258:b240/128"),
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("fd7a:115c:a1e0::/48"),
},
},
@@ -280,13 +279,13 @@ func TestPeerRoutes(t *testing.T) {
name: "has_2_v6",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("fd7a:115c:a1e0:ab12:4843:cd96:6258:b240/128"),
pp("fd7a:115c:a1e0:ab12:4843:cd96:6258:b241/128"),
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("fd7a:115c:a1e0::/48"),
},
},
@@ -294,7 +293,7 @@ func TestPeerRoutes(t *testing.T) {
name: "big_v4_big_v6",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("100.101.102.103/32"),
pp("100.101.102.104/32"),
pp("100.101.102.105/32"),
@@ -303,7 +302,7 @@ func TestPeerRoutes(t *testing.T) {
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("100.64.0.0/10"),
pp("fd7a:115c:a1e0::/48"),
},
@@ -312,19 +311,19 @@ func TestPeerRoutes(t *testing.T) {
name: "output-should-be-sorted",
peers: []wgcfg.Peer{
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("100.64.0.2/32"),
pp("10.0.0.0/16"),
},
},
{
- AllowedIPs: []netaddr.IPPrefix{
+ AllowedIPs: []netip.Prefix{
pp("100.64.0.1/32"),
pp("10.0.0.0/8"),
},
},
},
- want: []netaddr.IPPrefix{
+ want: []netip.Prefix{
pp("10.0.0.0/8"),
pp("10.0.0.0/16"),
pp("100.64.0.1/32"),
@@ -363,12 +362,12 @@ func TestPeerAPIBase(t *testing.T) {
{
name: "self_only_4_them_both",
nm: &netmap.NetworkMap{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
},
},
peer: &tailcfg.Node{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.2/32"),
netip.MustParsePrefix("fe70::2/128"),
},
@@ -384,12 +383,12 @@ func TestPeerAPIBase(t *testing.T) {
{
name: "self_only_6_them_both",
nm: &netmap.NetworkMap{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("fe70::1/128"),
},
},
peer: &tailcfg.Node{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.2/32"),
netip.MustParsePrefix("fe70::2/128"),
},
@@ -405,13 +404,13 @@ func TestPeerAPIBase(t *testing.T) {
{
name: "self_both_them_only_4",
nm: &netmap.NetworkMap{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
netip.MustParsePrefix("fe70::1/128"),
},
},
peer: &tailcfg.Node{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.2/32"),
netip.MustParsePrefix("fe70::2/128"),
},
@@ -426,13 +425,13 @@ func TestPeerAPIBase(t *testing.T) {
{
name: "self_both_them_only_6",
nm: &netmap.NetworkMap{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
netip.MustParsePrefix("fe70::1/128"),
},
},
peer: &tailcfg.Node{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.2/32"),
netip.MustParsePrefix("fe70::2/128"),
},
@@ -447,13 +446,13 @@ func TestPeerAPIBase(t *testing.T) {
{
name: "self_both_them_no_peerapi_service",
nm: &netmap.NetworkMap{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
netip.MustParsePrefix("fe70::1/128"),
},
},
peer: &tailcfg.Node{
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
netip.MustParsePrefix("100.64.1.2/32"),
netip.MustParsePrefix("fe70::2/128"),
},
@@ -543,10 +542,10 @@ func TestFileTargets(t *testing.T) {
func TestInternalAndExternalInterfaces(t *testing.T) {
type interfacePrefix struct {
i interfaces.Interface
- pfx netaddr.IPPrefix
+ pfx netip.Prefix
}
- masked := func(ips ...interfacePrefix) (pfxs []netaddr.IPPrefix) {
+ masked := func(ips ...interfacePrefix) (pfxs []netip.Prefix) {
for _, ip := range ips {
pfxs = append(pfxs, ip.pfx.Masked())
}
@@ -585,8 +584,8 @@ type interfacePrefix struct {
name string
goos string
il interfaces.List
- wantInt []netaddr.IPPrefix
- wantExt []netaddr.IPPrefix
+ wantInt []netip.Prefix
+ wantExt []netip.Prefix
}{
{
name: "single-interface",
diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go
index 40115971e..4bd935407 100644
--- a/ipn/ipnlocal/peerapi.go
+++ b/ipn/ipnlocal/peerapi.go
@@ -48,7 +48,7 @@
"tailscale.com/wgengine/filter"
)
-var initListenConfig func(*net.ListenConfig, netaddr.IP, *interfaces.State, string) error
+var initListenConfig func(*net.ListenConfig, netip.Addr, *interfaces.State, string) error
// addH2C is non-nil on platforms where we want to add H2C
// ("cleartext" HTTP/2) support to the peerAPI.
@@ -387,7 +387,7 @@ func (s *peerAPIServer) OpenFile(baseName string) (rc io.ReadCloser, size int64,
return f, fi.Size(), nil
}
-func (s *peerAPIServer) listen(ip netaddr.IP, ifState *interfaces.State) (ln net.Listener, err error) {
+func (s *peerAPIServer) listen(ip netip.Addr, ifState *interfaces.State) (ln net.Listener, err error) {
// Android for whatever reason often has problems creating the peerapi listener.
// But since we started intercepting it with netstack, it's not even important that
// we have a real kernel-level listener. So just create a dummy listener on Android
@@ -451,7 +451,7 @@ func (s *peerAPIServer) listen(ip netaddr.IP, ifState *interfaces.State) (ln net
type peerAPIListener struct {
ps *peerAPIServer
- ip netaddr.IP
+ ip netip.Addr
lb *LocalBackend
// ln is the Listener. It can be nil in netstack mode if there are more than
@@ -503,7 +503,7 @@ func (pln *peerAPIListener) serve() {
}
}
-func (pln *peerAPIListener) ServeConn(src netaddr.IPPort, c net.Conn) {
+func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) {
logf := pln.lb.logf
peerNode, peerUser, ok := pln.lb.WhoIs(src)
if !ok {
@@ -530,7 +530,7 @@ func (pln *peerAPIListener) ServeConn(src netaddr.IPPort, c net.Conn) {
// peerAPIHandler serves the Peer API for a source specific client.
type peerAPIHandler struct {
ps *peerAPIServer
- remoteAddr netaddr.IPPort
+ remoteAddr netip.AddrPort
isSelf bool // whether peerNode is owned by same user as this node
peerNode *tailcfg.Node // peerNode is who's making the request
peerUser tailcfg.UserProfile // profile of peerNode
@@ -609,7 +609,7 @@ func (h *peerAPIHandler) handleServeInterfaces(w http.ResponseWriter, r *http.Re
fmt.Fprintf(w, "
%v | ", v)
}
fmt.Fprint(w, "\n")
- i.ForeachInterface(func(iface interfaces.Interface, ipps []netaddr.IPPrefix) {
+ i.ForeachInterface(func(iface interfaces.Interface, ipps []netip.Prefix) {
fmt.Fprint(w, "")
for _, v := range []any{iface.Index, iface.Name, iface.MTU, iface.Flags, ipps} {
fmt.Fprintf(w, "%v | ", v)
@@ -1169,9 +1169,9 @@ func writePrettyDNSReply(w io.Writer, res []byte) (err error) {
// it's listening on the provided IP address and on TCP port 1.
//
// See docs on fakePeerAPIListener.
-func newFakePeerAPIListener(ip netaddr.IP) net.Listener {
+func newFakePeerAPIListener(ip netip.Addr) net.Listener {
return &fakePeerAPIListener{
- addr: net.TCPAddrFromAddrPort(netaddr.IPPortFrom(ip, 1)),
+ addr: net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, 1)),
closed: make(chan struct{}),
}
}
diff --git a/ipn/ipnlocal/peerapi_macios_ext.go b/ipn/ipnlocal/peerapi_macios_ext.go
index 315df1e4f..b10e999aa 100644
--- a/ipn/ipnlocal/peerapi_macios_ext.go
+++ b/ipn/ipnlocal/peerapi_macios_ext.go
@@ -11,9 +11,9 @@
import (
"fmt"
"net"
+ "net/netip"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
)
@@ -24,7 +24,7 @@ func init() {
// initListenConfigNetworkExtension configures nc for listening on IP
// through the iOS/macOS Network/System Extension (Packet Tunnel
// Provider) sandbox.
-func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netaddr.IP, st *interfaces.State, tunIfName string) error {
+func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netip.Addr, st *interfaces.State, tunIfName string) error {
tunIf, ok := st.Interface[tunIfName]
if !ok {
return fmt.Errorf("no interface with name %q", tunIfName)
diff --git a/ipn/ipnlocal/peerapi_test.go b/ipn/ipnlocal/peerapi_test.go
index e4bd3ccb4..bcfb44ac9 100644
--- a/ipn/ipnlocal/peerapi_test.go
+++ b/ipn/ipnlocal/peerapi_test.go
@@ -22,7 +22,6 @@
"go4.org/netipx"
"tailscale.com/ipn"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/tstest"
"tailscale.com/types/logger"
@@ -596,7 +595,7 @@ func TestPeerAPIReplyToDNSQueries(t *testing.T) {
t.Fatal("unexpectedly offering exit node")
}
h.ps.b.prefs = &ipn.Prefs{
- AdvertiseRoutes: []netaddr.IPPrefix{
+ AdvertiseRoutes: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
netip.MustParsePrefix("::/0"),
},
diff --git a/ipn/ipnserver/server.go b/ipn/ipnserver/server.go
index f04b135e3..42cccbeaa 100644
--- a/ipn/ipnserver/server.go
+++ b/ipn/ipnserver/server.go
@@ -37,7 +37,6 @@
"tailscale.com/ipn/ipnlocal"
"tailscale.com/ipn/localapi"
"tailscale.com/logtail/backoff"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netstat"
"tailscale.com/net/netutil"
"tailscale.com/net/tsdial"
@@ -1066,7 +1065,7 @@ func (s *Server) ServeHTMLStatus(w http.ResponseWriter, r *http.Request) {
st.WriteHTML(w)
}
-func peerPid(entries []netstat.Entry, la, ra netaddr.IPPort) int {
+func peerPid(entries []netstat.Entry, la, ra netip.AddrPort) int {
for _, e := range entries {
if e.Local == ra && e.Remote == la {
return e.Pid
diff --git a/ipn/ipnstate/ipnstate.go b/ipn/ipnstate/ipnstate.go
index d2c6ff27e..23b19ec9d 100644
--- a/ipn/ipnstate/ipnstate.go
+++ b/ipn/ipnstate/ipnstate.go
@@ -12,12 +12,12 @@
"html"
"io"
"log"
+ "net/netip"
"sort"
"strings"
"sync"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"tailscale.com/types/views"
@@ -35,7 +35,7 @@ type Status struct {
BackendState string
AuthURL string // current URL provided by control to authorize client
- TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node
+ TailscaleIPs []netip.Addr // Tailscale IP(s) assigned to this node
Self *PeerStatus
// ExitNodeStatus describes the current exit node.
@@ -94,7 +94,7 @@ type ExitNodeStatus struct {
Online bool
// TailscaleIPs are the exit node's IP addresses assigned to the node.
- TailscaleIPs []netaddr.IPPrefix
+ TailscaleIPs []netip.Prefix
}
func (s *Status) Peers() []key.NodePublic {
@@ -124,7 +124,7 @@ type PeerStatus struct {
DNSName string
OS string // HostInfo.OS
UserID tailcfg.UserID
- TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node
+ TailscaleIPs []netip.Addr // Tailscale IP(s) assigned to this node
// Tags are the list of ACL tags applied to this node.
// See tailscale.com/tailcfg#Node.Tags for more information.
@@ -240,7 +240,7 @@ func (sb *StatusBuilder) AddUser(id tailcfg.UserID, up tailcfg.UserProfile) {
}
// AddIP adds a Tailscale IP address to the status.
-func (sb *StatusBuilder) AddTailscaleIP(ip netaddr.IP) {
+func (sb *StatusBuilder) AddTailscaleIP(ip netip.Addr) {
sb.mu.Lock()
defer sb.mu.Unlock()
if sb.locked {
diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go
index ea2d2c384..f5b8ca455 100644
--- a/ipn/localapi/localapi.go
+++ b/ipn/localapi/localapi.go
@@ -29,7 +29,6 @@
"tailscale.com/ipn"
"tailscale.com/ipn/ipnlocal"
"tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netutil"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
@@ -223,7 +222,7 @@ func (h *Handler) serveWhoIs(w http.ResponseWriter, r *http.Request) {
return
}
b := h.b
- var ipp netaddr.IPPort
+ var ipp netip.AddrPort
if v := r.FormValue("addr"); v != "" {
var err error
ipp, err = netip.ParseAddrPort(v)
diff --git a/ipn/prefs.go b/ipn/prefs.go
index 8616767dd..b0b9fc250 100644
--- a/ipn/prefs.go
+++ b/ipn/prefs.go
@@ -99,7 +99,7 @@ type Prefs struct {
// blackhole route will be installed on the local system to
// prevent any traffic escaping to the local network.
ExitNodeID tailcfg.StableNodeID
- ExitNodeIP netaddr.IP
+ ExitNodeIP netip.Addr
// ExitNodeAllowLANAccess indicates whether locally accessible subnets should be
// routed directly or via the exit node.
@@ -168,7 +168,7 @@ type Prefs struct {
// AdvertiseRoutes specifies CIDR prefixes to advertise into the
// Tailscale network as reachable through the current
// node.
- AdvertiseRoutes []netaddr.IPPrefix
+ AdvertiseRoutes []netip.Prefix
// NoSNAT specifies whether to source NAT traffic going to
// destinations in AdvertiseRoutes. The default is to apply source
@@ -383,7 +383,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
p.Persist.Equals(p2.Persist)
}
-func compareIPNets(a, b []netaddr.IPPrefix) bool {
+func compareIPNets(a, b []netip.Prefix) bool {
if len(a) != len(b) {
return false
}
@@ -478,13 +478,13 @@ func (p *Prefs) SetAdvertiseExitNode(runExit bool) {
return
}
p.AdvertiseRoutes = append(p.AdvertiseRoutes,
- netaddr.IPPrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
- netaddr.IPPrefixFrom(netip.IPv6Unspecified(), 0))
+ netip.PrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
+ netip.PrefixFrom(netip.IPv6Unspecified(), 0))
}
// peerWithTailscaleIP returns the peer in st with the provided
// Tailscale IP.
-func peerWithTailscaleIP(st *ipnstate.Status, ip netaddr.IP) (ps *ipnstate.PeerStatus, ok bool) {
+func peerWithTailscaleIP(st *ipnstate.Status, ip netip.Addr) (ps *ipnstate.PeerStatus, ok bool) {
for _, ps := range st.Peer {
for _, ip2 := range ps.TailscaleIPs {
if ip == ip2 {
@@ -495,7 +495,7 @@ func peerWithTailscaleIP(st *ipnstate.Status, ip netaddr.IP) (ps *ipnstate.PeerS
return nil, false
}
-func isRemoteIP(st *ipnstate.Status, ip netaddr.IP) bool {
+func isRemoteIP(st *ipnstate.Status, ip netip.Addr) bool {
for _, selfIP := range st.TailscaleIPs {
if ip == selfIP {
return false
@@ -507,7 +507,7 @@ func isRemoteIP(st *ipnstate.Status, ip netaddr.IP) bool {
// ClearExitNode sets the ExitNodeID and ExitNodeIP to their zero values.
func (p *Prefs) ClearExitNode() {
p.ExitNodeID = ""
- p.ExitNodeIP = netaddr.IP{}
+ p.ExitNodeIP = netip.Addr{}
}
// ExitNodeLocalIPError is returned when the requested IP address for an exit
@@ -520,7 +520,7 @@ func (e ExitNodeLocalIPError) Error() string {
return fmt.Sprintf("cannot use %s as an exit node as it is a local IP address to this machine", e.hostOrIP)
}
-func exitNodeIPOfArg(s string, st *ipnstate.Status) (ip netaddr.IP, err error) {
+func exitNodeIPOfArg(s string, st *ipnstate.Status) (ip netip.Addr, err error) {
if s == "" {
return ip, os.ErrInvalid
}
diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go
index d95b5c115..ce567aae9 100644
--- a/ipn/prefs_test.go
+++ b/ipn/prefs_test.go
@@ -63,7 +63,7 @@ func TestPrefsEqual(t *testing.T) {
have, prefsHandles)
}
- nets := func(strs ...string) (ns []netaddr.IPPrefix) {
+ nets := func(strs ...string) (ns []netip.Prefix) {
for _, s := range strs {
n, err := netip.ParsePrefix(s)
if err != nil {
@@ -227,12 +227,12 @@ func TestPrefsEqual(t *testing.T) {
{
&Prefs{AdvertiseRoutes: nil},
- &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
+ &Prefs{AdvertiseRoutes: []netip.Prefix{}},
true,
},
{
- &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
- &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
+ &Prefs{AdvertiseRoutes: []netip.Prefix{}},
+ &Prefs{AdvertiseRoutes: []netip.Prefix{}},
true,
},
{
@@ -659,7 +659,7 @@ func TestPrefsExitNode(t *testing.T) {
if p.AdvertisesExitNode() {
t.Errorf("default shouldn't advertise exit node")
}
- p.AdvertiseRoutes = []netaddr.IPPrefix{
+ p.AdvertiseRoutes = []netip.Prefix{
netip.MustParsePrefix("10.0.0.0/16"),
}
p.SetAdvertiseExitNode(true)
@@ -688,7 +688,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
name string
arg string
st *ipnstate.Status
- want netaddr.IP
+ want netip.Addr
wantErr string
}{
{
@@ -714,7 +714,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
BackendState: "Running",
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
- TailscaleIPs: []netaddr.IP{mustIP("1.2.3.4")},
+ TailscaleIPs: []netip.Addr{mustIP("1.2.3.4")},
},
},
},
@@ -727,7 +727,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
BackendState: "Running",
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
- TailscaleIPs: []netaddr.IP{mustIP("1.2.3.4")},
+ TailscaleIPs: []netip.Addr{mustIP("1.2.3.4")},
ExitNodeOption: true,
},
},
@@ -748,7 +748,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
DNSName: "skippy.foo.",
- TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
+ TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
ExitNodeOption: true,
},
},
@@ -763,7 +763,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
DNSName: "skippy.foo.",
- TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
+ TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
},
},
},
@@ -777,12 +777,12 @@ func TestExitNodeIPOfArg(t *testing.T) {
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
DNSName: "skippy.foo.",
- TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
+ TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
ExitNodeOption: true,
},
key.NewNode().Public(): {
DNSName: "SKIPPY.foo.",
- TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
+ TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
ExitNodeOption: true,
},
},
diff --git a/net/dns/config.go b/net/dns/config.go
index 733e08c11..7fb5e5ebd 100644
--- a/net/dns/config.go
+++ b/net/dns/config.go
@@ -7,10 +7,10 @@
import (
"bufio"
"fmt"
+ "net/netip"
"sort"
"tailscale.com/net/dns/resolver"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/types/dnstype"
"tailscale.com/util/dnsname"
@@ -40,13 +40,13 @@ type Config struct {
// Adding an entry to Hosts merely creates the record. If you want
// it to resolve, you also need to add appropriate routes to
// Routes.
- Hosts map[dnsname.FQDN][]netaddr.IP
+ Hosts map[dnsname.FQDN][]netip.Addr
// OnlyIPv6, if true, uses the IPv6 service IP (for MagicDNS)
// instead of the IPv4 version (100.100.100.100).
OnlyIPv6 bool
}
-func (c *Config) serviceIP() netaddr.IP {
+func (c *Config) serviceIP() netip.Addr {
if c.OnlyIPv6 {
return tsaddr.TailscaleServiceIPv6()
}
@@ -143,7 +143,7 @@ func sameResolverNames(a, b []*dnstype.Resolver) bool {
return true
}
-func sameIPs(a, b []netaddr.IP) bool {
+func sameIPs(a, b []netip.Addr) bool {
if len(a) != len(b) {
return false
}
diff --git a/net/dns/direct.go b/net/dns/direct.go
index c32ce5688..4f698dcf5 100644
--- a/net/dns/direct.go
+++ b/net/dns/direct.go
@@ -13,6 +13,7 @@
"io"
"io/fs"
"io/ioutil"
+ "net/netip"
"os"
"os/exec"
"path/filepath"
@@ -21,7 +22,6 @@
"time"
"tailscale.com/net/dns/resolvconffile"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/util/dnsname"
"tailscale.com/version/distro"
@@ -33,7 +33,7 @@
)
// writeResolvConf writes DNS configuration in resolv.conf format to the given writer.
-func writeResolvConf(w io.Writer, servers []netaddr.IP, domains []dnsname.FQDN) error {
+func writeResolvConf(w io.Writer, servers []netip.Addr, domains []dnsname.FQDN) error {
c := &resolvconffile.Config{
Nameservers: servers,
SearchDomains: domains,
diff --git a/net/dns/direct_test.go b/net/dns/direct_test.go
index b9784ef5a..78dfd29e4 100644
--- a/net/dns/direct_test.go
+++ b/net/dns/direct_test.go
@@ -16,7 +16,6 @@
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)
@@ -82,7 +81,7 @@ func testDirect(t *testing.T, fs wholeFileFS) {
m := directManager{logf: t.Logf, fs: fs}
if err := m.SetDNS(OSConfig{
- Nameservers: []netaddr.IP{netip.MustParseAddr("8.8.8.8"), netip.MustParseAddr("8.8.4.4")},
+ Nameservers: []netip.Addr{netip.MustParseAddr("8.8.8.8"), netip.MustParseAddr("8.8.4.4")},
SearchDomains: []dnsname.FQDN{"ts.net.", "ts-dns.test."},
MatchDomains: []dnsname.FQDN{"ignored."},
}); err != nil {
@@ -109,7 +108,7 @@ func testDirect(t *testing.T, fs wholeFileFS) {
assertBaseState(t)
// Test that Close cleans up resolv.conf.
- if err := m.SetDNS(OSConfig{Nameservers: []netaddr.IP{netip.MustParseAddr("8.8.8.8")}}); err != nil {
+ if err := m.SetDNS(OSConfig{Nameservers: []netip.Addr{netip.MustParseAddr("8.8.8.8")}}); err != nil {
t.Fatal(err)
}
if err := m.Close(); err != nil {
@@ -150,21 +149,21 @@ func TestReadResolve(t *testing.T) {
}{
{in: `nameserver 192.168.0.100`,
want: OSConfig{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
},
{in: `nameserver 192.168.0.100 # comment`,
want: OSConfig{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
},
{in: `nameserver 192.168.0.100#`,
want: OSConfig{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
diff --git a/net/dns/manager.go b/net/dns/manager.go
index 1b99c3416..9889408d0 100644
--- a/net/dns/manager.go
+++ b/net/dns/manager.go
@@ -11,13 +11,13 @@
"errors"
"io"
"net"
+ "net/netip"
"runtime"
"sync/atomic"
"time"
"tailscale.com/health"
"tailscale.com/net/dns/resolver"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/net/tsdial"
@@ -67,7 +67,7 @@ func maxActiveQueries() int32 {
type response struct {
pkt []byte
- to netaddr.IPPort // response destination (request source)
+ to netip.AddrPort // response destination (request source)
}
// Manager manages system DNS settings.
@@ -175,7 +175,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig
// through quad-100.
rcfg.Routes = routes
rcfg.Routes["."] = cfg.DefaultResolvers
- ocfg.Nameservers = []netaddr.IP{cfg.serviceIP()}
+ ocfg.Nameservers = []netip.Addr{cfg.serviceIP()}
return rcfg, ocfg, nil
}
@@ -212,7 +212,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig
// or routes + MagicDNS, or just MagicDNS, or on an OS that cannot
// split-DNS. Install a split config pointing at quad-100.
rcfg.Routes = routes
- ocfg.Nameservers = []netaddr.IP{cfg.serviceIP()}
+ ocfg.Nameservers = []netip.Addr{cfg.serviceIP()}
// If the OS can't do native split-dns, read out the underlying
// resolver config and blend it into our config.
@@ -239,7 +239,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig
// toIPsOnly returns only the IP portion of dnstype.Resolver.
// Only safe to use if the resolvers slice has been cleared of
// DoH or custom-port entries with something like hasDefaultIPResolversOnly.
-func toIPsOnly(resolvers []*dnstype.Resolver) (ret []netaddr.IP) {
+func toIPsOnly(resolvers []*dnstype.Resolver) (ret []netip.Addr) {
for _, r := range resolvers {
if ipp, ok := r.IPPort(); ok && ipp.Port() == 53 {
ret = append(ret, ipp.Addr())
@@ -252,7 +252,7 @@ func toIPsOnly(resolvers []*dnstype.Resolver) (ret []netaddr.IP) {
// called with a DNS request payload.
//
// TODO(tom): Rip out once all platforms use netstack.
-func (m *Manager) EnqueuePacket(bs []byte, proto ipproto.Proto, from, to netaddr.IPPort) error {
+func (m *Manager) EnqueuePacket(bs []byte, proto ipproto.Proto, from, to netip.AddrPort) error {
if to.Port() != 53 || proto != ipproto.UDP {
return nil
}
@@ -334,7 +334,7 @@ func (m *Manager) NextPacket() ([]byte, error) {
// Query executes a DNS query recieved from the given address. The query is
// provided in bs as a wire-encoded DNS query without any transport header.
// This method is called for requests arriving over UDP and TCP.
-func (m *Manager) Query(ctx context.Context, bs []byte, from netaddr.IPPort) ([]byte, error) {
+func (m *Manager) Query(ctx context.Context, bs []byte, from netip.AddrPort) ([]byte, error) {
select {
case <-m.ctx.Done():
return nil, net.ErrClosed
@@ -368,7 +368,7 @@ type dnsTCPSession struct {
m *Manager
conn net.Conn
- srcAddr netaddr.IPPort
+ srcAddr netip.AddrPort
readClosing chan struct{}
responses chan []byte // DNS replies pending writing
@@ -455,7 +455,7 @@ func (s *dnsTCPSession) handleReads() {
// HandleTCPConn implements magicDNS over TCP, taking a connection and
// servicing DNS requests sent down it.
-func (m *Manager) HandleTCPConn(conn net.Conn, srcAddr netaddr.IPPort) {
+func (m *Manager) HandleTCPConn(conn net.Conn, srcAddr netip.AddrPort) {
s := dnsTCPSession{
m: m,
conn: conn,
diff --git a/net/dns/manager_tcp_test.go b/net/dns/manager_tcp_test.go
index 01ed32e02..5aafb1532 100644
--- a/net/dns/manager_tcp_test.go
+++ b/net/dns/manager_tcp_test.go
@@ -8,11 +8,11 @@
"encoding/binary"
"io"
"net"
+ "net/netip"
"testing"
"github.com/google/go-cmp/cmp"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsdial"
"tailscale.com/util/dnsname"
)
@@ -73,7 +73,7 @@ func TestDNSOverTCP(t *testing.T) {
c, s := net.Pipe()
defer s.Close()
- go m.HandleTCPConn(s, netaddr.IPPort{})
+ go m.HandleTCPConn(s, netip.AddrPort{})
defer c.Close()
wantResults := map[dnsname.FQDN]string{
diff --git a/net/dns/manager_test.go b/net/dns/manager_test.go
index e940ba288..84fb03d2e 100644
--- a/net/dns/manager_test.go
+++ b/net/dns/manager_test.go
@@ -13,7 +13,6 @@
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"tailscale.com/net/dns/resolver"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsdial"
"tailscale.com/types/dnstype"
"tailscale.com/util/dnsname"
@@ -394,8 +393,8 @@ func TestManager(t *testing.T) {
},
}
- trIP := cmp.Transformer("ipStr", func(ip netaddr.IP) string { return ip.String() })
- trIPPort := cmp.Transformer("ippStr", func(ipp netaddr.IPPort) string {
+ trIP := cmp.Transformer("ipStr", func(ip netip.Addr) string { return ip.String() })
+ trIPPort := cmp.Transformer("ippStr", func(ipp netip.AddrPort) string {
if ipp.Port() == 53 {
return ipp.Addr().String()
}
@@ -424,14 +423,14 @@ func TestManager(t *testing.T) {
}
}
-func mustIPs(strs ...string) (ret []netaddr.IP) {
+func mustIPs(strs ...string) (ret []netip.Addr) {
for _, s := range strs {
ret = append(ret, netip.MustParseAddr(s))
}
return ret
}
-func mustIPPs(strs ...string) (ret []netaddr.IPPort) {
+func mustIPPs(strs ...string) (ret []netip.AddrPort) {
for _, s := range strs {
ret = append(ret, netip.MustParseAddrPort(s))
}
@@ -456,9 +455,9 @@ func fqdns(strs ...string) (ret []dnsname.FQDN) {
return ret
}
-func hosts(strs ...string) (ret map[dnsname.FQDN][]netaddr.IP) {
+func hosts(strs ...string) (ret map[dnsname.FQDN][]netip.Addr) {
var key dnsname.FQDN
- ret = map[dnsname.FQDN][]netaddr.IP{}
+ ret = map[dnsname.FQDN][]netip.Addr{}
for _, s := range strs {
if ip, err := netip.ParseAddr(s); err == nil {
if key == "" {
diff --git a/net/dns/manager_windows.go b/net/dns/manager_windows.go
index 1dbca560b..3414fb000 100644
--- a/net/dns/manager_windows.go
+++ b/net/dns/manager_windows.go
@@ -90,7 +90,7 @@ func delValue(key registry.Key, name string) error {
// system's "primary" resolver.
//
// If no resolvers are provided, the Tailscale NRPT rules are deleted.
-func (m windowsManager) setSplitDNS(resolvers []netaddr.IP, domains []dnsname.FQDN) error {
+func (m windowsManager) setSplitDNS(resolvers []netip.Addr, domains []dnsname.FQDN) error {
if m.nrptDB == nil {
if resolvers == nil {
// Just a no-op in this case.
@@ -118,7 +118,7 @@ func (m windowsManager) setSplitDNS(resolvers []netaddr.IP, domains []dnsname.FQ
// "primary" resolvers.
// domains can be set without resolvers, which just contributes new
// paths to the global DNS search list.
-func (m windowsManager) setPrimaryDNS(resolvers []netaddr.IP, domains []dnsname.FQDN) error {
+func (m windowsManager) setPrimaryDNS(resolvers []netip.Addr, domains []dnsname.FQDN) error {
var ipsv4 []string
var ipsv6 []string
@@ -347,7 +347,7 @@ func (m windowsManager) GetBaseConfig() (OSConfig, error) {
// It's used on Windows 7 to emulate split DNS by trying to figure out
// what the "previous" primary resolver was. It might be wrong, or
// incomplete.
-func (m windowsManager) getBasePrimaryResolver() (resolvers []netaddr.IP, err error) {
+func (m windowsManager) getBasePrimaryResolver() (resolvers []netip.Addr, err error) {
tsGUID, err := windows.GUIDFromString(m.guid)
if err != nil {
return nil, err
@@ -422,7 +422,7 @@ type candidate struct {
return resolvers, nil
}
-var siteLocalResolvers = []netaddr.IP{
+var siteLocalResolvers = []netip.Addr{
netip.MustParseAddr("fec0:0:0:ffff::1"),
netip.MustParseAddr("fec0:0:0:ffff::2"),
netip.MustParseAddr("fec0:0:0:ffff::3"),
diff --git a/net/dns/manager_windows_test.go b/net/dns/manager_windows_test.go
index 44cf0cd36..d8efdbabd 100644
--- a/net/dns/manager_windows_test.go
+++ b/net/dns/manager_windows_test.go
@@ -15,7 +15,6 @@
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
"tailscale.com/util/winutil"
)
@@ -92,7 +91,7 @@ func TestManagerWindowsGPMove(t *testing.T) {
// Upon initialization of cfg, we should not have any NRPT rules
ensureNoRules(t)
- resolvers := []netaddr.IP{netip.MustParseAddr("1.1.1.1")}
+ resolvers := []netip.Addr{netip.MustParseAddr("1.1.1.1")}
domains := genRandomSubdomains(t, 1)
// 1. Populate local NRPT
@@ -216,7 +215,7 @@ func runTest(t *testing.T, isLocal bool) {
// Upon initialization of cfg, we should not have any NRPT rules
ensureNoRules(t)
- resolvers := []netaddr.IP{netip.MustParseAddr("1.1.1.1")}
+ resolvers := []netip.Addr{netip.MustParseAddr("1.1.1.1")}
domains := genRandomSubdomains(t, 2*nrptMaxDomainsPerRule+1)
diff --git a/net/dns/nm.go b/net/dns/nm.go
index b70a4f93f..6a9a90524 100644
--- a/net/dns/nm.go
+++ b/net/dns/nm.go
@@ -16,7 +16,6 @@
"github.com/godbus/dbus/v5"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
"tailscale.com/util/endian"
)
@@ -294,7 +293,7 @@ func (m *nmManager) GetBaseConfig() (OSConfig, error) {
}
type dnsPrio struct {
- resolvers []netaddr.IP
+ resolvers []netip.Addr
domains []string
priority int32
}
@@ -342,7 +341,7 @@ type dnsPrio struct {
var (
ret OSConfig
- seenResolvers = map[netaddr.IP]bool{}
+ seenResolvers = map[netip.Addr]bool{}
seenSearch = map[string]bool{}
)
diff --git a/net/dns/osconfig.go b/net/dns/osconfig.go
index b84ea5d72..94a7f25d3 100644
--- a/net/dns/osconfig.go
+++ b/net/dns/osconfig.go
@@ -6,8 +6,8 @@
import (
"errors"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)
@@ -40,7 +40,7 @@ type OSConfigurator interface {
// OSConfig is an OS DNS configuration.
type OSConfig struct {
// Nameservers are the IP addresses of the nameservers to use.
- Nameservers []netaddr.IP
+ Nameservers []netip.Addr
// SearchDomains are the domain suffixes to use when expanding
// single-label name queries. SearchDomains is additive to
// whatever non-Tailscale search domains the OS has.
diff --git a/net/dns/publicdns/publicdns.go b/net/dns/publicdns/publicdns.go
index 5cf5dac09..76467004a 100644
--- a/net/dns/publicdns/publicdns.go
+++ b/net/dns/publicdns/publicdns.go
@@ -9,31 +9,29 @@
import (
"net/netip"
"sync"
-
- "tailscale.com/net/netaddr"
)
-var knownDoH = map[netaddr.IP]string{} // 8.8.8.8 => "https://..."
-var dohIPsOfBase = map[string][]netaddr.IP{}
+var knownDoH = map[netip.Addr]string{} // 8.8.8.8 => "https://..."
+var dohIPsOfBase = map[string][]netip.Addr{}
var populateOnce sync.Once
// KnownDoH returns a map of well-known public DNS IPs to their DoH URL.
// The returned map should not be modified.
-func KnownDoH() map[netaddr.IP]string {
+func KnownDoH() map[netip.Addr]string {
populateOnce.Do(populate)
return knownDoH
}
// DoHIPsOfBase returns a map of DNS server IP addresses keyed
// by their DoH URL. It is the inverse of KnownDoH.
-func DoHIPsOfBase() map[string][]netaddr.IP {
+func DoHIPsOfBase() map[string][]netip.Addr {
populateOnce.Do(populate)
return dohIPsOfBase
}
// DoHV6 returns the first IPv6 DNS address from a given public DNS provider
// if found, along with a boolean indicating success.
-func DoHV6(base string) (ip netaddr.IP, ok bool) {
+func DoHV6(base string) (ip netip.Addr, ok bool) {
populateOnce.Do(populate)
for _, ip := range dohIPsOfBase[base] {
if ip.Is6() {
@@ -43,7 +41,7 @@ func DoHV6(base string) (ip netaddr.IP, ok bool) {
return ip, false
}
-// addDoH parses a given well-formed ip string into a netaddr.IP type and
+// addDoH parses a given well-formed ip string into a netip.Addr type and
// adds it to both knownDoH and dohIPsOFBase maps.
func addDoH(ipStr, base string) {
ip := netip.MustParseAddr(ipStr)
diff --git a/net/dns/publicdns/publicdns_test.go b/net/dns/publicdns/publicdns_test.go
index 8debe8116..0463b0877 100644
--- a/net/dns/publicdns/publicdns_test.go
+++ b/net/dns/publicdns/publicdns_test.go
@@ -7,8 +7,6 @@
import (
"net/netip"
"testing"
-
- "tailscale.com/net/netaddr"
)
func TestInit(t *testing.T) {
@@ -24,12 +22,12 @@ func TestInit(t *testing.T) {
func TestDohV6(t *testing.T) {
tests := []struct {
in string
- firstIP netaddr.IP
+ firstIP netip.Addr
want bool
}{
{"https://cloudflare-dns.com/dns-query", netip.MustParseAddr("2606:4700:4700::1111"), true},
{"https://dns.google/dns-query", netip.MustParseAddr("2001:4860:4860::8888"), true},
- {"bogus", netaddr.IP{}, false},
+ {"bogus", netip.Addr{}, false},
}
for _, test := range tests {
t.Run(test.in, func(t *testing.T) {
diff --git a/net/dns/resolvconffile/resolvconffile.go b/net/dns/resolvconffile/resolvconffile.go
index d9562a6cb..8ddc71357 100644
--- a/net/dns/resolvconffile/resolvconffile.go
+++ b/net/dns/resolvconffile/resolvconffile.go
@@ -20,7 +20,6 @@
"os"
"strings"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)
@@ -30,7 +29,7 @@
// Config represents a resolv.conf(5) file.
type Config struct {
// Nameservers are the IP addresses of the nameservers to use.
- Nameservers []netaddr.IP
+ Nameservers []netip.Addr
// SearchDomains are the domain suffixes to use when expanding
// single-label name queries. SearchDomains is additive to
diff --git a/net/dns/resolvconffile/resolvconffile_test.go b/net/dns/resolvconffile/resolvconffile_test.go
index b148d9cbd..ed9583a09 100644
--- a/net/dns/resolvconffile/resolvconffile_test.go
+++ b/net/dns/resolvconffile/resolvconffile_test.go
@@ -10,7 +10,6 @@
"strings"
"testing"
- "tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)
@@ -22,21 +21,21 @@ func TestParse(t *testing.T) {
}{
{in: `nameserver 192.168.0.100`,
want: &Config{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
},
{in: `nameserver 192.168.0.100 # comment`,
want: &Config{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
},
{in: `nameserver 192.168.0.100#`,
want: &Config{
- Nameservers: []netaddr.IP{
+ Nameservers: []netip.Addr{
netip.MustParseAddr("192.168.0.100"),
},
},
diff --git a/net/dns/resolver/forwarder.go b/net/dns/resolver/forwarder.go
index 56f7ee579..fc6f5e02e 100644
--- a/net/dns/resolver/forwarder.go
+++ b/net/dns/resolver/forwarder.go
@@ -15,6 +15,7 @@
"math/rand"
"net"
"net/http"
+ "net/netip"
"net/url"
"runtime"
"sort"
@@ -28,7 +29,6 @@
"tailscale.com/hostinfo"
"tailscale.com/net/dns/publicdns"
"tailscale.com/net/dnscache"
- "tailscale.com/net/netaddr"
"tailscale.com/net/neterror"
"tailscale.com/net/netns"
"tailscale.com/net/tsdial"
@@ -367,7 +367,7 @@ func (f *forwarder) setRoutes(routesBySuffix map[dnsname.FQDN][]*dnstype.Resolve
var stdNetPacketListener nettype.PacketListenerWithNetIP = nettype.MakePacketListenerWithNetIP(new(net.ListenConfig))
-func (f *forwarder) packetListener(ip netaddr.IP) (nettype.PacketListenerWithNetIP, error) {
+func (f *forwarder) packetListener(ip netip.Addr) (nettype.PacketListenerWithNetIP, error) {
if f.linkSel == nil || initListenConfig == nil {
return stdNetPacketListener, nil
}
diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go
index 4ba90ae24..f28c3142c 100644
--- a/net/dns/resolver/tsdns.go
+++ b/net/dns/resolver/tsdns.go
@@ -54,7 +54,7 @@
type packet struct {
bs []byte
- addr netaddr.IPPort // src for a request, dst for a response
+ addr netip.AddrPort // src for a request, dst for a response
}
// Config is a resolver configuration.
@@ -70,7 +70,7 @@ type Config struct {
// To register a "default route", add an entry for ".".
Routes map[dnsname.FQDN][]*dnstype.Resolver
// LocalHosts is a map of FQDNs to corresponding IPs.
- Hosts map[dnsname.FQDN][]netaddr.IP
+ Hosts map[dnsname.FQDN][]netip.Addr
// LocalDomains is a list of DNS name suffixes that should not be
// routed to upstream resolvers.
LocalDomains []dnsname.FQDN
@@ -106,7 +106,7 @@ func (c *Config) WriteToBufioWriter(w *bufio.Writer) {
}
// WriteIPPorts writes vv to w.
-func WriteIPPorts(w *bufio.Writer, vv []netaddr.IPPort) {
+func WriteIPPorts(w *bufio.Writer, vv []netip.AddrPort) {
w.WriteByte('[')
var b []byte
for i, v := range vv {
@@ -193,15 +193,15 @@ type Resolver struct {
// mu guards the following fields from being updated while used.
mu sync.Mutex
localDomains []dnsname.FQDN
- hostToIP map[dnsname.FQDN][]netaddr.IP
- ipToHost map[netaddr.IP]dnsname.FQDN
+ hostToIP map[dnsname.FQDN][]netip.Addr
+ ipToHost map[netip.Addr]dnsname.FQDN
}
type ForwardLinkSelector interface {
// PickLink returns which network device should be used to query
// the DNS server at the given IP.
// The empty string means to use an unspecified default.
- PickLink(netaddr.IP) (linkName string)
+ PickLink(netip.Addr) (linkName string)
}
// New returns a new resolver.
@@ -214,8 +214,8 @@ func New(logf logger.Logf, linkMon *monitor.Mon, linkSel ForwardLinkSelector, di
logf: logger.WithPrefix(logf, "resolver: "),
linkMon: linkMon,
closed: make(chan struct{}),
- hostToIP: map[dnsname.FQDN][]netaddr.IP{},
- ipToHost: map[netaddr.IP]dnsname.FQDN{},
+ hostToIP: map[dnsname.FQDN][]netip.Addr{},
+ ipToHost: map[netip.Addr]dnsname.FQDN{},
dialer: dialer,
}
r.forwarder = newForwarder(r.logf, linkMon, linkSel, dialer)
@@ -229,7 +229,7 @@ func (r *Resolver) SetConfig(cfg Config) error {
r.saveConfigForTests(cfg)
}
- reverse := make(map[netaddr.IP]dnsname.FQDN, len(cfg.Hosts))
+ reverse := make(map[netip.Addr]dnsname.FQDN, len(cfg.Hosts))
for host, ips := range cfg.Hosts {
for _, ip := range ips {
@@ -266,7 +266,7 @@ func (r *Resolver) Close() {
// bound on per-query resource usage.
const dnsQueryTimeout = 10 * time.Second
-func (r *Resolver) Query(ctx context.Context, bs []byte, from netaddr.IPPort) ([]byte, error) {
+func (r *Resolver) Query(ctx context.Context, bs []byte, from netip.AddrPort) ([]byte, error) {
metricDNSQueryLocal.Add(1)
select {
case <-r.closed:
@@ -323,7 +323,7 @@ func parseExitNodeQuery(q []byte) *response {
// still result in a response DNS packet (saying there's a failure)
// and a nil error.
// TODO: figure out if we even need an error result.
-func (r *Resolver) HandleExitNodeDNSQuery(ctx context.Context, q []byte, from netaddr.IPPort, allowName func(name string) bool) (res []byte, err error) {
+func (r *Resolver) HandleExitNodeDNSQuery(ctx context.Context, q []byte, from netip.AddrPort, allowName func(name string) bool) (res []byte, err error) {
metricDNSExitProxyQuery.Add(1)
ch := make(chan packet, 1)
@@ -489,7 +489,7 @@ func isGoNoSuchHostError(err error) bool {
type resolvConfCache struct {
mod time.Time
size int64
- ip netaddr.IP
+ ip netip.Addr
// TODO: inode/dev?
}
@@ -501,10 +501,10 @@ type resolvConfCache struct {
// stubResolverForOS returns the IP address of the first nameserver in
// /etc/resolv.conf.
-func stubResolverForOS() (ip netaddr.IP, err error) {
+func stubResolverForOS() (ip netip.Addr, err error) {
fi, err := os.Stat(resolvconffile.Path)
if err != nil {
- return netaddr.IP{}, err
+ return netip.Addr{}, err
}
cur := resolvConfCache{
mod: fi.ModTime(),
@@ -515,10 +515,10 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
}
conf, err := resolvconffile.ParseFile(resolvconffile.Path)
if err != nil {
- return netaddr.IP{}, err
+ return netip.Addr{}, err
}
if len(conf.Nameservers) == 0 {
- return netaddr.IP{}, errEmptyResolvConf
+ return netip.Addr{}, errEmptyResolvConf
}
ip = conf.Nameservers[0]
cur.ip = ip
@@ -531,12 +531,12 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
// typ (A, AAAA, ALL).
// Returns dns.RCodeRefused to indicate that the local map is not
// authoritative for domain.
-func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP, dns.RCode) {
+func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netip.Addr, dns.RCode) {
metricDNSResolveLocal.Add(1)
// Reject .onion domains per RFC 7686.
if dnsname.HasSuffix(domain.WithoutTrailingDot(), ".onion") {
metricDNSResolveLocalErrorOnion.Add(1)
- return netaddr.IP{}, dns.RCodeNameError
+ return netip.Addr{}, dns.RCodeNameError
}
// We return a symbolic domain if someone does a reverse lookup on the
@@ -566,11 +566,11 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
if suffix.Contains(domain) {
// We are authoritative for the queried domain.
metricDNSResolveLocalErrorMissing.Add(1)
- return netaddr.IP{}, dns.RCodeNameError
+ return netip.Addr{}, dns.RCodeNameError
}
}
// Not authoritative, signal that forwarding is advisable.
- return netaddr.IP{}, dns.RCodeRefused
+ return netip.Addr{}, dns.RCodeRefused
}
// Refactoring note: this must happen after we check suffixes,
@@ -588,7 +588,7 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
}
}
metricDNSResolveLocalNoA.Add(1)
- return netaddr.IP{}, dns.RCodeSuccess
+ return netip.Addr{}, dns.RCodeSuccess
case dns.TypeAAAA:
for _, ip := range addrs {
if ip.Is6() {
@@ -597,14 +597,14 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
}
}
metricDNSResolveLocalNoAAAA.Add(1)
- return netaddr.IP{}, dns.RCodeSuccess
+ return netip.Addr{}, dns.RCodeSuccess
case dns.TypeALL:
// Answer with whatever we've got.
// It could be IPv4, IPv6, or a zero addr.
// TODO: Return all available resolutions (A and AAAA, if we have them).
if len(addrs) == 0 {
metricDNSResolveLocalNoAll.Add(1)
- return netaddr.IP{}, dns.RCodeSuccess
+ return netip.Addr{}, dns.RCodeSuccess
}
metricDNSResolveLocalOKAll.Add(1)
return addrs[0], dns.RCodeSuccess
@@ -614,7 +614,7 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
// DNS semantics and might be implemented in the future.
case dns.TypeNS, dns.TypeSOA, dns.TypeAXFR, dns.TypeHINFO:
metricDNSResolveNotImplType.Add(1)
- return netaddr.IP{}, dns.RCodeNotImplemented
+ return netip.Addr{}, dns.RCodeNotImplemented
// For everything except for the few types above that are explicitly not implemented, return no records.
// This is what other DNS systems do: always return NOERROR
@@ -625,7 +625,7 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
default:
metricDNSResolveNoRecordType.Add(1)
// The name exists, but no records exist of the requested type.
- return netaddr.IP{}, dns.RCodeSuccess
+ return netip.Addr{}, dns.RCodeSuccess
}
}
@@ -639,13 +639,13 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
// (2022-06-02) to work around an issue in Chrome where it would treat
// "http://via-1.1.2.3.4" as a search string instead of a URL. We should rip out
// the old format in early 2023.
-func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP, bool) {
+func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netip.Addr, bool) {
fqdn := string(domain.WithoutTrailingDot())
if typ != dns.TypeAAAA {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
if len(fqdn) < len("via-X.0.0.0.0") {
- return netaddr.IP{}, false // too short to be valid
+ return netip.Addr{}, false // too short to be valid
}
var siteID string
@@ -653,18 +653,18 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP
if strings.HasPrefix(fqdn, "via-") {
firstDot := strings.Index(fqdn, ".")
if firstDot < 0 {
- return netaddr.IP{}, false // missing dot delimiters
+ return netip.Addr{}, false // missing dot delimiters
}
siteID = fqdn[len("via-"):firstDot]
ip4Str = fqdn[firstDot+1:]
} else {
lastDot := strings.LastIndex(fqdn, ".")
if lastDot < 0 {
- return netaddr.IP{}, false // missing dot delimiters
+ return netip.Addr{}, false // missing dot delimiters
}
suffix := fqdn[lastDot+1:]
if !strings.HasPrefix(suffix, "via-") {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
siteID = suffix[len("via-"):]
ip4Str = fqdn[:lastDot]
@@ -672,22 +672,22 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP
ip4, err := netip.ParseAddr(ip4Str)
if err != nil {
- return netaddr.IP{}, false // badly formed, dont respond
+ return netip.Addr{}, false // badly formed, dont respond
}
prefix, err := strconv.ParseUint(siteID, 0, 32)
if err != nil {
- return netaddr.IP{}, false // badly formed, dont respond
+ return netip.Addr{}, false // badly formed, dont respond
}
- // MapVia will never error when given an ipv4 netaddr.IPPrefix.
+ // MapVia will never error when given an ipv4 netip.Prefix.
out, _ := tsaddr.MapVia(uint32(prefix), netip.PrefixFrom(ip4, ip4.BitLen()))
return out.Addr(), true
}
// resolveReverse returns the unique domain name that maps to the given address.
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
- var ip netaddr.IP
+ var ip netip.Addr
var ok bool
switch {
case strings.HasSuffix(name.WithTrailingDot(), rdnsv4Suffix):
@@ -717,7 +717,7 @@ func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCo
}
// r.mu must be held.
-func (r *Resolver) fqdnForIPLocked(ip netaddr.IP, name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
+func (r *Resolver) fqdnForIPLocked(ip netip.Addr, name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
// If someone curiously does a reverse lookup on the DNS IP, we
// return a domain that helps indicate that Tailscale is using
// this IP for a special purpose and it is not a node on their
@@ -749,8 +749,8 @@ type response struct {
// IP and IPs are the responses to an A, AAAA, or ALL query.
// Either/both/neither can be populated.
- IP netaddr.IP
- IPs []netaddr.IP
+ IP netip.Addr
+ IPs []netip.Addr
// TXT is the response to a TXT query.
// Each one is its own RR with one string.
@@ -809,7 +809,7 @@ func (p *dnsParser) parseQuery(query []byte) error {
// marshalARecord serializes an A record into an active builder.
// The caller may continue using the builder following the call.
-func marshalARecord(name dns.Name, ip netaddr.IP, builder *dns.Builder) error {
+func marshalARecord(name dns.Name, ip netip.Addr, builder *dns.Builder) error {
var answer dns.AResource
answerHeader := dns.ResourceHeader{
@@ -825,7 +825,7 @@ func marshalARecord(name dns.Name, ip netaddr.IP, builder *dns.Builder) error {
// marshalAAAARecord serializes an AAAA record into an active builder.
// The caller may continue using the builder following the call.
-func marshalAAAARecord(name dns.Name, ip netaddr.IP, builder *dns.Builder) error {
+func marshalAAAARecord(name dns.Name, ip netip.Addr, builder *dns.Builder) error {
var answer dns.AAAAResource
answerHeader := dns.ResourceHeader{
@@ -839,7 +839,7 @@ func marshalAAAARecord(name dns.Name, ip netaddr.IP, builder *dns.Builder) error
return builder.AAAAResource(answerHeader, answer)
}
-func marshalIP(name dns.Name, ip netaddr.IP, builder *dns.Builder) error {
+func marshalIP(name dns.Name, ip netip.Addr, builder *dns.Builder) error {
if ip.Is4() {
return marshalARecord(name, ip, builder)
}
@@ -1066,14 +1066,14 @@ func rawNameToLower(name []byte) string {
// 4.3.2.1.in-addr.arpa
// is transformed to
// 1.2.3.4
-func rdnsNameToIPv4(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
+func rdnsNameToIPv4(name dnsname.FQDN) (ip netip.Addr, ok bool) {
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv4Suffix)
ip, err := netip.ParseAddr(s)
if err != nil {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
if !ip.Is4() {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
b := ip.As4()
return netaddr.IPv4(b[3], b[2], b[1], b[0]), true
@@ -1085,14 +1085,14 @@ func rdnsNameToIPv4(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
// is transformed to
// 2001:db8::567:89ab
-func rdnsNameToIPv6(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
+func rdnsNameToIPv6(name dnsname.FQDN) (ip netip.Addr, ok bool) {
var b [32]byte
var ipb [16]byte
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv6Suffix)
// 32 nibbles and 31 dots between them.
if len(s) != 63 {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
// Dots and hex digits alternate.
@@ -1101,7 +1101,7 @@ func rdnsNameToIPv6(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
for i, j := len(s)-1, 0; i >= 0; i-- {
thisDot := (s[i] == '.')
if prevDot == thisDot {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
prevDot = thisDot
@@ -1115,7 +1115,7 @@ func rdnsNameToIPv6(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
_, err := hex.Decode(ipb[:], b[:])
if err != nil {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
return netaddr.IPFrom16(ipb), true
diff --git a/net/dns/resolver/tsdns_server_test.go b/net/dns/resolver/tsdns_server_test.go
index ab0f6c2b0..72860b280 100644
--- a/net/dns/resolver/tsdns_server_test.go
+++ b/net/dns/resolver/tsdns_server_test.go
@@ -7,11 +7,11 @@
import (
"fmt"
"net"
+ "net/netip"
"strings"
"testing"
"github.com/miekg/dns"
- "tailscale.com/net/netaddr"
)
// This file exists to isolate the test infrastructure
@@ -22,7 +22,7 @@
// to queries of type A it receives with an A record containing ipv4,
// to queries of type AAAA with an AAAA record containing ipv6,
// to queries of type NS with an NS record containing name.
-func resolveToIP(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
+func resolveToIP(ipv4, ipv6 netip.Addr, ns string) dns.HandlerFunc {
return func(w dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
m.SetReply(req)
@@ -73,7 +73,7 @@ func resolveToIP(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
// to queries of type A it receives with an A record containing ipv4,
// to queries of type AAAA with an AAAA record containing ipv6,
// to queries of type NS with an NS record containing name.
-func resolveToIPLowercase(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
+func resolveToIPLowercase(ipv4, ipv6 netip.Addr, ns string) dns.HandlerFunc {
return func(w dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
m.SetReply(req)
@@ -220,7 +220,7 @@ func weirdoGoCNAMEHandler(target string) dns.HandlerFunc {
// dnsHandler returns a handler that replies with the answers/options
// provided.
//
-// Types supported: netaddr.IP.
+// Types supported: netip.Addr.
func dnsHandler(answers ...any) dns.HandlerFunc {
return func(w dns.ResponseWriter, req *dns.Msg) {
m := new(dns.Msg)
@@ -235,7 +235,7 @@ func dnsHandler(answers ...any) dns.HandlerFunc {
switch a := a.(type) {
default:
panic(fmt.Sprintf("unsupported dnsHandler arg %T", a))
- case netaddr.IP:
+ case netip.Addr:
ip := a
if ip.Is4() {
m.Answer = append(m.Answer, &dns.A{
diff --git a/net/dns/resolver/tsdns_test.go b/net/dns/resolver/tsdns_test.go
index ef73833be..774de0a2a 100644
--- a/net/dns/resolver/tsdns_test.go
+++ b/net/dns/resolver/tsdns_test.go
@@ -43,7 +43,7 @@
)
var dnsCfg = Config{
- Hosts: map[dnsname.FQDN][]netaddr.IP{
+ Hosts: map[dnsname.FQDN][]netip.Addr{
"test1.ipn.dev.": {testipv4},
"test2.ipn.dev.": {testipv6},
},
@@ -92,7 +92,7 @@ func dnspacket(domain dnsname.FQDN, tp dns.Type, ednsSize uint16) []byte {
}
type dnsResponse struct {
- ip netaddr.IP
+ ip netip.Addr
txt []string
name dnsname.FQDN
rcode dns.RCode
@@ -157,7 +157,7 @@ func unpackResponse(payload []byte) (dnsResponse, error) {
if err != nil {
return response, err
}
- response.ip = netaddr.IPv6Raw(res.AAAA)
+ response.ip = netip.AddrFrom16(res.AAAA)
case dns.TypeTXT:
res, err := parser.TXTResource()
if err != nil {
@@ -234,10 +234,10 @@ func unpackResponse(payload []byte) (dnsResponse, error) {
}
func syncRespond(r *Resolver, query []byte) ([]byte, error) {
- return r.Query(context.Background(), query, netaddr.IPPort{})
+ return r.Query(context.Background(), query, netip.AddrPort{})
}
-func mustIP(str string) netaddr.IP {
+func mustIP(str string) netip.Addr {
ip, err := netip.ParseAddr(str)
if err != nil {
panic(err)
@@ -249,13 +249,13 @@ func TestRDNSNameToIPv4(t *testing.T) {
tests := []struct {
name string
input dnsname.FQDN
- wantIP netaddr.IP
+ wantIP netip.Addr
wantOK bool
}{
{"valid", "4.123.24.1.in-addr.arpa.", netaddr.IPv4(1, 24, 123, 4), true},
- {"double_dot", "1..2.3.in-addr.arpa.", netaddr.IP{}, false},
- {"overflow", "1.256.3.4.in-addr.arpa.", netaddr.IP{}, false},
- {"not_ip", "sub.do.ma.in.in-addr.arpa.", netaddr.IP{}, false},
+ {"double_dot", "1..2.3.in-addr.arpa.", netip.Addr{}, false},
+ {"overflow", "1.256.3.4.in-addr.arpa.", netip.Addr{}, false},
+ {"not_ip", "sub.do.ma.in.in-addr.arpa.", netip.Addr{}, false},
}
for _, tt := range tests {
@@ -274,7 +274,7 @@ func TestRDNSNameToIPv6(t *testing.T) {
tests := []struct {
name string
input dnsname.FQDN
- wantIP netaddr.IP
+ wantIP netip.Addr
wantOK bool
}{
{
@@ -286,19 +286,19 @@ func TestRDNSNameToIPv6(t *testing.T) {
{
"double_dot",
"b..9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
- netaddr.IP{},
+ netip.Addr{},
false,
},
{
"double_hex",
"b.a.98.0.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
- netaddr.IP{},
+ netip.Addr{},
false,
},
{
"not_hex",
"b.a.g.0.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
- netaddr.IP{},
+ netip.Addr{},
false,
},
}
@@ -329,27 +329,27 @@ func TestResolveLocal(t *testing.T) {
name string
qname dnsname.FQDN
qtype dns.Type
- ip netaddr.IP
+ ip netip.Addr
code dns.RCode
}{
{"ipv4", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
{"ipv6", "test2.ipn.dev.", dns.TypeAAAA, testipv6, dns.RCodeSuccess},
- {"no-ipv6", "test1.ipn.dev.", dns.TypeAAAA, netaddr.IP{}, dns.RCodeSuccess},
- {"nxdomain", "test3.ipn.dev.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
- {"foreign domain", "google.com.", dns.TypeA, netaddr.IP{}, dns.RCodeRefused},
+ {"no-ipv6", "test1.ipn.dev.", dns.TypeAAAA, netip.Addr{}, dns.RCodeSuccess},
+ {"nxdomain", "test3.ipn.dev.", dns.TypeA, netip.Addr{}, dns.RCodeNameError},
+ {"foreign domain", "google.com.", dns.TypeA, netip.Addr{}, dns.RCodeRefused},
{"all", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
- {"mx-ipv4", "test1.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeSuccess},
- {"mx-ipv6", "test2.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeSuccess},
- {"mx-nxdomain", "test3.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeNameError},
- {"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netaddr.IP{}, dns.RCodeNameError},
- {"onion-domain", "footest.onion.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
+ {"mx-ipv4", "test1.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeSuccess},
+ {"mx-ipv6", "test2.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeSuccess},
+ {"mx-nxdomain", "test3.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeNameError},
+ {"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netip.Addr{}, dns.RCodeNameError},
+ {"onion-domain", "footest.onion.", dns.TypeA, netip.Addr{}, dns.RCodeNameError},
{"magicdns", dnsSymbolicFQDN, dns.TypeA, netip.MustParseAddr("100.100.100.100"), dns.RCodeSuccess},
{"via_hex", dnsname.FQDN("via-0xff.1.2.3.4."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:ff:1.2.3.4"), dns.RCodeSuccess},
{"via_dec", dnsname.FQDN("via-1.10.0.0.1."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:10.0.0.1"), dns.RCodeSuccess},
{"x_via_hex", dnsname.FQDN("4.3.2.1.via-0xff."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:ff:4.3.2.1"), dns.RCodeSuccess},
{"x_via_dec", dnsname.FQDN("1.0.0.10.via-1."), dns.TypeAAAA, netip.MustParseAddr("fd7a:115c:a1e0:b1a:0:1:1.0.0.10"), dns.RCodeSuccess},
- {"via_invalid", dnsname.FQDN("via-."), dns.TypeAAAA, netaddr.IP{}, dns.RCodeRefused},
- {"via_invalid_2", dnsname.FQDN("2.3.4.5.via-."), dns.TypeAAAA, netaddr.IP{}, dns.RCodeRefused},
+ {"via_invalid", dnsname.FQDN("via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
+ {"via_invalid_2", dnsname.FQDN("2.3.4.5.via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
}
for _, tt := range tests {
@@ -1003,7 +1003,7 @@ func TestForwardLinkSelection(t *testing.T) {
// routes differently.
specialIP := netaddr.IPv4(1, 2, 3, 4)
- fwd := newForwarder(t.Logf, nil, linkSelFunc(func(ip netaddr.IP) string {
+ fwd := newForwarder(t.Logf, nil, linkSelFunc(func(ip netip.Addr) string {
if ip == netaddr.IPv4(1, 2, 3, 4) {
return "special"
}
@@ -1011,7 +1011,7 @@ func TestForwardLinkSelection(t *testing.T) {
}), new(tsdial.Dialer))
// Test non-special IP.
- if got, err := fwd.packetListener(netaddr.IP{}); err != nil {
+ if got, err := fwd.packetListener(netip.Addr{}); err != nil {
t.Fatal(err)
} else if got != stdNetPacketListener {
t.Errorf("for IP zero value, didn't get expected packet listener")
@@ -1035,9 +1035,9 @@ func TestForwardLinkSelection(t *testing.T) {
}
}
-type linkSelFunc func(ip netaddr.IP) string
+type linkSelFunc func(ip netip.Addr) string
-func (f linkSelFunc) PickLink(ip netaddr.IP) string { return f(ip) }
+func (f linkSelFunc) PickLink(ip netip.Addr) string { return f(ip) }
func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
if runtime.GOOS == "windows" {
diff --git a/net/dnscache/dnscache.go b/net/dnscache/dnscache.go
index 18031af3b..875361a22 100644
--- a/net/dnscache/dnscache.go
+++ b/net/dnscache/dnscache.go
@@ -15,6 +15,7 @@
"fmt"
"log"
"net"
+ "net/netip"
"runtime"
"sync"
"time"
@@ -62,7 +63,7 @@ type Resolver struct {
// LookupIPFallback optionally provides a backup DNS mechanism
// to use if Forward returns an error or no results.
- LookupIPFallback func(ctx context.Context, host string) ([]netaddr.IP, error)
+ LookupIPFallback func(ctx context.Context, host string) ([]netip.Addr, error)
// TTL is how long to keep entries cached
//
@@ -76,7 +77,7 @@ type Resolver struct {
// SingleHostStaticResult, if non-nil, is the static result of IPs that is returned
// by Resolver.LookupIP for any hostname. When non-nil, SingleHost must also be
// set with the expected name.
- SingleHostStaticResult []netaddr.IP
+ SingleHostStaticResult []netip.Addr
// SingleHost is the hostname that SingleHostStaticResult is for.
// It is required when SingleHostStaticResult is present.
@@ -271,7 +272,7 @@ func (r *Resolver) lookupIP(host string) (ip, ip6 net.IP, allIPs []net.IPAddr, e
if (err != nil || len(ips) == 0) && r.LookupIPFallback != nil {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
- var fips []netaddr.IP
+ var fips []netip.Addr
fips, err = r.LookupIPFallback(ctx, host)
if err == nil {
ips = nil
@@ -344,7 +345,7 @@ func Dialer(fwd DialContextFunc, dnsCache *Resolver) DialContextFunc {
d := &dialer{
fwd: fwd,
dnsCache: dnsCache,
- pastConnect: map[netaddr.IP]time.Time{},
+ pastConnect: map[netip.Addr]time.Time{},
}
return d.DialContext
}
@@ -355,7 +356,7 @@ type dialer struct {
dnsCache *Resolver
mu sync.Mutex
- pastConnect map[netaddr.IP]time.Time
+ pastConnect map[netip.Addr]time.Time
}
func (d *dialer) DialContext(ctx context.Context, network, address string) (retConn net.Conn, ret error) {
@@ -426,7 +427,7 @@ type dialCall struct {
network, address, host, port string
mu sync.Mutex // lock ordering: dialer.mu, then dialCall.mu
- fails map[netaddr.IP]error // set of IPs that failed to dial thus far
+ fails map[netip.Addr]error // set of IPs that failed to dial thus far
}
// dnsWasTrustworthy reports whether we think the IP address(es) we
@@ -453,7 +454,7 @@ func (dc *dialCall) dnsWasTrustworthy() bool {
return false
}
-func (dc *dialCall) dialOne(ctx context.Context, ip netaddr.IP) (net.Conn, error) {
+func (dc *dialCall) dialOne(ctx context.Context, ip netip.Addr) (net.Conn, error) {
c, err := dc.d.fwd(ctx, dc.network, net.JoinHostPort(ip.String(), dc.port))
dc.noteDialResult(ip, err)
return c, err
@@ -461,7 +462,7 @@ func (dc *dialCall) dialOne(ctx context.Context, ip netaddr.IP) (net.Conn, error
// noteDialResult records that a dial to ip either succeeded or
// failed.
-func (dc *dialCall) noteDialResult(ip netaddr.IP, err error) {
+func (dc *dialCall) noteDialResult(ip netip.Addr, err error) {
if err == nil {
d := dc.d
d.mu.Lock()
@@ -472,17 +473,17 @@ func (dc *dialCall) noteDialResult(ip netaddr.IP, err error) {
dc.mu.Lock()
defer dc.mu.Unlock()
if dc.fails == nil {
- dc.fails = map[netaddr.IP]error{}
+ dc.fails = map[netip.Addr]error{}
}
dc.fails[ip] = err
}
// uniqueIPs returns a possibly-mutated subslice of ips, filtering out
// dups and ones that have already failed previously.
-func (dc *dialCall) uniqueIPs(ips []netaddr.IP) (ret []netaddr.IP) {
+func (dc *dialCall) uniqueIPs(ips []netip.Addr) (ret []netip.Addr) {
dc.mu.Lock()
defer dc.mu.Unlock()
- seen := map[netaddr.IP]bool{}
+ seen := map[netip.Addr]bool{}
ret = ips[:0]
for _, ip := range ips {
if seen[ip] {
@@ -504,7 +505,7 @@ func (dc *dialCall) uniqueIPs(ips []netaddr.IP) (ret []netaddr.IP) {
// raceDial tries to dial port on each ip in ips, starting a new race
// dial every fallbackDelay apart, returning whichever completes first.
-func (dc *dialCall) raceDial(ctx context.Context, ips []netaddr.IP) (net.Conn, error) {
+func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@@ -536,7 +537,7 @@ type res struct {
return
}
}
- go func(ip netaddr.IP) {
+ go func(ip netip.Addr) {
c, err := dc.dialOne(ctx, ip)
if err != nil {
// Best effort wake-up a pending dial.
@@ -580,7 +581,7 @@ type res struct {
}
}
-func v4addrs(aa []net.IPAddr) (ret []netaddr.IP) {
+func v4addrs(aa []net.IPAddr) (ret []netip.Addr) {
for _, a := range aa {
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is4() {
ret = append(ret, ip)
@@ -589,7 +590,7 @@ func v4addrs(aa []net.IPAddr) (ret []netaddr.IP) {
return ret
}
-func v6addrs(aa []net.IPAddr) (ret []netaddr.IP) {
+func v6addrs(aa []net.IPAddr) (ret []netip.Addr) {
for _, a := range aa {
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is6() {
ret = append(ret, ip)
diff --git a/net/dnscache/dnscache_test.go b/net/dnscache/dnscache_test.go
index 4e1451214..29fcd8e39 100644
--- a/net/dnscache/dnscache_test.go
+++ b/net/dnscache/dnscache_test.go
@@ -14,8 +14,6 @@
"reflect"
"testing"
"time"
-
- "tailscale.com/net/netaddr"
)
var dialTest = flag.String("dial-test", "", "if non-empty, addr:port to test dial")
@@ -40,7 +38,7 @@ func TestDialer(t *testing.T) {
func TestDialCall_DNSWasTrustworthy(t *testing.T) {
type step struct {
- ip netaddr.IP // IP we pretended to dial
+ ip netip.Addr // IP we pretended to dial
err error // the dial error or nil for success
}
mustIP := netip.MustParseAddr
@@ -73,7 +71,7 @@ type step struct {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := &dialer{
- pastConnect: map[netaddr.IP]time.Time{},
+ pastConnect: map[netip.Addr]time.Time{},
}
dc := &dialCall{
d: d,
@@ -95,7 +93,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
errFail := errors.New("some connect failure")
dc.noteDialResult(mustIP("2003::1"), errFail)
dc.noteDialResult(mustIP("2003::2"), errFail)
- got := dc.uniqueIPs([]netaddr.IP{
+ got := dc.uniqueIPs([]netip.Addr{
mustIP("2003::1"),
mustIP("2003::2"),
mustIP("2003::2"),
@@ -104,7 +102,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
mustIP("2003::4"),
mustIP("2003::4"),
})
- want := []netaddr.IP{
+ want := []netip.Addr{
mustIP("2003::3"),
mustIP("2003::4"),
}
@@ -116,7 +114,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
func TestResolverAllHostStaticResult(t *testing.T) {
r := &Resolver{
SingleHost: "foo.bar",
- SingleHostStaticResult: []netaddr.IP{
+ SingleHostStaticResult: []netip.Addr{
netip.MustParseAddr("2001:4860:4860::8888"),
netip.MustParseAddr("2001:4860:4860::8844"),
netip.MustParseAddr("8.8.8.8"),
diff --git a/net/dnsfallback/dnsfallback.go b/net/dnsfallback/dnsfallback.go
index 1cf698403..80bc1fcf1 100644
--- a/net/dnsfallback/dnsfallback.go
+++ b/net/dnsfallback/dnsfallback.go
@@ -22,21 +22,20 @@
"net/url"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
"tailscale.com/net/tlsdial"
"tailscale.com/net/tshttpproxy"
"tailscale.com/tailcfg"
)
-func Lookup(ctx context.Context, host string) ([]netaddr.IP, error) {
+func Lookup(ctx context.Context, host string) ([]netip.Addr, error) {
if ip, err := netip.ParseAddr(host); err == nil && ip.IsValid() {
- return []netaddr.IP{ip}, nil
+ return []netip.Addr{ip}, nil
}
type nameIP struct {
dnsName string
- ip netaddr.IP
+ ip netip.Addr
}
dm := getDERPMap()
@@ -94,7 +93,7 @@ type nameIP struct {
// serverName and serverIP of are, say, "derpN.tailscale.com".
// queryName is the name being sought (e.g. "controlplane.tailscale.com"), passed as hint.
-func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netaddr.IP, queryName string) (dnsMap, error) {
+func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netip.Addr, queryName string) (dnsMap, error) {
dialer := netns.NewDialer(log.Printf)
tr := http.DefaultTransport.(*http.Transport).Clone()
tr.Proxy = tshttpproxy.ProxyFromEnvironment
@@ -124,7 +123,7 @@ func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netaddr.IP
// dnsMap is the JSON type returned by the DERP /bootstrap-dns handler:
// https://derp10.tailscale.com/bootstrap-dns
-type dnsMap map[string][]netaddr.IP
+type dnsMap map[string][]netip.Addr
// getDERPMap returns some DERP map. The DERP servers also run a fallback
// DNS server.
diff --git a/net/flowtrack/flowtrack.go b/net/flowtrack/flowtrack.go
index 61cde8738..9fcf62618 100644
--- a/net/flowtrack/flowtrack.go
+++ b/net/flowtrack/flowtrack.go
@@ -13,16 +13,16 @@
import (
"container/list"
"fmt"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)
// Tuple is a 5-tuple of proto, source and destination IP and port.
type Tuple struct {
Proto ipproto.Proto
- Src netaddr.IPPort
- Dst netaddr.IPPort
+ Src netip.AddrPort
+ Dst netip.AddrPort
}
func (t Tuple) String() string {
diff --git a/net/interfaces/interfaces.go b/net/interfaces/interfaces.go
index 6a93054c4..bc1d138e6 100644
--- a/net/interfaces/interfaces.go
+++ b/net/interfaces/interfaces.go
@@ -28,7 +28,7 @@
// Tailscale returns the current machine's Tailscale 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() ([]netaddr.IP, *net.Interface, error) {
+func Tailscale() ([]netip.Addr, *net.Interface, error) {
ifs, err := netInterfaces()
if err != nil {
return nil, nil, err
@@ -41,7 +41,7 @@ func Tailscale() ([]netaddr.IP, *net.Interface, error) {
if err != nil {
continue
}
- var tsIPs []netaddr.IP
+ var tsIPs []netip.Addr
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok {
nip, ok := netaddr.FromStdIP(ipnet.IP)
@@ -86,13 +86,13 @@ func isProblematicInterface(nif *net.Interface) bool {
// whether they're loopback addresses. If there are no regular addresses
// it will return any IPv4 linklocal or IPv6 unique local addresses because we
// know of environments where these are used with NAT to provide connectivity.
-func LocalAddresses() (regular, loopback []netaddr.IP, err error) {
+func LocalAddresses() (regular, loopback []netip.Addr, err error) {
// TODO(crawshaw): don't serve interface addresses that we are routing
ifaces, err := netInterfaces()
if err != nil {
return nil, nil, err
}
- var regular4, regular6, linklocal4, ula6 []netaddr.IP
+ var regular4, regular6, linklocal4, ula6 []netip.Addr
for _, iface := range ifaces {
stdIf := iface.Interface
if !isUp(stdIf) || isProblematicInterface(stdIf) {
@@ -165,7 +165,7 @@ func LocalAddresses() (regular, loopback []netaddr.IP, err error) {
return regular, loopback, nil
}
-func sortIPs(s []netaddr.IP) {
+func sortIPs(s []netip.Addr) {
sort.Slice(s, func(i, j int) bool { return s[i].Less(s[j]) })
}
@@ -187,7 +187,7 @@ func (i Interface) Addrs() ([]net.Addr, error) {
// ForeachInterfaceAddress is a wrapper for GetList, then
// List.ForeachInterfaceAddress.
-func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
+func ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
ifaces, err := GetList()
if err != nil {
return err
@@ -198,7 +198,7 @@ func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
// ForeachInterfaceAddress calls fn for each interface in ifaces, with
// all its addresses. The IPPrefix's IP is the IP address assigned to
// the interface, and Bits are the subnet mask.
-func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
+func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
@@ -218,7 +218,7 @@ func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix))
// ForeachInterface is a wrapper for GetList, then
// List.ForeachInterface.
-func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
+func ForeachInterface(fn func(Interface, []netip.Prefix)) error {
ifaces, err := GetList()
if err != nil {
return err
@@ -229,7 +229,7 @@ func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
// ForeachInterface calls fn for each interface in ifaces, with
// all its addresses. The IPPrefix's IP is the IP address assigned to
// the interface, and Bits are the subnet mask.
-func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
+func (ifaces List) ForeachInterface(fn func(Interface, []netip.Prefix)) error {
ifaces, err := GetList()
if err != nil {
return err
@@ -239,7 +239,7 @@ func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) erro
if err != nil {
return err
}
- var pfxs []netaddr.IPPrefix
+ var pfxs []netip.Prefix
for _, a := range addrs {
switch v := a.(type) {
case *net.IPNet:
@@ -264,7 +264,7 @@ type State struct {
// configured on that interface. Each address is represented as an
// IPPrefix, where the IP is the interface IP address and Bits is
// the subnet mask.
- InterfaceIPs map[string][]netaddr.IPPrefix
+ InterfaceIPs map[string][]netip.Prefix
Interface map[string]Interface
// HaveV6 is whether this machine has an IPv6 Global or Unique Local Address
@@ -358,11 +358,11 @@ func (s *State) String() string {
// An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal.
// ips are all the IPPrefixes associated with i.
-type InterfaceFilter func(i Interface, ips []netaddr.IPPrefix) bool
+type InterfaceFilter func(i Interface, ips []netip.Prefix) bool
// An IPFilter indicates whether EqualFiltered should use ip when deciding whether two States are equal.
// ip is an ip address associated with some interface under consideration.
-type IPFilter func(ip netaddr.IP) bool
+type IPFilter func(ip netip.Addr) bool
// EqualFiltered reports whether s and s2 are equal,
// considering only interfaces in s for which filter returns true,
@@ -410,9 +410,9 @@ func interfacesEqual(a, b Interface) bool {
bytes.Equal([]byte(a.HardwareAddr), []byte(b.HardwareAddr))
}
-func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
+func filteredIPPs(ipps []netip.Prefix, useIP IPFilter) []netip.Prefix {
// TODO: rewrite prefixesEqualFiltered to avoid making copies
- x := make([]netaddr.IPPrefix, 0, len(ipps))
+ x := make([]netip.Prefix, 0, len(ipps))
for _, ipp := range ipps {
if useIP(ipp.Addr()) {
x = append(x, ipp)
@@ -421,11 +421,11 @@ func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
return x
}
-func prefixesEqualFiltered(a, b []netaddr.IPPrefix, useIP IPFilter) bool {
+func prefixesEqualFiltered(a, b []netip.Prefix, useIP IPFilter) bool {
return prefixesEqual(filteredIPPs(a, useIP), filteredIPPs(b, useIP))
}
-func prefixesEqual(a, b []netaddr.IPPrefix) bool {
+func prefixesEqual(a, b []netip.Prefix) bool {
if len(a) != len(b) {
return false
}
@@ -440,21 +440,21 @@ func prefixesEqual(a, b []netaddr.IPPrefix) bool {
// UseInterestingInterfaces is an InterfaceFilter that reports whether i is an interesting interface.
// An interesting interface if it is (a) not owned by Tailscale and (b) routes interesting IP addresses.
// See UseInterestingIPs for the defition of an interesting IP address.
-func UseInterestingInterfaces(i Interface, ips []netaddr.IPPrefix) bool {
+func UseInterestingInterfaces(i Interface, ips []netip.Prefix) bool {
return !isTailscaleInterface(i.Name, ips) && anyInterestingIP(ips)
}
// UseInterestingIPs is an IPFilter that reports whether ip is an interesting IP address.
// An IP address is interesting if it is neither a lopback not a link local unicast IP address.
-func UseInterestingIPs(ip netaddr.IP) bool {
+func UseInterestingIPs(ip netip.Addr) bool {
return isInterestingIP(ip)
}
// UseAllInterfaces is an InterfaceFilter that includes all interfaces.
-func UseAllInterfaces(i Interface, ips []netaddr.IPPrefix) bool { return true }
+func UseAllInterfaces(i Interface, ips []netip.Prefix) bool { return true }
// UseAllIPs is an IPFilter that includes all all IPs.
-func UseAllIPs(ips netaddr.IP) bool { return true }
+func UseAllIPs(ips netip.Addr) bool { return true }
func (s *State) HasPAC() bool { return s != nil && s.PAC != "" }
@@ -466,7 +466,7 @@ func (s *State) AnyInterfaceUp() bool {
return s != nil && (s.HaveV4 || s.HaveV6)
}
-func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
+func hasTailscaleIP(pfxs []netip.Prefix) bool {
for _, pfx := range pfxs {
if tsaddr.IsTailscaleIP(pfx.Addr()) {
return true
@@ -475,7 +475,7 @@ func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
return false
}
-func isTailscaleInterface(name string, ips []netaddr.IPPrefix) bool {
+func isTailscaleInterface(name string, ips []netip.Prefix) bool {
if runtime.GOOS == "darwin" && strings.HasPrefix(name, "utun") && hasTailscaleIP(ips) {
// On macOS in the sandboxed app (at least as of
// 2021-02-25), we often see two utun devices
@@ -497,10 +497,10 @@ func isTailscaleInterface(name string, ips []netaddr.IPPrefix) bool {
// It does not set the returned State.IsExpensive. The caller can populate that.
func GetState() (*State, error) {
s := &State{
- InterfaceIPs: make(map[string][]netaddr.IPPrefix),
+ InterfaceIPs: make(map[string][]netip.Prefix),
Interface: make(map[string]Interface),
}
- if err := ForeachInterface(func(ni Interface, pfxs []netaddr.IPPrefix) {
+ if err := ForeachInterface(func(ni Interface, pfxs []netip.Prefix) {
ifUp := ni.IsUp()
s.Interface[ni.Name] = ni
s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...)
@@ -556,7 +556,7 @@ func HTTPOfListener(ln net.Listener) string {
var goodIP string
var privateIP string
- ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
+ ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
ip := pfx.Addr()
if ip.IsPrivate() {
if privateIP == "" {
@@ -576,14 +576,14 @@ func HTTPOfListener(ln net.Listener) string {
}
-var likelyHomeRouterIP func() (netaddr.IP, bool)
+var likelyHomeRouterIP func() (netip.Addr, bool)
// LikelyHomeRouterIP returns the likely IP of the residential router,
// which will always be an IPv4 private address, if found.
// In addition, it returns the IP address of the current machine on
// the LAN using that gateway.
// This is used as the destination for UPnP, NAT-PMP, PCP, etc queries.
-func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
+func LikelyHomeRouterIP() (gateway, myIP netip.Addr, ok bool) {
if likelyHomeRouterIP != nil {
gateway, ok = likelyHomeRouterIP()
if !ok {
@@ -593,7 +593,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
if !ok {
return
}
- ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
+ ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
ip := pfx.Addr()
if !i.IsUp() || !ip.IsValid() || myIP.IsValid() {
return
@@ -611,7 +611,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
// conceivably be used to get Internet connectivity. Globally routable and
// private IPv4 addresses are always Usable, and link local 169.254.x.x
// addresses are in some environments.
-func isUsableV4(ip netaddr.IP) bool {
+func isUsableV4(ip netip.Addr) bool {
if !ip.Is4() || ip.IsLoopback() {
return false
}
@@ -625,7 +625,7 @@ func isUsableV4(ip netaddr.IP) bool {
// conceivably be used to get Internet connectivity. Globally routable
// IPv6 addresses are always Usable, and Unique Local Addresses
// (fc00::/7) are in some environments used with address translation.
-func isUsableV6(ip netaddr.IP) bool {
+func isUsableV6(ip netip.Addr) bool {
return v6Global1.Contains(ip) ||
(ip.Is6() && ip.IsPrivate() && !tsaddr.TailscaleULARange().Contains(ip))
}
@@ -636,7 +636,7 @@ func isUsableV6(ip netaddr.IP) bool {
// anyInterestingIP reports whether pfxs contains any IP that matches
// isInterestingIP.
-func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
+func anyInterestingIP(pfxs []netip.Prefix) bool {
for _, pfx := range pfxs {
if isInterestingIP(pfx.Addr()) {
return true
@@ -648,7 +648,7 @@ func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
// isInterestingIP reports whether ip is an interesting IP that we
// should log in interfaces.State logging. We don't need to show
// localhost or link-local addresses.
-func isInterestingIP(ip netaddr.IP) bool {
+func isInterestingIP(ip netip.Addr) bool {
return !ip.IsLoopback() && !ip.IsLinkLocalUnicast()
}
@@ -727,7 +727,7 @@ func DefaultRoute() (DefaultRouteDetails, error) {
func HasCGNATInterface() (bool, error) {
hasCGNATInterface := false
cgnatRange := tsaddr.CGNATRange()
- err := ForeachInterface(func(i Interface, pfxs []netaddr.IPPrefix) {
+ err := ForeachInterface(func(i Interface, pfxs []netip.Prefix) {
if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
return
}
diff --git a/net/interfaces/interfaces_bsd.go b/net/interfaces/interfaces_bsd.go
index 5e35ffbe9..60bba1d95 100644
--- a/net/interfaces/interfaces_bsd.go
+++ b/net/interfaces/interfaces_bsd.go
@@ -15,6 +15,7 @@
"fmt"
"log"
"net"
+ "net/netip"
"syscall"
"golang.org/x/net/route"
@@ -95,7 +96,7 @@ func init() {
likelyHomeRouterIP = likelyHomeRouterIPBSDFetchRIB
}
-func likelyHomeRouterIPBSDFetchRIB() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPBSDFetchRIB() (ret netip.Addr, ok bool) {
rib, err := fetchRoutingTable()
if err != nil {
log.Printf("routerIP/FetchRIB: %v", err)
diff --git a/net/interfaces/interfaces_darwin.go b/net/interfaces/interfaces_darwin.go
index 5453e9e6a..60335bf80 100644
--- a/net/interfaces/interfaces_darwin.go
+++ b/net/interfaces/interfaces_darwin.go
@@ -9,6 +9,7 @@
"fmt"
"log"
"net"
+ "net/netip"
"syscall"
"golang.org/x/net/route"
@@ -89,7 +90,7 @@ func init() {
likelyHomeRouterIP = likelyHomeRouterIPDarwinFetchRIB
}
-func likelyHomeRouterIPDarwinFetchRIB() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPDarwinFetchRIB() (ret netip.Addr, ok bool) {
rib, err := fetchRoutingTable()
if err != nil {
log.Printf("routerIP/FetchRIB: %v", err)
diff --git a/net/interfaces/interfaces_darwin_test.go b/net/interfaces/interfaces_darwin_test.go
index 36ceb890e..0ee238caf 100644
--- a/net/interfaces/interfaces_darwin_test.go
+++ b/net/interfaces/interfaces_darwin_test.go
@@ -11,7 +11,6 @@
"testing"
"go4.org/mem"
- "tailscale.com/net/netaddr"
"tailscale.com/util/lineread"
"tailscale.com/version"
)
@@ -42,7 +41,7 @@ func TestLikelyHomeRouterIPSyscallExec(t *testing.T) {
...
*/
-func likelyHomeRouterIPDarwinExec() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPDarwinExec() (ret netip.Addr, ok bool) {
if version.IsMobile() {
// Don't try to do subprocesses on iOS. Ends up with log spam like:
// kernel: "Sandbox: IPNExtension(86580) deny(1) process-fork"
diff --git a/net/interfaces/interfaces_linux.go b/net/interfaces/interfaces_linux.go
index e829eab8f..73c5ff22e 100644
--- a/net/interfaces/interfaces_linux.go
+++ b/net/interfaces/interfaces_linux.go
@@ -46,7 +46,7 @@ func init() {
ens18 00000000 0100000A 0003 0 0 0 00000000 0 0 0
ens18 0000000A 00000000 0001 0 0 0 0000FFFF 0 0 0
*/
-func likelyHomeRouterIPLinux() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPLinux() (ret netip.Addr, ok bool) {
if procNetRouteErr.Get() {
// If we failed to read /proc/net/route previously, don't keep trying.
// But if we're on Android, go into the Android path.
@@ -104,7 +104,7 @@ func likelyHomeRouterIPLinux() (ret netaddr.IP, ok bool) {
// Android apps don't have permission to read /proc/net/route, at
// least on Google devices and the Android emulator.
-func likelyHomeRouterIPAndroid() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPAndroid() (ret netip.Addr, ok bool) {
cmd := exec.Command("/system/bin/ip", "route", "show", "table", "0")
out, err := cmd.StdoutPipe()
if err != nil {
diff --git a/net/interfaces/interfaces_test.go b/net/interfaces/interfaces_test.go
index 9f7898ec3..7c1c135e6 100644
--- a/net/interfaces/interfaces_test.go
+++ b/net/interfaces/interfaces_test.go
@@ -9,8 +9,6 @@
"net"
"net/netip"
"testing"
-
- "tailscale.com/net/netaddr"
)
func TestGetState(t *testing.T) {
@@ -76,7 +74,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
// has gained an "uninteresting" IP address.
s1 := &State{
- InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
+ InterfaceIPs: map[string][]netip.Prefix{"x": {
netip.MustParsePrefix("42.0.0.0/8"),
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
}},
@@ -84,7 +82,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
}
s2 := &State{
- InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
+ InterfaceIPs: map[string][]netip.Prefix{"x": {
netip.MustParsePrefix("42.0.0.0/8"),
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
netip.MustParsePrefix("127.0.0.0/8"), // loopback (added)
@@ -126,8 +124,8 @@ func TestStateString(t *testing.T) {
Interface: &net.Interface{},
},
},
- InterfaceIPs: map[string][]netaddr.IPPrefix{
- "eth0": []netaddr.IPPrefix{
+ InterfaceIPs: map[string][]netip.Prefix{
+ "eth0": []netip.Prefix{
netip.MustParsePrefix("10.0.0.2/8"),
},
},
diff --git a/net/interfaces/interfaces_windows.go b/net/interfaces/interfaces_windows.go
index 3e82a87da..611d426fa 100644
--- a/net/interfaces/interfaces_windows.go
+++ b/net/interfaces/interfaces_windows.go
@@ -7,6 +7,7 @@
import (
"log"
"net"
+ "net/netip"
"net/url"
"strings"
"syscall"
@@ -27,7 +28,7 @@ func init() {
getPAC = getPACWindows
}
-func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
+func likelyHomeRouterIPWindows() (ret netip.Addr, ok bool) {
rs, err := winipcfg.GetIPForwardTable2(windows.AF_INET)
if err != nil {
log.Printf("routerIP/GetIPForwardTable2 error: %v", err)
@@ -94,7 +95,7 @@ func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
if ret.IsValid() && !ret.IsPrivate() {
// Default route has a non-private gateway
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
return ret, ret.IsValid()
diff --git a/net/netaddr/netaddr.go b/net/netaddr/netaddr.go
index bb50d9523..c4b2ea88c 100644
--- a/net/netaddr/netaddr.go
+++ b/net/netaddr/netaddr.go
@@ -15,14 +15,8 @@
"net/netip"
)
-type (
- IP = netip.Addr
- IPPort = netip.AddrPort
- IPPrefix = netip.Prefix
-)
-
// IPv4 returns the IP of the IPv4 address a.b.c.d.
-func IPv4(a, b, c, d uint8) IP {
+func IPv4(a, b, c, d uint8) netip.Addr {
return netip.AddrFrom4([4]byte{a, b, c, d})
}
@@ -30,41 +24,10 @@ func IPv4(a, b, c, d uint8) IP {
// v6-mapped IPv4 address.
//
// It is equivalent to calling IPv6Raw(addr).Unmap().
-func IPFrom16(a [16]byte) IP {
+func IPFrom16(a [16]byte) netip.Addr {
return netip.AddrFrom16(a).Unmap()
}
-// IPv6Raw returns the IPv6 address given by the bytes in addr, without an
-// implicit Unmap call to unmap any v6-mapped IPv4 address.
-func IPv6Raw(a [16]byte) IP {
- return netip.AddrFrom16(a) // no implicit unmapping
-}
-
-// IPFrom4 returns the IPv4 address given by the bytes in addr. It is equivalent
-// to calling IPv4(addr[0], addr[1], addr[2], addr[3]).
-func IPFrom4(a [4]byte) IP {
- return netip.AddrFrom4(a)
-}
-
-// IPPrefixFrom returns an IPPrefix with IP ip and provided bits prefix length.
-// It does not allocate.
-func IPPrefixFrom(ip IP, bits uint8) IPPrefix {
- return netip.PrefixFrom(ip, int(bits))
-}
-
-// IPPortFrom returns an IPPort with IP ip and port port. It does not allocate.
-func IPPortFrom(ip IP, port uint16) IPPort {
- return netip.AddrPortFrom(ip, port)
-}
-
-// FromStdIPRaw returns an IP from the standard library's IP type.
-// If std is invalid, ok is false.
-// Unlike FromStdIP, FromStdIPRaw does not do an implicit Unmap if
-// len(std) == 16 and contains an IPv6-mapped IPv4 address.
-func FromStdIPRaw(std net.IP) (ip IP, ok bool) {
- return netip.AddrFromSlice(std)
-}
-
// FromStdIP returns an IP from the standard library's IP type.
//
// If std is invalid, ok is false.
@@ -74,9 +37,9 @@ func FromStdIPRaw(std net.IP) (ip IP, ok bool) {
// returned, without the IPv6 wrapper. This is the common form returned by
// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
// To convert a standard library IP without the implicit unmapping, use
-// FromStdIPRaw.
-func FromStdIP(std net.IP) (ip IP, ok bool) {
- ret, ok := FromStdIPRaw(std)
+// netip.AddrFromSlice.
+func FromStdIP(std net.IP) (ip netip.Addr, ok bool) {
+ ret, ok := netip.AddrFromSlice(std)
if !ok {
return ret, false
}
@@ -88,21 +51,21 @@ func FromStdIP(std net.IP) (ip IP, ok bool) {
// FromStdIPNet returns an IPPrefix from the standard library's IPNet type.
// If std is invalid, ok is false.
-func FromStdIPNet(std *net.IPNet) (prefix IPPrefix, ok bool) {
+func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
ip, ok := FromStdIP(std.IP)
if !ok {
- return IPPrefix{}, false
+ return netip.Prefix{}, false
}
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
// Invalid mask.
- return IPPrefix{}, false
+ return netip.Prefix{}, false
}
ones, bits := std.Mask.Size()
if ones == 0 && bits == 0 {
// IPPrefix does not support non-contiguous masks.
- return IPPrefix{}, false
+ return netip.Prefix{}, false
}
return netip.PrefixFrom(ip, ones), true
@@ -110,7 +73,7 @@ func FromStdIPNet(std *net.IPNet) (prefix IPPrefix, ok bool) {
// FromStdAddr maps the components of a standard library TCPAddr or
// UDPAddr into an IPPort.
-func FromStdAddr(stdIP net.IP, port int, zone string) (_ IPPort, ok bool) {
+func FromStdAddr(stdIP net.IP, port int, zone string) (_ netip.AddrPort, ok bool) {
ip, ok := FromStdIP(stdIP)
if !ok || port < 0 || port > math.MaxUint16 {
return
diff --git a/net/netcheck/netcheck.go b/net/netcheck/netcheck.go
index 4bd72de32..577131feb 100644
--- a/net/netcheck/netcheck.go
+++ b/net/netcheck/netcheck.go
@@ -211,7 +211,7 @@ func (c *Client) vlogf(format string, a ...any) {
// handleHairSTUN reports whether pkt (from src) was our magic hairpin
// probe packet that we sent to ourselves.
-func (c *Client) handleHairSTUNLocked(pkt []byte, src netaddr.IPPort) bool {
+func (c *Client) handleHairSTUNLocked(pkt []byte, src netip.AddrPort) bool {
rs := c.curState
if rs == nil {
return false
@@ -234,7 +234,7 @@ func (c *Client) MakeNextReportFull() {
c.nextFull = true
}
-func (c *Client) ReceiveSTUNPacket(pkt []byte, src netaddr.IPPort) {
+func (c *Client) ReceiveSTUNPacket(pkt []byte, src netip.AddrPort) {
c.vlogf("received STUN packet from %s", src)
if src.Addr().Is4() {
@@ -526,7 +526,7 @@ func (c *Client) readPackets(ctx context.Context, pc net.PacketConn) {
type reportState struct {
c *Client
hairTX stun.TxID
- gotHairSTUN chan netaddr.IPPort
+ gotHairSTUN chan netip.AddrPort
hairTimeout chan struct{} // closed on timeout
pc4 STUNConn
pc6 STUNConn
@@ -538,7 +538,7 @@ type reportState struct {
mu sync.Mutex
sentHairCheck bool
report *Report // to be returned by GetReport
- inFlight map[stun.TxID]func(netaddr.IPPort) // called without c.mu held
+ inFlight map[stun.TxID]func(netip.AddrPort) // called without c.mu held
gotEP4 string
timers []*time.Timer
}
@@ -590,7 +590,7 @@ func (rs *reportState) probeWouldHelp(probe probe, node *tailcfg.DERPNode) bool
return false
}
-func (rs *reportState) startHairCheckLocked(dst netaddr.IPPort) {
+func (rs *reportState) startHairCheckLocked(dst netip.AddrPort) {
if rs.sentHairCheck || rs.incremental {
return
}
@@ -642,9 +642,9 @@ func (rs *reportState) stopTimers() {
// addNodeLatency updates rs to note that node's latency is d. If ipp
// is non-zero (for all but HTTPS replies), it's recorded as our UDP
// IP:port.
-func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netaddr.IPPort, d time.Duration) {
+func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netip.AddrPort, d time.Duration) {
var ipPortStr string
- if ipp != (netaddr.IPPort{}) {
+ if ipp != (netip.AddrPort{}) {
ipPortStr = net.JoinHostPort(ipp.Addr().String(), fmt.Sprint(ipp.Port()))
}
@@ -772,9 +772,9 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (_ *Report,
rs := &reportState{
c: c,
report: newReport(),
- inFlight: map[stun.TxID]func(netaddr.IPPort){},
+ inFlight: map[stun.TxID]func(netip.AddrPort){},
hairTX: stun.NewTxID(), // random payload
- gotHairSTUN: make(chan netaddr.IPPort, 1),
+ gotHairSTUN: make(chan netip.AddrPort, 1),
hairTimeout: make(chan struct{}),
stopProbeCh: make(chan struct{}, 1),
}
@@ -1008,20 +1008,20 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
return
}
d := c.timeNow().Sub(t0)
- rs.addNodeLatency(node, netaddr.IPPort{}, d)
+ rs.addNodeLatency(node, netip.AddrPort{}, d)
}()
}
wg.Wait()
return nil
}
-func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegion) (time.Duration, netaddr.IP, error) {
+func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegion) (time.Duration, netip.Addr, error) {
metricHTTPSend.Add(1)
var result httpstat.Result
ctx, cancel := context.WithTimeout(httpstat.WithHTTPStat(ctx, &result), overallProbeTimeout)
defer cancel()
- var ip netaddr.IP
+ var ip netip.Addr
dc := derphttp.NewNetcheckClient(c.logf)
tlsConn, tcpConn, node, err := dc.DialRegionTLS(ctx, reg)
@@ -1033,7 +1033,7 @@ func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegio
if ta, ok := tlsConn.RemoteAddr().(*net.TCPAddr); ok {
ip, _ = netaddr.FromStdIP(ta.IP)
}
- if ip == (netaddr.IP{}) {
+ if ip == (netip.Addr{}) {
return 0, ip, fmt.Errorf("no unexpected RemoteAddr %#v", tlsConn.RemoteAddr())
}
@@ -1250,7 +1250,7 @@ func (rs *reportState) runProbe(ctx context.Context, dm *tailcfg.DERPMap, probe
sent := time.Now() // after DNS lookup above
rs.mu.Lock()
- rs.inFlight[txID] = func(ipp netaddr.IPPort) {
+ rs.inFlight[txID] = func(ipp netip.AddrPort) {
rs.addNodeLatency(node, ipp, time.Since(sent))
cancelSet() // abort other nodes in this set
}
diff --git a/net/netcheck/netcheck_test.go b/net/netcheck/netcheck_test.go
index ebb513240..6dec50a25 100644
--- a/net/netcheck/netcheck_test.go
+++ b/net/netcheck/netcheck_test.go
@@ -9,6 +9,7 @@
"context"
"fmt"
"net"
+ "net/netip"
"reflect"
"sort"
"strconv"
@@ -17,7 +18,6 @@
"time"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/stun"
"tailscale.com/net/stun/stuntest"
"tailscale.com/tailcfg"
@@ -28,14 +28,14 @@ func TestHairpinSTUN(t *testing.T) {
c := &Client{
curState: &reportState{
hairTX: tx,
- gotHairSTUN: make(chan netaddr.IPPort, 1),
+ gotHairSTUN: make(chan netip.AddrPort, 1),
},
}
req := stun.Request(tx)
if !stun.Is(req) {
t.Fatal("expected STUN message")
}
- if !c.handleHairSTUNLocked(req, netaddr.IPPort{}) {
+ if !c.handleHairSTUNLocked(req, netip.AddrPort{}) {
t.Fatal("expected true")
}
select {
diff --git a/net/netstat/netstat.go b/net/netstat/netstat.go
index aa969d8ba..13edf0afb 100644
--- a/net/netstat/netstat.go
+++ b/net/netstat/netstat.go
@@ -7,15 +7,14 @@
import (
"errors"
+ "net/netip"
"runtime"
-
- "tailscale.com/net/netaddr"
)
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)
type Entry struct {
- Local, Remote netaddr.IPPort
+ Local, Remote netip.AddrPort
Pid int
State string // TODO: type?
}
diff --git a/net/netstat/netstat_windows.go b/net/netstat/netstat_windows.go
index b2979e65f..7d2467632 100644
--- a/net/netstat/netstat_windows.go
+++ b/net/netstat/netstat_windows.go
@@ -9,6 +9,7 @@
"errors"
"fmt"
"math/bits"
+ "net/netip"
"syscall"
"unsafe"
@@ -153,22 +154,22 @@ func state(v uint32) string {
return fmt.Sprintf("unknown-state-%d", v)
}
-func ipport4(addr uint32, port uint16) netaddr.IPPort {
+func ipport4(addr uint32, port uint16) netip.AddrPort {
if !endian.Big {
addr = bits.ReverseBytes32(addr)
}
- return netaddr.IPPortFrom(
+ return netip.AddrPortFrom(
netaddr.IPv4(byte(addr>>24), byte(addr>>16), byte(addr>>8), byte(addr)),
port)
}
-func ipport6(addr [16]byte, scope uint32, port uint16) netaddr.IPPort {
+func ipport6(addr [16]byte, scope uint32, port uint16) netip.AddrPort {
ip := netaddr.IPFrom16(addr)
if scope != 0 {
// TODO: something better here?
ip = ip.WithZone(fmt.Sprint(scope))
}
- return netaddr.IPPortFrom(ip, port)
+ return netip.AddrPortFrom(ip, port)
}
func port(v *uint32) uint16 {
diff --git a/net/netutil/ip_forward.go b/net/netutil/ip_forward.go
index c42f2b240..f737538da 100644
--- a/net/netutil/ip_forward.go
+++ b/net/netutil/ip_forward.go
@@ -8,6 +8,7 @@
import (
"bytes"
"fmt"
+ "net/netip"
"os"
"os/exec"
"path/filepath"
@@ -16,19 +17,18 @@
"strings"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
)
// protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are
// required to forward the specified routes.
// The state param must be specified.
-func protocolsRequiredForForwarding(routes []netaddr.IPPrefix, state *interfaces.State) (v4, v6 bool) {
+func protocolsRequiredForForwarding(routes []netip.Prefix, state *interfaces.State) (v4, v6 bool) {
if len(routes) == 0 {
// Nothing to route, so no need to warn.
return false, false
}
- localIPs := make(map[netaddr.IP]bool)
+ localIPs := make(map[netip.Addr]bool)
for _, addrs := range state.InterfaceIPs {
for _, pfx := range addrs {
localIPs[pfx.Addr()] = true
@@ -59,7 +59,7 @@ func protocolsRequiredForForwarding(routes []netaddr.IPPrefix, state *interfaces
// It returns an error if it is unable to determine if IP forwarding is enabled.
// It returns a warning describing configuration issues if IP forwarding is
// non-functional or partly functional.
-func CheckIPForwarding(routes []netaddr.IPPrefix, state *interfaces.State) (warn, err error) {
+func CheckIPForwarding(routes []netip.Prefix, state *interfaces.State) (warn, err error) {
if runtime.GOOS != "linux" {
switch runtime.GOOS {
case "dragonfly", "freebsd", "netbsd", "openbsd":
diff --git a/net/packet/ip4.go b/net/packet/ip4.go
index 21941d733..2b9ccf8d4 100644
--- a/net/packet/ip4.go
+++ b/net/packet/ip4.go
@@ -7,8 +7,8 @@
import (
"encoding/binary"
"errors"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)
@@ -19,8 +19,8 @@
type IP4Header struct {
IPProto ipproto.Proto
IPID uint16
- Src netaddr.IP
- Dst netaddr.IP
+ Src netip.Addr
+ Dst netip.Addr
}
// Len implements Header.
diff --git a/net/packet/ip6.go b/net/packet/ip6.go
index 4f30aea3c..f829f3f28 100644
--- a/net/packet/ip6.go
+++ b/net/packet/ip6.go
@@ -6,8 +6,8 @@
import (
"encoding/binary"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)
@@ -18,8 +18,8 @@
type IP6Header struct {
IPProto ipproto.Proto
IPID uint32 // only lower 20 bits used
- Src netaddr.IP
- Dst netaddr.IP
+ Src netip.Addr
+ Dst netip.Addr
}
// Len implements Header.
diff --git a/net/packet/packet.go b/net/packet/packet.go
index 79e5b7412..7b97d856a 100644
--- a/net/packet/packet.go
+++ b/net/packet/packet.go
@@ -54,9 +54,9 @@ type Parsed struct {
IPProto ipproto.Proto
// SrcIP4 is the source address. Family matches IPVersion. Port is
// valid iff IPProto == TCP || IPProto == UDP.
- Src netaddr.IPPort
+ Src netip.AddrPort
// DstIP4 is the destination address. Family matches IPVersion.
- Dst netaddr.IPPort
+ Dst netip.AddrPort
// TCPFlags is the packet's TCP flag bits. Valid iff IPProto == TCP.
TCPFlags TCPFlag
}
diff --git a/net/packet/packet_test.go b/net/packet/packet_test.go
index a7064713b..510808adf 100644
--- a/net/packet/packet_test.go
+++ b/net/packet/packet_test.go
@@ -10,7 +10,6 @@
"reflect"
"testing"
- "tailscale.com/net/netaddr"
"tailscale.com/tstest"
"tailscale.com/types/ipproto"
)
@@ -27,7 +26,7 @@
Fragment = ipproto.Fragment
)
-func mustIPPort(s string) netaddr.IPPort {
+func mustIPPort(s string) netip.AddrPort {
ipp, err := netip.ParseAddrPort(s)
if err != nil {
panic(err)
diff --git a/net/packet/tsmp.go b/net/packet/tsmp.go
index 7f116c618..76642b97b 100644
--- a/net/packet/tsmp.go
+++ b/net/packet/tsmp.go
@@ -14,9 +14,9 @@
"encoding/binary"
"errors"
"fmt"
+ "net/netip"
"tailscale.com/net/flowtrack"
- "tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)
@@ -36,10 +36,10 @@
// In the future it might also accept 16 byte IP flow src/dst IPs
// after the header, if they're different than the IP-level ones.
type TailscaleRejectedHeader struct {
- IPSrc netaddr.IP // IPv4 or IPv6 header's src IP
- IPDst netaddr.IP // IPv4 or IPv6 header's dst IP
- Src netaddr.IPPort // rejected flow's src
- Dst netaddr.IPPort // rejected flow's dst
+ IPSrc netip.Addr // IPv4 or IPv6 header's src IP
+ IPDst netip.Addr // IPv4 or IPv6 header's dst IP
+ Src netip.AddrPort // rejected flow's src
+ Dst netip.AddrPort // rejected flow's dst
Proto ipproto.Proto // proto that was rejected (TCP or UDP)
Reason TailscaleRejectReason // why the connection was rejected
@@ -192,8 +192,8 @@ func (pp *Parsed) AsTailscaleRejectedHeader() (h TailscaleRejectedHeader, ok boo
Reason: TailscaleRejectReason(p[2]),
IPSrc: pp.Src.Addr(),
IPDst: pp.Dst.Addr(),
- Src: netaddr.IPPortFrom(pp.Dst.Addr(), binary.BigEndian.Uint16(p[3:5])),
- Dst: netaddr.IPPortFrom(pp.Src.Addr(), binary.BigEndian.Uint16(p[5:7])),
+ Src: netip.AddrPortFrom(pp.Dst.Addr(), binary.BigEndian.Uint16(p[3:5])),
+ Dst: netip.AddrPortFrom(pp.Src.Addr(), binary.BigEndian.Uint16(p[5:7])),
}
if len(p) > 7 {
flags := p[7]
diff --git a/net/portmapper/disabled_stubs.go b/net/portmapper/disabled_stubs.go
index 67e250a3b..f738e6e28 100644
--- a/net/portmapper/disabled_stubs.go
+++ b/net/portmapper/disabled_stubs.go
@@ -9,8 +9,7 @@
import (
"context"
-
- "tailscale.com/net/netaddr"
+ "net/netip"
)
type upnpClient any
@@ -23,9 +22,9 @@ func parseUPnPDiscoResponse([]byte) (uPnPDiscoResponse, error) {
func (c *Client) getUPnPPortMapping(
ctx context.Context,
- gw netaddr.IP,
- internal netaddr.IPPort,
+ gw netip.Addr,
+ internal netip.AddrPort,
prevPort uint16,
-) (external netaddr.IPPort, ok bool) {
- return netaddr.IPPort{}, false
+) (external netip.AddrPort, ok bool) {
+ return netip.AddrPort{}, false
}
diff --git a/net/portmapper/igd_test.go b/net/portmapper/igd_test.go
index f7516eb28..717dd9946 100644
--- a/net/portmapper/igd_test.go
+++ b/net/portmapper/igd_test.go
@@ -10,6 +10,7 @@
"net"
"net/http"
"net/http/httptest"
+ "net/netip"
"sync"
"testing"
@@ -101,7 +102,7 @@ func (d *TestIGD) TestUPnPPort() uint16 {
return uint16(d.upnpConn.LocalAddr().(*net.UDPAddr).Port)
}
-func testIPAndGateway() (gw, ip netaddr.IP, ok bool) {
+func testIPAndGateway() (gw, ip netip.Addr, ok bool) {
return netaddr.IPv4(127, 0, 0, 1), netaddr.IPv4(1, 2, 3, 4), true
}
@@ -187,7 +188,7 @@ func (d *TestIGD) servePxP() {
}
}
-func (d *TestIGD) handlePMPQuery(pkt []byte, src netaddr.IPPort) {
+func (d *TestIGD) handlePMPQuery(pkt []byte, src netip.AddrPort) {
d.inc(&d.counters.numPMPRecv)
if len(pkt) < 2 {
return
@@ -205,7 +206,7 @@ func (d *TestIGD) handlePMPQuery(pkt []byte, src netaddr.IPPort) {
// TODO
}
-func (d *TestIGD) handlePCPQuery(pkt []byte, src netaddr.IPPort) {
+func (d *TestIGD) handlePCPQuery(pkt []byte, src netip.AddrPort) {
d.inc(&d.counters.numPCPRecv)
if len(pkt) < 24 {
return
diff --git a/net/portmapper/pcp.go b/net/portmapper/pcp.go
index db5848c36..9cfe7c8a7 100644
--- a/net/portmapper/pcp.go
+++ b/net/portmapper/pcp.go
@@ -9,6 +9,7 @@
"crypto/rand"
"encoding/binary"
"fmt"
+ "net/netip"
"time"
"tailscale.com/net/netaddr"
@@ -49,9 +50,9 @@
type pcpMapping struct {
c *Client
- gw netaddr.IPPort
- internal netaddr.IPPort
- external netaddr.IPPort
+ gw netip.AddrPort
+ internal netip.AddrPort
+ external netip.AddrPort
renewAfter time.Time
goodUntil time.Time
@@ -62,7 +63,7 @@ type pcpMapping struct {
func (p *pcpMapping) GoodUntil() time.Time { return p.goodUntil }
func (p *pcpMapping) RenewAfter() time.Time { return p.renewAfter }
-func (p *pcpMapping) External() netaddr.IPPort { return p.external }
+func (p *pcpMapping) External() netip.AddrPort { return p.external }
func (p *pcpMapping) Release(ctx context.Context) {
uc, err := p.c.listenPacket(ctx, "udp4", ":0")
if err != nil {
@@ -78,10 +79,10 @@ func (p *pcpMapping) Release(ctx context.Context) {
// If prevPort is not known, it should be set to 0.
// If prevExternalIP is not known, it should be set to 0.0.0.0.
func buildPCPRequestMappingPacket(
- myIP netaddr.IP,
+ myIP netip.Addr,
localPort, prevPort uint16,
lifetimeSec uint32,
- prevExternalIP netaddr.IP,
+ prevExternalIP netip.Addr,
) (pkt []byte) {
// 24 byte common PCP header + 36 bytes of MAP-specific fields
pkt = make([]byte, 24+36)
@@ -127,7 +128,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
copy(externalIPBytes[:], resp[44:])
externalIP := netaddr.IPFrom16(externalIPBytes)
- external := netaddr.IPPortFrom(externalIP, externalPort)
+ external := netip.AddrPortFrom(externalIP, externalPort)
lifetime := time.Second * time.Duration(res.Lifetime)
now := time.Now()
@@ -141,7 +142,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
}
// pcpAnnounceRequest generates a PCP packet with an ANNOUNCE opcode.
-func pcpAnnounceRequest(myIP netaddr.IP) []byte {
+func pcpAnnounceRequest(myIP netip.Addr) []byte {
// See https://tools.ietf.org/html/rfc6887#section-7.1
pkt := make([]byte, 24)
pkt[0] = pcpVersion
diff --git a/net/portmapper/portmapper.go b/net/portmapper/portmapper.go
index e59a3ab4a..3b5efd1d4 100644
--- a/net/portmapper/portmapper.go
+++ b/net/portmapper/portmapper.go
@@ -57,7 +57,7 @@
// Client is a port mapping client.
type Client struct {
logf logger.Logf
- ipAndGateway func() (gw, ip netaddr.IP, ok bool)
+ ipAndGateway func() (gw, ip netip.Addr, ok bool)
onChange func() // or nil
testPxPPort uint16 // if non-zero, pxpPort to use for tests
testUPnPPort uint16 // if non-zero, uPnPPort to use for tests
@@ -69,13 +69,13 @@ type Client struct {
// off a createMapping goroutine).
runningCreate bool
- lastMyIP netaddr.IP
- lastGW netaddr.IP
+ lastMyIP netip.Addr
+ lastGW netip.Addr
closed bool
lastProbe time.Time
- pmpPubIP netaddr.IP // non-zero if known
+ pmpPubIP netip.Addr // non-zero if known
pmpPubIPTime time.Time // time pmpPubIP last verified
pmpLastEpoch uint32
@@ -105,7 +105,7 @@ type mapping interface {
// renewAfter returns the earliest time that the mapping should be renewed.
RenewAfter() time.Time
// externalIPPort indicates what port the mapping can be reached from on the outside.
- External() netaddr.IPPort
+ External() netip.AddrPort
}
// HaveMapping reports whether we have a current valid mapping.
@@ -120,9 +120,9 @@ func (c *Client) HaveMapping() bool {
// All fields are immutable once created.
type pmpMapping struct {
c *Client
- gw netaddr.IPPort
- external netaddr.IPPort
- internal netaddr.IPPort
+ gw netip.AddrPort
+ external netip.AddrPort
+ internal netip.AddrPort
renewAfter time.Time // the time at which we want to renew the mapping
goodUntil time.Time // the mapping's total lifetime
epoch uint32
@@ -135,7 +135,7 @@ func (m *pmpMapping) externalValid() bool {
func (p *pmpMapping) GoodUntil() time.Time { return p.goodUntil }
func (p *pmpMapping) RenewAfter() time.Time { return p.renewAfter }
-func (p *pmpMapping) External() netaddr.IPPort { return p.external }
+func (p *pmpMapping) External() netip.AddrPort { return p.external }
// Release does a best effort fire-and-forget release of the PMP mapping m.
func (m *pmpMapping) Release(ctx context.Context) {
@@ -164,7 +164,7 @@ func NewClient(logf logger.Logf, onChange func()) *Client {
// SetGatewayLookupFunc set the func that returns the machine's default gateway IP, and
// the primary IP address for that gateway. It must be called before the client is used.
// If not called, interfaces.LikelyHomeRouterIP is used.
-func (c *Client) SetGatewayLookupFunc(f func() (gw, myIP netaddr.IP, ok bool)) {
+func (c *Client) SetGatewayLookupFunc(f func() (gw, myIP netip.Addr, ok bool)) {
c.ipAndGateway = f
}
@@ -203,11 +203,11 @@ func (c *Client) SetLocalPort(localPort uint16) {
c.invalidateMappingsLocked(true)
}
-func (c *Client) gatewayAndSelfIP() (gw, myIP netaddr.IP, ok bool) {
+func (c *Client) gatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) {
gw, myIP, ok = c.ipAndGateway()
if !ok {
- gw = netaddr.IP{}
- myIP = netaddr.IP{}
+ gw = netip.Addr{}
+ myIP = netip.Addr{}
}
c.mu.Lock()
defer c.mu.Unlock()
@@ -273,7 +273,7 @@ func (c *Client) invalidateMappingsLocked(releaseOld bool) {
}
c.mapping = nil
}
- c.pmpPubIP = netaddr.IP{}
+ c.pmpPubIP = netip.Addr{}
c.pmpPubIPTime = time.Time{}
c.pcpSawTime = time.Time{}
c.uPnPSawTime = time.Time{}
@@ -350,7 +350,7 @@ func IsNoMappingError(err error) bool {
// If there's not one, it starts up a background goroutine to create one.
// If the background goroutine ends up creating one, the onChange hook registered with the
// NewClient constructor (if any) will fire.
-func (c *Client) GetCachedMappingOrStartCreatingOne() (external netaddr.IPPort, ok bool) {
+func (c *Client) GetCachedMappingOrStartCreatingOne() (external netip.AddrPort, ok bool) {
c.mu.Lock()
defer c.mu.Unlock()
@@ -366,7 +366,7 @@ func (c *Client) GetCachedMappingOrStartCreatingOne() (external netaddr.IPPort,
}
c.maybeStartMappingLocked()
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
// maybeStartMappingLocked starts a createMapping goroutine up, if one isn't already running.
@@ -404,21 +404,21 @@ func (c *Client) createMapping() {
//
// If no mapping is available, the error will be of type
// NoMappingError; see IsNoMappingError.
-func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPort, err error) {
+func (c *Client) createOrGetMapping(ctx context.Context) (external netip.AddrPort, err error) {
if DisableUPnP && DisablePCP && DisablePMP {
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
gw, myIP, ok := c.gatewayAndSelfIP()
if !ok {
- return netaddr.IPPort{}, NoMappingError{ErrGatewayRange}
+ return netip.AddrPort{}, NoMappingError{ErrGatewayRange}
}
if gw.Is6() {
- return netaddr.IPPort{}, NoMappingError{ErrGatewayIPv6}
+ return netip.AddrPort{}, NoMappingError{ErrGatewayIPv6}
}
c.mu.Lock()
localPort := c.localPort
- internalAddr := netaddr.IPPortFrom(myIP, localPort)
+ internalAddr := netip.AddrPortFrom(myIP, localPort)
// prevPort is the port we had most previously, if any. We try
// to ask for the same port. 0 means to give us any port.
@@ -440,7 +440,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
return external, nil
}
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
// If we just did a Probe (e.g. via netchecker) but didn't
@@ -457,7 +457,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
// construct it upon receiving that packet.
m := &pmpMapping{
c: c,
- gw: netaddr.IPPortFrom(gw, c.pxpPort()),
+ gw: netip.AddrPortFrom(gw, c.pxpPort()),
internal: internalAddr,
}
if haveRecentPMP {
@@ -469,20 +469,20 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
return external, nil
}
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
c.mu.Unlock()
uc, err := c.listenPacket(ctx, "udp4", ":0")
if err != nil {
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
defer uc.Close()
uc.SetReadDeadline(time.Now().Add(portMapServiceTimeout))
defer closeCloserOnContextDone(ctx, uc)()
- pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
+ pxpAddr := netip.AddrPortFrom(gw, c.pxpPort())
preferPCP := !DisablePCP && (DisablePMP || (!haveRecentPMP && haveRecentPCP))
@@ -495,7 +495,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if neterror.TreatAsLostUDP(err) {
err = NoMappingError{ErrNoPortMappingServices}
}
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
} else {
// Ask for our external address if needed.
@@ -504,7 +504,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if neterror.TreatAsLostUDP(err) {
err = NoMappingError{ErrNoPortMappingServices}
}
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
}
@@ -513,7 +513,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if neterror.TreatAsLostUDP(err) {
err = NoMappingError{ErrNoPortMappingServices}
}
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
}
@@ -522,13 +522,13 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
n, srci, err := uc.ReadFrom(res)
if err != nil {
if ctx.Err() == context.Canceled {
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
// fallback to UPnP portmapping
if mapping, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
return mapping, nil
}
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
srcu := srci.(*net.UDPAddr)
src, ok := netaddr.FromStdAddr(srcu.IP, srcu.Port, srcu.Zone)
@@ -545,7 +545,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
continue
}
if pres.ResultCode != 0 {
- return netaddr.IPPort{}, NoMappingError{fmt.Errorf("PMP response Op=0x%x,Res=0x%x", pres.OpCode, pres.ResultCode)}
+ return netip.AddrPort{}, NoMappingError{fmt.Errorf("PMP response Op=0x%x,Res=0x%x", pres.OpCode, pres.ResultCode)}
}
if pres.OpCode == pmpOpReply|pmpOpMapPublicAddr {
m.external = netip.AddrPortFrom(pres.PublicAddr, m.external.Port())
@@ -563,18 +563,18 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
if err != nil {
c.logf("failed to get PCP mapping: %v", err)
// PCP should only have a single packet response
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
pcpMapping.c = c
pcpMapping.internal = m.internal
- pcpMapping.gw = netaddr.IPPortFrom(gw, c.pxpPort())
+ pcpMapping.gw = netip.AddrPortFrom(gw, c.pxpPort())
c.mu.Lock()
defer c.mu.Unlock()
c.mapping = pcpMapping
return pcpMapping.external, nil
default:
c.logf("unknown PMP/PCP version number: %d %v", version, res[:n])
- return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
+ return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
}
}
@@ -632,7 +632,7 @@ type pmpResponse struct {
ExternalPort uint16
// For public addr ops:
- PublicAddr netaddr.IP
+ PublicAddr netip.Addr
}
func parsePMPResponse(pkt []byte) (res pmpResponse, ok bool) {
@@ -701,9 +701,9 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
defer cancel()
defer closeCloserOnContextDone(ctx, uc)()
- pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
- upnpAddr := netaddr.IPPortFrom(gw, c.upnpPort())
- upnpMulticastAddr := netaddr.IPPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort())
+ pxpAddr := netip.AddrPortFrom(gw, c.pxpPort())
+ upnpAddr := netip.AddrPortFrom(gw, c.upnpPort())
+ upnpMulticastAddr := netip.AddrPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort())
// Don't send probes to services that we recently learned (for
// the same gw/myIP) are available. See
diff --git a/net/portmapper/upnp.go b/net/portmapper/upnp.go
index 63c368abd..65f2c612f 100644
--- a/net/portmapper/upnp.go
+++ b/net/portmapper/upnp.go
@@ -24,7 +24,6 @@
"github.com/tailscale/goupnp"
"github.com/tailscale/goupnp/dcps/internetgateway2"
"tailscale.com/control/controlknobs"
- "tailscale.com/net/netaddr"
"tailscale.com/net/netns"
"tailscale.com/types/logger"
)
@@ -36,9 +35,9 @@
// upnpMapping is a port mapping over the upnp protocol. After being created it is immutable,
// but the client field may be shared across mapping instances.
type upnpMapping struct {
- gw netaddr.IP
- external netaddr.IPPort
- internal netaddr.IPPort
+ gw netip.Addr
+ external netip.AddrPort
+ internal netip.AddrPort
goodUntil time.Time
renewAfter time.Time
@@ -48,7 +47,7 @@ type upnpMapping struct {
func (u *upnpMapping) GoodUntil() time.Time { return u.goodUntil }
func (u *upnpMapping) RenewAfter() time.Time { return u.renewAfter }
-func (u *upnpMapping) External() netaddr.IPPort { return u.external }
+func (u *upnpMapping) External() netip.AddrPort { return u.external }
func (u *upnpMapping) Release(ctx context.Context) {
u.client.DeletePortMapping(ctx, "", u.external.Port(), "udp")
}
@@ -154,7 +153,7 @@ func addAnyPortMapping(
//
// The provided ctx is not retained in the returned upnpClient, but
// its associated HTTP client is (if set via goupnp.WithHTTPClient).
-func getUPnPClient(ctx context.Context, logf logger.Logf, gw netaddr.IP, meta uPnPDiscoResponse) (client upnpClient, err error) {
+func getUPnPClient(ctx context.Context, logf logger.Logf, gw netip.Addr, meta uPnPDiscoResponse) (client upnpClient, err error) {
if controlknobs.DisableUPnP() || DisableUPnP {
return nil, nil
}
@@ -233,12 +232,12 @@ func (c *Client) upnpHTTPClientLocked() *http.Client {
// port and an error.
func (c *Client) getUPnPPortMapping(
ctx context.Context,
- gw netaddr.IP,
- internal netaddr.IPPort,
+ gw netip.Addr,
+ internal netip.AddrPort,
prevPort uint16,
-) (external netaddr.IPPort, ok bool) {
+) (external netip.AddrPort, ok bool) {
if controlknobs.DisableUPnP() || DisableUPnP {
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
now := time.Now()
upnp := &upnpMapping{
@@ -262,11 +261,11 @@ func (c *Client) getUPnPPortMapping(
c.logf("getUPnPClient: %T, %v", client, err)
}
if err != nil {
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
}
if client == nil {
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
var newPort uint16
@@ -282,7 +281,7 @@ func (c *Client) getUPnPPortMapping(
c.logf("addAnyPortMapping: %v, %v", newPort, err)
}
if err != nil {
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
// TODO cache this ip somewhere?
extIP, err := client.GetExternalIPAddress(ctx)
@@ -291,14 +290,14 @@ func (c *Client) getUPnPPortMapping(
}
if err != nil {
// TODO this doesn't seem right
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
externalIP, err := netip.ParseAddr(extIP)
if err != nil {
- return netaddr.IPPort{}, false
+ return netip.AddrPort{}, false
}
- upnp.external = netaddr.IPPortFrom(externalIP, newPort)
+ upnp.external = netip.AddrPortFrom(externalIP, newPort)
d := time.Duration(pmpMapLifetimeSec) * time.Second
upnp.goodUntil = now.Add(d)
upnp.renewAfter = now.Add(d / 2)
diff --git a/net/tsaddr/tsaddr.go b/net/tsaddr/tsaddr.go
index 5d4ac44b1..e728e725e 100644
--- a/net/tsaddr/tsaddr.go
+++ b/net/tsaddr/tsaddr.go
@@ -17,7 +17,7 @@
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
// ChromeOS to interconnect the host OS to containers and VMs. We
// avoid allocating Tailscale IPs from it, to avoid conflicts.
-func ChromeOSVMRange() netaddr.IPPrefix {
+func ChromeOSVMRange() netip.Prefix {
chromeOSRange.Do(func() { mustPrefix(&chromeOSRange.v, "100.115.92.0/23") })
return chromeOSRange.v
}
@@ -28,7 +28,7 @@ func ChromeOSVMRange() netaddr.IPPrefix {
// is the superset range that Tailscale assigns out of.
// See https://tailscale.com/kb/1015/100.x-addresses.
// Note that Tailscale does not assign out of the ChromeOSVMRange.
-func CGNATRange() netaddr.IPPrefix {
+func CGNATRange() netip.Prefix {
cgnatRange.Do(func() { mustPrefix(&cgnatRange.v, "100.64.0.0/10") })
return cgnatRange.v
}
@@ -47,7 +47,7 @@ func CGNATRange() netaddr.IPPrefix {
// provided by Tailscale itself such as the MagicDNS proxy.
//
// For IPv6, use TailscaleServiceIPv6.
-func TailscaleServiceIP() netaddr.IP {
+func TailscaleServiceIP() netip.Addr {
return netaddr.IPv4(100, 100, 100, 100) // "100.100.100.100" for those grepping
}
@@ -55,14 +55,14 @@ func TailscaleServiceIP() netaddr.IP {
// provided by Tailscale itself such as the MagicDNS proxy.
//
// For IPv4, use TailscaleServiceIP.
-func TailscaleServiceIPv6() netaddr.IP {
+func TailscaleServiceIPv6() netip.Addr {
serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, "fd7a:115c:a1e0::53/128") })
return serviceIPv6.v.Addr()
}
// IsTailscaleIP reports whether ip is an IP address in a range that
// Tailscale assigns from.
-func IsTailscaleIP(ip netaddr.IP) bool {
+func IsTailscaleIP(ip netip.Addr) bool {
if ip.Is4() {
return CGNATRange().Contains(ip) && !ChromeOSVMRange().Contains(ip)
}
@@ -71,14 +71,14 @@ func IsTailscaleIP(ip netaddr.IP) bool {
// TailscaleULARange returns the IPv6 Unique Local Address range that
// is the superset range that Tailscale assigns out of.
-func TailscaleULARange() netaddr.IPPrefix {
+func TailscaleULARange() netip.Prefix {
tsUlaRange.Do(func() { mustPrefix(&tsUlaRange.v, "fd7a:115c:a1e0::/48") })
return tsUlaRange.v
}
// TailscaleViaRange returns the IPv6 Unique Local Address subset range
// TailscaleULARange that's used for IPv4 tunneling via IPv6.
-func TailscaleViaRange() netaddr.IPPrefix {
+func TailscaleViaRange() netip.Prefix {
// Mnemonic: "b1a" sounds like "via".
tsViaRange.Do(func() { mustPrefix(&tsViaRange.v, "fd7a:115c:a1e0:b1a::/64") })
return tsViaRange.v
@@ -86,7 +86,7 @@ func TailscaleViaRange() netaddr.IPPrefix {
// Tailscale4To6Range returns the subset of TailscaleULARange used for
// auto-translated Tailscale ipv4 addresses.
-func Tailscale4To6Range() netaddr.IPPrefix {
+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.
@@ -96,7 +96,7 @@ func Tailscale4To6Range() netaddr.IPPrefix {
// TailscaleEphemeral6Range returns the subset of TailscaleULARange
// used for ephemeral IPv6-only Tailscale nodes.
-func TailscaleEphemeral6Range() netaddr.IPPrefix {
+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
@@ -112,16 +112,16 @@ func TailscaleEphemeral6Range() netaddr.IPPrefix {
//
// Currently used to work around a Windows limitation when programming
// IPv6 routes in corner cases.
-func Tailscale4To6Placeholder() netaddr.IP {
+func Tailscale4To6Placeholder() netip.Addr {
return Tailscale4To6Range().Addr()
}
// Tailscale4To6 returns a Tailscale IPv6 address that maps 1:1 to the
// given Tailscale IPv4 address. Returns a zero IP if ipv4 isn't a
// Tailscale IPv4 address.
-func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
+func Tailscale4To6(ipv4 netip.Addr) netip.Addr {
if !ipv4.Is4() || !IsTailscaleIP(ipv4) {
- return netaddr.IP{}
+ return netip.Addr{}
}
ret := Tailscale4To6Range().Addr().As16()
v4 := ipv4.As4()
@@ -133,15 +133,15 @@ func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
// tailscale IPv6 address within the 4To6 range. The IPv4 address
// and true are returned if the given address was in the correct range,
// false if not.
-func Tailscale6to4(ipv6 netaddr.IP) (netaddr.IP, bool) {
+func Tailscale6to4(ipv6 netip.Addr) (netip.Addr, bool) {
if !ipv6.Is6() || !Tailscale4To6Range().Contains(ipv6) {
- return netaddr.IP{}, false
+ return netip.Addr{}, false
}
v6 := ipv6.As16()
return netaddr.IPv4(100, v6[13], v6[14], v6[15]), true
}
-func mustPrefix(v *netaddr.IPPrefix, prefix string) {
+func mustPrefix(v *netip.Prefix, prefix string) {
var err error
*v, err = netip.ParsePrefix(prefix)
if err != nil {
@@ -151,7 +151,7 @@ func mustPrefix(v *netaddr.IPPrefix, prefix string) {
type oncePrefix struct {
sync.Once
- v netaddr.IPPrefix
+ v netip.Prefix
}
// NewContainsIPFunc returns a func that reports whether ip is in addrs.
@@ -161,11 +161,11 @@ type oncePrefix struct {
// one IPv6 address).
//
// Otherwise the implementation is somewhat slow.
-func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
+func NewContainsIPFunc(addrs []netip.Prefix) func(ip netip.Addr) bool {
// Specialize the three common cases: no address, just IPv4
// (or just IPv6), and both IPv4 and IPv6.
if len(addrs) == 0 {
- return func(netaddr.IP) bool { return false }
+ return func(netip.Addr) bool { return false }
}
// If any addr is more than a single IP, then just do the slow
// linear thing until
@@ -174,8 +174,8 @@ func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
if a.IsSingleIP() {
continue
}
- acopy := append([]netaddr.IPPrefix(nil), addrs...)
- return func(ip netaddr.IP) bool {
+ acopy := append([]netip.Prefix(nil), addrs...)
+ return func(ip netip.Addr) bool {
for _, a := range acopy {
if a.Contains(ip) {
return true
@@ -187,23 +187,23 @@ func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
// Fast paths for 1 and 2 IPs:
if len(addrs) == 1 {
a := addrs[0]
- return func(ip netaddr.IP) bool { return ip == a.Addr() }
+ return func(ip netip.Addr) bool { return ip == a.Addr() }
}
if len(addrs) == 2 {
a, b := addrs[0], addrs[1]
- return func(ip netaddr.IP) bool { return ip == a.Addr() || ip == b.Addr() }
+ return func(ip netip.Addr) bool { return ip == a.Addr() || ip == b.Addr() }
}
// General case:
- m := map[netaddr.IP]bool{}
+ m := map[netip.Addr]bool{}
for _, a := range addrs {
m[a.Addr()] = true
}
- return func(ip netaddr.IP) bool { return m[ip] }
+ return func(ip netip.Addr) bool { return m[ip] }
}
// PrefixesContainsFunc reports whether f is true for any IPPrefix in
// ipp.
-func PrefixesContainsFunc(ipp []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool) bool {
+func PrefixesContainsFunc(ipp []netip.Prefix, f func(netip.Prefix) bool) bool {
for _, v := range ipp {
if f(v) {
return true
@@ -213,7 +213,7 @@ func PrefixesContainsFunc(ipp []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool)
}
// PrefixesContainsIP reports whether any prefix in ipp contains ip.
-func PrefixesContainsIP(ipp []netaddr.IPPrefix, ip netaddr.IP) bool {
+func PrefixesContainsIP(ipp []netip.Prefix, ip netip.Addr) bool {
for _, r := range ipp {
if r.Contains(ip) {
return true
@@ -223,7 +223,7 @@ func PrefixesContainsIP(ipp []netaddr.IPPrefix, ip netaddr.IP) bool {
}
// IPsContainsFunc reports whether f is true for any IP in ips.
-func IPsContainsFunc(ips []netaddr.IP, f func(netaddr.IP) bool) bool {
+func IPsContainsFunc(ips []netip.Addr, f func(netip.Addr) bool) bool {
for _, v := range ips {
if f(v) {
return true
@@ -233,14 +233,14 @@ func IPsContainsFunc(ips []netaddr.IP, f func(netaddr.IP) bool) bool {
}
// PrefixIs4 reports whether p is an IPv4 prefix.
-func PrefixIs4(p netaddr.IPPrefix) bool { return p.Addr().Is4() }
+func PrefixIs4(p netip.Prefix) bool { return p.Addr().Is4() }
// PrefixIs6 reports whether p is an IPv6 prefix.
-func PrefixIs6(p netaddr.IPPrefix) bool { return p.Addr().Is6() }
+func PrefixIs6(p netip.Prefix) bool { return p.Addr().Is6() }
// ContainsExitRoutes reports whether rr contains both the IPv4 and
// IPv6 /0 route.
-func ContainsExitRoutes(rr []netaddr.IPPrefix) bool {
+func ContainsExitRoutes(rr []netip.Prefix) bool {
var v4, v6 bool
for _, r := range rr {
if r == allIPv4 {
@@ -258,18 +258,18 @@ func ContainsExitRoutes(rr []netaddr.IPPrefix) bool {
)
// AllIPv4 returns 0.0.0.0/0.
-func AllIPv4() netaddr.IPPrefix { return allIPv4 }
+func AllIPv4() netip.Prefix { return allIPv4 }
// AllIPv6 returns ::/0.
-func AllIPv6() netaddr.IPPrefix { return allIPv6 }
+func AllIPv6() netip.Prefix { return allIPv6 }
// ExitRoutes returns a slice containing AllIPv4 and AllIPv6.
-func ExitRoutes() []netaddr.IPPrefix { return []netaddr.IPPrefix{allIPv4, allIPv6} }
+func ExitRoutes() []netip.Prefix { return []netip.Prefix{allIPv4, allIPv6} }
// FilterPrefixes returns a new slice, not aliasing in, containing elements of
// in that match f.
-func FilterPrefixesCopy(in []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool) []netaddr.IPPrefix {
- var out []netaddr.IPPrefix
+func FilterPrefixesCopy(in []netip.Prefix, f func(netip.Prefix) bool) []netip.Prefix {
+ var out []netip.Prefix
for _, v := range in {
if f(v) {
out = append(out, v)
@@ -280,7 +280,7 @@ func FilterPrefixesCopy(in []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool) []
// IsViaPrefix reports whether p is a CIDR in the Tailscale "via" range.
// See TailscaleViaRange.
-func IsViaPrefix(p netaddr.IPPrefix) bool {
+func IsViaPrefix(p netip.Prefix) bool {
return TailscaleViaRange().Contains(p.Addr())
}
@@ -288,16 +288,16 @@ func IsViaPrefix(p netaddr.IPPrefix) bool {
// "via" IPv4-in-IPv6 address.
//
// If ip is not a via address, it returns ip unchanged.
-func UnmapVia(ip netaddr.IP) netaddr.IP {
+func UnmapVia(ip netip.Addr) netip.Addr {
if TailscaleViaRange().Contains(ip) {
a := ip.As16()
- return netaddr.IPFrom4(*(*[4]byte)(a[12:16]))
+ return netip.AddrFrom4(*(*[4]byte)(a[12:16]))
}
return ip
}
// MapVia returns an IPv6 "via" route for an IPv4 CIDR in a given siteID.
-func MapVia(siteID uint32, v4 netaddr.IPPrefix) (via netaddr.IPPrefix, err error) {
+func MapVia(siteID uint32, v4 netip.Prefix) (via netip.Prefix, err error) {
if !v4.Addr().Is4() {
return via, errors.New("want IPv4 CIDR with a site ID")
}
diff --git a/net/tsaddr/tsaddr_test.go b/net/tsaddr/tsaddr_test.go
index cf306dd25..812475ac1 100644
--- a/net/tsaddr/tsaddr_test.go
+++ b/net/tsaddr/tsaddr_test.go
@@ -13,7 +13,7 @@
func TestInCrostiniRange(t *testing.T) {
tests := []struct {
- ip netaddr.IP
+ ip netip.Addr
want bool
}{
{netaddr.IPv4(192, 168, 0, 1), false},
@@ -53,25 +53,25 @@ func TestCGNATRange(t *testing.T) {
}
func TestNewContainsIPFunc(t *testing.T) {
- f := NewContainsIPFunc([]netaddr.IPPrefix{netip.MustParsePrefix("10.0.0.0/8")})
+ f := NewContainsIPFunc([]netip.Prefix{netip.MustParsePrefix("10.0.0.0/8")})
if f(netip.MustParseAddr("8.8.8.8")) {
t.Fatal("bad")
}
if !f(netip.MustParseAddr("10.1.2.3")) {
t.Fatal("bad")
}
- f = NewContainsIPFunc([]netaddr.IPPrefix{netip.MustParsePrefix("10.1.2.3/32")})
+ f = NewContainsIPFunc([]netip.Prefix{netip.MustParsePrefix("10.1.2.3/32")})
if !f(netip.MustParseAddr("10.1.2.3")) {
t.Fatal("bad")
}
- f = NewContainsIPFunc([]netaddr.IPPrefix{
+ f = NewContainsIPFunc([]netip.Prefix{
netip.MustParsePrefix("10.1.2.3/32"),
netip.MustParsePrefix("::2/128"),
})
if !f(netip.MustParseAddr("::2")) {
t.Fatal("bad")
}
- f = NewContainsIPFunc([]netaddr.IPPrefix{
+ f = NewContainsIPFunc([]netip.Prefix{
netip.MustParsePrefix("10.1.2.3/32"),
netip.MustParsePrefix("10.1.2.4/32"),
netip.MustParsePrefix("::2/128"),
@@ -81,7 +81,7 @@ func TestNewContainsIPFunc(t *testing.T) {
}
}
-var sinkIP netaddr.IP
+var sinkIP netip.Addr
func BenchmarkTailscaleServiceAddr(b *testing.B) {
b.ReportAllocs()
diff --git a/net/tsdial/dnsmap.go b/net/tsdial/dnsmap.go
index f56025f80..f98cb6011 100644
--- a/net/tsdial/dnsmap.go
+++ b/net/tsdial/dnsmap.go
@@ -13,7 +13,6 @@
"strconv"
"strings"
- "tailscale.com/net/netaddr"
"tailscale.com/types/netmap"
"tailscale.com/util/dnsname"
)
@@ -23,7 +22,7 @@
//
// Example keys are "foo.domain.tld.beta.tailscale.net" and "foo",
// both without trailing dots, and both always lowercase.
-type dnsMap map[string]netaddr.IP
+type dnsMap map[string]netip.Addr
// canonMapKey canonicalizes its input s to be a dnsMap map key.
func canonMapKey(s string) string {
@@ -98,15 +97,15 @@ func splitHostPort(addr string) (host string, port uint16, err error) {
//
// The error is [exactly] errUnresolved if the addr is a name that isn't known
// in the map.
-func (m dnsMap) resolveMemory(ctx context.Context, network, addr string) (_ netaddr.IPPort, err error) {
+func (m dnsMap) resolveMemory(ctx context.Context, network, addr string) (_ netip.AddrPort, err error) {
host, port, err := splitHostPort(addr)
if err != nil {
// addr malformed or invalid port.
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
if ip, err := netip.ParseAddr(host); err == nil {
// addr was literal ip:port.
- return netaddr.IPPortFrom(ip, port), nil
+ return netip.AddrPortFrom(ip, port), nil
}
// Host is not an IP, so assume it's a DNS name.
@@ -114,8 +113,8 @@ func (m dnsMap) resolveMemory(ctx context.Context, network, addr string) (_ neta
// Try MagicDNS first, otherwise a real DNS lookup.
ip := m[canonMapKey(host)]
if ip.IsValid() {
- return netaddr.IPPortFrom(ip, port), nil
+ return netip.AddrPortFrom(ip, port), nil
}
- return netaddr.IPPort{}, errUnresolved
+ return netip.AddrPort{}, errUnresolved
}
diff --git a/net/tsdial/dnsmap_test.go b/net/tsdial/dnsmap_test.go
index 4991688f1..afa315cfe 100644
--- a/net/tsdial/dnsmap_test.go
+++ b/net/tsdial/dnsmap_test.go
@@ -9,7 +9,6 @@
"reflect"
"testing"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/netmap"
)
@@ -26,7 +25,7 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
name: "self",
nm: &netmap.NetworkMap{
Name: "foo.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100.102.103.104/32"),
pfx("100::123/128"),
},
@@ -40,21 +39,21 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
name: "self_and_peers",
nm: &netmap.NetworkMap{
Name: "foo.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100.102.103.104/32"),
pfx("100::123/128"),
},
Peers: []*tailcfg.Node{
{
Name: "a.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100.0.0.201/32"),
pfx("100::201/128"),
},
},
{
Name: "b.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100::202/128"),
},
},
@@ -73,20 +72,20 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
name: "self_has_v6_only",
nm: &netmap.NetworkMap{
Name: "foo.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100::123/128"),
},
Peers: []*tailcfg.Node{
{
Name: "a.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100.0.0.201/32"),
pfx("100::201/128"),
},
},
{
Name: "b.tailnet",
- Addresses: []netaddr.IPPrefix{
+ Addresses: []netip.Prefix{
pfx("100::202/128"),
},
},
diff --git a/net/tsdial/tsdial.go b/net/tsdial/tsdial.go
index 7edbca75b..4f5211361 100644
--- a/net/tsdial/tsdial.go
+++ b/net/tsdial/tsdial.go
@@ -38,11 +38,11 @@ type Dialer struct {
Logf logger.Logf
// UseNetstackForIP if non-nil is whether NetstackDialTCP (if
// it's non-nil) should be used to dial the provided IP.
- UseNetstackForIP func(netaddr.IP) bool
+ UseNetstackForIP func(netip.Addr) bool
// NetstackDialTCP dials the provided IPPort using netstack.
// If nil, it's not used.
- NetstackDialTCP func(context.Context, netaddr.IPPort) (net.Conn, error)
+ NetstackDialTCP func(context.Context, netip.AddrPort) (net.Conn, error)
peerDialControlFuncAtomic atomic.Value // of func() func(network, address string, c syscall.RawConn) error
@@ -208,7 +208,7 @@ func (d *Dialer) SetNetMap(nm *netmap.NetworkMap) {
d.dns = m
}
-func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (netaddr.IPPort, error) {
+func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (netip.AddrPort, error) {
d.mu.Lock()
dns := d.dns
exitDNSDoH := d.exitDNSDoHBase
@@ -227,7 +227,7 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
host, port, err := splitHostPort(addr)
if err != nil {
// addr is malformed.
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
var r net.Resolver
@@ -245,13 +245,13 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
ips, err := r.LookupIP(ctx, ipNetOfNetwork(network), host)
if err != nil {
- return netaddr.IPPort{}, err
+ return netip.AddrPort{}, err
}
if len(ips) == 0 {
- return netaddr.IPPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
+ return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
}
ip, _ := netaddr.FromStdIP(ips[0])
- return netaddr.IPPortFrom(ip, port), nil
+ return netip.AddrPortFrom(ip, port), nil
}
// ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding
diff --git a/net/tstun/tap_linux.go b/net/tstun/tap_linux.go
index 9ff8a9029..e6b699aec 100644
--- a/net/tstun/tap_linux.go
+++ b/net/tstun/tap_linux.go
@@ -7,6 +7,7 @@
import (
"fmt"
"net"
+ "net/netip"
"os"
"os/exec"
@@ -246,8 +247,8 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
pkt := packLayer2UDP(
offer.ToBytes(),
ourMAC, ethSrcMAC,
- netaddr.IPPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
- netaddr.IPPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
+ netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
+ netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
)
n, err := t.tdev.Write(pkt, 0)
if tapDebug {
@@ -273,8 +274,8 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
pkt := packLayer2UDP(
ack.ToBytes(),
ourMAC, ethSrcMAC,
- netaddr.IPPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
- netaddr.IPPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
+ netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
+ netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
)
n, err := t.tdev.Write(pkt, 0)
if tapDebug {
@@ -288,7 +289,7 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
return consumePacket
}
-func packLayer2UDP(payload []byte, srcMAC, dstMAC net.HardwareAddr, src, dst netaddr.IPPort) []byte {
+func packLayer2UDP(payload []byte, srcMAC, dstMAC net.HardwareAddr, src, dst netip.AddrPort) []byte {
buf := make([]byte, header.EthernetMinimumSize+header.UDPMinimumSize+header.IPv4MinimumSize+len(payload))
payloadStart := len(buf) - len(payload)
copy(buf[payloadStart:], payload)
diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go
index f4b678614..909340416 100644
--- a/net/tstun/wrap.go
+++ b/net/tstun/wrap.go
@@ -10,6 +10,7 @@
"errors"
"fmt"
"io"
+ "net/netip"
"os"
"strings"
"sync"
@@ -21,7 +22,6 @@
"golang.zx2c4.com/wireguard/tun"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"tailscale.com/disco"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/tstime/mono"
@@ -82,7 +82,7 @@ type Wrapper struct {
// you might need to add a pad32.Four field here.
lastActivityAtomic mono.Time // time of last send or receive
- destIPActivity atomic.Value // of map[netaddr.IP]func()
+ destIPActivity atomic.Value // of map[netip.Addr]func()
destMACAtomic atomic.Value // of [6]byte
discoKey atomic.Value // of key.DiscoPublic
@@ -158,7 +158,7 @@ type Wrapper struct {
// PeerAPIPort, if non-nil, returns the peerapi port that's
// running for the given IP address.
- PeerAPIPort func(netaddr.IP) (port uint16, ok bool)
+ PeerAPIPort func(netip.Addr) (port uint16, ok bool)
// disableFilter disables all filtering when set. This should only be used in tests.
disableFilter bool
@@ -222,7 +222,7 @@ func wrap(logf logger.Logf, tdev tun.Device, isTAP bool) *Wrapper {
// destination (the map keys).
//
// The map ownership passes to the Wrapper. It must be non-nil.
-func (t *Wrapper) SetDestIPActivityFuncs(m map[netaddr.IP]func()) {
+func (t *Wrapper) SetDestIPActivityFuncs(m map[netip.Addr]func()) {
t.destIPActivity.Store(m)
}
@@ -429,8 +429,8 @@ func (t *Wrapper) sendOutbound(r tunReadResult) {
}
var (
- magicDNSIPPort = netaddr.IPPortFrom(tsaddr.TailscaleServiceIP(), 0) // 100.100.100.100:0
- magicDNSIPPortv6 = netaddr.IPPortFrom(tsaddr.TailscaleServiceIPv6(), 0)
+ magicDNSIPPort = netip.AddrPortFrom(tsaddr.TailscaleServiceIP(), 0) // 100.100.100.100:0
+ magicDNSIPPortv6 = netip.AddrPortFrom(tsaddr.TailscaleServiceIPv6(), 0)
)
func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response {
@@ -544,7 +544,7 @@ func (t *Wrapper) Read(buf []byte, offset int) (int, error) {
defer parsedPacketPool.Put(p)
p.Decode(buf[offset : offset+n])
- if m, ok := t.destIPActivity.Load().(map[netaddr.IP]func()); ok {
+ if m, ok := t.destIPActivity.Load().(map[netip.Addr]func()); ok {
if fn := m[p.Dst.Addr()]; fn != nil {
fn()
}
diff --git a/net/tstun/wrap_test.go b/net/tstun/wrap_test.go
index 412d95424..ccb155e51 100644
--- a/net/tstun/wrap_test.go
+++ b/net/tstun/wrap_test.go
@@ -77,7 +77,7 @@ func tcp4syn(src, dst string, sport, dport uint16) []byte {
return both
}
-func nets(nets ...string) (ret []netaddr.IPPrefix) {
+func nets(nets ...string) (ret []netip.Prefix) {
for _, s := range nets {
if i := strings.IndexByte(s, '/'); i == -1 {
ip, err := netip.ParseAddr(s)
@@ -88,7 +88,7 @@ func nets(nets ...string) (ret []netaddr.IPPrefix) {
if ip.Is6() {
bits = 128
}
- ret = append(ret, netaddr.IPPrefixFrom(ip, bits))
+ ret = append(ret, netip.PrefixFrom(ip, int(bits)))
} else {
pfx, err := netip.ParsePrefix(s)
if err != nil {
@@ -428,7 +428,7 @@ func TestAtomic64Alignment(t *testing.T) {
func TestPeerAPIBypass(t *testing.T) {
wrapperWithPeerAPI := &Wrapper{
- PeerAPIPort: func(ip netaddr.IP) (port uint16, ok bool) {
+ PeerAPIPort: func(ip netip.Addr) (port uint16, ok bool) {
if ip == netip.MustParseAddr("100.64.1.2") {
return 60000, true
}
@@ -446,7 +446,7 @@ func TestPeerAPIBypass(t *testing.T) {
{
name: "reject_nil_filter",
w: &Wrapper{
- PeerAPIPort: func(netaddr.IP) (port uint16, ok bool) {
+ PeerAPIPort: func(netip.Addr) (port uint16, ok bool) {
return 60000, true
},
},
diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go
index 0d2c46517..7d6ad72e6 100644
--- a/ssh/tailssh/tailssh.go
+++ b/ssh/tailssh/tailssh.go
@@ -405,7 +405,7 @@ func (c *conn) sshPolicy() (_ *tailcfg.SSHPolicy, ok bool) {
return nil, false
}
-func toIPPort(a net.Addr) (ipp netaddr.IPPort) {
+func toIPPort(a net.Addr) (ipp netip.AddrPort) {
ta, ok := a.(*net.TCPAddr)
if !ok {
return
@@ -414,7 +414,7 @@ func toIPPort(a net.Addr) (ipp netaddr.IPPort) {
if !ok {
return
}
- return netaddr.IPPortFrom(tanetaddr, uint16(ta.Port))
+ return netip.AddrPortFrom(tanetaddr, uint16(ta.Port))
}
// connInfo returns a populated sshConnInfo from the provided arguments,
@@ -1103,10 +1103,10 @@ type sshConnInfo struct {
sshUser string
// src is the Tailscale IP and port that the connection came from.
- src netaddr.IPPort
+ src netip.AddrPort
// dst is the Tailscale IP and port that the connection came for.
- dst netaddr.IPPort
+ dst netip.AddrPort
// node is srcIP's node.
node *tailcfg.Node
diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go
index ad36c0c77..b37293325 100644
--- a/tailcfg/tailcfg.go
+++ b/tailcfg/tailcfg.go
@@ -10,11 +10,11 @@
"encoding/hex"
"errors"
"fmt"
+ "net/netip"
"reflect"
"strings"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/types/dnstype"
"tailscale.com/types/key"
"tailscale.com/types/opt"
@@ -170,10 +170,10 @@ type Node struct {
KeyExpiry time.Time
Machine key.MachinePublic
DiscoKey key.DiscoPublic
- Addresses []netaddr.IPPrefix // IP addresses of this Node directly
- AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node
- Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs)
- DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint
+ Addresses []netip.Prefix // IP addresses of this Node directly
+ AllowedIPs []netip.Prefix // range of IP addresses to route to this node
+ Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs)
+ DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint
Hostinfo HostinfoView
Created time.Time
@@ -190,7 +190,7 @@ type Node struct {
// is currently the primary subnet router for, as determined
// by the control plane. It does not include the self address
// values from Addresses that are in AllowedIPs.
- PrimaryRoutes []netaddr.IPPrefix `json:",omitempty"`
+ PrimaryRoutes []netip.Prefix `json:",omitempty"`
// LastSeen is when the node was last online. It is not
// updated when Online is true. It is nil if the current
@@ -454,24 +454,24 @@ type Service struct {
// Because it contains pointers (slices), this type should not be used
// as a value type.
type Hostinfo struct {
- IPNVersion string `json:",omitempty"` // version of this code
- FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance
- BackendLogID string `json:",omitempty"` // logtail ID of backend instance
- OS string `json:",omitempty"` // operating system the client runs on (a version.OS value)
- OSVersion string `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041")
- Desktop opt.Bool `json:",omitempty"` // if a desktop was detected on Linux
- Package string `json:",omitempty"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown)
- DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3")
- Hostname string `json:",omitempty"` // name of the host the client runs on
- ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections
- ShareeNode bool `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user
- GoArch string `json:",omitempty"` // the host's GOARCH value (of the running binary)
- RoutableIPs []netaddr.IPPrefix `json:",omitempty"` // set of IP ranges this client can route
- RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim
- Services []Service `json:",omitempty"` // services advertised by this machine
- NetInfo *NetInfo `json:",omitempty"`
- SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised
- Cloud string `json:",omitempty"`
+ IPNVersion string `json:",omitempty"` // version of this code
+ FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance
+ BackendLogID string `json:",omitempty"` // logtail ID of backend instance
+ OS string `json:",omitempty"` // operating system the client runs on (a version.OS value)
+ OSVersion string `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041")
+ Desktop opt.Bool `json:",omitempty"` // if a desktop was detected on Linux
+ Package string `json:",omitempty"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown)
+ DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3")
+ Hostname string `json:",omitempty"` // name of the host the client runs on
+ ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections
+ ShareeNode bool `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user
+ GoArch string `json:",omitempty"` // the host's GOARCH value (of the running binary)
+ RoutableIPs []netip.Prefix `json:",omitempty"` // set of IP ranges this client can route
+ RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim
+ Services []Service `json:",omitempty"` // services advertised by this machine
+ NetInfo *NetInfo `json:",omitempty"`
+ SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised
+ Cloud string `json:",omitempty"`
// NOTE: any new fields containing pointers in this type
// require changes to Hostinfo.Equal.
@@ -854,7 +854,7 @@ func (et EndpointType) String() string {
// broken up into two parallel slices in MapRequest, for compatibility
// reasons. But this type is used in the codebase.
type Endpoint struct {
- Addr netaddr.IPPort
+ Addr netip.AddrPort
Type EndpointType
}
@@ -946,7 +946,7 @@ type NetPortRange struct {
type CapGrant struct {
// Dsts are the destination IP ranges that this capabilty
// grant matches.
- Dsts []netaddr.IPPrefix
+ Dsts []netip.Prefix
// Caps are the capabilities the source IP matched by
// FilterRule.SrcIPs are granted to the destination IP,
@@ -1059,7 +1059,7 @@ type DNSConfig struct {
// MapRequest.Version >=9 and <14.
// Nameservers are the IP addresses of the nameservers to use.
- Nameservers []netaddr.IP `json:",omitempty"`
+ Nameservers []netip.Addr `json:",omitempty"`
// PerDomain is not set by the control server, and does nothing.
PerDomain bool `json:",omitempty"`
@@ -1149,7 +1149,7 @@ type PingRequest struct {
// IP is the ping target.
// It is used in TSMP pings, if IP is invalid or empty then do a HEAD request to the URL.
- IP netaddr.IP
+ IP netip.Addr
}
// PingResponse provides result information for a TSMP or Disco PingRequest.
@@ -1446,7 +1446,7 @@ func eqStrings(a, b []string) bool {
return true
}
-func eqCIDRs(a, b []netaddr.IPPrefix) bool {
+func eqCIDRs(a, b []netip.Prefix) bool {
if len(a) != len(b) || ((a == nil) != (b == nil)) {
return false
}
diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go
index 829eaab69..28ecc7dbc 100644
--- a/tailcfg/tailcfg_test.go
+++ b/tailcfg/tailcfg_test.go
@@ -13,7 +13,6 @@
"testing"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tstest"
"tailscale.com/types/key"
"tailscale.com/version"
@@ -40,7 +39,7 @@ func TestHostinfoEqual(t *testing.T) {
have, hiHandles)
}
- nets := func(strs ...string) (ns []netaddr.IPPrefix) {
+ nets := func(strs ...string) (ns []netip.Prefix) {
for _, s := range strs {
n, err := netip.ParsePrefix(s)
if err != nil {
@@ -225,12 +224,12 @@ func TestHostinfoHowEqual(t *testing.T) {
a: &Hostinfo{
IPNVersion: "1",
ShieldsUp: false,
- RoutableIPs: []netaddr.IPPrefix{netip.MustParsePrefix("1.2.3.0/24")},
+ RoutableIPs: []netip.Prefix{netip.MustParsePrefix("1.2.3.0/24")},
},
b: &Hostinfo{
IPNVersion: "2",
ShieldsUp: true,
- RoutableIPs: []netaddr.IPPrefix{netip.MustParsePrefix("1.2.3.0/25")},
+ RoutableIPs: []netip.Prefix{netip.MustParsePrefix("1.2.3.0/25")},
},
want: []string{"IPNVersion", "ShieldsUp", "RoutableIPs"},
},
@@ -403,23 +402,23 @@ func TestNodeEqual(t *testing.T) {
true,
},
{
- &Node{Addresses: []netaddr.IPPrefix{}},
+ &Node{Addresses: []netip.Prefix{}},
&Node{Addresses: nil},
false,
},
{
- &Node{Addresses: []netaddr.IPPrefix{}},
- &Node{Addresses: []netaddr.IPPrefix{}},
+ &Node{Addresses: []netip.Prefix{}},
+ &Node{Addresses: []netip.Prefix{}},
true,
},
{
- &Node{AllowedIPs: []netaddr.IPPrefix{}},
+ &Node{AllowedIPs: []netip.Prefix{}},
&Node{AllowedIPs: nil},
false,
},
{
- &Node{Addresses: []netaddr.IPPrefix{}},
- &Node{Addresses: []netaddr.IPPrefix{}},
+ &Node{Addresses: []netip.Prefix{}},
+ &Node{Addresses: []netip.Prefix{}},
true,
},
{
@@ -566,8 +565,8 @@ func TestCloneNode(t *testing.T) {
}{
{"nil_fields", &Node{}},
{"zero_fields", &Node{
- Addresses: make([]netaddr.IPPrefix, 0),
- AllowedIPs: make([]netaddr.IPPrefix, 0),
+ Addresses: make([]netip.Prefix, 0),
+ AllowedIPs: make([]netip.Prefix, 0),
Endpoints: make([]string, 0),
}},
}
diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go
index 62071c56f..0f8f1a03d 100644
--- a/tsnet/tsnet.go
+++ b/tsnet/tsnet.go
@@ -14,6 +14,7 @@
"log"
"net"
"net/http"
+ "net/netip"
"os"
"path/filepath"
"strings"
@@ -32,7 +33,6 @@
"tailscale.com/logpolicy"
"tailscale.com/logtail"
"tailscale.com/logtail/filch"
- "tailscale.com/net/netaddr"
"tailscale.com/net/nettest"
"tailscale.com/net/tsdial"
"tailscale.com/smallzstd"
@@ -272,11 +272,11 @@ func (s *Server) start() error {
if err := ns.Start(); err != nil {
return fmt.Errorf("failed to start netstack: %w", err)
}
- s.dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
+ s.dialer.UseNetstackForIP = func(ip netip.Addr) bool {
_, ok := eng.PeerForIP(ip)
return ok
}
- s.dialer.NetstackDialTCP = func(ctx context.Context, dst netaddr.IPPort) (net.Conn, error) {
+ s.dialer.NetstackDialTCP = func(ctx context.Context, dst netip.AddrPort) (net.Conn, error) {
return ns.DialContextTCP(ctx, dst)
}
diff --git a/tstest/integration/integration_test.go b/tstest/integration/integration_test.go
index 75388e437..787bef758 100644
--- a/tstest/integration/integration_test.go
+++ b/tstest/integration/integration_test.go
@@ -34,7 +34,6 @@
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
"tailscale.com/ipn/store"
- "tailscale.com/net/netaddr"
"tailscale.com/safesocket"
"tailscale.com/tailcfg"
"tailscale.com/tstest"
@@ -814,10 +813,10 @@ func (n *testNode) AwaitListening() {
}
}
-func (n *testNode) AwaitIPs() []netaddr.IP {
+func (n *testNode) AwaitIPs() []netip.Addr {
t := n.env.t
t.Helper()
- var addrs []netaddr.IP
+ var addrs []netip.Addr
if err := tstest.WaitFor(20*time.Second, func() error {
cmd := n.Tailscale("ip")
cmd.Stdout = nil // in case --verbose-tailscale was set
@@ -828,7 +827,7 @@ func (n *testNode) AwaitIPs() []netaddr.IP {
}
ips := string(out)
ipslice := strings.Fields(ips)
- addrs = make([]netaddr.IP, len(ipslice))
+ addrs = make([]netip.Addr, len(ipslice))
for i, ip := range ipslice {
netIP, err := netip.ParseAddr(ip)
@@ -848,7 +847,7 @@ func (n *testNode) AwaitIPs() []netaddr.IP {
}
// AwaitIP returns the IP address of n.
-func (n *testNode) AwaitIP() netaddr.IP {
+func (n *testNode) AwaitIP() netip.Addr {
t := n.env.t
t.Helper()
ips := n.AwaitIPs()
diff --git a/tstest/integration/tailscaled_deps_test_darwin.go b/tstest/integration/tailscaled_deps_test_darwin.go
index 60ee07949..b5250c39c 100644
--- a/tstest/integration/tailscaled_deps_test_darwin.go
+++ b/tstest/integration/tailscaled_deps_test_darwin.go
@@ -23,7 +23,6 @@
_ "tailscale.com/logtail"
_ "tailscale.com/net/dns"
_ "tailscale.com/net/interfaces"
- _ "tailscale.com/net/netaddr"
_ "tailscale.com/net/netns"
_ "tailscale.com/net/portmapper"
_ "tailscale.com/net/proxymux"
diff --git a/tstest/integration/tailscaled_deps_test_freebsd.go b/tstest/integration/tailscaled_deps_test_freebsd.go
index abf79d8cb..37bf376c5 100644
--- a/tstest/integration/tailscaled_deps_test_freebsd.go
+++ b/tstest/integration/tailscaled_deps_test_freebsd.go
@@ -23,7 +23,6 @@
_ "tailscale.com/logtail"
_ "tailscale.com/net/dns"
_ "tailscale.com/net/interfaces"
- _ "tailscale.com/net/netaddr"
_ "tailscale.com/net/netns"
_ "tailscale.com/net/portmapper"
_ "tailscale.com/net/proxymux"
diff --git a/tstest/integration/tailscaled_deps_test_linux.go b/tstest/integration/tailscaled_deps_test_linux.go
index 60ee07949..b5250c39c 100644
--- a/tstest/integration/tailscaled_deps_test_linux.go
+++ b/tstest/integration/tailscaled_deps_test_linux.go
@@ -23,7 +23,6 @@
_ "tailscale.com/logtail"
_ "tailscale.com/net/dns"
_ "tailscale.com/net/interfaces"
- _ "tailscale.com/net/netaddr"
_ "tailscale.com/net/netns"
_ "tailscale.com/net/portmapper"
_ "tailscale.com/net/proxymux"
diff --git a/tstest/integration/tailscaled_deps_test_openbsd.go b/tstest/integration/tailscaled_deps_test_openbsd.go
index abf79d8cb..37bf376c5 100644
--- a/tstest/integration/tailscaled_deps_test_openbsd.go
+++ b/tstest/integration/tailscaled_deps_test_openbsd.go
@@ -23,7 +23,6 @@
_ "tailscale.com/logtail"
_ "tailscale.com/net/dns"
_ "tailscale.com/net/interfaces"
- _ "tailscale.com/net/netaddr"
_ "tailscale.com/net/netns"
_ "tailscale.com/net/portmapper"
_ "tailscale.com/net/proxymux"
diff --git a/tstest/integration/tailscaled_deps_test_windows.go b/tstest/integration/tailscaled_deps_test_windows.go
index a82637ac5..122c99528 100644
--- a/tstest/integration/tailscaled_deps_test_windows.go
+++ b/tstest/integration/tailscaled_deps_test_windows.go
@@ -28,7 +28,6 @@
_ "tailscale.com/logtail/backoff"
_ "tailscale.com/net/dns"
_ "tailscale.com/net/interfaces"
- _ "tailscale.com/net/netaddr"
_ "tailscale.com/net/netns"
_ "tailscale.com/net/portmapper"
_ "tailscale.com/net/proxymux"
diff --git a/tstest/integration/testcontrol/testcontrol.go b/tstest/integration/testcontrol/testcontrol.go
index cf972488f..e20e41b75 100644
--- a/tstest/integration/testcontrol/testcontrol.go
+++ b/tstest/integration/testcontrol/testcontrol.go
@@ -312,7 +312,7 @@ func (s *Server) AddFakeNode() {
r := nk.Raw32()
id := int64(binary.LittleEndian.Uint64(r[:]))
ip := netaddr.IPv4(r[0], r[1], r[2], r[3])
- addr := netaddr.IPPrefixFrom(ip, 32)
+ addr := netip.PrefixFrom(ip, 32)
s.nodes[nk] = &tailcfg.Node{
ID: tailcfg.NodeID(id),
StableID: tailcfg.StableNodeID(fmt.Sprintf("TESTCTRL%08x", id)),
@@ -321,8 +321,8 @@ func (s *Server) AddFakeNode() {
Key: nk,
MachineAuthorized: true,
DiscoKey: dk,
- Addresses: []netaddr.IPPrefix{addr},
- AllowedIPs: []netaddr.IPPrefix{addr},
+ Addresses: []netip.Prefix{addr},
+ AllowedIPs: []netip.Prefix{addr},
}
// TODO: send updates to other (non-fake?) nodes
}
@@ -475,10 +475,10 @@ func (s *Server) serveRegister(w http.ResponseWriter, r *http.Request, mkey key.
machineAuthorized := true // TODO: add Server.RequireMachineAuth
- v4Prefix := netaddr.IPPrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
- v6Prefix := netaddr.IPPrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
+ v4Prefix := netip.PrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
+ v6Prefix := netip.PrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
- allowedIPs := []netaddr.IPPrefix{
+ allowedIPs := []netip.Prefix{
v4Prefix,
v6Prefix,
}
@@ -761,10 +761,10 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
return res.Peers[i].ID < res.Peers[j].ID
})
- v4Prefix := netaddr.IPPrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
- v6Prefix := netaddr.IPPrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
+ v4Prefix := netip.PrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
+ v6Prefix := netip.PrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
- res.Node.Addresses = []netaddr.IPPrefix{
+ res.Node.Addresses = []netip.Prefix{
v4Prefix,
v6Prefix,
}
diff --git a/tstest/integration/vms/derive_bindhost_test.go b/tstest/integration/vms/derive_bindhost_test.go
index eeac158f4..da793d5a0 100644
--- a/tstest/integration/vms/derive_bindhost_test.go
+++ b/tstest/integration/vms/derive_bindhost_test.go
@@ -6,11 +6,11 @@
import (
"io"
+ "net/netip"
"runtime"
"testing"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
)
func deriveBindhost(t *testing.T) string {
@@ -22,7 +22,7 @@ func deriveBindhost(t *testing.T) string {
}
var ret string
- err = interfaces.ForeachInterfaceAddress(func(i interfaces.Interface, prefix netaddr.IPPrefix) {
+ err = interfaces.ForeachInterfaceAddress(func(i interfaces.Interface, prefix netip.Prefix) {
if ret != "" || i.Name != ifName {
return
}
diff --git a/tstest/integration/vms/harness_test.go b/tstest/integration/vms/harness_test.go
index 6fb9cff2a..5785635cf 100644
--- a/tstest/integration/vms/harness_test.go
+++ b/tstest/integration/vms/harness_test.go
@@ -26,7 +26,6 @@
"golang.org/x/crypto/ssh"
"golang.org/x/net/proxy"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/tstest/integration"
"tailscale.com/tstest/integration/testcontrol"
@@ -43,7 +42,7 @@ type Harness struct {
signer ssh.Signer
cs *testcontrol.Server
loginServerURL string
- testerV4 netaddr.IP
+ testerV4 netip.Addr
ipMu *sync.Mutex
ipMap map[string]ipMapping
}
@@ -240,6 +239,6 @@ func (h *Harness) makeTestNode(t *testing.T, controlURL string) {
h.testerV4 = bytes2Netaddr(h.Tailscale(t, "ip", "-4"))
}
-func bytes2Netaddr(inp []byte) netaddr.IP {
+func bytes2Netaddr(inp []byte) netip.Addr {
return netip.MustParseAddr(string(bytes.TrimSpace(inp)))
}
diff --git a/tstest/integration/vms/vms_steps_test.go b/tstest/integration/vms/vms_steps_test.go
index 684ceb3d2..5fb4b6b42 100644
--- a/tstest/integration/vms/vms_steps_test.go
+++ b/tstest/integration/vms/vms_steps_test.go
@@ -13,12 +13,12 @@
"fmt"
"net"
"net/http"
+ "net/netip"
"strings"
"testing"
"time"
"golang.org/x/crypto/ssh"
- "tailscale.com/net/netaddr"
)
const timeout = 15 * time.Second
@@ -40,7 +40,7 @@ func retry(t *testing.T, fn func() error) {
t.Fatalf("tried %d times, got: %v", tries, err)
}
-func (h *Harness) testPing(t *testing.T, ipAddr netaddr.IP, cli *ssh.Client) {
+func (h *Harness) testPing(t *testing.T, ipAddr netip.Addr, cli *ssh.Client) {
retry(t, func() error {
sess := getSession(t, cli)
cmd := fmt.Sprintf("tailscale ping --verbose %s", ipAddr)
@@ -85,7 +85,7 @@ func getSession(t *testing.T, cli *ssh.Client) *ssh.Session {
return sess
}
-func (h *Harness) testOutgoingTCP(t *testing.T, ipAddr netaddr.IP, cli *ssh.Client) {
+func (h *Harness) testOutgoingTCP(t *testing.T, ipAddr netip.Addr, cli *ssh.Client) {
const sendmsg = "this is a message that curl won't print"
ctx, cancel := context.WithCancel(context.Background())
s := &http.Server{
diff --git a/tstest/integration/vms/vms_test.go b/tstest/integration/vms/vms_test.go
index d9524c8d8..aaa29df4a 100644
--- a/tstest/integration/vms/vms_test.go
+++ b/tstest/integration/vms/vms_test.go
@@ -29,7 +29,6 @@
expect "github.com/tailscale/goexpect"
"golang.org/x/crypto/ssh"
"golang.org/x/sync/semaphore"
- "tailscale.com/net/netaddr"
"tailscale.com/tstest"
"tailscale.com/tstest/integration"
"tailscale.com/types/logger"
@@ -441,7 +440,7 @@ func (h *Harness) testDistro(t *testing.T, d Distro, ipm ipMapping) {
for _, tt := range []struct {
ipProto string
- addr netaddr.IP
+ addr netip.Addr
}{
{"ipv4", h.testerV4},
} {
diff --git a/tstest/natlab/firewall.go b/tstest/natlab/firewall.go
index 2fc458d40..1e8cb4e67 100644
--- a/tstest/natlab/firewall.go
+++ b/tstest/natlab/firewall.go
@@ -9,8 +9,6 @@
"net/netip"
"sync"
"time"
-
- "tailscale.com/net/netaddr"
)
// FirewallType is the type of filtering a stateful firewall
@@ -38,8 +36,8 @@
// some fields, so in practice the key is either a 2-tuple (src only),
// 3-tuple (src ip+port and dst ip) or 4-tuple (src+dst ip+port).
type fwKey struct {
- src netaddr.IPPort
- dst netaddr.IPPort
+ src netip.AddrPort
+ dst netip.AddrPort
}
// key returns an fwKey for the given src and dst, trimmed according
@@ -48,7 +46,7 @@ type fwKey struct {
// world), it's the caller's responsibility to swap src and dst in the
// call to key when processing packets inbound from the "untrusted"
// world.
-func (s FirewallType) key(src, dst netaddr.IPPort) fwKey {
+func (s FirewallType) key(src, dst netip.AddrPort) fwKey {
k := fwKey{src: src}
switch s {
case EndpointIndependentFirewall:
diff --git a/tstest/natlab/nat.go b/tstest/natlab/nat.go
index f6b8f46fb..88676d591 100644
--- a/tstest/natlab/nat.go
+++ b/tstest/natlab/nat.go
@@ -11,15 +11,13 @@
"net/netip"
"sync"
"time"
-
- "tailscale.com/net/netaddr"
)
// mapping is the state of an allocated NAT session.
type mapping struct {
- lanSrc netaddr.IPPort
- lanDst netaddr.IPPort
- wanSrc netaddr.IPPort
+ lanSrc netip.AddrPort
+ lanDst netip.AddrPort
+ wanSrc netip.AddrPort
deadline time.Time
// pc is a PacketConn that reserves an outbound port on the NAT's
@@ -55,10 +53,10 @@ type mapping struct {
// fields, so in practice the key is either a 2-tuple (src only),
// 3-tuple (src ip+port and dst ip) or 4-tuple (src+dst ip+port).
type natKey struct {
- src, dst netaddr.IPPort
+ src, dst netip.AddrPort
}
-func (t NATType) key(src, dst netaddr.IPPort) natKey {
+func (t NATType) key(src, dst netip.AddrPort) natKey {
k := natKey{src: src}
switch t {
case EndpointIndependentNAT:
@@ -102,7 +100,7 @@ type SNAT44 struct {
mu sync.Mutex
byLAN map[natKey]*mapping // lookup by outbound packet tuple
- byWAN map[netaddr.IPPort]*mapping // lookup by wan ip:port only
+ byWAN map[netip.AddrPort]*mapping // lookup by wan ip:port only
}
func (n *SNAT44) timeNow() time.Time {
@@ -122,7 +120,7 @@ func (n *SNAT44) mappingTimeout() time.Duration {
func (n *SNAT44) initLocked() {
if n.byLAN == nil {
n.byLAN = map[natKey]*mapping{}
- n.byWAN = map[netaddr.IPPort]*mapping{}
+ n.byWAN = map[netip.AddrPort]*mapping{}
}
if n.ExternalInterface.Machine() != n.Machine {
panic(fmt.Sprintf("NAT given interface %s that is not part of given machine %s", n.ExternalInterface, n.Machine.Name))
@@ -228,7 +226,7 @@ func (n *SNAT44) HandleForward(p *Packet, iif, oif *Interface) *Packet {
}
}
-func (n *SNAT44) allocateMappedPort() (net.PacketConn, netaddr.IPPort) {
+func (n *SNAT44) allocateMappedPort() (net.PacketConn, netip.AddrPort) {
// Clean up old entries before trying to allocate, to free up any
// expired ports.
n.gc()
@@ -238,7 +236,7 @@ func (n *SNAT44) allocateMappedPort() (net.PacketConn, netaddr.IPPort) {
if err != nil {
panic(fmt.Sprintf("ran out of NAT ports: %v", err))
}
- addr := netaddr.IPPortFrom(ip, uint16(pc.LocalAddr().(*net.UDPAddr).Port))
+ addr := netip.AddrPortFrom(ip, uint16(pc.LocalAddr().(*net.UDPAddr).Port))
return pc, addr
}
diff --git a/tstest/natlab/natlab.go b/tstest/natlab/natlab.go
index 5f2ce9cbb..a55a2e485 100644
--- a/tstest/natlab/natlab.go
+++ b/tstest/natlab/natlab.go
@@ -31,7 +31,7 @@
// Packet represents a UDP packet flowing through the virtual network.
type Packet struct {
- Src, Dst netaddr.IPPort
+ Src, Dst netip.AddrPort
Payload []byte
// Prefix set by various internal methods of natlab, to locate
@@ -80,7 +80,7 @@ func (p *Packet) setLocator(msg string, args ...any) {
p.locator = fmt.Sprintf(" "+msg, args...)
}
-func mustPrefix(s string) netaddr.IPPrefix {
+func mustPrefix(s string) netip.Prefix {
ipp, err := netip.ParsePrefix(s)
if err != nil {
panic(err)
@@ -100,14 +100,14 @@ func NewInternet() *Network {
type Network struct {
Name string
- Prefix4 netaddr.IPPrefix
- Prefix6 netaddr.IPPrefix
+ Prefix4 netip.Prefix
+ Prefix6 netip.Prefix
mu sync.Mutex
- machine map[netaddr.IP]*Interface
+ machine map[netip.Addr]*Interface
defaultGW *Interface // optional
- lastV4 netaddr.IP
- lastV6 netaddr.IP
+ lastV4 netip.Addr
+ lastV6 netip.Addr
}
func (n *Network) SetDefaultGateway(gwIf *Interface) {
@@ -119,21 +119,21 @@ func (n *Network) SetDefaultGateway(gwIf *Interface) {
n.defaultGW = gwIf
}
-func (n *Network) addMachineLocked(ip netaddr.IP, iface *Interface) {
+func (n *Network) addMachineLocked(ip netip.Addr, iface *Interface) {
if iface == nil {
return // for tests
}
if n.machine == nil {
- n.machine = map[netaddr.IP]*Interface{}
+ n.machine = map[netip.Addr]*Interface{}
}
n.machine[ip] = iface
}
-func (n *Network) allocIPv4(iface *Interface) netaddr.IP {
+func (n *Network) allocIPv4(iface *Interface) netip.Addr {
n.mu.Lock()
defer n.mu.Unlock()
if !n.Prefix4.IsValid() {
- return netaddr.IP{}
+ return netip.Addr{}
}
if !n.lastV4.IsValid() {
n.lastV4 = n.Prefix4.Addr()
@@ -148,11 +148,11 @@ func (n *Network) allocIPv4(iface *Interface) netaddr.IP {
return n.lastV4
}
-func (n *Network) allocIPv6(iface *Interface) netaddr.IP {
+func (n *Network) allocIPv6(iface *Interface) netip.Addr {
n.mu.Lock()
defer n.mu.Unlock()
if !n.Prefix6.IsValid() {
- return netaddr.IP{}
+ return netip.Addr{}
}
if !n.lastV6.IsValid() {
n.lastV6 = n.Prefix6.Addr()
@@ -212,7 +212,7 @@ type Interface struct {
machine *Machine
net *Network
name string // optional
- ips []netaddr.IP // static; not mutated once created
+ ips []netip.Addr // static; not mutated once created
}
func (f *Interface) Machine() *Machine {
@@ -224,18 +224,18 @@ func (f *Interface) Network() *Network {
}
// V4 returns the machine's first IPv4 address, or the zero value if none.
-func (f *Interface) V4() netaddr.IP { return f.pickIP(netaddr.IP.Is4) }
+func (f *Interface) V4() netip.Addr { return f.pickIP(netip.Addr.Is4) }
// V6 returns the machine's first IPv6 address, or the zero value if none.
-func (f *Interface) V6() netaddr.IP { return f.pickIP(netaddr.IP.Is6) }
+func (f *Interface) V6() netip.Addr { return f.pickIP(netip.Addr.Is6) }
-func (f *Interface) pickIP(pred func(netaddr.IP) bool) netaddr.IP {
+func (f *Interface) pickIP(pred func(netip.Addr) bool) netip.Addr {
for _, ip := range f.ips {
if pred(ip) {
return ip
}
}
- return netaddr.IP{}
+ return netip.Addr{}
}
func (f *Interface) String() string {
@@ -247,7 +247,7 @@ func (f *Interface) String() string {
}
// Contains reports whether f contains ip as an IP.
-func (f *Interface) Contains(ip netaddr.IP) bool {
+func (f *Interface) Contains(ip netip.Addr) bool {
for _, v := range f.ips {
if ip == v {
return true
@@ -257,7 +257,7 @@ func (f *Interface) Contains(ip netaddr.IP) bool {
}
type routeEntry struct {
- prefix netaddr.IPPrefix
+ prefix netip.Prefix
iface *Interface
}
@@ -341,11 +341,11 @@ type Machine struct {
interfaces []*Interface
routes []routeEntry // sorted by longest prefix to shortest
- conns4 map[netaddr.IPPort]*conn // conns that want IPv4 packets
- conns6 map[netaddr.IPPort]*conn // conns that want IPv6 packets
+ conns4 map[netip.AddrPort]*conn // conns that want IPv4 packets
+ conns6 map[netip.AddrPort]*conn // conns that want IPv6 packets
}
-func (m *Machine) isLocalIP(ip netaddr.IP) bool {
+func (m *Machine) isLocalIP(ip netip.Addr) bool {
m.mu.Lock()
defer m.mu.Unlock()
for _, intf := range m.interfaces {
@@ -392,10 +392,10 @@ func (m *Machine) deliverLocalPacket(p *Packet, iface *Interface) {
if p.Dst.Addr().Is6() {
conns = m.conns6
}
- possibleDsts := []netaddr.IPPort{
+ possibleDsts := []netip.AddrPort{
p.Dst,
- netaddr.IPPortFrom(v6unspec, p.Dst.Port()),
- netaddr.IPPortFrom(v4unspec, p.Dst.Port()),
+ netip.AddrPortFrom(v6unspec, p.Dst.Port()),
+ netip.AddrPortFrom(v4unspec, p.Dst.Port()),
}
for _, dest := range possibleDsts {
c, ok := conns[dest]
@@ -443,7 +443,7 @@ func (m *Machine) forwardPacket(p *Packet, iif *Interface) {
oif.net.write(p)
}
-func unspecOf(ip netaddr.IP) netaddr.IP {
+func unspecOf(ip netip.Addr) netip.Addr {
if ip.Is4() {
return v4unspec
}
@@ -562,7 +562,7 @@ func (m *Machine) writePacket(p *Packet) (n int, err error) {
return iface.net.write(p)
}
-func (m *Machine) interfaceForIP(ip netaddr.IP) (*Interface, error) {
+func (m *Machine) interfaceForIP(ip netip.Addr) (*Interface, error) {
m.mu.Lock()
defer m.mu.Unlock()
for _, re := range m.routes {
@@ -642,12 +642,12 @@ func (m *Machine) unregisterConn6(c *conn) {
delete(m.conns6, c.ipp)
}
-func registerConn(conns *map[netaddr.IPPort]*conn, c *conn) error {
+func registerConn(conns *map[netip.AddrPort]*conn, c *conn) error {
if _, ok := (*conns)[c.ipp]; ok {
return fmt.Errorf("duplicate conn listening on %v", c.ipp)
}
if *conns == nil {
- *conns = map[netaddr.IPPort]*conn{}
+ *conns = map[netip.AddrPort]*conn{}
}
(*conns)[c.ipp] = c
return nil
@@ -659,7 +659,7 @@ func (m *Machine) ListenPacket(ctx context.Context, network, address string) (ne
// if udp4, udp6, etc... look at address IP vs unspec
var (
fam uint8
- ip netaddr.IP
+ ip netip.Addr
)
switch network {
default:
@@ -705,7 +705,7 @@ func (m *Machine) ListenPacket(ctx context.Context, network, address string) (ne
return nil, nil
}
}
- ipp := netaddr.IPPortFrom(ip, port)
+ ipp := netip.AddrPortFrom(ip, port)
c := &conn{
m: m,
@@ -738,7 +738,7 @@ func (m *Machine) ListenPacket(ctx context.Context, network, address string) (ne
type conn struct {
m *Machine
fam uint8 // 0, 4, or 6
- ipp netaddr.IPPort
+ ipp netip.AddrPort
mu sync.Mutex
closed bool
diff --git a/tstest/natlab/natlab_test.go b/tstest/natlab/natlab_test.go
index c8896000b..8a1a9cdc0 100644
--- a/tstest/natlab/natlab_test.go
+++ b/tstest/natlab/natlab_test.go
@@ -12,15 +12,14 @@
"testing"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tstest"
)
func TestAllocIPs(t *testing.T) {
n := NewInternet()
- saw := map[netaddr.IP]bool{}
+ saw := map[netip.Addr]bool{}
for i := 0; i < 255; i++ {
- for _, f := range []func(*Interface) netaddr.IP{n.allocIPv4, n.allocIPv6} {
+ for _, f := range []func(*Interface) netip.Addr{n.allocIPv4, n.allocIPv6} {
ip := f(nil)
if saw[ip] {
t.Fatalf("got duplicate %v", ip)
@@ -51,8 +50,8 @@ func TestSendPacket(t *testing.T) {
ifFoo := foo.Attach("eth0", internet)
ifBar := bar.Attach("enp0s1", internet)
- fooAddr := netaddr.IPPortFrom(ifFoo.V4(), 123)
- barAddr := netaddr.IPPortFrom(ifBar.V4(), 456)
+ fooAddr := netip.AddrPortFrom(ifFoo.V4(), 123)
+ barAddr := netip.AddrPortFrom(ifBar.V4(), 456)
ctx := context.Background()
fooPC, err := foo.ListenPacket(ctx, "udp4", fooAddr.String())
@@ -113,10 +112,10 @@ func TestMultiNetwork(t *testing.T) {
t.Fatal(err)
}
- clientAddr := netaddr.IPPortFrom(ifClient.V4(), 123)
- natLANAddr := netaddr.IPPortFrom(ifNATLAN.V4(), 456)
- natWANAddr := netaddr.IPPortFrom(ifNATWAN.V4(), 456)
- serverAddr := netaddr.IPPortFrom(ifServer.V4(), 789)
+ clientAddr := netip.AddrPortFrom(ifClient.V4(), 123)
+ natLANAddr := netip.AddrPortFrom(ifNATLAN.V4(), 456)
+ natWANAddr := netip.AddrPortFrom(ifNATWAN.V4(), 456)
+ serverAddr := netip.AddrPortFrom(ifServer.V4(), 789)
const msg1, msg2 = "hello", "world"
if _, err := natPC.WriteTo([]byte(msg1), net.UDPAddrFromAddrPort(clientAddr)); err != nil {
@@ -151,7 +150,7 @@ func TestMultiNetwork(t *testing.T) {
}
type trivialNAT struct {
- clientIP netaddr.IP
+ clientIP netip.Addr
lanIf, wanIf *Interface
}
@@ -218,7 +217,7 @@ func TestPacketHandler(t *testing.T) {
}
const msg = "some message"
- serverAddr := netaddr.IPPortFrom(ifServer.V4(), 456)
+ serverAddr := netip.AddrPortFrom(ifServer.V4(), 456)
if _, err := clientPC.WriteTo([]byte(msg), net.UDPAddrFromAddrPort(serverAddr)); err != nil {
t.Fatal(err)
}
@@ -232,7 +231,7 @@ func TestPacketHandler(t *testing.T) {
if string(buf) != msg {
t.Errorf("read %q; want %q", buf, msg)
}
- mappedAddr := netaddr.IPPortFrom(ifNATWAN.V4(), 123)
+ mappedAddr := netip.AddrPortFrom(ifNATWAN.V4(), 123)
if addr.String() != mappedAddr.String() {
t.Errorf("addr = %q; want %q", addr, mappedAddr)
}
@@ -318,7 +317,7 @@ func TestFirewall(t *testing.T) {
type fwTest struct {
iif, oif *Interface
- src, dst netaddr.IPPort
+ src, dst netip.AddrPort
ok bool
}
@@ -341,7 +340,7 @@ func testFirewall(t *testing.T, f *Firewall, tests []fwTest) {
}
}
-func ipp(str string) netaddr.IPPort {
+func ipp(str string) netip.AddrPort {
ipp, err := netip.ParseAddrPort(str)
if err != nil {
panic(err)
@@ -455,7 +454,7 @@ func TestNAT(t *testing.T) {
}
type natTest struct {
- src, dst netaddr.IPPort
+ src, dst netip.AddrPort
wantNewMapping bool
}
@@ -463,7 +462,7 @@ func testNAT(t *testing.T, n *SNAT44, lanIf, wanIf *Interface, tests []natTest)
clock := &tstest.Clock{}
n.TimeNow = clock.Now
- mappings := map[netaddr.IPPort]bool{}
+ mappings := map[netip.AddrPort]bool{}
for _, test := range tests {
clock.Advance(time.Second)
p := &Packet{
diff --git a/types/dnstype/dnstype.go b/types/dnstype/dnstype.go
index 7eb41049f..9a3db4744 100644
--- a/types/dnstype/dnstype.go
+++ b/types/dnstype/dnstype.go
@@ -9,8 +9,6 @@
import (
"net/netip"
-
- "tailscale.com/net/netaddr"
)
// Resolver is the configuration for one DNS resolver.
@@ -29,20 +27,20 @@ type Resolver struct {
// BootstrapResolution may be empty, in which case clients should
// look up the DoT/DoH server using their local "classic" DNS
// resolver.
- BootstrapResolution []netaddr.IP `json:",omitempty"`
+ BootstrapResolution []netip.Addr `json:",omitempty"`
}
// IPPort returns r.Addr as an IP address and port if either
// r.Addr is an IP address (the common case) or if r.Addr
// is an IP:port (as done in tests).
-func (r *Resolver) IPPort() (ipp netaddr.IPPort, ok bool) {
+func (r *Resolver) IPPort() (ipp netip.AddrPort, ok bool) {
if r.Addr == "" || r.Addr[0] == 'h' || r.Addr[0] == 't' {
// Fast path to avoid ParseIP error allocation for obviously not IP
// cases.
return
}
if ip, err := netip.ParseAddr(r.Addr); err == nil {
- return netaddr.IPPortFrom(ip, 53), true
+ return netip.AddrPortFrom(ip, 53), true
}
if ipp, err := netip.ParseAddrPort(r.Addr); err == nil {
return ipp, true
diff --git a/types/dnstype/dnstype_view.go b/types/dnstype/dnstype_view.go
index 6c3345c5b..7a68f6381 100644
--- a/types/dnstype/dnstype_view.go
+++ b/types/dnstype/dnstype_view.go
@@ -9,8 +9,8 @@
import (
"encoding/json"
"errors"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/types/views"
)
@@ -58,12 +58,12 @@ func (v *ResolverView) UnmarshalJSON(b []byte) error {
}
func (v ResolverView) Addr() string { return v.ж.Addr }
-func (v ResolverView) BootstrapResolution() views.Slice[netaddr.IP] {
+func (v ResolverView) BootstrapResolution() views.Slice[netip.Addr] {
return views.SliceOf(v.ж.BootstrapResolution)
}
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
var _ResolverViewNeedsRegeneration = Resolver(struct {
Addr string
- BootstrapResolution []netaddr.IP
+ BootstrapResolution []netip.Addr
}{})
diff --git a/types/netmap/netmap.go b/types/netmap/netmap.go
index d56304544..27992eb8a 100644
--- a/types/netmap/netmap.go
+++ b/types/netmap/netmap.go
@@ -8,11 +8,11 @@
import (
"encoding/json"
"fmt"
+ "net/netip"
"reflect"
"strings"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"tailscale.com/wgengine/filter"
@@ -31,7 +31,7 @@ type NetworkMap struct {
Expiry time.Time
// Name is the DNS name assigned to this node.
Name string
- Addresses []netaddr.IPPrefix // same as tailcfg.Node.Addresses (IP addresses of this Node directly)
+ Addresses []netip.Prefix // same as tailcfg.Node.Addresses (IP addresses of this Node directly)
MachineStatus tailcfg.MachineStatus
MachineKey key.MachinePublic
Peers []*tailcfg.Node // sorted by Node.ID
@@ -74,7 +74,7 @@ type NetworkMap struct {
// PeerByTailscaleIP returns a peer's Node based on its Tailscale IP.
//
// If nm is nil or no peer is found, ok is false.
-func (nm *NetworkMap) PeerByTailscaleIP(ip netaddr.IP) (peer *tailcfg.Node, ok bool) {
+func (nm *NetworkMap) PeerByTailscaleIP(ip netip.Addr) (peer *tailcfg.Node, ok bool) {
// TODO(bradfitz):
if nm == nil {
return nil, false
@@ -305,7 +305,7 @@ func eqStringsIgnoreNil(a, b []string) bool {
// eqCIDRsIgnoreNil reports whether a and b have the same length and
// contents, but ignore whether a or b are nil.
-func eqCIDRsIgnoreNil(a, b []netaddr.IPPrefix) bool {
+func eqCIDRsIgnoreNil(a, b []netip.Prefix) bool {
if len(a) != len(b) {
return false
}
diff --git a/types/netmap/netmap_test.go b/types/netmap/netmap_test.go
index 41f0e12df..9bd54c980 100644
--- a/types/netmap/netmap_test.go
+++ b/types/netmap/netmap_test.go
@@ -6,6 +6,7 @@
import (
"encoding/hex"
+ "net/netip"
"testing"
"go4.org/mem"
@@ -256,7 +257,7 @@ func TestConciseDiffFrom(t *testing.T) {
DERP: "127.3.3.40:2",
Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"},
DiscoKey: testDiscoKey("f00f00f00f"),
- AllowedIPs: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
+ AllowedIPs: []netip.Prefix{netip.PrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
},
},
},
@@ -269,7 +270,7 @@ func TestConciseDiffFrom(t *testing.T) {
DERP: "127.3.3.40:2",
Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"},
DiscoKey: testDiscoKey("ba4ba4ba4b"),
- AllowedIPs: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
+ AllowedIPs: []netip.Prefix{netip.PrefixFrom(netaddr.IPv4(100, 102, 103, 104), 32)},
},
},
},
diff --git a/types/views/views.go b/types/views/views.go
index c0e20bb99..bfefbef4d 100644
--- a/types/views/views.go
+++ b/types/views/views.go
@@ -9,8 +9,8 @@
import (
"encoding/json"
"errors"
+ "net/netip"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
)
@@ -169,13 +169,13 @@ func SliceContains[T comparable](v Slice[T], e T) bool {
return false
}
-// IPPrefixSlice is a read-only accessor for a slice of netaddr.IPPrefix.
+// IPPrefixSlice is a read-only accessor for a slice of netip.Prefix.
type IPPrefixSlice struct {
- ж Slice[netaddr.IPPrefix]
+ ж Slice[netip.Prefix]
}
// IPPrefixSliceOf returns a IPPrefixSlice for the provided slice.
-func IPPrefixSliceOf(x []netaddr.IPPrefix) IPPrefixSlice { return IPPrefixSlice{SliceOf(x)} }
+func IPPrefixSliceOf(x []netip.Prefix) IPPrefixSlice { return IPPrefixSlice{SliceOf(x)} }
// IsNil reports whether the underlying slice is nil.
func (v IPPrefixSlice) IsNil() bool { return v.ж.IsNil() }
@@ -184,30 +184,30 @@ func (v IPPrefixSlice) IsNil() bool { return v.ж.IsNil() }
func (v IPPrefixSlice) Len() int { return v.ж.Len() }
// At returns the IPPrefix at index `i` of the slice.
-func (v IPPrefixSlice) At(i int) netaddr.IPPrefix { return v.ж.At(i) }
+func (v IPPrefixSlice) At(i int) netip.Prefix { return v.ж.At(i) }
// AppendTo appends the underlying slice values to dst.
-func (v IPPrefixSlice) AppendTo(dst []netaddr.IPPrefix) []netaddr.IPPrefix {
+func (v IPPrefixSlice) AppendTo(dst []netip.Prefix) []netip.Prefix {
return v.ж.AppendTo(dst)
}
-// Unwrap returns the underlying Slice[netaddr.IPPrefix].
-func (v IPPrefixSlice) Unwrap() Slice[netaddr.IPPrefix] {
+// Unwrap returns the underlying Slice[netip.Prefix].
+func (v IPPrefixSlice) Unwrap() Slice[netip.Prefix] {
return v.ж
}
// AsSlice returns a copy of underlying slice.
-func (v IPPrefixSlice) AsSlice() []netaddr.IPPrefix {
+func (v IPPrefixSlice) AsSlice() []netip.Prefix {
return v.ж.AsSlice()
}
// PrefixesContainsIP reports whether any IPPrefix contains IP.
-func (v IPPrefixSlice) ContainsIP(ip netaddr.IP) bool {
+func (v IPPrefixSlice) ContainsIP(ip netip.Addr) bool {
return tsaddr.PrefixesContainsIP(v.ж.ж, ip)
}
// PrefixesContainsFunc reports whether f is true for any IPPrefix in the slice.
-func (v IPPrefixSlice) ContainsFunc(f func(netaddr.IPPrefix) bool) bool {
+func (v IPPrefixSlice) ContainsFunc(f func(netip.Prefix) bool) bool {
return tsaddr.PrefixesContainsFunc(v.ж.ж, f)
}
diff --git a/types/views/views_test.go b/types/views/views_test.go
index a9242aca0..b22f253b3 100644
--- a/types/views/views_test.go
+++ b/types/views/views_test.go
@@ -13,11 +13,10 @@
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/net/netaddr"
)
func TestViewsJSON(t *testing.T) {
- mustCIDR := func(cidrs ...string) (out []netaddr.IPPrefix) {
+ mustCIDR := func(cidrs ...string) (out []netip.Prefix) {
for _, cidr := range cidrs {
out = append(out, netip.MustParsePrefix(cidr))
}
diff --git a/util/codegen/codegen.go b/util/codegen/codegen.go
index 3c8151d68..61ec85de8 100644
--- a/util/codegen/codegen.go
+++ b/util/codegen/codegen.go
@@ -226,7 +226,7 @@ func ContainsPointers(typ types.Type) bool {
case "time.Time":
// time.Time contains a pointer that does not need copying
return false
- case "inet.af/netaddr.IP", "net/netip.Addr", "net/netip.Prefix", "net/netip.AddrPort":
+ case "inet.af/netip.Addr", "net/netip.Addr", "net/netip.Prefix", "net/netip.AddrPort":
return false
}
switch ft := typ.Underlying().(type) {
diff --git a/util/deephash/deephash_test.go b/util/deephash/deephash_test.go
index 8ceb19a9e..e7897d0cf 100644
--- a/util/deephash/deephash_test.go
+++ b/util/deephash/deephash_test.go
@@ -191,7 +191,7 @@ func getVal() []any {
return []any{
&wgcfg.Config{
Name: "foo",
- Addresses: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPFrom16([16]byte{3: 3}), 5)},
+ Addresses: []netip.Prefix{netip.PrefixFrom(netaddr.IPFrom16([16]byte{3: 3}), 5)},
Peers: []wgcfg.Peer{
{
PublicKey: key.NodePublic{},
@@ -199,12 +199,12 @@ func getVal() []any {
},
},
&router.Config{
- Routes: []netaddr.IPPrefix{
+ Routes: []netip.Prefix{
netip.MustParsePrefix("1.2.3.0/24"),
netip.MustParsePrefix("1234::/64"),
},
},
- map[dnsname.FQDN][]netaddr.IP{
+ map[dnsname.FQDN][]netip.Addr{
dnsname.FQDN("a."): {netip.MustParseAddr("1.2.3.4"), netip.MustParseAddr("4.3.2.1")},
dnsname.FQDN("b."): {netip.MustParseAddr("8.8.8.8"), netip.MustParseAddr("9.9.9.9")},
dnsname.FQDN("c."): {netip.MustParseAddr("6.6.6.6"), netip.MustParseAddr("7.7.7.7")},
@@ -212,7 +212,7 @@ func getVal() []any {
dnsname.FQDN("e."): {netip.MustParseAddr("6.8.6.6"), netip.MustParseAddr("7.7.7.9")},
dnsname.FQDN("f."): {netip.MustParseAddr("6.9.6.6"), netip.MustParseAddr("7.7.7.0")},
},
- map[dnsname.FQDN][]netaddr.IPPort{
+ map[dnsname.FQDN][]netip.AddrPort{
dnsname.FQDN("a."): {netip.MustParseAddrPort("1.2.3.4:11"), netip.MustParseAddrPort("4.3.2.1:22")},
dnsname.FQDN("b."): {netip.MustParseAddrPort("8.8.8.8:11"), netip.MustParseAddrPort("9.9.9.9:22")},
dnsname.FQDN("c."): {netip.MustParseAddrPort("8.8.8.8:12"), netip.MustParseAddrPort("9.9.9.9:23")},
@@ -497,18 +497,18 @@ func TestGetTypeHasher(t *testing.T) {
out32: "\x04\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00*\v\x00\x00\x00\x00\x00\x00\x0010.1.3.4/32\v\x00\x00\x00\x00\x00\x00\x0010.0.0.0/24\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01 \x00\x00\x00\x01\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x001.2.3.4/32\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00foo\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00foooooooooo\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00baaaaaarrrrr\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
},
{
- name: "netaddr.IP",
+ name: "netip.Addr",
val: netip.MustParseAddr("fe80::123%foo"),
out: "\r\x00\x00\x00\x00\x00\x00\x00fe80::123%foo",
},
{
- name: "ptr-netaddr.IP",
+ name: "ptr-netip.Addr",
val: &someIP,
out: "\x01\a\x00\x00\x00\x00\x00\x00\x001.2.3.4",
},
{
- name: "ptr-nil-netaddr.IP",
- val: (*netaddr.IP)(nil),
+ name: "ptr-nil-netip.Addr",
+ val: (*netip.Addr)(nil),
out: "\x00",
},
{
@@ -651,7 +651,7 @@ func ptrTo[T any](v T) *T { return &v }
}},
IPProto: []int{1, 2, 3, 4},
CapGrant: []tailcfg.CapGrant{{
- Dsts: []netaddr.IPPrefix{netip.MustParsePrefix("1.2.3.4/32")},
+ Dsts: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32")},
Caps: []string{"foo"},
}},
},
diff --git a/wf/firewall.go b/wf/firewall.go
index bfc168137..e10f8d93b 100644
--- a/wf/firewall.go
+++ b/wf/firewall.go
@@ -85,7 +85,7 @@ type Firewall struct {
sublayerID wf.SublayerID
session *wf.Session
- permittedRoutes map[netaddr.IPPrefix][]*wf.Rule
+ permittedRoutes map[netip.Prefix][]*wf.Rule
}
// New returns a new Firewall for the provdied interface ID.
@@ -125,7 +125,7 @@ func New(luid uint64) (*Firewall, error) {
session: session,
providerID: providerID,
sublayerID: sublayerID,
- permittedRoutes: make(map[netaddr.IPPrefix][]*wf.Rule),
+ permittedRoutes: make(map[netip.Prefix][]*wf.Rule),
}
if err := f.enable(); err != nil {
return nil, err
@@ -188,16 +188,16 @@ func (f *Firewall) enable() error {
// UpdatedPermittedRoutes adds rules to allow incoming and outgoing connections
// from the provided prefixes. It will also remove rules for routes that were
// previously added but have been removed.
-func (f *Firewall) UpdatePermittedRoutes(newRoutes []netaddr.IPPrefix) error {
- var routesToAdd []netaddr.IPPrefix
- routeMap := make(map[netaddr.IPPrefix]bool)
+func (f *Firewall) UpdatePermittedRoutes(newRoutes []netip.Prefix) error {
+ var routesToAdd []netip.Prefix
+ routeMap := make(map[netip.Prefix]bool)
for _, r := range newRoutes {
routeMap[r] = true
if _, ok := f.permittedRoutes[r]; !ok {
routesToAdd = append(routesToAdd, r)
}
}
- var routesToRemove []netaddr.IPPrefix
+ var routesToRemove []netip.Prefix
for r := range f.permittedRoutes {
if !routeMap[r] {
routesToRemove = append(routesToRemove, r)
diff --git a/wgengine/bench/trafficgen.go b/wgengine/bench/trafficgen.go
index 00de0b1f4..4038ff1da 100644
--- a/wgengine/bench/trafficgen.go
+++ b/wgengine/bench/trafficgen.go
@@ -8,10 +8,10 @@
"encoding/binary"
"fmt"
"log"
+ "net/netip"
"sync"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/types/ipproto"
)
@@ -94,7 +94,7 @@ func NewTrafficGen(onFirstPacket func()) *TrafficGen {
// Start starts the traffic generator. It assumes mu is already locked,
// and unlocks it.
-func (t *TrafficGen) Start(src, dst netaddr.IP, bytesPerPacket int, maxPackets int64) {
+func (t *TrafficGen) Start(src, dst netip.Addr, bytesPerPacket int, maxPackets int64) {
h12 := packet.ICMP4Header{
IP4Header: packet.IP4Header{
IPProto: ipproto.ICMPv4,
diff --git a/wgengine/bench/wg.go b/wgengine/bench/wg.go
index 410ff45c7..d5e8df1d1 100644
--- a/wgengine/bench/wg.go
+++ b/wgengine/bench/wg.go
@@ -8,12 +8,12 @@
"errors"
"io"
"log"
+ "net/netip"
"os"
"sync"
"testing"
"golang.zx2c4.com/wireguard/tun"
- "tailscale.com/net/netaddr"
"tailscale.com/net/dns"
"tailscale.com/tailcfg"
@@ -26,14 +26,14 @@
"tailscale.com/wgengine/wgcfg"
)
-func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netaddr.IPPrefix) {
+func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netip.Prefix) {
l1 := logger.WithPrefix(logf, "e1: ")
k1 := key.NewNode()
c1 := wgcfg.Config{
Name: "e1",
PrivateKey: k1,
- Addresses: []netaddr.IPPrefix{a1},
+ Addresses: []netip.Prefix{a1},
}
t1 := &sourceTun{
logf: logger.WithPrefix(logf, "tun1: "),
@@ -57,7 +57,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netadd
c2 := wgcfg.Config{
Name: "e2",
PrivateKey: k2,
- Addresses: []netaddr.IPPrefix{a2},
+ Addresses: []netip.Prefix{a2},
}
t2 := &sinkTun{
logf: logger.WithPrefix(logf, "tun2: "),
@@ -100,8 +100,8 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netadd
n := tailcfg.Node{
ID: tailcfg.NodeID(0),
Name: "n1",
- Addresses: []netaddr.IPPrefix{a1},
- AllowedIPs: []netaddr.IPPrefix{a1},
+ Addresses: []netip.Prefix{a1},
+ AllowedIPs: []netip.Prefix{a1},
Endpoints: eps,
}
e2.SetNetworkMap(&netmap.NetworkMap{
@@ -112,7 +112,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netadd
p := wgcfg.Peer{
PublicKey: c1.PrivateKey.Public(),
- AllowedIPs: []netaddr.IPPrefix{a1},
+ AllowedIPs: []netip.Prefix{a1},
}
c2.Peers = []wgcfg.Peer{p}
e2.Reconfig(&c2, &router.Config{}, new(dns.Config), nil)
@@ -137,8 +137,8 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netadd
n := tailcfg.Node{
ID: tailcfg.NodeID(0),
Name: "n2",
- Addresses: []netaddr.IPPrefix{a2},
- AllowedIPs: []netaddr.IPPrefix{a2},
+ Addresses: []netip.Prefix{a2},
+ AllowedIPs: []netip.Prefix{a2},
Endpoints: eps,
}
e1.SetNetworkMap(&netmap.NetworkMap{
@@ -149,7 +149,7 @@ func setupWGTest(b *testing.B, logf logger.Logf, traf *TrafficGen, a1, a2 netadd
p := wgcfg.Peer{
PublicKey: c2.PrivateKey.Public(),
- AllowedIPs: []netaddr.IPPrefix{a2},
+ AllowedIPs: []netip.Prefix{a2},
}
c1.Peers = []wgcfg.Peer{p}
e1.Reconfig(&c1, &router.Config{}, new(dns.Config), nil)
diff --git a/wgengine/filter/filter.go b/wgengine/filter/filter.go
index 483642fea..e7faf8eaf 100644
--- a/wgengine/filter/filter.go
+++ b/wgengine/filter/filter.go
@@ -7,6 +7,7 @@
import (
"fmt"
+ "net/netip"
"sync"
"time"
@@ -107,12 +108,12 @@ func (r Response) IsDrop() bool {
// everything. Use in tests only, as it permits some kinds of spoofing
// attacks to reach the OS network stack.
func NewAllowAllForTest(logf logger.Logf) *Filter {
- any4 := netaddr.IPPrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0)
- any6 := netaddr.IPPrefixFrom(netaddr.IPFrom16([16]byte{}), 0)
+ any4 := netip.PrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0)
+ any6 := netip.PrefixFrom(netaddr.IPFrom16([16]byte{}), 0)
ms := []Match{
{
IPProto: []ipproto.Proto{ipproto.TCP, ipproto.UDP, ipproto.ICMPv4},
- Srcs: []netaddr.IPPrefix{any4},
+ Srcs: []netip.Prefix{any4},
Dsts: []NetPortRange{
{
Net: any4,
@@ -125,7 +126,7 @@ func NewAllowAllForTest(logf logger.Logf) *Filter {
},
{
IPProto: []ipproto.Proto{ipproto.TCP, ipproto.UDP, ipproto.ICMPv6},
- Srcs: []netaddr.IPPrefix{any6},
+ Srcs: []netip.Prefix{any6},
Dsts: []NetPortRange{
{
Net: any6,
@@ -180,10 +181,10 @@ func New(matches []Match, localNets *netipx.IPSet, logIPs *netipx.IPSet, shareSt
}
f := &Filter{
logf: logf,
- matches4: matchesFamily(matches, netaddr.IP.Is4),
- matches6: matchesFamily(matches, netaddr.IP.Is6),
- cap4: capMatchesFunc(matches, netaddr.IP.Is4),
- cap6: capMatchesFunc(matches, netaddr.IP.Is6),
+ matches4: matchesFamily(matches, netip.Addr.Is4),
+ matches6: matchesFamily(matches, netip.Addr.Is6),
+ cap4: capMatchesFunc(matches, netip.Addr.Is4),
+ cap6: capMatchesFunc(matches, netip.Addr.Is6),
local: localNets,
logIPs: logIPs,
state: state,
@@ -193,7 +194,7 @@ func New(matches []Match, localNets *netipx.IPSet, logIPs *netipx.IPSet, shareSt
// matchesFamily returns the subset of ms for which keep(srcNet.IP)
// and keep(dstNet.IP) are both true.
-func matchesFamily(ms matches, keep func(netaddr.IP) bool) matches {
+func matchesFamily(ms matches, keep func(netip.Addr) bool) matches {
var ret matches
for _, m := range ms {
var retm Match
@@ -217,7 +218,7 @@ func matchesFamily(ms matches, keep func(netaddr.IP) bool) matches {
// capMatchesFunc returns a copy of the subset of ms for which keep(srcNet.IP)
// and the match is a capability grant.
-func capMatchesFunc(ms matches, keep func(netaddr.IP) bool) matches {
+func capMatchesFunc(ms matches, keep func(netip.Addr) bool) matches {
var ret matches
for _, m := range ms {
if len(m.Caps) == 0 {
@@ -299,7 +300,7 @@ func (f *Filter) logRateLimit(runflags RunFlags, q *packet.Parsed, dir direction
// CheckTCP determines whether TCP traffic from srcIP to dstIP:dstPort
// is allowed.
-func (f *Filter) CheckTCP(srcIP, dstIP netaddr.IP, dstPort uint16) Response {
+func (f *Filter) CheckTCP(srcIP, dstIP netip.Addr, dstPort uint16) Response {
pkt := &packet.Parsed{}
pkt.Decode(dummyPacket) // initialize private fields
switch {
@@ -314,8 +315,8 @@ func (f *Filter) CheckTCP(srcIP, dstIP netaddr.IP, dstPort uint16) Response {
default:
panic("unreachable")
}
- pkt.Src = netaddr.IPPortFrom(srcIP, 0)
- pkt.Dst = netaddr.IPPortFrom(dstIP, dstPort)
+ pkt.Src = netip.AddrPortFrom(srcIP, 0)
+ pkt.Dst = netip.AddrPortFrom(dstIP, dstPort)
pkt.IPProto = ipproto.TCP
pkt.TCPFlags = packet.TCPSyn
@@ -324,7 +325,7 @@ func (f *Filter) CheckTCP(srcIP, dstIP netaddr.IP, dstPort uint16) Response {
// AppendCaps appends to base the capabilities that srcIP has talking
// to dstIP.
-func (f *Filter) AppendCaps(base []string, srcIP, dstIP netaddr.IP) []string {
+func (f *Filter) AppendCaps(base []string, srcIP, dstIP netip.Addr) []string {
ret := base
var mm matches
switch {
diff --git a/wgengine/filter/filter_test.go b/wgengine/filter/filter_test.go
index 8a165e73a..9caf377e1 100644
--- a/wgengine/filter/filter_test.go
+++ b/wgengine/filter/filter_test.go
@@ -15,7 +15,6 @@
"github.com/google/go-cmp/cmp"
"go4.org/netipx"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
@@ -32,7 +31,7 @@
testDeniedProto ipproto.Proto = 127 // CRUDP, appropriately cruddy
)
-func m(srcs []netaddr.IPPrefix, dsts []NetPortRange, protos ...ipproto.Proto) Match {
+func m(srcs []netip.Prefix, dsts []NetPortRange, protos ...ipproto.Proto) Match {
if protos == nil {
protos = defaultProtos
}
@@ -243,7 +242,7 @@ func TestParseIPSet(t *testing.T) {
tests := []struct {
host string
bits int
- want []netaddr.IPPrefix
+ want []netip.Prefix
wantErr string
}{
{"8.8.8.8", 24, pfx("8.8.8.8/24"), ""},
@@ -273,8 +272,8 @@ func TestParseIPSet(t *testing.T) {
}
t.Errorf("parseIPSet(%q, %v) error: %v; want error %q", tt.host, tt.bits, err, tt.wantErr)
}
- compareIP := cmp.Comparer(func(a, b netaddr.IP) bool { return a == b })
- compareIPPrefix := cmp.Comparer(func(a, b netaddr.IPPrefix) bool { return a == b })
+ compareIP := cmp.Comparer(func(a, b netip.Addr) bool { return a == b })
+ compareIPPrefix := cmp.Comparer(func(a, b netip.Prefix) bool { return a == b })
if diff := cmp.Diff(got, tt.want, compareIP, compareIPPrefix); diff != "" {
t.Errorf("parseIPSet(%q, %v) = %s; want %s", tt.host, tt.bits, got, tt.want)
continue
@@ -446,10 +445,10 @@ func TestLoggingPrivacy(t *testing.T) {
f.logIPs, _ = logB.IPSet()
var (
- ts4 = netaddr.IPPortFrom(tsaddr.CGNATRange().Addr().Next(), 1234)
- internet4 = netaddr.IPPortFrom(netip.MustParseAddr("8.8.8.8"), 1234)
- ts6 = netaddr.IPPortFrom(tsaddr.TailscaleULARange().Addr().Next(), 1234)
- internet6 = netaddr.IPPortFrom(netip.MustParseAddr("2001::1"), 1234)
+ ts4 = netip.AddrPortFrom(tsaddr.CGNATRange().Addr().Next(), 1234)
+ internet4 = netip.AddrPortFrom(netip.MustParseAddr("8.8.8.8"), 1234)
+ ts6 = netip.AddrPortFrom(tsaddr.TailscaleULARange().Addr().Next(), 1234)
+ internet6 = netip.AddrPortFrom(netip.MustParseAddr("2001::1"), 1234)
)
tests := []struct {
@@ -560,8 +559,8 @@ func parsed(proto ipproto.Proto, src, dst string, sport, dport uint16) packet.Pa
var ret packet.Parsed
ret.Decode(dummyPacket)
ret.IPProto = proto
- ret.Src = netaddr.IPPortFrom(sip, sport)
- ret.Dst = netaddr.IPPortFrom(dip, dport)
+ ret.Src = netip.AddrPortFrom(sip, sport)
+ ret.Dst = netip.AddrPortFrom(dip, dport)
ret.TCPFlags = packet.TCPSyn
if sip.Is4() {
@@ -657,7 +656,7 @@ func parseHexPkt(t *testing.T, h string) *packet.Parsed {
return p
}
-func mustIPPort(s string) netaddr.IPPort {
+func mustIPPort(s string) netip.AddrPort {
ipp, err := netip.ParseAddrPort(s)
if err != nil {
panic(err)
@@ -665,7 +664,7 @@ func mustIPPort(s string) netaddr.IPPort {
return ipp
}
-func pfx(strs ...string) (ret []netaddr.IPPrefix) {
+func pfx(strs ...string) (ret []netip.Prefix) {
for _, s := range strs {
pfx, err := netip.ParsePrefix(s)
if err != nil {
@@ -676,7 +675,7 @@ func pfx(strs ...string) (ret []netaddr.IPPrefix) {
return ret
}
-func nets(nets ...string) (ret []netaddr.IPPrefix) {
+func nets(nets ...string) (ret []netip.Prefix) {
for _, s := range nets {
if !strings.Contains(s, "/") {
ip, err := netip.ParseAddr(s)
@@ -687,7 +686,7 @@ func nets(nets ...string) (ret []netaddr.IPPrefix) {
if ip.Is6() {
bits = 128
}
- ret = append(ret, netaddr.IPPrefixFrom(ip, bits))
+ ret = append(ret, netip.PrefixFrom(ip, int(bits)))
} else {
pfx, err := netip.ParsePrefix(s)
if err != nil {
@@ -779,7 +778,7 @@ func TestMatchesFromFilterRules(t *testing.T) {
Ports: PortRange{22, 22},
},
},
- Srcs: []netaddr.IPPrefix{
+ Srcs: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
},
Caps: []CapMatch{},
@@ -809,7 +808,7 @@ func TestMatchesFromFilterRules(t *testing.T) {
Ports: PortRange{22, 22},
},
},
- Srcs: []netaddr.IPPrefix{
+ Srcs: []netip.Prefix{
netip.MustParsePrefix("100.64.1.1/32"),
},
Caps: []CapMatch{},
@@ -824,8 +823,8 @@ func TestMatchesFromFilterRules(t *testing.T) {
t.Fatal(err)
}
- compareIP := cmp.Comparer(func(a, b netaddr.IP) bool { return a == b })
- compareIPPrefix := cmp.Comparer(func(a, b netaddr.IPPrefix) bool { return a == b })
+ compareIP := cmp.Comparer(func(a, b netip.Addr) bool { return a == b })
+ compareIPPrefix := cmp.Comparer(func(a, b netip.Prefix) bool { return a == b })
if diff := cmp.Diff(got, tt.want, compareIP, compareIPPrefix); diff != "" {
t.Errorf("wrong (-got+want)\n%s", diff)
}
@@ -885,7 +884,7 @@ func TestCaps(t *testing.T) {
{
SrcIPs: []string{"*"},
CapGrant: []tailcfg.CapGrant{{
- Dsts: []netaddr.IPPrefix{
+ Dsts: []netip.Prefix{
netip.MustParsePrefix("0.0.0.0/0"),
},
Caps: []string{"is_ipv4"},
@@ -894,7 +893,7 @@ func TestCaps(t *testing.T) {
{
SrcIPs: []string{"*"},
CapGrant: []tailcfg.CapGrant{{
- Dsts: []netaddr.IPPrefix{
+ Dsts: []netip.Prefix{
netip.MustParsePrefix("::/0"),
},
Caps: []string{"is_ipv6"},
@@ -903,7 +902,7 @@ func TestCaps(t *testing.T) {
{
SrcIPs: []string{"100.199.0.0/16"},
CapGrant: []tailcfg.CapGrant{{
- Dsts: []netaddr.IPPrefix{
+ Dsts: []netip.Prefix{
netip.MustParsePrefix("100.200.0.0/16"),
},
Caps: []string{"some_super_admin"},
diff --git a/wgengine/filter/match.go b/wgengine/filter/match.go
index a045163a9..10484ce41 100644
--- a/wgengine/filter/match.go
+++ b/wgengine/filter/match.go
@@ -6,9 +6,9 @@
import (
"fmt"
+ "net/netip"
"strings"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/types/ipproto"
)
@@ -39,7 +39,7 @@ func (pr PortRange) contains(port uint16) bool {
// NetPortRange combines an IP address prefix and PortRange.
type NetPortRange struct {
- Net netaddr.IPPrefix
+ Net netip.Prefix
Ports PortRange
}
@@ -51,7 +51,7 @@ func (npr NetPortRange) String() string {
type CapMatch struct {
// Dst is the IP prefix that the destination IP address matches against
// to get the capability.
- Dst netaddr.IPPrefix
+ Dst netip.Prefix
// Cap is the capability that's granted if the destination IP addresses
// matches Dst.
@@ -62,7 +62,7 @@ type CapMatch struct {
// Dsts.
type Match struct {
IPProto []ipproto.Proto // required set (no default value at this layer)
- Srcs []netaddr.IPPrefix
+ Srcs []netip.Prefix
Dsts []NetPortRange // optional, if Srcs match
Caps []CapMatch // optional, if Srcs match
}
@@ -152,7 +152,7 @@ func (ms matches) matchProtoAndIPsOnlyIfAllPorts(q *packet.Parsed) bool {
return false
}
-func ipInList(ip netaddr.IP, netlist []netaddr.IPPrefix) bool {
+func ipInList(ip netip.Addr, netlist []netip.Prefix) bool {
for _, net := range netlist {
if net.Contains(ip) {
return true
diff --git a/wgengine/filter/tailcfg.go b/wgengine/filter/tailcfg.go
index 8e44de7b4..fea673f2f 100644
--- a/wgengine/filter/tailcfg.go
+++ b/wgengine/filter/tailcfg.go
@@ -34,7 +34,7 @@ func MatchesFromFilterRules(pf []tailcfg.FilterRule) ([]Match, error) {
// of time in runtime.growslice. As such, we attempt to
// pre-allocate some slices. Multipliers were chosen arbitrarily.
m := Match{
- Srcs: make([]netaddr.IPPrefix, 0, len(r.SrcIPs)),
+ Srcs: make([]netip.Prefix, 0, len(r.SrcIPs)),
Dsts: make([]NetPortRange, 0, 2*len(r.DstPorts)),
Caps: make([]CapMatch, 0, 3*len(r.CapGrant)),
}
@@ -114,12 +114,12 @@ func MatchesFromFilterRules(pf []tailcfg.FilterRule) ([]Match, error) {
// around, and ultimately use a new version of IPSet.ContainsFunc like
// Contains16Func that works in [16]byte address, so we we can match
// at runtime without allocating?
-func parseIPSet(arg string, bits *int) ([]netaddr.IPPrefix, error) {
+func parseIPSet(arg string, bits *int) ([]netip.Prefix, error) {
if arg == "*" {
// User explicitly requested wildcard.
- return []netaddr.IPPrefix{
- netaddr.IPPrefixFrom(zeroIP4, 0),
- netaddr.IPPrefixFrom(zeroIP6, 0),
+ return []netip.Prefix{
+ netip.PrefixFrom(zeroIP4, 0),
+ netip.PrefixFrom(zeroIP6, 0),
}, nil
}
if strings.Contains(arg, "/") {
@@ -130,7 +130,7 @@ func parseIPSet(arg string, bits *int) ([]netaddr.IPPrefix, error) {
if pfx != pfx.Masked() {
return nil, fmt.Errorf("%v contains non-network bits set", pfx)
}
- return []netaddr.IPPrefix{pfx}, nil
+ return []netip.Prefix{pfx}, nil
}
if strings.Count(arg, "-") == 1 {
ip1s, ip2s, _ := strings.Cut(arg, "-")
@@ -159,5 +159,5 @@ func parseIPSet(arg string, bits *int) ([]netaddr.IPPrefix, error) {
}
bits8 = uint8(*bits)
}
- return []netaddr.IPPrefix{netaddr.IPPrefixFrom(ip, bits8)}, nil
+ return []netip.Prefix{netip.PrefixFrom(ip, int(bits8))}, nil
}
diff --git a/wgengine/magicsock/debughttp.go b/wgengine/magicsock/debughttp.go
index 4094c6ff5..89164f21e 100644
--- a/wgengine/magicsock/debughttp.go
+++ b/wgengine/magicsock/debughttp.go
@@ -9,11 +9,11 @@
"html"
"io"
"net/http"
+ "net/netip"
"sort"
"strings"
"time"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/tstime/mono"
"tailscale.com/types/key"
@@ -73,7 +73,7 @@ type D struct {
fmt.Fprintf(w, "# ip:port to endpoint
")
{
type kv struct {
- ipp netaddr.IPPort
+ ipp netip.AddrPort
pi *peerInfo
}
ent := make([]kv, 0, len(c.peerMap.byIPPort))
@@ -147,7 +147,7 @@ func printEndpointHTML(w io.Writer, ep *endpoint) {
fmt.Fprintf(w, "lastSend: %v ago
\n", fmtMono(ep.lastSend))
fmt.Fprintf(w, "lastFullPing: %v ago
\n", fmtMono(ep.lastFullPing))
- eps := make([]netaddr.IPPort, 0, len(ep.endpointState))
+ eps := make([]netip.AddrPort, 0, len(ep.endpointState))
for ipp := range ep.endpointState {
eps = append(eps, ipp)
}
@@ -155,7 +155,7 @@ func printEndpointHTML(w io.Writer, ep *endpoint) {
io.WriteString(w, "Endpoints:
")
for _, ipp := range eps {
s := ep.endpointState[ipp]
- if ipp == ep.bestAddr.IPPort {
+ if ipp == ep.bestAddr.AddrPort {
fmt.Fprintf(w, "- %s: (best)
", ipp)
} else {
fmt.Fprintf(w, "- %s: ...
", ipp)
@@ -194,7 +194,7 @@ func peerDebugName(p *tailcfg.Node) string {
return p.Hostinfo.Hostname()
}
-func ipPortLess(a, b netaddr.IPPort) bool {
+func ipPortLess(a, b netip.AddrPort) bool {
if v := a.Addr().Compare(b.Addr()); v != 0 {
return v < 0
}
diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go
index 6fccc245c..ec846e953 100644
--- a/wgengine/magicsock/magicsock.go
+++ b/wgengine/magicsock/magicsock.go
@@ -81,13 +81,13 @@ type peerInfo struct {
// that when we're deleting this node, we can rapidly find out the
// keys that need deleting from peerMap.byIPPort without having to
// iterate over every IPPort known for any peer.
- ipPorts map[netaddr.IPPort]bool
+ ipPorts map[netip.AddrPort]bool
}
func newPeerInfo(ep *endpoint) *peerInfo {
return &peerInfo{
ep: ep,
- ipPorts: map[netaddr.IPPort]bool{},
+ ipPorts: map[netip.AddrPort]bool{},
}
}
@@ -97,7 +97,7 @@ func newPeerInfo(ep *endpoint) *peerInfo {
// Doesn't do any locking, all access must be done with Conn.mu held.
type peerMap struct {
byNodeKey map[key.NodePublic]*peerInfo
- byIPPort map[netaddr.IPPort]*peerInfo
+ byIPPort map[netip.AddrPort]*peerInfo
// nodesOfDisco contains the set of nodes that are using a
// DiscoKey. Usually those sets will be just one node.
@@ -107,7 +107,7 @@ type peerMap struct {
func newPeerMap() peerMap {
return peerMap{
byNodeKey: map[key.NodePublic]*peerInfo{},
- byIPPort: map[netaddr.IPPort]*peerInfo{},
+ byIPPort: map[netip.AddrPort]*peerInfo{},
nodesOfDisco: map[key.DiscoPublic]map[key.NodePublic]bool{},
}
}
@@ -137,7 +137,7 @@ func (m *peerMap) endpointForNodeKey(nk key.NodePublic) (ep *endpoint, ok bool)
// endpointForIPPort returns the endpoint for the peer we
// believe to be at ipp, or nil if we don't know of any such peer.
-func (m *peerMap) endpointForIPPort(ipp netaddr.IPPort) (ep *endpoint, ok bool) {
+func (m *peerMap) endpointForIPPort(ipp netip.AddrPort) (ep *endpoint, ok bool) {
if info, ok := m.byIPPort[ipp]; ok {
return info.ep, true
}
@@ -194,7 +194,7 @@ func (m *peerMap) upsertEndpoint(ep *endpoint, oldDiscoKey key.DiscoPublic) {
// This should only be called with a fully verified mapping of ipp to
// nk, because calling this function defines the endpoint we hand to
// WireGuard for packets received from ipp.
-func (m *peerMap) setNodeKeyForIPPort(ipp netaddr.IPPort, nk key.NodePublic) {
+func (m *peerMap) setNodeKeyForIPPort(ipp netip.AddrPort, nk key.NodePublic) {
if pi := m.byIPPort[ipp]; pi != nil {
delete(pi.ipPorts, ipp)
delete(m.byIPPort, ipp)
@@ -579,7 +579,7 @@ func NewConn(opts Options) (*Conn, error) {
// ignoreSTUNPackets sets a STUN packet processing func that does nothing.
func (c *Conn) ignoreSTUNPackets() {
- c.stunReceiveFunc.Store(func([]byte, netaddr.IPPort) {})
+ c.stunReceiveFunc.Store(func([]byte, netip.AddrPort) {})
}
// doPeriodicSTUN is called (in a new goroutine) by
@@ -843,7 +843,7 @@ func (c *Conn) callNetInfoCallbackLocked(ni *tailcfg.NetInfo) {
// discoKey. It's used in tests to enable receiving of packets from
// addr without having to spin up the entire active discovery
// machinery.
-func (c *Conn) addValidDiscoPathForTest(nodeKey key.NodePublic, addr netaddr.IPPort) {
+func (c *Conn) addValidDiscoPathForTest(nodeKey key.NodePublic, addr netip.AddrPort) {
c.mu.Lock()
defer c.mu.Unlock()
c.peerMap.setNodeKeyForIPPort(addr, nodeKey)
@@ -908,7 +908,7 @@ func (c *Conn) Ping(peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnst
}
// c.mu must be held
-func (c *Conn) populateCLIPingResponseLocked(res *ipnstate.PingResult, latency time.Duration, ep netaddr.IPPort) {
+func (c *Conn) populateCLIPingResponseLocked(res *ipnstate.PingResult, latency time.Duration, ep netip.AddrPort) {
res.LatencySeconds = latency.Seconds()
if ep.Addr() != derpMagicIPAddr {
res.Endpoint = ep.String()
@@ -1008,7 +1008,7 @@ func (c *Conn) goDerpConnect(node int) {
if node == 0 {
return
}
- go c.derpWriteChanOfAddr(netaddr.IPPortFrom(derpMagicIPAddr, uint16(node)), key.NodePublic{})
+ go c.derpWriteChanOfAddr(netip.AddrPortFrom(derpMagicIPAddr, uint16(node)), key.NodePublic{})
}
// determineEndpoints returns the machine's endpoint addresses. It
@@ -1017,7 +1017,7 @@ func (c *Conn) goDerpConnect(node int) {
// c.mu must NOT be held.
func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, error) {
var havePortmap bool
- var portmapExt netaddr.IPPort
+ var portmapExt netip.AddrPort
if runtime.GOOS != "js" {
portmapExt, havePortmap = c.portMapper.GetCachedMappingOrStartCreatingOne()
}
@@ -1040,14 +1040,14 @@ func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, erro
}, nil
}
- var already map[netaddr.IPPort]tailcfg.EndpointType // endpoint -> how it was found
+ var already map[netip.AddrPort]tailcfg.EndpointType // endpoint -> how it was found
var eps []tailcfg.Endpoint // unique endpoints
- ipp := func(s string) (ipp netaddr.IPPort) {
+ ipp := func(s string) (ipp netip.AddrPort) {
ipp, _ = netip.ParseAddrPort(s)
return
}
- addAddr := func(ipp netaddr.IPPort, et tailcfg.EndpointType) {
+ addAddr := func(ipp netip.AddrPort, et tailcfg.EndpointType) {
if !ipp.IsValid() || (debugOmitLocalAddresses && et == tailcfg.EndpointLocal) {
return
}
@@ -1100,7 +1100,7 @@ func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, erro
ips = loopback
}
for _, ip := range ips {
- addAddr(netaddr.IPPortFrom(ip, uint16(localAddr.Port)), tailcfg.EndpointLocal)
+ addAddr(netip.AddrPortFrom(ip, uint16(localAddr.Port)), tailcfg.EndpointLocal)
}
} else {
// Our local endpoint is bound to a particular address.
@@ -1186,7 +1186,7 @@ func (c *Conn) Send(b []byte, ep conn.Endpoint) error {
// sendUDP sends UDP packet b to ipp.
// See sendAddr's docs on the return value meanings.
-func (c *Conn) sendUDP(ipp netaddr.IPPort, b []byte) (sent bool, err error) {
+func (c *Conn) sendUDP(ipp netip.AddrPort, b []byte) (sent bool, err error) {
if runtime.GOOS == "js" {
return false, errNoUDP
}
@@ -1235,7 +1235,7 @@ func (c *Conn) sendUDPStd(addr netip.AddrPort, b []byte) (sent bool, err error)
// An example of when they might be different: sending to an
// IPv6 address when the local machine doesn't have IPv6 support
// returns (false, nil); it's not an error, but nothing was sent.
-func (c *Conn) sendAddr(addr netaddr.IPPort, pubKey key.NodePublic, b []byte) (sent bool, err error) {
+func (c *Conn) sendAddr(addr netip.AddrPort, pubKey key.NodePublic, b []byte) (sent bool, err error) {
if addr.Addr() != derpMagicIPAddr {
return c.sendUDP(addr, b)
}
@@ -1281,7 +1281,7 @@ func (c *Conn) sendAddr(addr netaddr.IPPort, pubKey key.NodePublic, b []byte) (s
//
// If peer is non-zero, it can be used to find an active reverse
// path, without using addr.
-func (c *Conn) derpWriteChanOfAddr(addr netaddr.IPPort, peer key.NodePublic) chan<- derpWriteRequest {
+func (c *Conn) derpWriteChanOfAddr(addr netip.AddrPort, peer key.NodePublic) chan<- derpWriteRequest {
if addr.Addr() != derpMagicIPAddr {
return nil
}
@@ -1468,7 +1468,7 @@ type derpReadResult struct {
// runDerpReader runs in a goroutine for the life of a DERP
// connection, handling received packets.
-func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr netaddr.IPPort, dc *derphttp.Client, wg *syncs.WaitGroupChan, startGate <-chan struct{}) {
+func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr netip.AddrPort, dc *derphttp.Client, wg *syncs.WaitGroupChan, startGate <-chan struct{}) {
defer wg.Decr()
defer dc.Close()
@@ -1599,7 +1599,7 @@ func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr netaddr.IPPort, d
}
type derpWriteRequest struct {
- addr netaddr.IPPort
+ addr netip.AddrPort
pubKey key.NodePublic
b []byte // copied; ownership passed to receiver
}
@@ -1666,9 +1666,9 @@ func (c *Conn) receiveIPv4(b []byte) (n int, ep conn.Endpoint, err error) {
//
// ok is whether this read should be reported up to wireguard-go (our
// caller).
-func (c *Conn) receiveIP(b []byte, ipp netaddr.IPPort, cache *ippEndpointCache) (ep *endpoint, ok bool) {
+func (c *Conn) receiveIP(b []byte, ipp netip.AddrPort, cache *ippEndpointCache) (ep *endpoint, ok bool) {
if stun.Is(b) {
- c.stunReceiveFunc.Load().(func([]byte, netaddr.IPPort))(b, ipp)
+ c.stunReceiveFunc.Load().(func([]byte, netip.AddrPort))(b, ipp)
return nil, false
}
if c.handleDiscoMessage(b, ipp, key.NodePublic{}) {
@@ -1734,7 +1734,7 @@ func (c *Conn) processDERPReadResult(dm derpReadResult, b []byte) (n int, ep *en
return 0, nil
}
- ipp := netaddr.IPPortFrom(derpMagicIPAddr, uint16(regionID))
+ ipp := netip.AddrPortFrom(derpMagicIPAddr, uint16(regionID))
if c.handleDiscoMessage(b[:n], ipp, dm.src) {
return 0, nil
}
@@ -1771,7 +1771,7 @@ func (c *Conn) processDERPReadResult(dm derpReadResult, b []byte) (n int, ep *en
//
// The dstKey should only be non-zero if the dstDisco key
// unambiguously maps to exactly one peer.
-func (c *Conn) sendDiscoMessage(dst netaddr.IPPort, dstKey key.NodePublic, dstDisco key.DiscoPublic, m disco.Message, logLevel discoLogLevel) (sent bool, err error) {
+func (c *Conn) sendDiscoMessage(dst netip.AddrPort, dstKey key.NodePublic, dstDisco key.DiscoPublic, m disco.Message, logLevel discoLogLevel) (sent bool, err error) {
c.mu.Lock()
if c.closed {
c.mu.Unlock()
@@ -1842,7 +1842,7 @@ func (c *Conn) sendDiscoMessage(dst netaddr.IPPort, dstKey key.NodePublic, dstDi
// src.Port() being the region ID) and the derpNodeSrc will be the node key
// it was received from at the DERP layer. derpNodeSrc is zero when received
// over UDP.
-func (c *Conn) handleDiscoMessage(msg []byte, src netaddr.IPPort, derpNodeSrc key.NodePublic) (isDiscoMsg bool) {
+func (c *Conn) handleDiscoMessage(msg []byte, src netip.AddrPort, derpNodeSrc key.NodePublic) (isDiscoMsg bool) {
const headerLen = len(disco.Magic) + key.DiscoPublicRawLen
if len(msg) < headerLen || string(msg[:len(disco.Magic)]) != disco.Magic {
return false
@@ -2012,7 +2012,7 @@ func (c *Conn) unambiguousNodeKeyOfPingLocked(dm *disco.Ping, dk key.DiscoPublic
// di is the discoInfo of the source of the ping.
// derpNodeSrc is non-zero if the ping arrived via DERP.
-func (c *Conn) handlePingLocked(dm *disco.Ping, src netaddr.IPPort, di *discoInfo, derpNodeSrc key.NodePublic) {
+func (c *Conn) handlePingLocked(dm *disco.Ping, src netip.AddrPort, di *discoInfo, derpNodeSrc key.NodePublic) {
likelyHeartBeat := src == di.lastPingFrom && time.Since(di.lastPingTime) < 5*time.Second
di.lastPingFrom = src
di.lastPingTime = time.Now()
@@ -2089,7 +2089,7 @@ func (c *Conn) handlePingLocked(dm *disco.Ping, src netaddr.IPPort, di *discoInf
// flipping primary DERPs in the 0-30ms it takes to confirm our STUN endpoint.
// If they do, traffic will just go over DERP for a bit longer until the next
// discovery round.
-func (c *Conn) enqueueCallMeMaybe(derpAddr netaddr.IPPort, de *endpoint) {
+func (c *Conn) enqueueCallMeMaybe(derpAddr netip.AddrPort, de *endpoint) {
c.mu.Lock()
defer c.mu.Unlock()
@@ -2114,7 +2114,7 @@ func (c *Conn) enqueueCallMeMaybe(derpAddr netaddr.IPPort, de *endpoint) {
return
}
- eps := make([]netaddr.IPPort, 0, len(c.lastEndpoints))
+ eps := make([]netip.AddrPort, 0, len(c.lastEndpoints))
for _, ep := range c.lastEndpoints {
eps = append(eps, ep.Addr)
}
@@ -2347,7 +2347,7 @@ func (c *Conn) SetNetworkMap(nm *netmap.NetworkMap) {
c: c,
publicKey: n.Key,
sentPing: map[stun.TxID]sentPing{},
- endpointState: map[netaddr.IPPort]*endpointState{},
+ endpointState: map[netip.AddrPort]*endpointState{},
}
if !n.DiscoKey.IsZero() {
ep.discoKey = n.DiscoKey
@@ -2425,7 +2425,7 @@ func (c *Conn) closeAllDerpLocked(why string) {
// maybeCloseDERPsOnRebind, in response to a rebind, closes all
// DERP connections that don't have a local address in okayLocalIPs
// and pings all those that do.
-func (c *Conn) maybeCloseDERPsOnRebind(okayLocalIPs []netaddr.IPPrefix) {
+func (c *Conn) maybeCloseDERPsOnRebind(okayLocalIPs []netip.Prefix) {
c.mu.Lock()
defer c.mu.Unlock()
for regionID, ad := range c.activeDerp {
@@ -2910,7 +2910,7 @@ func (c *Conn) Rebind() {
return
}
- var ifIPs []netaddr.IPPrefix
+ var ifIPs []netip.Prefix
if c.linkMon != nil {
st := c.linkMon.InterfaceState()
defIf := st.DefaultRouteInterface
@@ -2934,7 +2934,7 @@ func (c *Conn) resetEndpointStates() {
}
// packIPPort packs an IPPort into the form wanted by WireGuard.
-func packIPPort(ua netaddr.IPPort) []byte {
+func packIPPort(ua netip.AddrPort) []byte {
ip := ua.Addr().Unmap()
a := ip.As16()
ipb := a[:]
@@ -3000,12 +3000,12 @@ func (c *RebindingUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
// ReadFromNetaddr reads a packet from c into b.
// It returns the number of bytes copied and the return address.
-// It is identical to c.ReadFrom, except that it returns a netaddr.IPPort instead of a net.Addr.
+// It is identical to c.ReadFrom, except that it returns a netip.AddrPort instead of a net.Addr.
// ReadFromNetaddr is designed to work with specific underlying connection types.
// If c's underlying connection returns a non-*net.UPDAddr return address, ReadFromNetaddr will return an error.
// ReadFromNetaddr exists because it removes an allocation per read,
// when c's underlying connection is a net.UDPConn.
-func (c *RebindingUDPConn) ReadFromNetaddr(b []byte) (n int, ipp netaddr.IPPort, err error) {
+func (c *RebindingUDPConn) ReadFromNetaddr(b []byte) (n int, ipp netip.AddrPort, err error) {
for {
pconn := c.currentConn()
@@ -3019,12 +3019,12 @@ func (c *RebindingUDPConn) ReadFromNetaddr(b []byte) (n int, ipp netaddr.IPPort,
n, addr, err = pconn.ReadFrom(b)
pAddr, ok := addr.(*net.UDPAddr)
if addr != nil && !ok {
- return 0, netaddr.IPPort{}, fmt.Errorf("RebindingUDPConn.ReadFromNetaddr: underlying connection returned address of type %T, want *netaddr.UDPAddr", addr)
+ return 0, netip.AddrPort{}, fmt.Errorf("RebindingUDPConn.ReadFromNetaddr: underlying connection returned address of type %T, want *netaddr.UDPAddr", addr)
}
if pAddr != nil {
ipp, ok = netaddr.FromStdAddr(pAddr.IP, pAddr.Port, pAddr.Zone)
if !ok {
- return 0, netaddr.IPPort{}, errors.New("netaddr.FromStdAddr failed")
+ return 0, netip.AddrPort{}, errors.New("netaddr.FromStdAddr failed")
}
}
}
@@ -3167,7 +3167,7 @@ func simpleDur(d time.Duration) time.Duration {
return d.Round(time.Minute)
}
-func sbPrintAddr(sb *strings.Builder, a netaddr.IPPort) {
+func sbPrintAddr(sb *strings.Builder, a netip.AddrPort) {
is6 := a.Addr().Is6()
if is6 {
sb.WriteByte('[')
@@ -3205,9 +3205,9 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
c.mu.Lock()
defer c.mu.Unlock()
- var tailscaleIPs []netaddr.IP
+ var tailscaleIPs []netip.Addr
if c.netMap != nil {
- tailscaleIPs = make([]netaddr.IP, 0, len(c.netMap.Addresses))
+ tailscaleIPs = make([]netip.Addr, 0, len(c.netMap.Addresses))
for _, addr := range c.netMap.Addresses {
if !addr.IsSingleIP() {
continue
@@ -3250,7 +3250,7 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
})
}
-func ippDebugString(ua netaddr.IPPort) string {
+func ippDebugString(ua netip.AddrPort) string {
if ua.Addr() == derpMagicIPAddr {
return fmt.Sprintf("derp-%d", ua.Port())
}
@@ -3268,7 +3268,7 @@ type endpoint struct {
// These fields are initialized once and never modified.
c *Conn
publicKey key.NodePublic // peer public key (for WireGuard + DERP)
- fakeWGAddr netaddr.IPPort // the UDP address we tell wireguard-go we're using
+ fakeWGAddr netip.AddrPort // the UDP address we tell wireguard-go we're using
wgEndpoint string // string from ParseEndpoint, holds a JSON-serialized wgcfg.Endpoints
// mu protects all following fields.
@@ -3280,14 +3280,14 @@ type endpoint struct {
heartBeatTimer *time.Timer // nil when idle
lastSend mono.Time // last time there was outgoing packets sent to this peer (from wireguard-go)
lastFullPing mono.Time // last time we pinged all endpoints
- derpAddr netaddr.IPPort // fallback/bootstrap path, if non-zero (non-zero for well-behaved clients)
+ derpAddr netip.AddrPort // fallback/bootstrap path, if non-zero (non-zero for well-behaved clients)
bestAddr addrLatency // best non-DERP path; zero if none
bestAddrAt mono.Time // time best address re-confirmed
trustBestAddrUntil mono.Time // time when bestAddr expires
sentPing map[stun.TxID]sentPing
- endpointState map[netaddr.IPPort]*endpointState
- isCallMeMaybeEP map[netaddr.IPPort]bool
+ endpointState map[netip.AddrPort]*endpointState
+ isCallMeMaybeEP map[netip.AddrPort]bool
pendingCLIPings []pendingCLIPing // any outstanding "tailscale ping" commands running
}
@@ -3390,9 +3390,9 @@ func (st *endpointState) shouldDeleteLocked() bool {
}
}
-func (de *endpoint) deleteEndpointLocked(ep netaddr.IPPort) {
+func (de *endpoint) deleteEndpointLocked(ep netip.AddrPort) {
delete(de.endpointState, ep)
- if de.bestAddr.IPPort == ep {
+ if de.bestAddr.AddrPort == ep {
de.bestAddr = addrLatency{}
}
}
@@ -3403,12 +3403,12 @@ func (de *endpoint) deleteEndpointLocked(ep netaddr.IPPort) {
type pongReply struct {
latency time.Duration
pongAt mono.Time // when we received the pong
- from netaddr.IPPort // the pong's src (usually same as endpoint map key)
- pongSrc netaddr.IPPort // what they reported they heard
+ from netip.AddrPort // the pong's src (usually same as endpoint map key)
+ pongSrc netip.AddrPort // what they reported they heard
}
type sentPing struct {
- to netaddr.IPPort
+ to netip.AddrPort
at mono.Time
timer *time.Timer // timeout timer
purpose discoPingPurpose
@@ -3422,7 +3422,7 @@ func (de *endpoint) initFakeUDPAddr() {
addr[0] = 0xfd
addr[1] = 0x00
binary.BigEndian.PutUint64(addr[2:], uint64(reflect.ValueOf(de).Pointer()))
- de.fakeWGAddr = netaddr.IPPortFrom(netaddr.IPFrom16(addr), 12345)
+ de.fakeWGAddr = netip.AddrPortFrom(netaddr.IPFrom16(addr), 12345)
}
// noteRecvActivity records receive activity on de, and invokes
@@ -3467,8 +3467,8 @@ func (de *endpoint) canP2P() bool {
// addr may be non-zero.
//
// de.mu must be held.
-func (de *endpoint) addrForSendLocked(now mono.Time) (udpAddr, derpAddr netaddr.IPPort) {
- udpAddr = de.bestAddr.IPPort
+func (de *endpoint) addrForSendLocked(now mono.Time) (udpAddr, derpAddr netip.AddrPort) {
+ udpAddr = de.bestAddr.AddrPort
if !udpAddr.IsValid() || now.After(de.trustBestAddrUntil) {
// We had a bestAddr but it expired so send both to it
// and DERP.
@@ -3639,7 +3639,7 @@ func (de *endpoint) removeSentPingLocked(txid stun.TxID, sp sentPing) {
//
// The caller should use de.discoKey as the discoKey argument.
// It is passed in so that sendDiscoPing doesn't need to lock de.mu.
-func (de *endpoint) sendDiscoPing(ep netaddr.IPPort, discoKey key.DiscoPublic, txid stun.TxID, logLevel discoLogLevel) {
+func (de *endpoint) sendDiscoPing(ep netip.AddrPort, discoKey key.DiscoPublic, txid stun.TxID, logLevel discoLogLevel) {
selfPubKey, _ := de.c.publicKeyAtomic.Load().(key.NodePublic)
sent, _ := de.c.sendDiscoMessage(ep, de.publicKey, discoKey, &disco.Ping{
TxID: [12]byte(txid),
@@ -3668,7 +3668,7 @@ func (de *endpoint) sendDiscoPing(ep netaddr.IPPort, discoKey key.DiscoPublic, t
pingCLI
)
-func (de *endpoint) startPingLocked(ep netaddr.IPPort, now mono.Time, purpose discoPingPurpose) {
+func (de *endpoint) startPingLocked(ep netip.AddrPort, now mono.Time, purpose discoPingPurpose) {
if !de.canP2P() {
panic("tried to disco ping a peer that can't disco")
}
@@ -3749,7 +3749,7 @@ func (de *endpoint) updateFromNode(n *tailcfg.Node) {
de.resetLocked()
}
if n.DERP == "" {
- de.derpAddr = netaddr.IPPort{}
+ de.derpAddr = netip.AddrPort{}
} else {
de.derpAddr, _ = netip.ParseAddrPort(n.DERP)
}
@@ -3788,7 +3788,7 @@ func (de *endpoint) updateFromNode(n *tailcfg.Node) {
//
// This is called once we've already verified that we got a valid
// discovery message from de via ep.
-func (de *endpoint) addCandidateEndpoint(ep netaddr.IPPort) {
+func (de *endpoint) addCandidateEndpoint(ep netip.AddrPort) {
de.mu.Lock()
defer de.mu.Unlock()
@@ -3833,7 +3833,7 @@ func (de *endpoint) noteConnectivityChange() {
// It should be called with the Conn.mu held.
//
// It reports whether m.TxID corresponds to a ping that this endpoint sent.
-func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netaddr.IPPort) (knownTxID bool) {
+func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netip.AddrPort) (knownTxID bool) {
de.mu.Lock()
defer de.mu.Unlock()
@@ -3890,7 +3890,7 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netad
de.c.logf("magicsock: disco: node %v %v now using %v", de.publicKey.ShortString(), de.discoShort, sp.to)
de.bestAddr = thisPong
}
- if de.bestAddr.IPPort == thisPong.IPPort {
+ if de.bestAddr.AddrPort == thisPong.AddrPort {
de.bestAddr.latency = latency
de.bestAddrAt = now
de.trustBestAddrUntil = now.Add(trustUDPAddrDuration)
@@ -3901,13 +3901,13 @@ func (de *endpoint) handlePongConnLocked(m *disco.Pong, di *discoInfo, src netad
// addrLatency is an IPPort with an associated latency.
type addrLatency struct {
- netaddr.IPPort
+ netip.AddrPort
latency time.Duration
}
// betterAddr reports whether a is a better addr to use than b.
func betterAddr(a, b addrLatency) bool {
- if a.IPPort == b.IPPort {
+ if a.AddrPort == b.AddrPort {
return false
}
if !b.IsValid() {
@@ -3965,7 +3965,7 @@ func (de *endpoint) handleCallMeMaybe(m *disco.CallMeMaybe) {
for ep := range de.isCallMeMaybeEP {
de.isCallMeMaybeEP[ep] = false // mark for deletion
}
- var newEPs []netaddr.IPPort
+ var newEPs []netip.AddrPort
for _, ep := range m.MyNumber {
if ep.Addr().Is6() && ep.Addr().IsLinkLocalUnicast() {
// We send these out, but ignore them for now.
@@ -4074,9 +4074,9 @@ func (de *endpoint) numStopAndReset() int64 {
func derpStr(s string) string { return strings.ReplaceAll(s, "127.3.3.40:", "derp-") }
// ippEndpointCache is a mutex-free single-element cache, mapping from
-// a single netaddr.IPPort to a single endpoint.
+// a single netip.AddrPort to a single endpoint.
type ippEndpointCache struct {
- ipp netaddr.IPPort
+ ipp netip.AddrPort
gen int64
de *endpoint
}
@@ -4107,7 +4107,7 @@ type discoInfo struct {
// Mutable fields follow, owned by Conn.mu:
// lastPingFrom is the src of a ping for discoKey.
- lastPingFrom netaddr.IPPort
+ lastPingFrom netip.AddrPort
// lastPingTime is the last time of a ping for discoKey.
lastPingTime time.Time
diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go
index 89c8ffa13..9551dc7fb 100644
--- a/wgengine/magicsock/magicsock_test.go
+++ b/wgengine/magicsock/magicsock_test.go
@@ -82,7 +82,7 @@ func (c *Conn) WaitReady(t testing.TB) {
}
}
-func runDERPAndStun(t *testing.T, logf logger.Logf, l nettype.PacketListener, stunIP netaddr.IP) (derpMap *tailcfg.DERPMap, cleanup func()) {
+func runDERPAndStun(t *testing.T, logf logger.Logf, l nettype.PacketListener, stunIP netip.Addr) (derpMap *tailcfg.DERPMap, cleanup func()) {
d := derp.NewServer(key.NewNode(), logf)
httpsrv := httptest.NewUnstartedServer(derphttp.Handler(d))
@@ -222,7 +222,7 @@ func (s *magicStack) Status() *ipnstate.Status {
// Something external needs to provide a NetworkMap and WireGuard
// configs to the magicStack in order for it to acquire an IP
// address. See meshStacks for one possible source of netmaps and IPs.
-func (s *magicStack) IP() netaddr.IP {
+func (s *magicStack) IP() netip.Addr {
for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); time.Sleep(10 * time.Millisecond) {
st := s.Status()
if len(st.TailscaleIPs) > 0 {
@@ -251,13 +251,13 @@ func meshStacks(logf logger.Logf, mutateNetmap func(idx int, nm *netmap.NetworkM
nm := &netmap.NetworkMap{
PrivateKey: me.privateKey,
NodeKey: me.privateKey.Public(),
- Addresses: []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(1, 0, 0, byte(myIdx+1)), 32)},
+ Addresses: []netip.Prefix{netip.PrefixFrom(netaddr.IPv4(1, 0, 0, byte(myIdx+1)), 32)},
}
for i, peer := range ms {
if i == myIdx {
continue
}
- addrs := []netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.IPv4(1, 0, 0, byte(i+1)), 32)}
+ addrs := []netip.Prefix{netip.PrefixFrom(netaddr.IPv4(1, 0, 0, byte(i+1)), 32)}
peer := &tailcfg.Node{
ID: tailcfg.NodeID(i + 1),
Name: fmt.Sprintf("node%d", i+1),
@@ -833,13 +833,13 @@ func TestActiveDiscovery(t *testing.T) {
type devices struct {
m1 nettype.PacketListener
- m1IP netaddr.IP
+ m1IP netip.Addr
m2 nettype.PacketListener
- m2IP netaddr.IP
+ m2IP netip.Addr
stun nettype.PacketListener
- stunIP netaddr.IP
+ stunIP netip.Addr
}
// newPinger starts continuously sending test packets from srcM to
@@ -1010,24 +1010,24 @@ func testTwoDevicePing(t *testing.T, d *devices) {
m1cfg := &wgcfg.Config{
Name: "peer1",
PrivateKey: m1.privateKey,
- Addresses: []netaddr.IPPrefix{netip.MustParsePrefix("1.0.0.1/32")},
+ Addresses: []netip.Prefix{netip.MustParsePrefix("1.0.0.1/32")},
Peers: []wgcfg.Peer{
{
PublicKey: m2.privateKey.Public(),
DiscoKey: m2.conn.DiscoPublicKey(),
- AllowedIPs: []netaddr.IPPrefix{netip.MustParsePrefix("1.0.0.2/32")},
+ AllowedIPs: []netip.Prefix{netip.MustParsePrefix("1.0.0.2/32")},
},
},
}
m2cfg := &wgcfg.Config{
Name: "peer2",
PrivateKey: m2.privateKey,
- Addresses: []netaddr.IPPrefix{netip.MustParsePrefix("1.0.0.2/32")},
+ Addresses: []netip.Prefix{netip.MustParsePrefix("1.0.0.2/32")},
Peers: []wgcfg.Peer{
{
PublicKey: m1.privateKey.Public(),
DiscoKey: m1.conn.DiscoPublicKey(),
- AllowedIPs: []netaddr.IPPrefix{netip.MustParsePrefix("1.0.0.1/32")},
+ AllowedIPs: []netip.Prefix{netip.MustParsePrefix("1.0.0.1/32")},
},
},
}
@@ -1157,7 +1157,7 @@ func TestDiscoMessage(t *testing.T) {
box := peer1Priv.Shared(c.discoPrivate.Public()).Seal([]byte(payload))
pkt = append(pkt, box...)
- got := c.handleDiscoMessage(pkt, netaddr.IPPort{}, key.NodePublic{})
+ got := c.handleDiscoMessage(pkt, netip.AddrPort{}, key.NodePublic{})
if !got {
t.Error("failed to open it")
}
@@ -1538,7 +1538,7 @@ func TestEndpointSetsEqual(t *testing.T) {
s := func(ports ...uint16) (ret []tailcfg.Endpoint) {
for _, port := range ports {
ret = append(ret, tailcfg.Endpoint{
- Addr: netaddr.IPPortFrom(netaddr.IP{}, port),
+ Addr: netip.AddrPortFrom(netip.Addr{}, port),
})
}
return
diff --git a/wgengine/monitor/monitor.go b/wgengine/monitor/monitor.go
index c57dd368d..ba099196d 100644
--- a/wgengine/monitor/monitor.go
+++ b/wgengine/monitor/monitor.go
@@ -10,12 +10,12 @@
import (
"encoding/json"
"errors"
+ "net/netip"
"runtime"
"sync"
"time"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
)
@@ -69,8 +69,8 @@ type Mon struct {
ruleDelCB map[*callbackHandle]RuleDeleteCallback
ifState *interfaces.State
gwValid bool // whether gw and gwSelfIP are valid
- gw netaddr.IP // our gateway's IP
- gwSelfIP netaddr.IP // our own IP address (that corresponds to gw)
+ gw netip.Addr // our gateway's IP
+ gwSelfIP netip.Addr // our own IP address (that corresponds to gw)
started bool
closed bool
goroutines sync.WaitGroup
@@ -127,7 +127,7 @@ func (m *Mon) interfaceStateUncached() (*interfaces.State, error) {
//
// It's the same as interfaces.LikelyHomeRouterIP, but it caches the
// result until the monitor detects a network change.
-func (m *Mon) GatewayAndSelfIP() (gw, myIP netaddr.IP, ok bool) {
+func (m *Mon) GatewayAndSelfIP() (gw, myIP netip.Addr, ok bool) {
m.mu.Lock()
defer m.mu.Unlock()
if m.gwValid {
@@ -289,7 +289,7 @@ func (m *Mon) notifyRuleDeleted(rdm ipRuleDeletedMessage) {
// isInterestingInterface reports whether the provided interface should be
// considered when checking for network state changes.
// The ips parameter should be the IPs of the provided interface.
-func (m *Mon) isInterestingInterface(i interfaces.Interface, ips []netaddr.IPPrefix) bool {
+func (m *Mon) isInterestingInterface(i interfaces.Interface, ips []netip.Prefix) bool {
return m.om.IsInterestingInterface(i.Name) && interfaces.UseInterestingInterfaces(i, ips)
}
diff --git a/wgengine/monitor/monitor_darwin.go b/wgengine/monitor/monitor_darwin.go
index be99a7f2d..33e1f001e 100644
--- a/wgengine/monitor/monitor_darwin.go
+++ b/wgengine/monitor/monitor_darwin.go
@@ -6,6 +6,7 @@
import (
"fmt"
+ "net/netip"
"strings"
"sync"
@@ -170,20 +171,20 @@ func (m *darwinRouteMon) logAddrs(addrs []route.Addr) {
}
}
-// ipOfAddr returns the route.Addr (possibly nil) as a netaddr.IP
+// ipOfAddr returns the route.Addr (possibly nil) as a netip.Addr
// (possibly zero).
-func ipOfAddr(a route.Addr) netaddr.IP {
+func ipOfAddr(a route.Addr) netip.Addr {
switch a := a.(type) {
case *route.Inet4Addr:
return netaddr.IPv4(a.IP[0], a.IP[1], a.IP[2], a.IP[3])
case *route.Inet6Addr:
- ip := netaddr.IPv6Raw(a.IP)
+ ip := netip.AddrFrom16(a.IP)
if a.ZoneID != 0 {
ip = ip.WithZone(fmt.Sprint(a.ZoneID)) // TODO: look up net.InterfaceByIndex? but it might be changing?
}
return ip
}
- return netaddr.IP{}
+ return netip.Addr{}
}
func fmtAddr(a route.Addr) any {
diff --git a/wgengine/monitor/monitor_linux.go b/wgengine/monitor/monitor_linux.go
index db12595f4..f2596726e 100644
--- a/wgengine/monitor/monitor_linux.go
+++ b/wgengine/monitor/monitor_linux.go
@@ -9,6 +9,7 @@
import (
"net"
+ "net/netip"
"time"
"github.com/jsimonetti/rtnetlink"
@@ -43,7 +44,7 @@ type nlConn struct {
// used to suppress duplicate RTM_NEWADDR messages. It is populated
// by RTM_NEWADDR messages and de-populated by RTM_DELADDR. See
// issue #4282.
- addrCache map[uint32]map[netaddr.IP]bool
+ addrCache map[uint32]map[netip.Addr]bool
}
func newOSMon(logf logger.Logf, m *Mon) (osMon, error) {
@@ -61,7 +62,7 @@ func newOSMon(logf logger.Logf, m *Mon) (osMon, error) {
logf("monitor_linux: AF_NETLINK RTMGRP failed, falling back to polling")
return newPollingMon(logf, m)
}
- return &nlConn{logf: logf, conn: conn, addrCache: make(map[uint32]map[netaddr.IP]bool)}, nil
+ return &nlConn{logf: logf, conn: conn, addrCache: make(map[uint32]map[netip.Addr]bool)}, nil
}
func (c *nlConn) IsInterestingInterface(iface string) bool { return true }
@@ -120,7 +121,7 @@ func (c *nlConn) Receive() (message, error) {
// detect them. See nlConn.addrcache and issue #4282.
if msg.Header.Type == unix.RTM_NEWADDR {
if addrs == nil {
- addrs = make(map[netaddr.IP]bool)
+ addrs = make(map[netip.Addr]bool)
c.addrCache[rmsg.Index] = addrs
}
@@ -235,24 +236,24 @@ func (c *nlConn) Receive() (message, error) {
}
}
-func netaddrIP(std net.IP) netaddr.IP {
+func netaddrIP(std net.IP) netip.Addr {
ip, _ := netaddr.FromStdIP(std)
return ip
}
-func netaddrIPPrefix(std net.IP, bits uint8) netaddr.IPPrefix {
+func netaddrIPPrefix(std net.IP, bits uint8) netip.Prefix {
ip, _ := netaddr.FromStdIP(std)
- return netaddr.IPPrefixFrom(ip, bits)
+ return netip.PrefixFrom(ip, int(bits))
}
-func condNetAddrPrefix(ipp netaddr.IPPrefix) string {
+func condNetAddrPrefix(ipp netip.Prefix) string {
if !ipp.Addr().IsValid() {
return ""
}
return ipp.String()
}
-func condNetAddrIP(ip netaddr.IP) string {
+func condNetAddrIP(ip netip.Addr) string {
if !ip.IsValid() {
return ""
}
@@ -261,8 +262,8 @@ func condNetAddrIP(ip netaddr.IP) string {
// newRouteMessage is a message for a new route being added.
type newRouteMessage struct {
- Src, Dst netaddr.IPPrefix
- Gateway netaddr.IP
+ Src, Dst netip.Prefix
+ Gateway netip.Addr
Table uint8
}
@@ -275,7 +276,7 @@ func (m *newRouteMessage) ignore() bool {
// newAddrMessage is a message for a new address being added.
type newAddrMessage struct {
Delete bool
- Addr netaddr.IP
+ Addr netip.Addr
IfIndex uint32 // interface index
}
diff --git a/wgengine/monitor/monitor_linux_test.go b/wgengine/monitor/monitor_linux_test.go
index 61d2846c4..631b380f9 100644
--- a/wgengine/monitor/monitor_linux_test.go
+++ b/wgengine/monitor/monitor_linux_test.go
@@ -6,12 +6,12 @@
import (
"net"
+ "net/netip"
"testing"
"github.com/jsimonetti/rtnetlink"
"github.com/mdlayher/netlink"
"golang.org/x/sys/unix"
- "tailscale.com/net/netaddr"
)
func newAddrMsg(iface uint32, addr string, typ netlink.HeaderType) netlink.Message {
@@ -54,7 +54,7 @@ func TestIgnoreDuplicateNEWADDR(t *testing.T) {
newAddrMsg(1, "192.168.0.5", unix.RTM_NEWADDR),
newAddrMsg(1, "192.168.0.5", unix.RTM_NEWADDR),
},
- addrCache: make(map[uint32]map[netaddr.IP]bool),
+ addrCache: make(map[uint32]map[netip.Addr]bool),
}
msg := mustReceive(&c)
@@ -75,7 +75,7 @@ func TestIgnoreDuplicateNEWADDR(t *testing.T) {
newAddrMsg(1, "192.168.0.5", unix.RTM_DELADDR),
newAddrMsg(1, "192.168.0.5", unix.RTM_NEWADDR),
},
- addrCache: make(map[uint32]map[netaddr.IP]bool),
+ addrCache: make(map[uint32]map[netip.Addr]bool),
}
msg := mustReceive(&c)
diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go
index 07263187a..531171501 100644
--- a/wgengine/netstack/netstack.go
+++ b/wgengine/netstack/netstack.go
@@ -12,6 +12,7 @@
"io"
"log"
"net"
+ "net/netip"
"os"
"os/exec"
"runtime"
@@ -116,14 +117,14 @@ type Impl struct {
// is a local (non-subnet) Tailscale IP address of this
// machine. It's always a non-nil func. It's changed on netmap
// updates.
- atomicIsLocalIPFunc atomic.Value // of func(netaddr.IP) bool
+ atomicIsLocalIPFunc atomic.Value // of func(netip.Addr) bool
mu sync.Mutex
// connsOpenBySubnetIP keeps track of number of connections open
// for each subnet IP temporarily registered on netstack for active
// TCP connections, so they can be unregistered when connections are
// closed.
- connsOpenBySubnetIP map[netaddr.IP]int
+ connsOpenBySubnetIP map[netip.Addr]int
}
// handleSSH is initialized in ssh.go (on Linux only) to register an SSH server
@@ -191,7 +192,7 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
e: e,
mc: mc,
dialer: dialer,
- connsOpenBySubnetIP: make(map[netaddr.IP]int),
+ connsOpenBySubnetIP: make(map[netip.Addr]int),
dns: dns,
}
ns.ctx, ns.ctxCancel = context.WithCancel(context.Background())
@@ -246,7 +247,7 @@ func (ns *Impl) Start() error {
return nil
}
-func (ns *Impl) addSubnetAddress(ip netaddr.IP) {
+func (ns *Impl) addSubnetAddress(ip netip.Addr) {
ns.mu.Lock()
ns.connsOpenBySubnetIP[ip]++
needAdd := ns.connsOpenBySubnetIP[ip] == 1
@@ -271,7 +272,7 @@ func (ns *Impl) addSubnetAddress(ip netaddr.IP) {
}
}
-func (ns *Impl) removeSubnetAddress(ip netaddr.IP) {
+func (ns *Impl) removeSubnetAddress(ip netip.Addr) {
ns.mu.Lock()
defer ns.mu.Unlock()
ns.connsOpenBySubnetIP[ip]--
@@ -282,7 +283,7 @@ func (ns *Impl) removeSubnetAddress(ip netaddr.IP) {
}
}
-func ipPrefixToAddressWithPrefix(ipp netaddr.IPPrefix) tcpip.AddressWithPrefix {
+func ipPrefixToAddressWithPrefix(ipp netip.Prefix) tcpip.AddressWithPrefix {
return tcpip.AddressWithPrefix{
Address: tcpip.Address(ipp.Addr().AsSlice()),
PrefixLen: int(ipp.Bits()),
@@ -308,7 +309,7 @@ func (ns *Impl) updateIPs(nm *netmap.NetworkMap) {
}
newIPs := make(map[tcpip.AddressWithPrefix]bool)
- isAddr := map[netaddr.IPPrefix]bool{}
+ isAddr := map[netip.Prefix]bool{}
if nm.SelfNode != nil {
for _, ipp := range nm.SelfNode.Addresses {
isAddr[ipp] = true
@@ -411,7 +412,7 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Re
return filter.DropSilently
}
-func (ns *Impl) DialContextTCP(ctx context.Context, ipp netaddr.IPPort) (*gonet.TCPConn, error) {
+func (ns *Impl) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.TCPConn, error) {
remoteAddress := tcpip.FullAddress{
NIC: nicID,
Addr: tcpip.Address(ipp.Addr().AsSlice()),
@@ -427,7 +428,7 @@ func (ns *Impl) DialContextTCP(ctx context.Context, ipp netaddr.IPPort) (*gonet.
return gonet.DialContextTCP(ctx, ns.ipstack, remoteAddress, ipType)
}
-func (ns *Impl) DialContextUDP(ctx context.Context, ipp netaddr.IPPort) (*gonet.UDPConn, error) {
+func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error) {
remoteAddress := &tcpip.FullAddress{
NIC: nicID,
Addr: tcpip.Address(ipp.Addr().AsSlice()),
@@ -510,15 +511,15 @@ func (ns *Impl) inject() {
// isLocalIP reports whether ip is a Tailscale IP assigned to this
// node directly (but not a subnet-routed IP).
-func (ns *Impl) isLocalIP(ip netaddr.IP) bool {
- return ns.atomicIsLocalIPFunc.Load().(func(netaddr.IP) bool)(ip)
+func (ns *Impl) isLocalIP(ip netip.Addr) bool {
+ return ns.atomicIsLocalIPFunc.Load().(func(netip.Addr) bool)(ip)
}
func (ns *Impl) processSSH() bool {
return ns.lb != nil && ns.lb.ShouldRunSSH()
}
-func (ns *Impl) peerAPIPortAtomic(ip netaddr.IP) *uint32 {
+func (ns *Impl) peerAPIPortAtomic(ip netip.Addr) *uint32 {
if ip.Is4() {
return &ns.peerapiPort4Atomic
} else {
@@ -588,7 +589,7 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool {
//
// TODO(bradfitz): when we're running on Windows as the system user, use
// raw socket APIs instead of ping child processes.
-func (ns *Impl) userPing(dstIP netaddr.IP, pingResPkt []byte) {
+func (ns *Impl) userPing(dstIP netip.Addr, pingResPkt []byte) {
if !userPingSem.TryAcquire() {
return
}
@@ -702,7 +703,7 @@ func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper) filter.Respons
return filter.DropSilently
}
-func netaddrIPFromNetstackIP(s tcpip.Address) netaddr.IP {
+func netaddrIPFromNetstackIP(s tcpip.Address) netip.Addr {
switch len(s) {
case 4:
return netaddr.IPv4(s[0], s[1], s[2], s[3])
@@ -711,7 +712,7 @@ func netaddrIPFromNetstackIP(s tcpip.Address) netaddr.IP {
copy(a[:], s)
return netaddr.IPFrom16(a)
}
- return netaddr.IP{}
+ return netip.Addr{}
}
func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
@@ -776,7 +777,7 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
c := gonet.NewTCPConn(&wq, ep)
if reqDetails.LocalPort == 53 && (dialIP == magicDNSIP || dialIP == magicDNSIPv6) {
- go ns.dns.HandleTCPConn(c, netaddr.IPPortFrom(clientRemoteIP, reqDetails.RemotePort))
+ go ns.dns.HandleTCPConn(c, netip.AddrPortFrom(clientRemoteIP, reqDetails.RemotePort))
return
}
@@ -789,8 +790,8 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
}
if port, ok := ns.lb.GetPeerAPIPort(dialIP); ok {
if reqDetails.LocalPort == port && ns.isLocalIP(dialIP) {
- src := netaddr.IPPortFrom(clientRemoteIP, reqDetails.RemotePort)
- dst := netaddr.IPPortFrom(dialIP, port)
+ src := netip.AddrPortFrom(clientRemoteIP, reqDetails.RemotePort)
+ dst := netip.AddrPortFrom(dialIP, port)
ns.lb.ServePeerAPIConnection(src, dst, c)
return
}
@@ -808,11 +809,11 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
if isTailscaleIP {
dialIP = netaddr.IPv4(127, 0, 0, 1)
}
- dialAddr := netaddr.IPPortFrom(dialIP, uint16(reqDetails.LocalPort))
+ dialAddr := netip.AddrPortFrom(dialIP, uint16(reqDetails.LocalPort))
ns.forwardTCP(c, clientRemoteIP, &wq, dialAddr)
}
-func (ns *Impl) forwardTCP(client *gonet.TCPConn, clientRemoteIP netaddr.IP, wq *waiter.Queue, dialAddr netaddr.IPPort) {
+func (ns *Impl) forwardTCP(client *gonet.TCPConn, clientRemoteIP netip.Addr, wq *waiter.Queue, dialAddr netip.AddrPort) {
defer client.Close()
dialAddrStr := dialAddr.String()
if debugNetstack {
@@ -900,7 +901,7 @@ func (ns *Impl) acceptUDP(r *udp.ForwarderRequest) {
go ns.forwardUDP(c, &wq, srcAddr, dstAddr)
}
-func (ns *Impl) handleMagicDNSUDP(srcAddr netaddr.IPPort, c *gonet.UDPConn) {
+func (ns *Impl) handleMagicDNSUDP(srcAddr netip.AddrPort, c *gonet.UDPConn) {
// In practice, implementations are advised not to exceed 512 bytes
// due to fragmenting. Just to be sure, we bump all the way to the MTU.
const maxUDPReqSize = mtu
@@ -941,7 +942,7 @@ func (ns *Impl) handleMagicDNSUDP(srcAddr netaddr.IPPort, c *gonet.UDPConn) {
// dstAddr may be either a local Tailscale IP, in which we case we proxy to
// 127.0.0.1, or any other IP (from an advertised subnet), in which case we
// proxy to it directly.
-func (ns *Impl) forwardUDP(client *gonet.UDPConn, wq *waiter.Queue, clientAddr, dstAddr netaddr.IPPort) {
+func (ns *Impl) forwardUDP(client *gonet.UDPConn, wq *waiter.Queue, clientAddr, dstAddr netip.AddrPort) {
port, srcPort := dstAddr.Port(), clientAddr.Port()
if debugNetstack {
ns.logf("[v2] netstack: forwarding incoming UDP connection on port %v", port)
@@ -955,7 +956,7 @@ func (ns *Impl) forwardUDP(client *gonet.UDPConn, wq *waiter.Queue, clientAddr,
backendListenAddr = &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: int(srcPort)}
} else {
if dstIP := dstAddr.Addr(); viaRange.Contains(dstIP) {
- dstAddr = netaddr.IPPortFrom(tsaddr.UnmapVia(dstIP), dstAddr.Port())
+ dstAddr = netip.AddrPortFrom(tsaddr.UnmapVia(dstIP), dstAddr.Port())
}
backendRemoteAddr = net.UDPAddrFromAddrPort(dstAddr)
if dstAddr.Addr().Is4() {
@@ -1058,6 +1059,6 @@ func stringifyTEI(tei stack.TransportEndpointID) string {
return fmt.Sprintf("%s -> %s", remoteHostPort, localHostPort)
}
-func ipPortOfNetstackAddr(a tcpip.Address, port uint16) (ipp netaddr.IPPort, ok bool) {
+func ipPortOfNetstackAddr(a tcpip.Address, port uint16) (ipp netip.AddrPort, ok bool) {
return netaddr.FromStdAddr(net.IP(a), int(port), "") // TODO(bradfitz): can do without allocs
}
diff --git a/wgengine/netstack/netstack_test.go b/wgengine/netstack/netstack_test.go
index 1bfb7a543..626808306 100644
--- a/wgengine/netstack/netstack_test.go
+++ b/wgengine/netstack/netstack_test.go
@@ -5,11 +5,11 @@
package netstack
import (
+ "net/netip"
"runtime"
"testing"
"gvisor.dev/gvisor/pkg/refs"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsdial"
"tailscale.com/net/tstun"
@@ -53,7 +53,7 @@ func TestInjectInboundLeak(t *testing.T) {
if err := ns.Start(); err != nil {
t.Fatalf("Start: %v", err)
}
- ns.atomicIsLocalIPFunc.Store(func(netaddr.IP) bool { return true })
+ ns.atomicIsLocalIPFunc.Store(func(netip.Addr) bool { return true })
pkt := &packet.Parsed{}
const N = 10_000
diff --git a/wgengine/router/ifconfig_windows.go b/wgengine/router/ifconfig_windows.go
index 22e905e4d..aaac2f57a 100644
--- a/wgengine/router/ifconfig_windows.go
+++ b/wgengine/router/ifconfig_windows.go
@@ -768,8 +768,8 @@ func getAllInterfaceRoutes(ifc *winipcfg.IPAdapterAddresses) ([]*winipcfg.RouteD
// filterRoutes removes routes that have been added by Windows and should not
// be managed by us.
-func filterRoutes(routes []*winipcfg.RouteData, dontDelete []netaddr.IPPrefix) []*winipcfg.RouteData {
- ddm := make(map[netaddr.IPPrefix]bool)
+func filterRoutes(routes []*winipcfg.RouteData, dontDelete []netip.Prefix) []*winipcfg.RouteData {
+ ddm := make(map[netip.Prefix]bool)
for _, dd := range dontDelete {
// See issue 1448: we don't want to touch the routes added
// by Windows for our interface addresses.
@@ -802,7 +802,7 @@ func filterRoutes(routes []*winipcfg.RouteData, dontDelete []netaddr.IPPrefix) [
// This avoids a full ifc.FlushRoutes call.
// dontDelete is a list of interface address routes that the
// synchronization logic should never delete.
-func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*winipcfg.RouteData, dontDelete []netaddr.IPPrefix) error {
+func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*winipcfg.RouteData, dontDelete []netip.Prefix) error {
existingRoutes, err := getAllInterfaceRoutes(ifc)
if err != nil {
return err
diff --git a/wgengine/router/router.go b/wgengine/router/router.go
index 0e2acf146..84933a18f 100644
--- a/wgengine/router/router.go
+++ b/wgengine/router/router.go
@@ -7,10 +7,10 @@
package router
import (
+ "net/netip"
"reflect"
"golang.zx2c4.com/wireguard/tun"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/types/preftype"
"tailscale.com/wgengine/monitor"
@@ -55,21 +55,21 @@ type Config struct {
// LocalAddrs are the address(es) for this node. This is
// typically one IPv4/32 (the 100.x.y.z CGNAT) and one
// IPv6/128 (Tailscale ULA).
- LocalAddrs []netaddr.IPPrefix
+ LocalAddrs []netip.Prefix
// Routes are the routes that point into the Tailscale
// interface. These are the /32 and /128 routes to peers, as
// well as any other subnets that peers are advertising and
// this node has chosen to use.
- Routes []netaddr.IPPrefix
+ Routes []netip.Prefix
// LocalRoutes are the routes that should not be routed through Tailscale.
// There are no priorities set in how these routes are added, normal
// routing rules apply.
- LocalRoutes []netaddr.IPPrefix
+ LocalRoutes []netip.Prefix
// Linux-only things below, ignored on other platforms.
- SubnetRoutes []netaddr.IPPrefix // subnets being advertised to other Tailscale nodes
+ SubnetRoutes []netip.Prefix // subnets being advertised to other Tailscale nodes
SNATSubnetRoutes bool // SNAT traffic to local subnets
NetfilterMode preftype.NetfilterMode // how much to manage netfilter rules
}
diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go
index 51c210bcc..5087a3e34 100644
--- a/wgengine/router/router_linux.go
+++ b/wgengine/router/router_linux.go
@@ -9,6 +9,7 @@
"errors"
"fmt"
"io/ioutil"
+ "net/netip"
"os"
"os/exec"
"strconv"
@@ -23,7 +24,6 @@
"golang.org/x/time/rate"
"golang.zx2c4.com/wireguard/tun"
"tailscale.com/envknob"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/syncs"
"tailscale.com/types/logger"
@@ -89,9 +89,9 @@ type linuxRouter struct {
tunname string
linkMon *monitor.Mon
unregLinkMon func()
- addrs map[netaddr.IPPrefix]bool
- routes map[netaddr.IPPrefix]bool
- localRoutes map[netaddr.IPPrefix]bool
+ addrs map[netip.Prefix]bool
+ routes map[netip.Prefix]bool
+ localRoutes map[netip.Prefix]bool
snatSubnetRoutes bool
netfilterMode preftype.NetfilterMode
@@ -451,7 +451,7 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error {
// addAddress adds an IP/mask to the tunnel interface. Fails if the
// address is already assigned to the interface, or if the addition
// fails.
-func (r *linuxRouter) addAddress(addr netaddr.IPPrefix) error {
+func (r *linuxRouter) addAddress(addr netip.Prefix) error {
if !r.v6Available && addr.Addr().Is6() {
return nil
}
@@ -477,7 +477,7 @@ func (r *linuxRouter) addAddress(addr netaddr.IPPrefix) error {
// delAddress removes an IP/mask from the tunnel interface. Fails if
// the address is not assigned to the interface, or if the removal
// fails.
-func (r *linuxRouter) delAddress(addr netaddr.IPPrefix) error {
+func (r *linuxRouter) delAddress(addr netip.Prefix) error {
if !r.v6Available && addr.Addr().Is6() {
return nil
}
@@ -502,7 +502,7 @@ func (r *linuxRouter) delAddress(addr netaddr.IPPrefix) error {
// addLoopbackRule adds a firewall rule to permit loopback traffic to
// a local Tailscale IP.
-func (r *linuxRouter) addLoopbackRule(addr netaddr.IP) error {
+func (r *linuxRouter) addLoopbackRule(addr netip.Addr) error {
if r.netfilterMode == netfilterOff {
return nil
}
@@ -524,7 +524,7 @@ func (r *linuxRouter) addLoopbackRule(addr netaddr.IP) error {
// delLoopbackRule removes the firewall rule permitting loopback
// traffic to a Tailscale IP.
-func (r *linuxRouter) delLoopbackRule(addr netaddr.IP) error {
+func (r *linuxRouter) delLoopbackRule(addr netip.Addr) error {
if r.netfilterMode == netfilterOff {
return nil
}
@@ -547,7 +547,7 @@ func (r *linuxRouter) delLoopbackRule(addr netaddr.IP) error {
// addRoute adds a route for cidr, pointing to the tunnel
// interface. Fails if the route already exists, or if adding the
// route fails.
-func (r *linuxRouter) addRoute(cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) addRoute(cidr netip.Prefix) error {
if !r.v6Available && cidr.Addr().Is6() {
return nil
}
@@ -569,7 +569,7 @@ func (r *linuxRouter) addRoute(cidr netaddr.IPPrefix) error {
// This has the effect that lookup in the routing table is terminated
// pretending that no route was found. Fails if the route already exists,
// or if adding the route fails.
-func (r *linuxRouter) addThrowRoute(cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) addThrowRoute(cidr netip.Prefix) error {
if !r.ipRuleAvailable {
return nil
}
@@ -590,7 +590,7 @@ func (r *linuxRouter) addThrowRoute(cidr netaddr.IPPrefix) error {
return err
}
-func (r *linuxRouter) addRouteDef(routeDef []string, cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) addRouteDef(routeDef []string, cidr netip.Prefix) error {
if !r.v6Available && cidr.Addr().Is6() {
return nil
}
@@ -624,7 +624,7 @@ func (r *linuxRouter) addRouteDef(routeDef []string, cidr netaddr.IPPrefix) erro
// delRoute removes the route for cidr pointing to the tunnel
// interface. Fails if the route doesn't exist, or if removing the
// route fails.
-func (r *linuxRouter) delRoute(cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) delRoute(cidr netip.Prefix) error {
if !r.v6Available && cidr.Addr().Is6() {
return nil
}
@@ -649,7 +649,7 @@ func (r *linuxRouter) delRoute(cidr netaddr.IPPrefix) error {
// delThrowRoute removes the throw route for the cidr. Fails if the route
// doesn't exist, or if removing the route fails.
-func (r *linuxRouter) delThrowRoute(cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) delThrowRoute(cidr netip.Prefix) error {
if !r.ipRuleAvailable {
return nil
}
@@ -671,7 +671,7 @@ func (r *linuxRouter) delThrowRoute(cidr netaddr.IPPrefix) error {
return err
}
-func (r *linuxRouter) delRouteDef(routeDef []string, cidr netaddr.IPPrefix) error {
+func (r *linuxRouter) delRouteDef(routeDef []string, cidr netip.Prefix) error {
if !r.v6Available && cidr.Addr().Is6() {
return nil
}
@@ -694,14 +694,14 @@ func (r *linuxRouter) delRouteDef(routeDef []string, cidr netaddr.IPPrefix) erro
return err
}
-func dashFam(ip netaddr.IP) string {
+func dashFam(ip netip.Addr) string {
if ip.Is6() {
return "-6"
}
return "-4"
}
-func (r *linuxRouter) hasRoute(routeDef []string, cidr netaddr.IPPrefix) (bool, error) {
+func (r *linuxRouter) hasRoute(routeDef []string, cidr netip.Prefix) (bool, error) {
args := append([]string{"ip", dashFam(cidr.Addr()), "route", "show"}, routeDef...)
if r.ipRuleAvailable {
args = append(args, "table", tailscaleRouteTable.ipCmdArg())
@@ -1378,8 +1378,8 @@ func (r *linuxRouter) delSNATRule() error {
// old and new match. Returns a map reflecting the actual new state
// (which may be somewhere in between old and new if some commands
// failed), and any error encountered while reconfiguring.
-func cidrDiff(kind string, old map[netaddr.IPPrefix]bool, new []netaddr.IPPrefix, add, del func(netaddr.IPPrefix) error, logf logger.Logf) (map[netaddr.IPPrefix]bool, error) {
- newMap := make(map[netaddr.IPPrefix]bool, len(new))
+func cidrDiff(kind string, old map[netip.Prefix]bool, new []netip.Prefix, add, del func(netip.Prefix) error, logf logger.Logf) (map[netip.Prefix]bool, error) {
+ newMap := make(map[netip.Prefix]bool, len(new))
for _, cidr := range new {
newMap[cidr] = true
}
@@ -1387,7 +1387,7 @@ func cidrDiff(kind string, old map[netaddr.IPPrefix]bool, new []netaddr.IPPrefix
// ret starts out as a copy of old, and updates as we
// add/delete. That way we can always return it and have it be the
// true state of what we've done so far.
- ret := make(map[netaddr.IPPrefix]bool, len(old))
+ ret := make(map[netip.Prefix]bool, len(old))
for cidr := range old {
ret[cidr] = true
}
@@ -1442,7 +1442,7 @@ func tsChain(chain string) string {
// normalizeCIDR returns cidr as an ip/mask string, with the host bits
// of the IP address zeroed out.
-func normalizeCIDR(cidr netaddr.IPPrefix) string {
+func normalizeCIDR(cidr netip.Prefix) string {
return cidr.Masked().String()
}
@@ -1548,7 +1548,7 @@ func checkIPRuleSupportsV6(logf logger.Logf) error {
return netlink.RuleAdd(rule)
}
-func nlAddrOfPrefix(p netaddr.IPPrefix) *netlink.Addr {
+func nlAddrOfPrefix(p netip.Prefix) *netlink.Addr {
return &netlink.Addr{
IPNet: netipx.PrefixIPNet(p),
}
diff --git a/wgengine/router/router_openbsd.go b/wgengine/router/router_openbsd.go
index 561e3783a..859b4be34 100644
--- a/wgengine/router/router_openbsd.go
+++ b/wgengine/router/router_openbsd.go
@@ -8,11 +8,11 @@
"errors"
"fmt"
"log"
+ "net/netip"
"os/exec"
"go4.org/netipx"
"golang.zx2c4.com/wireguard/tun"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
@@ -25,9 +25,9 @@ type openbsdRouter struct {
logf logger.Logf
linkMon *monitor.Mon
tunname string
- local4 netaddr.IPPrefix
- local6 netaddr.IPPrefix
- routes map[netaddr.IPPrefix]struct{}
+ local4 netip.Prefix
+ local6 netip.Prefix
+ routes map[netip.Prefix]struct{}
}
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
@@ -59,7 +59,7 @@ func (r *openbsdRouter) Up() error {
return nil
}
-func inet(p netaddr.IPPrefix) string {
+func inet(p netip.Prefix) string {
if p.Addr().Is6() {
return "inet6"
}
@@ -77,8 +77,8 @@ func (r *openbsdRouter) Set(cfg *Config) error {
}
numIPv4 := 0
numIPv6 := 0
- localAddr4 := netaddr.IPPrefix{}
- localAddr6 := netaddr.IPPrefix{}
+ localAddr4 := netip.Prefix{}
+ localAddr6 := netip.Prefix{}
for _, addr := range cfg.LocalAddrs {
if addr.Addr().Is4() {
numIPv4++
@@ -145,7 +145,7 @@ func (r *openbsdRouter) Set(cfg *Config) error {
// in https://github.com/tailscale/tailscale/issues/1307 we made
// FreeBSD use a /48 for IPv6 addresses, which is nice because we
// don't need to additionally add routing entries. Do that here too.
- localAddr6 = netaddr.IPPrefixFrom(localAddr6.Addr(), 48)
+ localAddr6 = netip.PrefixFrom(localAddr6.Addr(), 48)
}
if localAddr6 != r.local6 {
@@ -174,7 +174,7 @@ func (r *openbsdRouter) Set(cfg *Config) error {
}
}
- newRoutes := make(map[netaddr.IPPrefix]struct{})
+ newRoutes := make(map[netip.Prefix]struct{})
for _, route := range cfg.Routes {
newRoutes[route] = struct{}{}
}
diff --git a/wgengine/router/router_test.go b/wgengine/router/router_test.go
index 9d7cb0a82..00c4d2f73 100644
--- a/wgengine/router/router_test.go
+++ b/wgengine/router/router_test.go
@@ -9,12 +9,11 @@
"reflect"
"testing"
- "tailscale.com/net/netaddr"
"tailscale.com/types/preftype"
)
-func mustCIDRs(ss ...string) []netaddr.IPPrefix {
- var ret []netaddr.IPPrefix
+func mustCIDRs(ss ...string) []netip.Prefix {
+ var ret []netip.Prefix
for _, s := range ss {
ret = append(ret, netip.MustParsePrefix(s))
}
@@ -36,7 +35,7 @@ func TestConfigEqual(t *testing.T) {
configFields, testedFields)
}
- nets := func(strs ...string) (ns []netaddr.IPPrefix) {
+ nets := func(strs ...string) (ns []netip.Prefix) {
for _, s := range strs {
n, err := netip.ParsePrefix(s)
if err != nil {
diff --git a/wgengine/router/router_userspace_bsd.go b/wgengine/router/router_userspace_bsd.go
index 5e374b3f5..205cd0ee2 100644
--- a/wgengine/router/router_userspace_bsd.go
+++ b/wgengine/router/router_userspace_bsd.go
@@ -10,12 +10,12 @@
import (
"fmt"
"log"
+ "net/netip"
"os/exec"
"runtime"
"go4.org/netipx"
"golang.zx2c4.com/wireguard/tun"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/types/logger"
"tailscale.com/version"
@@ -26,8 +26,8 @@ type userspaceBSDRouter struct {
logf logger.Logf
linkMon *monitor.Mon
tunname string
- local []netaddr.IPPrefix
- routes map[netaddr.IPPrefix]struct{}
+ local []netip.Prefix
+ routes map[netip.Prefix]struct{}
}
func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
@@ -43,7 +43,7 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor
}, nil
}
-func (r *userspaceBSDRouter) addrsToRemove(newLocalAddrs []netaddr.IPPrefix) (remove []netaddr.IPPrefix) {
+func (r *userspaceBSDRouter) addrsToRemove(newLocalAddrs []netip.Prefix) (remove []netip.Prefix) {
for _, cur := range r.local {
found := false
for _, v := range newLocalAddrs {
@@ -59,7 +59,7 @@ func (r *userspaceBSDRouter) addrsToRemove(newLocalAddrs []netaddr.IPPrefix) (re
return
}
-func (r *userspaceBSDRouter) addrsToAdd(newLocalAddrs []netaddr.IPPrefix) (add []netaddr.IPPrefix) {
+func (r *userspaceBSDRouter) addrsToAdd(newLocalAddrs []netip.Prefix) (add []netip.Prefix) {
for _, cur := range newLocalAddrs {
found := false
for _, v := range r.local {
@@ -91,7 +91,7 @@ func (r *userspaceBSDRouter) Up() error {
return nil
}
-func inet(p netaddr.IPPrefix) string {
+func inet(p netip.Prefix) string {
if p.Addr().Is6() {
return "inet6"
}
@@ -126,7 +126,7 @@ func (r *userspaceBSDRouter) Set(cfg *Config) (reterr error) {
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=218508
// Instead add our whole /48, which works because we use a /48 route.
// Full history: https://github.com/tailscale/tailscale/issues/1307
- tmp := netaddr.IPPrefixFrom(addr.Addr(), 48)
+ tmp := netip.PrefixFrom(addr.Addr(), 48)
arg = []string{"ifconfig", r.tunname, inet(tmp), tmp.String()}
} else {
arg = []string{"ifconfig", r.tunname, inet(addr), addr.String(), addr.Addr().String()}
@@ -138,7 +138,7 @@ func (r *userspaceBSDRouter) Set(cfg *Config) (reterr error) {
}
}
- newRoutes := make(map[netaddr.IPPrefix]struct{})
+ newRoutes := make(map[netip.Prefix]struct{})
for _, route := range cfg.Routes {
if runtime.GOOS != "darwin" && route == tsaddr.TailscaleULARange() {
// Because we added the interface address as a /48 above,
@@ -187,7 +187,7 @@ func (r *userspaceBSDRouter) Set(cfg *Config) (reterr error) {
// Store the interface and routes so we know what to change on an update.
if errq == nil {
- r.local = append([]netaddr.IPPrefix{}, cfg.LocalAddrs...)
+ r.local = append([]netip.Prefix{}, cfg.LocalAddrs...)
}
r.routes = newRoutes
diff --git a/wgengine/router/router_windows.go b/wgengine/router/router_windows.go
index 58ab7fc1d..59388ff02 100644
--- a/wgengine/router/router_windows.go
+++ b/wgengine/router/router_windows.go
@@ -10,6 +10,7 @@
"encoding/json"
"fmt"
"io"
+ "net/netip"
"os"
"os/exec"
"strings"
@@ -22,7 +23,6 @@
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"tailscale.com/logtail/backoff"
"tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
@@ -93,7 +93,7 @@ func (r *winRouter) Set(cfg *Config) error {
return nil
}
-func hasDefaultRoute(routes []netaddr.IPPrefix) bool {
+func hasDefaultRoute(routes []netip.Prefix) bool {
for _, route := range routes {
if route.Bits() == 0 {
return true
@@ -132,8 +132,8 @@ type firewallTweaker struct {
wantLocal []string // next value we want, or "" to delete the firewall rule
lastLocal []string // last set value, if known
- localRoutes []netaddr.IPPrefix
- lastLocalRoutes []netaddr.IPPrefix
+ localRoutes []netip.Prefix
+ lastLocalRoutes []netip.Prefix
wantKillswitch bool
lastKillswitch bool
@@ -156,7 +156,7 @@ func (ft *firewallTweaker) clear() { ft.set(nil, nil, nil) }
// Empty slices remove firewall rules.
//
// set takes ownership of cidrs, but not routes.
-func (ft *firewallTweaker) set(cidrs []string, routes, localRoutes []netaddr.IPPrefix) {
+func (ft *firewallTweaker) set(cidrs []string, routes, localRoutes []netip.Prefix) {
ft.mu.Lock()
defer ft.mu.Unlock()
@@ -236,7 +236,7 @@ func (ft *firewallTweaker) doAsyncSet() {
// process to dial out as it pleases.
//
// Must only be invoked from doAsyncSet.
-func (ft *firewallTweaker) doSet(local []string, killswitch bool, clear bool, procRule bool, allowedRoutes []netaddr.IPPrefix) error {
+func (ft *firewallTweaker) doSet(local []string, killswitch bool, clear bool, procRule bool, allowedRoutes []netip.Prefix) error {
if clear {
ft.logf("clearing Tailscale-In firewall rules...")
// We ignore the error here, because netsh returns an error for
@@ -343,7 +343,7 @@ func (ft *firewallTweaker) doSet(local []string, killswitch bool, clear bool, pr
return ft.fwProcEncoder.Encode(allowedRoutes)
}
-func routesEqual(a, b []netaddr.IPPrefix) bool {
+func routesEqual(a, b []netip.Prefix) bool {
if len(a) != len(b) {
return false
}
diff --git a/wgengine/userspace.go b/wgengine/userspace.go
index 987d6b23e..ca4aecdc6 100644
--- a/wgengine/userspace.go
+++ b/wgengine/userspace.go
@@ -31,7 +31,6 @@
"tailscale.com/net/dns/resolver"
"tailscale.com/net/flowtrack"
"tailscale.com/net/interfaces"
- "tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/net/tsdial"
@@ -108,11 +107,11 @@ type userspaceEngine struct {
// isLocalAddr reports the whether an IP is assigned to the local
// tunnel interface. It's used to reflect local packets
// incorrectly sent to us.
- isLocalAddr atomic.Value // of func(netaddr.IP)bool
+ isLocalAddr atomic.Value // of func(netip.Addr)bool
// isDNSIPOverTailscale reports the whether a DNS resolver's IP
// is being routed over Tailscale.
- isDNSIPOverTailscale atomic.Value // of func(netaddr.IP)bool
+ isDNSIPOverTailscale atomic.Value // of func(netip.Addr)bool
wgLock sync.Mutex // serializes all wgdev operations; see lock order comment below
lastCfgFull wgcfg.Config
@@ -124,8 +123,8 @@ type userspaceEngine struct {
lastIsSubnetRouter bool // was the node a primary subnet router in the last run.
recvActivityAt map[key.NodePublic]mono.Time
trimmedNodes map[key.NodePublic]bool // set of node keys of peers currently excluded from wireguard config
- sentActivityAt map[netaddr.IP]*mono.Time // value is accessed atomically
- destIPActivityFuncs map[netaddr.IP]func()
+ sentActivityAt map[netip.Addr]*mono.Time // value is accessed atomically
+ destIPActivityFuncs map[netip.Addr]func()
statusBufioReader *bufio.Reader // reusable for UAPI
lastStatusPollTime mono.Time // last time we polled the engine status
@@ -137,7 +136,7 @@ type userspaceEngine struct {
endpoints []tailcfg.Endpoint
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
networkMapCallbacks map[*someHandle]NetworkMapCallback
- tsIPByIPPort map[netaddr.IPPort]netaddr.IP // allows registration of IP:ports as belonging to a certain Tailscale IP for whois lookups
+ tsIPByIPPort map[netip.AddrPort]netip.Addr // allows registration of IP:ports as belonging to a certain Tailscale IP for whois lookups
// pongCallback is the map of response handlers waiting for disco or TSMP
// pong callbacks. The map key is a random slice of bytes.
@@ -498,7 +497,7 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper)
}
if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- isLocalAddr, ok := e.isLocalAddr.Load().(func(netaddr.IP) bool)
+ isLocalAddr, ok := e.isLocalAddr.Load().(func(netip.Addr) bool)
if !ok {
e.logf("[unexpected] e.isLocalAddr was nil, can't check for loopback packet")
} else if isLocalAddr(p.Dst.Addr()) {
@@ -629,7 +628,7 @@ func (e *userspaceEngine) noteRecvActivity(nk key.NodePublic) {
// has had a packet sent to or received from it since t.
//
// e.wgLock must be held.
-func (e *userspaceEngine) isActiveSinceLocked(nk key.NodePublic, ip netaddr.IP, t mono.Time) bool {
+func (e *userspaceEngine) isActiveSinceLocked(nk key.NodePublic, ip netip.Addr, t mono.Time) bool {
if e.recvActivityAt[nk].After(t) {
return true
}
@@ -673,7 +672,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node
// to install tracking hooks for to watch their send/receive
// activity.
trackNodes := make([]key.NodePublic, 0, len(full.Peers))
- trackIPs := make([]netaddr.IP, 0, len(full.Peers))
+ trackIPs := make([]netip.Addr, 0, len(full.Peers))
trimmedNodes := map[key.NodePublic]bool{} // TODO: don't re-alloc this map each time
@@ -747,7 +746,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Node
// as given to wireguard-go.
//
// e.wgLock must be held.
-func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic, trackIPs []netaddr.IP) {
+func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic, trackIPs []netip.Addr) {
// Generate the new map of which nodekeys we want to track
// receive times for.
mr := map[key.NodePublic]mono.Time{} // TODO: only recreate this if set of keys changed
@@ -762,9 +761,9 @@ func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic,
e.recvActivityAt = mr
oldTime := e.sentActivityAt
- e.sentActivityAt = make(map[netaddr.IP]*mono.Time, len(oldTime))
+ e.sentActivityAt = make(map[netip.Addr]*mono.Time, len(oldTime))
oldFunc := e.destIPActivityFuncs
- e.destIPActivityFuncs = make(map[netaddr.IP]func(), len(oldFunc))
+ e.destIPActivityFuncs = make(map[netip.Addr]func(), len(oldFunc))
updateFn := func(timePtr *mono.Time) func() {
return func() {
@@ -810,7 +809,7 @@ func (e *userspaceEngine) updateActivityMapsLocked(trackNodes []key.NodePublic,
// hasOverlap checks if there is a IPPrefix which is common amongst the two
// provided slices.
-func hasOverlap(aips, rips []netaddr.IPPrefix) bool {
+func hasOverlap(aips, rips []netip.Prefix) bool {
for _, aip := range aips {
for _, rip := range rips {
if aip == rip {
@@ -1290,7 +1289,7 @@ func (e *userspaceEngine) UpdateStatus(sb *ipnstate.StatusBuilder) {
e.magicConn.UpdateStatus(sb)
}
-func (e *userspaceEngine) Ping(ip netaddr.IP, pingType tailcfg.PingType, cb func(*ipnstate.PingResult)) {
+func (e *userspaceEngine) Ping(ip netip.Addr, pingType tailcfg.PingType, cb func(*ipnstate.PingResult)) {
res := &ipnstate.PingResult{IP: ip.String()}
pip, ok := e.PeerForIP(ip)
if !ok {
@@ -1318,11 +1317,11 @@ func (e *userspaceEngine) Ping(ip netaddr.IP, pingType tailcfg.PingType, cb func
}
}
-func (e *userspaceEngine) mySelfIPMatchingFamily(dst netaddr.IP) (src netaddr.IP, err error) {
+func (e *userspaceEngine) mySelfIPMatchingFamily(dst netip.Addr) (src netip.Addr, err error) {
e.mu.Lock()
defer e.mu.Unlock()
if e.netMap == nil {
- return netaddr.IP{}, errors.New("no netmap")
+ return netip.Addr{}, errors.New("no netmap")
}
for _, a := range e.netMap.Addresses {
if a.IsSingleIP() && a.Addr().BitLen() == dst.BitLen() {
@@ -1330,12 +1329,12 @@ func (e *userspaceEngine) mySelfIPMatchingFamily(dst netaddr.IP) (src netaddr.IP
}
}
if len(e.netMap.Addresses) == 0 {
- return netaddr.IP{}, errors.New("no self address in netmap")
+ return netip.Addr{}, errors.New("no self address in netmap")
}
- return netaddr.IP{}, errors.New("no self address in netmap matching address family")
+ return netip.Addr{}, errors.New("no self address in netmap matching address family")
}
-func (e *userspaceEngine) sendICMPEchoRequest(destIP netaddr.IP, peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) {
+func (e *userspaceEngine) sendICMPEchoRequest(destIP netip.Addr, peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) {
srcIP, err := e.mySelfIPMatchingFamily(destIP)
if err != nil {
res.Err = err.Error()
@@ -1384,7 +1383,7 @@ func (e *userspaceEngine) sendICMPEchoRequest(destIP netaddr.IP, peer *tailcfg.N
e.tundev.InjectOutbound(icmpPing)
}
-func (e *userspaceEngine) sendTSMPPing(ip netaddr.IP, peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) {
+func (e *userspaceEngine) sendTSMPPing(ip netip.Addr, peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) {
srcIP, err := e.mySelfIPMatchingFamily(ip)
if err != nil {
res.Err = err.Error()
@@ -1454,16 +1453,16 @@ func (e *userspaceEngine) setICMPEchoResponseCallback(idSeq uint32, cb func()) {
}
}
-func (e *userspaceEngine) RegisterIPPortIdentity(ipport netaddr.IPPort, tsIP netaddr.IP) {
+func (e *userspaceEngine) RegisterIPPortIdentity(ipport netip.AddrPort, tsIP netip.Addr) {
e.mu.Lock()
defer e.mu.Unlock()
if e.tsIPByIPPort == nil {
- e.tsIPByIPPort = make(map[netaddr.IPPort]netaddr.IP)
+ e.tsIPByIPPort = make(map[netip.AddrPort]netip.Addr)
}
e.tsIPByIPPort[ipport] = tsIP
}
-func (e *userspaceEngine) UnregisterIPPortIdentity(ipport netaddr.IPPort) {
+func (e *userspaceEngine) UnregisterIPPortIdentity(ipport netip.AddrPort) {
e.mu.Lock()
defer e.mu.Unlock()
if e.tsIPByIPPort == nil {
@@ -1480,7 +1479,7 @@ func (e *userspaceEngine) UnregisterIPPortIdentity(ipport netaddr.IPPort) {
100 * time.Millisecond,
}
-func (e *userspaceEngine) WhoIsIPPort(ipport netaddr.IPPort) (tsIP netaddr.IP, ok bool) {
+func (e *userspaceEngine) WhoIsIPPort(ipport netip.AddrPort) (tsIP netip.Addr, ok bool) {
// We currently have a registration race,
// https://github.com/tailscale/tailscale/issues/1616,
// so loop a few times for now waiting for the registration
@@ -1507,7 +1506,7 @@ func (e *userspaceEngine) WhoIsIPPort(ipport netaddr.IPPort) (tsIP netaddr.IP, o
//
// peerForIP acquires both e.mu and e.wgLock, but neither at the same
// time.
-func (e *userspaceEngine) PeerForIP(ip netaddr.IP) (ret PeerForIP, ok bool) {
+func (e *userspaceEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
e.mu.Lock()
nm := e.netMap
e.mu.Unlock()
@@ -1534,7 +1533,7 @@ func (e *userspaceEngine) PeerForIP(ip netaddr.IP) (ret PeerForIP, ok bool) {
defer e.wgLock.Unlock()
// TODO(bradfitz): this is O(n peers). Add ART to netaddr?
- var best netaddr.IPPrefix
+ var best netip.Prefix
var bestKey key.NodePublic
for _, p := range e.lastCfgFull.Peers {
for _, cidr := range p.AllowedIPs {
@@ -1572,7 +1571,7 @@ func (p closeOnErrorPool) closeAllIfError(errp *error) {
}
// ipInPrefixes reports whether ip is in any of pp.
-func ipInPrefixes(ip netaddr.IP, pp []netaddr.IPPrefix) bool {
+func ipInPrefixes(ip netip.Addr, pp []netip.Prefix) bool {
for _, p := range pp {
if p.Contains(ip) {
return true
@@ -1584,8 +1583,8 @@ func ipInPrefixes(ip netaddr.IP, pp []netaddr.IPPrefix) bool {
// dnsIPsOverTailscale returns the IPPrefixes of DNS resolver IPs that are
// routed over Tailscale. The returned value does not contain duplicates is
// not necessarily sorted.
-func dnsIPsOverTailscale(dnsCfg *dns.Config, routerCfg *router.Config) (ret []netaddr.IPPrefix) {
- m := map[netaddr.IP]bool{}
+func dnsIPsOverTailscale(dnsCfg *dns.Config, routerCfg *router.Config) (ret []netip.Prefix) {
+ m := map[netip.Addr]bool{}
add := func(resolvers []*dnstype.Resolver) {
for _, r := range resolvers {
@@ -1608,7 +1607,7 @@ func dnsIPsOverTailscale(dnsCfg *dns.Config, routerCfg *router.Config) (ret []ne
add(resolvers)
}
- ret = make([]netaddr.IPPrefix, 0, len(m))
+ ret = make([]netip.Prefix, 0, len(m))
for ip := range m {
ret = append(ret, netip.PrefixFrom(ip, ip.BitLen()))
}
@@ -1622,8 +1621,8 @@ type fwdDNSLinkSelector struct {
tunName string
}
-func (ls fwdDNSLinkSelector) PickLink(ip netaddr.IP) (linkName string) {
- if ls.ue.isDNSIPOverTailscale.Load().(func(netaddr.IP) bool)(ip) {
+func (ls fwdDNSLinkSelector) PickLink(ip netip.Addr) (linkName string) {
+ if ls.ue.isDNSIPOverTailscale.Load().(func(netip.Addr) bool)(ip) {
return ls.tunName
}
return ""
diff --git a/wgengine/userspace_test.go b/wgengine/userspace_test.go
index c17c6dc90..f6ba3a96b 100644
--- a/wgengine/userspace_test.go
+++ b/wgengine/userspace_test.go
@@ -113,8 +113,8 @@ func TestUserspaceEngineReconfig(t *testing.T) {
Peers: []wgcfg.Peer{
{
PublicKey: nk,
- AllowedIPs: []netaddr.IPPrefix{
- netaddr.IPPrefixFrom(netaddr.IPv4(100, 100, 99, 1), 32),
+ AllowedIPs: []netip.Prefix{
+ netip.PrefixFrom(netaddr.IPv4(100, 100, 99, 1), 32),
},
},
},
@@ -173,8 +173,8 @@ func TestUserspaceEnginePortReconfig(t *testing.T) {
Peers: []wgcfg.Peer{
{
PublicKey: nodeKey,
- AllowedIPs: []netaddr.IPPrefix{
- netaddr.IPPrefixFrom(netaddr.IPv4(100, 100, 99, 1), 32),
+ AllowedIPs: []netip.Prefix{
+ netip.PrefixFrom(netaddr.IPv4(100, 100, 99, 1), 32),
},
},
},
@@ -231,7 +231,7 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) {
b.Run("map1", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
- m := map[netaddr.IP]bool{
+ m := map[netip.Addr]bool{
la1: true,
}
for i := 0; i < b.N; i++ {
@@ -242,7 +242,7 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) {
b.Run("map2", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
- m := map[netaddr.IP]bool{
+ m := map[netip.Addr]bool{
la1: true,
la2: true,
}
@@ -254,7 +254,7 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) {
b.Run("or1", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
- f := func(t netaddr.IP) bool {
+ f := func(t netip.Addr) bool {
return t == la1
}
for i := 0; i < b.N; i++ {
@@ -265,7 +265,7 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) {
b.Run("or2", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
- f := func(t netaddr.IP) bool {
+ f := func(t netip.Addr) bool {
return t == la1 || t == la2
}
for i := 0; i < b.N; i++ {
diff --git a/wgengine/watchdog.go b/wgengine/watchdog.go
index 2248535d3..432d869dd 100644
--- a/wgengine/watchdog.go
+++ b/wgengine/watchdog.go
@@ -9,6 +9,7 @@
import (
"log"
+ "net/netip"
"runtime/pprof"
"strings"
"time"
@@ -17,7 +18,6 @@
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/dns"
"tailscale.com/net/dns/resolver"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tstun"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
@@ -120,16 +120,16 @@ func (e *watchdogEngine) DiscoPublicKey() (k key.DiscoPublic) {
e.watchdog("DiscoPublicKey", func() { k = e.wrap.DiscoPublicKey() })
return k
}
-func (e *watchdogEngine) Ping(ip netaddr.IP, pingType tailcfg.PingType, cb func(*ipnstate.PingResult)) {
+func (e *watchdogEngine) Ping(ip netip.Addr, pingType tailcfg.PingType, cb func(*ipnstate.PingResult)) {
e.watchdog("Ping", func() { e.wrap.Ping(ip, pingType, cb) })
}
-func (e *watchdogEngine) RegisterIPPortIdentity(ipp netaddr.IPPort, tsIP netaddr.IP) {
+func (e *watchdogEngine) RegisterIPPortIdentity(ipp netip.AddrPort, tsIP netip.Addr) {
e.watchdog("RegisterIPPortIdentity", func() { e.wrap.RegisterIPPortIdentity(ipp, tsIP) })
}
-func (e *watchdogEngine) UnregisterIPPortIdentity(ipp netaddr.IPPort) {
+func (e *watchdogEngine) UnregisterIPPortIdentity(ipp netip.AddrPort) {
e.watchdog("UnregisterIPPortIdentity", func() { e.wrap.UnregisterIPPortIdentity(ipp) })
}
-func (e *watchdogEngine) WhoIsIPPort(ipp netaddr.IPPort) (tsIP netaddr.IP, ok bool) {
+func (e *watchdogEngine) WhoIsIPPort(ipp netip.AddrPort) (tsIP netip.Addr, ok bool) {
e.watchdog("UnregisterIPPortIdentity", func() { tsIP, ok = e.wrap.WhoIsIPPort(ipp) })
return tsIP, ok
}
@@ -148,7 +148,7 @@ func (e *watchdogEngine) GetResolver() (r *resolver.Resolver, ok bool) {
}
return nil, false
}
-func (e *watchdogEngine) PeerForIP(ip netaddr.IP) (ret PeerForIP, ok bool) {
+func (e *watchdogEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
e.watchdog("PeerForIP", func() { ret, ok = e.wrap.PeerForIP(ip) })
return ret, ok
}
diff --git a/wgengine/wgcfg/config.go b/wgengine/wgcfg/config.go
index e086aaf1c..80acd0d20 100644
--- a/wgengine/wgcfg/config.go
+++ b/wgengine/wgcfg/config.go
@@ -6,7 +6,8 @@
package wgcfg
import (
- "tailscale.com/net/netaddr"
+ "net/netip"
+
"tailscale.com/types/key"
)
@@ -17,16 +18,16 @@
type Config struct {
Name string
PrivateKey key.NodePrivate
- Addresses []netaddr.IPPrefix
+ Addresses []netip.Prefix
MTU uint16
- DNS []netaddr.IP
+ DNS []netip.Addr
Peers []Peer
}
type Peer struct {
PublicKey key.NodePublic
DiscoKey key.DiscoPublic // present only so we can handle restarts within wgengine, not passed to WireGuard
- AllowedIPs []netaddr.IPPrefix
+ AllowedIPs []netip.Prefix
PersistentKeepalive uint16
// wireguard-go's endpoint for this peer. It should always equal Peer.PublicKey.
// We represent it explicitly so that we can detect if they diverge and recover.
diff --git a/wgengine/wgcfg/device_test.go b/wgengine/wgcfg/device_test.go
index 29a13430f..8868ad785 100644
--- a/wgengine/wgcfg/device_test.go
+++ b/wgengine/wgcfg/device_test.go
@@ -19,7 +19,6 @@
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
)
@@ -42,7 +41,7 @@ func TestDeviceConfig(t *testing.T) {
PrivateKey: pk1,
Peers: []Peer{{
PublicKey: k2,
- AllowedIPs: []netaddr.IPPrefix{ip2},
+ AllowedIPs: []netip.Prefix{ip2},
}},
}
@@ -50,7 +49,7 @@ func TestDeviceConfig(t *testing.T) {
PrivateKey: pk2,
Peers: []Peer{{
PublicKey: k1,
- AllowedIPs: []netaddr.IPPrefix{ip1},
+ AllowedIPs: []netip.Prefix{ip1},
PersistentKeepalive: 5,
}},
}
@@ -143,7 +142,7 @@ func TestDeviceConfig(t *testing.T) {
t.Run("device1 add new peer", func(t *testing.T) {
cfg1.Peers = append(cfg1.Peers, Peer{
PublicKey: k3,
- AllowedIPs: []netaddr.IPPrefix{ip3},
+ AllowedIPs: []netip.Prefix{ip3},
})
sort.Slice(cfg1.Peers, func(i, j int) bool {
return cfg1.Peers[i].PublicKey.Less(cfg1.Peers[j].PublicKey)
diff --git a/wgengine/wgcfg/nmcfg/nmcfg.go b/wgengine/wgcfg/nmcfg/nmcfg.go
index 00c1aed08..e553b9148 100644
--- a/wgengine/wgcfg/nmcfg/nmcfg.go
+++ b/wgengine/wgcfg/nmcfg/nmcfg.go
@@ -8,9 +8,9 @@
import (
"bytes"
"fmt"
+ "net/netip"
"strings"
- "tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
@@ -34,7 +34,7 @@ func nodeDebugName(n *tailcfg.Node) string {
// cidrIsSubnet reports whether cidr is a non-default-route subnet
// exported by node that is not one of its own self addresses.
-func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
+func cidrIsSubnet(node *tailcfg.Node, cidr netip.Prefix) bool {
if cidr.Bits() == 0 {
return false
}
diff --git a/wgengine/wgcfg/parser.go b/wgengine/wgcfg/parser.go
index 2cbd83b4e..21d8ad41d 100644
--- a/wgengine/wgcfg/parser.go
+++ b/wgengine/wgcfg/parser.go
@@ -9,11 +9,11 @@
"fmt"
"io"
"net"
+ "net/netip"
"strconv"
"strings"
"go4.org/mem"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
)
@@ -163,7 +163,7 @@ func (cfg *Config) handlePeerLine(peer *Peer, k, value mem.RO, valueBytes []byte
}
peer.PersistentKeepalive = uint16(n)
case k.EqualString("allowed_ip"):
- ipp := netaddr.IPPrefix{}
+ ipp := netip.Prefix{}
err := ipp.UnmarshalText(valueBytes)
if err != nil {
return err
diff --git a/wgengine/wgcfg/parser_test.go b/wgengine/wgcfg/parser_test.go
index 57af49d12..54e0c34d5 100644
--- a/wgengine/wgcfg/parser_test.go
+++ b/wgengine/wgcfg/parser_test.go
@@ -13,7 +13,6 @@
"runtime"
"testing"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
)
@@ -72,7 +71,7 @@ func BenchmarkFromUAPI(b *testing.B) {
peer := Peer{
PublicKey: k1,
- AllowedIPs: []netaddr.IPPrefix{ip1},
+ AllowedIPs: []netip.Prefix{ip1},
}
cfg1 := &Config{
PrivateKey: pk1,
diff --git a/wgengine/wgcfg/writer.go b/wgengine/wgcfg/writer.go
index 9ad123800..9aa01c69f 100644
--- a/wgengine/wgcfg/writer.go
+++ b/wgengine/wgcfg/writer.go
@@ -7,9 +7,9 @@
import (
"fmt"
"io"
+ "net/netip"
"strconv"
- "tailscale.com/net/netaddr"
"tailscale.com/types/key"
"tailscale.com/types/logger"
)
@@ -101,7 +101,7 @@ func (cfg *Config) ToUAPI(logf logger.Logf, w io.Writer, prev *Config) error {
return stickyErr
}
-func cidrsEqual(x, y []netaddr.IPPrefix) bool {
+func cidrsEqual(x, y []netip.Prefix) bool {
// TODO: re-implement using netaddr.IPSet.Equal.
if len(x) != len(y) {
return false
@@ -119,7 +119,7 @@ func cidrsEqual(x, y []netaddr.IPPrefix) bool {
}
// Otherwise, see if they're the same, but out of order.
- m := make(map[netaddr.IPPrefix]bool)
+ m := make(map[netip.Prefix]bool)
for _, v := range x {
m[v] = true
}
diff --git a/wgengine/wgengine.go b/wgengine/wgengine.go
index 2923a3cb0..437249b36 100644
--- a/wgengine/wgengine.go
+++ b/wgengine/wgengine.go
@@ -6,11 +6,11 @@
import (
"errors"
+ "net/netip"
"time"
"tailscale.com/ipn/ipnstate"
"tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/key"
"tailscale.com/types/netmap"
@@ -62,7 +62,7 @@ type PeerForIP struct {
// Route is the route that matched the IP provided
// to Engine.PeerForIP.
- Route netaddr.IPPrefix
+ Route netip.Prefix
}
// Engine is the Tailscale WireGuard engine interface.
@@ -80,7 +80,7 @@ type Engine interface {
// PeerForIP returns the node to which the provided IP routes,
// if any. If none is found, (nil, nil) is returned.
- PeerForIP(netaddr.IP) (_ PeerForIP, ok bool)
+ PeerForIP(netip.Addr) (_ PeerForIP, ok bool)
// GetFilter returns the current packet filter, if any.
GetFilter() *filter.Filter
@@ -156,20 +156,20 @@ type Engine interface {
// Ping is a request to start a ping with the peer handling the given IP and
// then call cb with its ping latency & method.
- Ping(ip netaddr.IP, pingType tailcfg.PingType, cb func(*ipnstate.PingResult))
+ Ping(ip netip.Addr, pingType tailcfg.PingType, cb func(*ipnstate.PingResult))
// RegisterIPPortIdentity registers a given node (identified by its
// Tailscale IP) as temporarily having the given IP:port for whois lookups.
// The IP:port is generally a localhost IP and an ephemeral port, used
// while proxying connections to localhost when tailscaled is running
// in netstack mode.
- RegisterIPPortIdentity(netaddr.IPPort, netaddr.IP)
+ RegisterIPPortIdentity(netip.AddrPort, netip.Addr)
// UnregisterIPPortIdentity removes a temporary IP:port registration
// made previously by RegisterIPPortIdentity.
- UnregisterIPPortIdentity(netaddr.IPPort)
+ UnregisterIPPortIdentity(netip.AddrPort)
// WhoIsIPPort looks up an IP:port in the temporary registrations,
// and returns a matching Tailscale IP, if it exists.
- WhoIsIPPort(netaddr.IPPort) (netaddr.IP, bool)
+ WhoIsIPPort(netip.AddrPort) (netip.Addr, bool)
}