mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
all: convert more code to use net/netip directly
perl -i -npe 's,netaddr.IPPrefixFrom,netip.PrefixFrom,' $(git grep -l -F netaddr.) perl -i -npe 's,netaddr.IPPortFrom,netip.AddrPortFrom,' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPPrefix,netip.Prefix,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPPort,netip.AddrPort,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IP\b,netip.Addr,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPv6Raw\b,netip.AddrFrom16,g' $(git grep -l -F netaddr. ) goimports -w . Then delete some stuff from the net/netaddr shim package which is no longer neeed. Updates #5162 Change-Id: Ia7a86893fe21c7e3ee1ec823e8aba288d4566cd8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
6a396731eb
commit
a12aad6b47
@ -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 {
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
})
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 ""
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
|
@ -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+
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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(),
|
||||
},
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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{},
|
||||
},
|
||||
},
|
||||
|
@ -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 {
|
||||
|
@ -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",
|
||||
|
@ -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, "<th>%v</th> ", v)
|
||||
}
|
||||
fmt.Fprint(w, "</tr>\n")
|
||||
i.ForeachInterface(func(iface interfaces.Interface, ipps []netaddr.IPPrefix) {
|
||||
i.ForeachInterface(func(iface interfaces.Interface, ipps []netip.Prefix) {
|
||||
fmt.Fprint(w, "<tr>")
|
||||
for _, v := range []any{iface.Index, iface.Name, iface.MTU, iface.Flags, ipps} {
|
||||
fmt.Fprintf(w, "<td>%v</td> ", 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{}),
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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"),
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
18
ipn/prefs.go
18
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
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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"),
|
||||
},
|
||||
},
|
||||
|
@ -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,
|
||||
|
@ -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{
|
||||
|
@ -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 == "" {
|
||||
|
@ -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"),
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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{}
|
||||
)
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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" {
|
||||
|
@ -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)
|
||||
|
@ -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"),
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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"),
|
||||
},
|
||||
},
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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?
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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":
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"),
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
},
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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),
|
||||
}},
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user