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"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ACLRow defines a rule that grants access by a set of users or groups to a set
|
// 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,
|
// 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.
|
// the call is still successful but Matches will be an empty slice.
|
||||||
// Returns error if the provided ACL is invalid.
|
// 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.
|
// Format return errors to be descriptive.
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptrace"
|
"net/http/httptrace"
|
||||||
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -31,7 +32,6 @@
|
|||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/paths"
|
"tailscale.com/paths"
|
||||||
"tailscale.com/safesocket"
|
"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
|
// Ping sends a ping of the provided type to the provided IP and waits
|
||||||
// for its response.
|
// 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 := url.Values{}
|
||||||
v.Set("ip", ip.String())
|
v.Set("ip", ip.String())
|
||||||
v.Set("type", string(pingtype))
|
v.Set("type", string(pingtype))
|
||||||
|
@ -13,15 +13,14 @@
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Routes contains the lists of subnet routes that are currently advertised by a device,
|
// 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.
|
// as well as the subnets that are enabled to be routed by the device.
|
||||||
type Routes struct {
|
type Routes struct {
|
||||||
AdvertisedRoutes []netaddr.IPPrefix `json:"advertisedRoutes"`
|
AdvertisedRoutes []netip.Prefix `json:"advertisedRoutes"`
|
||||||
EnabledRoutes []netaddr.IPPrefix `json:"enabledRoutes"`
|
EnabledRoutes []netip.Prefix `json:"enabledRoutes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes retrieves the list of subnet routes that have been enabled for a device.
|
// 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 {
|
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.
|
// SetRoutes updates the list of subnets that are enabled for a device.
|
||||||
// Subnets must be parsable by net/netip.ParsePrefix.
|
// Subnets must be parsable by net/netip.ParsePrefix.
|
||||||
// Subnets do not have to be currently advertised by a device, they may be pre-enabled.
|
// 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.
|
// 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() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("tailscale.SetRoutes: %w", err)
|
err = fmt.Errorf("tailscale.SetRoutes: %w", err)
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/persist"
|
"tailscale.com/types/persist"
|
||||||
"tailscale.com/types/preftype"
|
"tailscale.com/types/preftype"
|
||||||
@ -57,7 +56,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
flags []string // argv to be parsed by FlagSet
|
flags []string // argv to be parsed by FlagSet
|
||||||
curPrefs *ipn.Prefs
|
curPrefs *ipn.Prefs
|
||||||
|
|
||||||
curExitNodeIP netaddr.IP
|
curExitNodeIP netip.Addr
|
||||||
curUser string // os.Getenv("USER") on the client side
|
curUser string // os.Getenv("USER") on the client side
|
||||||
goos string // empty means "linux"
|
goos string // empty means "linux"
|
||||||
distro distro.Distro
|
distro distro.Distro
|
||||||
@ -153,7 +152,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.42.0/24"),
|
netip.MustParsePrefix("10.0.42.0/24"),
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
@ -169,7 +168,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.42.0/24"),
|
netip.MustParsePrefix("10.0.42.0/24"),
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
@ -185,7 +184,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.42.0/24"),
|
netip.MustParsePrefix("10.0.42.0/24"),
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
@ -213,7 +212,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
|
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("1.2.0.0/16"),
|
netip.MustParsePrefix("1.2.0.0/16"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -227,7 +226,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
netip.MustParsePrefix("1.2.0.0/16"),
|
netip.MustParsePrefix("1.2.0.0/16"),
|
||||||
@ -262,7 +261,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AdvertiseTags: []string{"tag:foo", "tag:bar"},
|
AdvertiseTags: []string{"tag:foo", "tag:bar"},
|
||||||
Hostname: "myhostname",
|
Hostname: "myhostname",
|
||||||
ForceDaemon: true,
|
ForceDaemon: true,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.0.0/16"),
|
netip.MustParsePrefix("10.0.0.0/16"),
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
@ -287,7 +286,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AdvertiseTags: []string{"tag:foo", "tag:bar"},
|
AdvertiseTags: []string{"tag:foo", "tag:bar"},
|
||||||
Hostname: "myhostname",
|
Hostname: "myhostname",
|
||||||
ForceDaemon: true,
|
ForceDaemon: true,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.0.0/16"),
|
netip.MustParsePrefix("10.0.0.0/16"),
|
||||||
},
|
},
|
||||||
NetfilterMode: preftype.NetfilterNoDivert,
|
NetfilterMode: preftype.NetfilterNoDivert,
|
||||||
@ -345,7 +344,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
netip.MustParsePrefix("1.2.0.0/16"),
|
netip.MustParsePrefix("1.2.0.0/16"),
|
||||||
@ -361,7 +360,7 @@ func TestCheckForAccidentalSettingReverts(t *testing.T) {
|
|||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
NetfilterMode: preftype.NetfilterOn,
|
NetfilterMode: preftype.NetfilterOn,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
netip.MustParsePrefix("1.2.0.0/16"),
|
netip.MustParsePrefix("1.2.0.0/16"),
|
||||||
@ -563,7 +562,7 @@ func TestPrefsFromUpArgs(t *testing.T) {
|
|||||||
WantRunning: true,
|
WantRunning: true,
|
||||||
AllowSingleHosts: true,
|
AllowSingleHosts: true,
|
||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
},
|
},
|
||||||
@ -632,7 +631,7 @@ func TestPrefsFromUpArgs(t *testing.T) {
|
|||||||
exitNodeIP: "100.105.106.107",
|
exitNodeIP: "100.105.106.107",
|
||||||
},
|
},
|
||||||
st: &ipnstate.Status{
|
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?`,
|
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{
|
want: &ipn.Prefs{
|
||||||
WantRunning: true,
|
WantRunning: true,
|
||||||
NoSNAT: true,
|
NoSNAT: true,
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("fd7a:115c:a1e0:b1a::bb:10.0.0.0/112"),
|
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
|
return a == b
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/version"
|
"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
|
// fileTargetErrorDetail returns a non-nil error saying why ip is an
|
||||||
// invalid file sharing target.
|
// invalid file sharing target.
|
||||||
func fileTargetErrorDetail(ctx context.Context, ip netaddr.IP) error {
|
func fileTargetErrorDetail(ctx context.Context, ip netip.Addr) error {
|
||||||
found := false
|
found := false
|
||||||
if st, err := localClient.Status(ctx); err == nil && st.Self != nil {
|
if st, err := localClient.Status(ctx); err == nil && st.Self != nil {
|
||||||
for _, peer := range st.Peer {
|
for _, peer := range st.Peer {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -21,7 +22,6 @@
|
|||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ func ownerLogin(st *ipnstate.Status, ps *ipnstate.PeerStatus) string {
|
|||||||
return u.LoginName
|
return u.LoginName
|
||||||
}
|
}
|
||||||
|
|
||||||
func firstIPString(v []netaddr.IP) string {
|
func firstIPString(v []netip.Addr) string {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
qrcode "github.com/skip2/go-qrcode"
|
qrcode "github.com/skip2/go-qrcode"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/safesocket"
|
"tailscale.com/safesocket"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -204,7 +203,7 @@ func warnf(format string, args ...any) {
|
|||||||
ipv6default = netip.MustParsePrefix("::/0")
|
ipv6default = netip.MustParsePrefix("::/0")
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateViaPrefix(ipp netaddr.IPPrefix) error {
|
func validateViaPrefix(ipp netip.Prefix) error {
|
||||||
if !tsaddr.IsViaPrefix(ipp) {
|
if !tsaddr.IsViaPrefix(ipp) {
|
||||||
return fmt.Errorf("%v is not a 4-in-6 prefix", 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]netaddr.IPPrefix, error) {
|
func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]netip.Prefix, error) {
|
||||||
routeMap := map[netaddr.IPPrefix]bool{}
|
routeMap := map[netip.Prefix]bool{}
|
||||||
if advertiseRoutes != "" {
|
if advertiseRoutes != "" {
|
||||||
var default4, default6 bool
|
var default4, default6 bool
|
||||||
advroutes := strings.Split(advertiseRoutes, ",")
|
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.0.0.0/0")] = true
|
||||||
routeMap[netip.MustParsePrefix("::/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 {
|
for r := range routeMap {
|
||||||
routes = append(routes, r)
|
routes = append(routes, r)
|
||||||
}
|
}
|
||||||
@ -791,7 +790,7 @@ type upCheckEnv struct {
|
|||||||
flagSet *flag.FlagSet
|
flagSet *flag.FlagSet
|
||||||
upArgs upArgsT
|
upArgs upArgsT
|
||||||
backendState string
|
backendState string
|
||||||
curExitNodeIP netaddr.IP
|
curExitNodeIP netip.Addr
|
||||||
distro distro.Distro
|
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)))
|
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
|
var v4, v6 bool
|
||||||
for _, r := range rr {
|
for _, r := range rr {
|
||||||
if r.Bits() == 0 {
|
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
|
// 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
|
// routes. If it has both IPv4 and IPv6 /0 routes, then it returns
|
||||||
// a copy with all /0 routes removed.
|
// a copy with all /0 routes removed.
|
||||||
func withoutExitNodes(rr []netaddr.IPPrefix) []netaddr.IPPrefix {
|
func withoutExitNodes(rr []netip.Prefix) []netip.Prefix {
|
||||||
if !hasExitNodeRoutes(rr) {
|
if !hasExitNodeRoutes(rr) {
|
||||||
return rr
|
return rr
|
||||||
}
|
}
|
||||||
var out []netaddr.IPPrefix
|
var out []netip.Prefix
|
||||||
for _, r := range rr {
|
for _, r := range rr {
|
||||||
if r.Bits() > 0 {
|
if r.Bits() > 0 {
|
||||||
out = append(out, r)
|
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
|
// exitNodeIP returns the exit node IP from p, using st to map
|
||||||
// it from its ID form to an IP address if needed.
|
// 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 {
|
if p == nil {
|
||||||
return
|
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/dnsfallback from tailscale.com/control/controlhttp
|
||||||
tailscale.com/net/flowtrack from tailscale.com/wgengine/filter+
|
tailscale.com/net/flowtrack from tailscale.com/wgengine/filter+
|
||||||
💣 tailscale.com/net/interfaces from tailscale.com/cmd/tailscale/cli+
|
💣 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/netcheck from tailscale.com/cmd/tailscale/cli
|
||||||
tailscale.com/net/neterror from tailscale.com/net/netcheck+
|
tailscale.com/net/neterror from tailscale.com/net/netcheck+
|
||||||
tailscale.com/net/netknob from tailscale.com/net/netns
|
tailscale.com/net/netknob from tailscale.com/net/netns
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/portmapper"
|
"tailscale.com/net/portmapper"
|
||||||
"tailscale.com/net/tshttpproxy"
|
"tailscale.com/net/tshttpproxy"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -267,7 +266,7 @@ func debugPortmap(ctx context.Context) error {
|
|||||||
return err
|
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, "/") {
|
if v := os.Getenv("TS_DEBUG_GW_SELF"); strings.Contains(v, "/") {
|
||||||
i := strings.Index(v, "/")
|
i := strings.Index(v, "/")
|
||||||
gw = netip.MustParseAddr(v[:i])
|
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/dnsfallback from tailscale.com/control/controlclient+
|
||||||
tailscale.com/net/flowtrack from tailscale.com/net/packet+
|
tailscale.com/net/flowtrack from tailscale.com/net/packet+
|
||||||
💣 tailscale.com/net/interfaces from tailscale.com/control/controlclient+
|
💣 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/netcheck from tailscale.com/wgengine/magicsock
|
||||||
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
|
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
|
||||||
tailscale.com/net/netknob from tailscale.com/net/netns+
|
tailscale.com/net/netknob from tailscale.com/net/netns+
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -38,7 +39,6 @@
|
|||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/proxymux"
|
"tailscale.com/net/proxymux"
|
||||||
"tailscale.com/net/socks5"
|
"tailscale.com/net/socks5"
|
||||||
@ -366,11 +366,11 @@ func run() error {
|
|||||||
ns.ProcessSubnets = useNetstack || wrapNetstack
|
ns.ProcessSubnets = useNetstack || wrapNetstack
|
||||||
|
|
||||||
if useNetstack {
|
if useNetstack {
|
||||||
dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
|
dialer.UseNetstackForIP = func(ip netip.Addr) bool {
|
||||||
_, ok := e.PeerForIP(ip)
|
_, ok := e.PeerForIP(ip)
|
||||||
return ok
|
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)
|
return ns.DialContextTCP(ctx, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -37,7 +38,6 @@
|
|||||||
"tailscale.com/ipn/store"
|
"tailscale.com/ipn/store"
|
||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/net/tstun"
|
"tailscale.com/net/tstun"
|
||||||
"tailscale.com/safesocket"
|
"tailscale.com/safesocket"
|
||||||
@ -245,7 +245,7 @@ func beFirewallKillswitch() bool {
|
|||||||
// is passed in via stdin encoded in json.
|
// is passed in via stdin encoded in json.
|
||||||
dcd := json.NewDecoder(os.Stdin)
|
dcd := json.NewDecoder(os.Stdin)
|
||||||
for {
|
for {
|
||||||
var routes []netaddr.IPPrefix
|
var routes []netip.Prefix
|
||||||
if err := dcd.Decode(&routes); err != nil {
|
if err := dcd.Decode(&routes); err != nil {
|
||||||
log.Fatalf("parent process died or requested exit, exiting (%v)", err)
|
log.Fatalf("parent process died or requested exit, exiting (%v)", err)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
"time"
|
"time"
|
||||||
@ -29,7 +30,6 @@
|
|||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
"tailscale.com/ipn/ipnserver"
|
"tailscale.com/ipn/ipnserver"
|
||||||
"tailscale.com/ipn/store/mem"
|
"tailscale.com/ipn/store/mem"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/safesocket"
|
"tailscale.com/safesocket"
|
||||||
@ -78,10 +78,10 @@ func newIPN(jsConfig js.Value) map[string]any {
|
|||||||
if err := ns.Start(); err != nil {
|
if err := ns.Start(); err != nil {
|
||||||
log.Fatalf("failed to start netstack: %v", err)
|
log.Fatalf("failed to start netstack: %v", err)
|
||||||
}
|
}
|
||||||
dialer.UseNetstackForIP = func(ip netaddr.IP) bool {
|
dialer.UseNetstackForIP = func(ip netip.Addr) bool {
|
||||||
return true
|
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)
|
return ns.DialContextTCP(ctx, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
|
|||||||
Self: jsNetMapSelfNode{
|
Self: jsNetMapSelfNode{
|
||||||
jsNetMapNode: jsNetMapNode{
|
jsNetMapNode: jsNetMapNode{
|
||||||
Name: nm.Name,
|
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(),
|
NodeKey: nm.NodeKey.String(),
|
||||||
MachineKey: nm.MachineKey.String(),
|
MachineKey: nm.MachineKey.String(),
|
||||||
},
|
},
|
||||||
@ -185,7 +185,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
|
|||||||
return jsNetMapPeerNode{
|
return jsNetMapPeerNode{
|
||||||
jsNetMapNode: jsNetMapNode{
|
jsNetMapNode: jsNetMapNode{
|
||||||
Name: p.Name,
|
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(),
|
MachineKey: p.Machine.String(),
|
||||||
NodeKey: p.Key.String(),
|
NodeKey: p.Key.String(),
|
||||||
},
|
},
|
||||||
|
@ -7,15 +7,14 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run tailscale.com/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices
|
//go:generate go run tailscale.com/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices
|
||||||
|
|
||||||
type StructWithoutPtrs struct {
|
type StructWithoutPtrs struct {
|
||||||
Int int
|
Int int
|
||||||
Pfx netaddr.IPPrefix
|
Pfx netip.Prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
type Map struct {
|
type Map struct {
|
||||||
@ -54,6 +53,6 @@ type StructWithSlices struct {
|
|||||||
Ints []*int
|
Ints []*int
|
||||||
|
|
||||||
Slice []string
|
Slice []string
|
||||||
Prefixes []netaddr.IPPrefix
|
Prefixes []netip.Prefix
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, thi
|
|||||||
case "byte":
|
case "byte":
|
||||||
it.Import("go4.org/mem")
|
it.Import("go4.org/mem")
|
||||||
writeTemplate("byteSliceField")
|
writeTemplate("byteSliceField")
|
||||||
case "inet.af/netaddr.IPPrefix", "net/netip.Prefix":
|
case "inet.af/netip.Prefix", "net/netip.Prefix":
|
||||||
it.Import("tailscale.com/types/views")
|
it.Import("tailscale.com/types/views")
|
||||||
writeTemplate("ipPrefixSliceField")
|
writeTemplate("ipPrefixSliceField")
|
||||||
default:
|
default:
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -36,7 +37,6 @@
|
|||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/dnsfallback"
|
"tailscale.com/net/dnsfallback"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/net/tlsdial"
|
"tailscale.com/net/tlsdial"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -129,7 +129,7 @@ type Options struct {
|
|||||||
// Pinger is the LocalBackend.Ping method.
|
// Pinger is the LocalBackend.Ping method.
|
||||||
type Pinger interface {
|
type Pinger interface {
|
||||||
// Ping is a request to do a ping with the peer handling the given IP.
|
// 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 {
|
type Decompressor interface {
|
||||||
@ -1167,8 +1167,8 @@ func TrimWGConfig() opt.Bool {
|
|||||||
// It should not return false positives.
|
// It should not return false positives.
|
||||||
//
|
//
|
||||||
// TODO(bradfitz): Change controlclient.Options.SkipIPForwardingCheck into a
|
// TODO(bradfitz): Change controlclient.Options.SkipIPForwardingCheck into a
|
||||||
// func([]netaddr.IPPrefix) error signature instead.
|
// func([]netip.Prefix) error signature instead.
|
||||||
func ipForwardingBroken(routes []netaddr.IPPrefix, state *interfaces.State) bool {
|
func ipForwardingBroken(routes []netip.Prefix, state *interfaces.State) bool {
|
||||||
warn, err := netutil.CheckIPForwarding(routes, state)
|
warn, err := netutil.CheckIPForwarding(routes, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Oh well, we tried. This is just for debugging.
|
// Oh well, we tried. This is just for debugging.
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
@ -86,7 +86,7 @@ func TestNewDirect(t *testing.T) {
|
|||||||
func fakeEndpoints(ports ...uint16) (ret []tailcfg.Endpoint) {
|
func fakeEndpoints(ports ...uint16) (ret []tailcfg.Endpoint) {
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
ret = append(ret, tailcfg.Endpoint{
|
ret = append(ret, tailcfg.Endpoint{
|
||||||
Addr: netaddr.IPPortFrom(netaddr.IP{}, port),
|
Addr: netip.AddrPortFrom(netip.Addr{}, port),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net/netip"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -303,7 +303,7 @@ func cloneNodes(v1 []*tailcfg.Node) []*tailcfg.Node {
|
|||||||
|
|
||||||
var debugSelfIPv6Only = envknob.Bool("TS_DEBUG_SELF_V6_ONLY")
|
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 {
|
switch {
|
||||||
default:
|
default:
|
||||||
return in
|
return in
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"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
|
// If the client is broken in some previously detectable way, it
|
||||||
// returns an error.
|
// returns an error.
|
||||||
func (c *Client) LocalAddr() (netaddr.IPPort, error) {
|
func (c *Client) LocalAddr() (netip.AddrPort, error) {
|
||||||
readErr, _ := c.readErr.Load().(error)
|
readErr, _ := c.readErr.Load().(error)
|
||||||
if readErr != nil {
|
if readErr != nil {
|
||||||
return netaddr.IPPort{}, readErr
|
return netip.AddrPort{}, readErr
|
||||||
}
|
}
|
||||||
if c.nc == nil {
|
if c.nc == nil {
|
||||||
return netaddr.IPPort{}, errors.New("nil conn")
|
return netip.AddrPort{}, errors.New("nil conn")
|
||||||
}
|
}
|
||||||
a := c.nc.LocalAddr()
|
a := c.nc.LocalAddr()
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return netaddr.IPPort{}, errors.New("nil addr")
|
return netip.AddrPort{}, errors.New("nil addr")
|
||||||
}
|
}
|
||||||
return netip.ParseAddrPort(a.String())
|
return netip.ParseAddrPort(a.String())
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
"tailscale.com/disco"
|
"tailscale.com/disco"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/metrics"
|
"tailscale.com/metrics"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/syncs"
|
"tailscale.com/syncs"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -163,8 +162,8 @@ type Server struct {
|
|||||||
// src.
|
// src.
|
||||||
sentTo map[key.NodePublic]map[key.NodePublic]int64 // src => dst => dst's latest sclient.connNum
|
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
|
// maps from netip.AddrPort to a client's public key
|
||||||
keyOfAddr map[netaddr.IPPort]key.NodePublic
|
keyOfAddr map[netip.AddrPort]key.NodePublic
|
||||||
}
|
}
|
||||||
|
|
||||||
// clientSet represents 1 or more *sclients.
|
// clientSet represents 1 or more *sclients.
|
||||||
@ -315,7 +314,7 @@ func NewServer(privateKey key.NodePrivate, logf logger.Logf) *Server {
|
|||||||
watchers: map[*sclient]bool{},
|
watchers: map[*sclient]bool{},
|
||||||
sentTo: map[key.NodePublic]map[key.NodePublic]int64{},
|
sentTo: map[key.NodePublic]map[key.NodePublic]int64{},
|
||||||
avgQueueDuration: new(uint64),
|
avgQueueDuration: new(uint64),
|
||||||
keyOfAddr: map[netaddr.IPPort]key.NodePublic{},
|
keyOfAddr: map[netip.AddrPort]key.NodePublic{},
|
||||||
}
|
}
|
||||||
s.initMetacert()
|
s.initMetacert()
|
||||||
s.packetsRecvDisco = s.packetsRecvByKind.Get("disco")
|
s.packetsRecvDisco = s.packetsRecvByKind.Get("disco")
|
||||||
@ -1247,7 +1246,7 @@ type sclient struct {
|
|||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
done <-chan struct{} // closed when connection closes
|
done <-chan struct{} // closed when connection closes
|
||||||
remoteAddr string // usually ip:port from net.Conn.RemoteAddr().String()
|
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
|
sendQueue chan pkt // packets queued to this client; never closed
|
||||||
discoSendQueue chan pkt // important 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
|
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.
|
// parseSSOutput parses the output from the specific call to ss in ServeDebugTraffic.
|
||||||
// Separated out for ease of testing.
|
// Separated out for ease of testing.
|
||||||
func parseSSOutput(raw string) map[netaddr.IPPort]BytesSentRecv {
|
func parseSSOutput(raw string) map[netip.AddrPort]BytesSentRecv {
|
||||||
newState := map[netaddr.IPPort]BytesSentRecv{}
|
newState := map[netip.AddrPort]BytesSentRecv{}
|
||||||
// parse every 2 lines and get src and dst ips, and kv pairs
|
// parse every 2 lines and get src and dst ips, and kv pairs
|
||||||
lines := strings.Split(raw, "\n")
|
lines := strings.Split(raw, "\n")
|
||||||
for i := 0; i < len(lines); i += 2 {
|
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) {
|
func (s *Server) ServeDebugTraffic(w http.ResponseWriter, r *http.Request) {
|
||||||
prevState := map[netaddr.IPPort]BytesSentRecv{}
|
prevState := map[netip.AddrPort]BytesSentRecv{}
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
for r.Context().Err() == nil {
|
for r.Context().Err() == nil {
|
||||||
output, err := exec.Command("ss", "-i", "-H", "-t").Output()
|
output, err := exec.Command("ss", "-i", "-H", "-t").Output()
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
"tailscale.com/derp"
|
"tailscale.com/derp"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/tlsdial"
|
"tailscale.com/net/tlsdial"
|
||||||
"tailscale.com/net/tshttpproxy"
|
"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
|
// address (given in s) is valid. An empty value means to dial, but to
|
||||||
// use DNS. The predicate function reports whether the non-empty
|
// use DNS. The predicate function reports whether the non-empty
|
||||||
// string s contained a valid IP address of the right family.
|
// 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 == "" {
|
if s == "" {
|
||||||
return true
|
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")
|
startDial(n.IPv4, "tcp4")
|
||||||
}
|
}
|
||||||
if shouldDialProto(n.IPv6, netaddr.IP.Is6) {
|
if shouldDialProto(n.IPv6, netip.Addr.Is6) {
|
||||||
startDial(n.IPv6, "tcp6")
|
startDial(n.IPv6, "tcp6")
|
||||||
}
|
}
|
||||||
if nwait == 0 {
|
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
|
// LocalAddr reports c's local TCP address, without any implicit
|
||||||
// connect or reconnect.
|
// connect or reconnect.
|
||||||
func (c *Client) LocalAddr() (netaddr.IPPort, error) {
|
func (c *Client) LocalAddr() (netip.AddrPort, error) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
closed, client := c.closed, c.client
|
closed, client := c.closed, c.client
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
if closed {
|
if closed {
|
||||||
return netaddr.IPPort{}, ErrClientClosed
|
return netip.AddrPort{}, ErrClientClosed
|
||||||
}
|
}
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return netaddr.IPPort{}, errors.New("client not connected")
|
return netip.AddrPort{}, errors.New("client not connected")
|
||||||
}
|
}
|
||||||
return client.LocalAddr()
|
return client.LocalAddr()
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"tailscale.com/net/netaddr"
|
"tailscale.com/net/netaddr"
|
||||||
@ -172,7 +173,7 @@ type CallMeMaybe struct {
|
|||||||
// in this field, but might not yet be in control's endpoints.
|
// in this field, but might not yet be in control's endpoints.
|
||||||
// (And in the future, control will stop distributing endpoints
|
// (And in the future, control will stop distributing endpoints
|
||||||
// when clients are suitably new.)
|
// when clients are suitably new.)
|
||||||
MyNumber []netaddr.IPPort
|
MyNumber []netip.AddrPort
|
||||||
}
|
}
|
||||||
|
|
||||||
const epLength = 16 + 2 // 16 byte IP address + 2 byte port
|
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 {
|
if len(p)%epLength != 0 || ver != 0 || len(p) == 0 {
|
||||||
return m, nil
|
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 {
|
for len(p) > 0 {
|
||||||
var a [16]byte
|
var a [16]byte
|
||||||
copy(a[:], p)
|
copy(a[:], p)
|
||||||
m.MyNumber = append(m.MyNumber, netaddr.IPPortFrom(
|
m.MyNumber = append(m.MyNumber, netip.AddrPortFrom(
|
||||||
netaddr.IPFrom16(a),
|
netaddr.IPFrom16(a),
|
||||||
binary.BigEndian.Uint16(p[16:18])))
|
binary.BigEndian.Uint16(p[16:18])))
|
||||||
p = p[epLength:]
|
p = p[epLength:]
|
||||||
@ -211,7 +212,7 @@ func parseCallMeMaybe(ver uint8, p []byte) (m *CallMeMaybe, err error) {
|
|||||||
// STUN response.
|
// STUN response.
|
||||||
type Pong struct {
|
type Pong struct {
|
||||||
TxID [12]byte
|
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
|
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]))
|
srcIP, _ := netaddr.FromStdIP(net.IP(p[:16]))
|
||||||
p = p[16:]
|
p = p[16:]
|
||||||
port := binary.BigEndian.Uint16(p)
|
port := binary.BigEndian.Uint16(p)
|
||||||
m.Src = netaddr.IPPortFrom(srcIP, port)
|
m.Src = netip.AddrPortFrom(srcIP, port)
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ func TestMarshalAndParse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "call_me_maybe_endpoints",
|
name: "call_me_maybe_endpoints",
|
||||||
m: &CallMeMaybe{
|
m: &CallMeMaybe{
|
||||||
MyNumber: []netaddr.IPPort{
|
MyNumber: []netip.AddrPort{
|
||||||
netip.MustParseAddrPort("1.2.3.4:567"),
|
netip.MustParseAddrPort("1.2.3.4:567"),
|
||||||
netip.MustParseAddrPort("[2001::3456]:789"),
|
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)
|
ipp, err := netip.ParseAddrPort(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
package ipn
|
package ipn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
@ -126,7 +126,7 @@ func (h *Handle) EngineStatus() EngineStatus {
|
|||||||
return h.engineStatusCache
|
return h.engineStatusCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) LocalAddrs() []netaddr.IPPrefix {
|
func (h *Handle) LocalAddrs() []netip.Prefix {
|
||||||
h.mu.Lock()
|
h.mu.Lock()
|
||||||
defer h.mu.Unlock()
|
defer h.mu.Unlock()
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ func (h *Handle) LocalAddrs() []netaddr.IPPrefix {
|
|||||||
if nm != nil {
|
if nm != nil {
|
||||||
return nm.Addresses
|
return nm.Addresses
|
||||||
}
|
}
|
||||||
return []netaddr.IPPrefix{}
|
return []netip.Prefix{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) NetMap() *netmap.NetworkMap {
|
func (h *Handle) NetMap() *netmap.NetworkMap {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
@ -21,7 +20,7 @@
|
|||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ipps(ippStrs ...string) (ipps []netaddr.IPPrefix) {
|
func ipps(ippStrs ...string) (ipps []netip.Prefix) {
|
||||||
for _, s := range ippStrs {
|
for _, s := range ippStrs {
|
||||||
if ip, err := netip.ParseAddr(s); err == nil {
|
if ip, err := netip.ParseAddr(s); err == nil {
|
||||||
ipps = append(ipps, netip.PrefixFrom(ip, ip.BitLen()))
|
ipps = append(ipps, netip.PrefixFrom(ip, ip.BitLen()))
|
||||||
@ -32,7 +31,7 @@ func ipps(ippStrs ...string) (ipps []netaddr.IPPrefix) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ips(ss ...string) (ips []netaddr.IP) {
|
func ips(ss ...string) (ips []netip.Addr) {
|
||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
ips = append(ips, netip.MustParseAddr(s))
|
ips = append(ips, netip.MustParseAddr(s))
|
||||||
}
|
}
|
||||||
@ -55,7 +54,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
prefs: &ipn.Prefs{},
|
prefs: &ipn.Prefs{},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
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{},
|
prefs: &ipn.Prefs{},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
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"),
|
"b.net.": ips("100.102.0.1", "100.102.0.2"),
|
||||||
"myname.net.": ips("100.101.101.101"),
|
"myname.net.": ips("100.101.101.101"),
|
||||||
"peera.net.": ips("100.102.0.1", "100.102.0.2"),
|
"peera.net.": ips("100.102.0.1", "100.102.0.2"),
|
||||||
@ -116,7 +115,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
OnlyIPv6: true,
|
OnlyIPv6: true,
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{
|
Hosts: map[dnsname.FQDN][]netip.Addr{
|
||||||
"b.net.": ips("fe75::2"),
|
"b.net.": ips("fe75::2"),
|
||||||
"myname.net.": ips("fe75::1"),
|
"myname.net.": ips("fe75::1"),
|
||||||
"peera.net.": ips("fe75::1001"),
|
"peera.net.": ips("fe75::1001"),
|
||||||
@ -140,7 +139,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
prefs: &ipn.Prefs{},
|
prefs: &ipn.Prefs{},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
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"),
|
"myname.net.": ips("100.101.101.101"),
|
||||||
"foo.com.": ips("1.2.3.4"),
|
"foo.com.": ips("1.2.3.4"),
|
||||||
"bar.com.": ips("1::6"),
|
"bar.com.": ips("1::6"),
|
||||||
@ -160,7 +159,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
},
|
},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{},
|
Hosts: map[dnsname.FQDN][]netip.Addr{},
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
|
Routes: map[dnsname.FQDN][]*dnstype.Resolver{
|
||||||
"0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.": nil,
|
"0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.": nil,
|
||||||
"100.100.in-addr.arpa.": nil,
|
"100.100.in-addr.arpa.": nil,
|
||||||
@ -260,7 +259,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
},
|
},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{},
|
Hosts: map[dnsname.FQDN][]netip.Addr{},
|
||||||
DefaultResolvers: []*dnstype.Resolver{
|
DefaultResolvers: []*dnstype.Resolver{
|
||||||
{Addr: "8.8.8.8"},
|
{Addr: "8.8.8.8"},
|
||||||
},
|
},
|
||||||
@ -283,7 +282,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
ExitNodeID: "some-id",
|
ExitNodeID: "some-id",
|
||||||
},
|
},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{},
|
Hosts: map[dnsname.FQDN][]netip.Addr{},
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
||||||
DefaultResolvers: []*dnstype.Resolver{
|
DefaultResolvers: []*dnstype.Resolver{
|
||||||
{Addr: "8.8.4.4"},
|
{Addr: "8.8.4.4"},
|
||||||
@ -303,7 +302,7 @@ func TestDNSConfigForNetmap(t *testing.T) {
|
|||||||
CorpDNS: true,
|
CorpDNS: true,
|
||||||
},
|
},
|
||||||
want: &dns.Config{
|
want: &dns.Config{
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{},
|
Hosts: map[dnsname.FQDN][]netip.Addr{},
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
"tailscale.com/ipn/policy"
|
"tailscale.com/ipn/policy"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -130,7 +129,7 @@ type LocalBackend struct {
|
|||||||
shutdownCalled bool // if Shutdown has been called
|
shutdownCalled bool // if Shutdown has been called
|
||||||
|
|
||||||
filterAtomic atomic.Value // of *filter.Filter
|
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.
|
// The mutex protects the following elements.
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@ -152,7 +151,7 @@ type LocalBackend struct {
|
|||||||
hostinfo *tailcfg.Hostinfo
|
hostinfo *tailcfg.Hostinfo
|
||||||
// netMap is not mutated in-place once set.
|
// netMap is not mutated in-place once set.
|
||||||
netMap *netmap.NetworkMap
|
netMap *netmap.NetworkMap
|
||||||
nodeByAddr map[netaddr.IP]*tailcfg.Node
|
nodeByAddr map[netip.Addr]*tailcfg.Node
|
||||||
activeLogin string // last logged LoginName from netMap
|
activeLogin string // last logged LoginName from netMap
|
||||||
engineStatus ipn.EngineStatus
|
engineStatus ipn.EngineStatus
|
||||||
endpoints []tailcfg.Endpoint
|
endpoints []tailcfg.Endpoint
|
||||||
@ -498,13 +497,13 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
|
|||||||
if p.LastSeen != nil {
|
if p.LastSeen != nil {
|
||||||
lastSeen = *p.LastSeen
|
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 {
|
for _, addr := range p.Addresses {
|
||||||
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
|
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
|
||||||
tailscaleIPs = append(tailscaleIPs, 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
|
return r.Bits() == 0
|
||||||
})
|
})
|
||||||
var tags *views.Slice[string]
|
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.
|
// 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 the IP address is a Tailscale IP, the provided port may be 0.
|
||||||
// If ok == true, n and u are valid.
|
// 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()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
n, ok = b.nodeByAddr[ipp.Addr()]
|
n, ok = b.nodeByAddr[ipp.Addr()]
|
||||||
if !ok {
|
if !ok {
|
||||||
var ip netaddr.IP
|
var ip netip.Addr
|
||||||
if ipp.Port() != 0 {
|
if ipp.Port() != 0 {
|
||||||
ip, ok = b.e.WhoIsIPPort(ipp)
|
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
|
// PeerCaps returns the capabilities that remote src IP has to
|
||||||
// ths current node.
|
// ths current node.
|
||||||
func (b *LocalBackend) PeerCaps(src netaddr.IP) []string {
|
func (b *LocalBackend) PeerCaps(src netip.Addr) []string {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
if b.netMap == nil {
|
if b.netMap == nil {
|
||||||
@ -770,7 +769,7 @@ func (b *LocalBackend) findExitNodeIDLocked(nm *netmap.NetworkMap) (prefsChanged
|
|||||||
// Found the node being referenced, upgrade prefs to
|
// Found the node being referenced, upgrade prefs to
|
||||||
// reference it directly for next time.
|
// reference it directly for next time.
|
||||||
b.prefs.ExitNodeID = peer.StableID
|
b.prefs.ExitNodeID = peer.StableID
|
||||||
b.prefs.ExitNodeIP = netaddr.IP{}
|
b.prefs.ExitNodeIP = netip.Addr{}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1123,7 +1122,7 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs *ipn.
|
|||||||
// quite hard to debug, so save yourself the trouble.
|
// quite hard to debug, so save yourself the trouble.
|
||||||
var (
|
var (
|
||||||
haveNetmap = netMap != nil
|
haveNetmap = netMap != nil
|
||||||
addrs []netaddr.IPPrefix
|
addrs []netip.Prefix
|
||||||
packetFilter []filter.Match
|
packetFilter []filter.Match
|
||||||
localNetsB netipx.IPSetBuilder
|
localNetsB netipx.IPSetBuilder
|
||||||
logNetsB netipx.IPSetBuilder
|
logNetsB netipx.IPSetBuilder
|
||||||
@ -1206,7 +1205,7 @@ func (b *LocalBackend) setFilter(f *filter.Filter) {
|
|||||||
b.e.SetFilter(f)
|
b.e.SetFilter(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeFromDefaultRoute = []netaddr.IPPrefix{
|
var removeFromDefaultRoute = []netip.Prefix{
|
||||||
// RFC1918 LAN ranges
|
// RFC1918 LAN ranges
|
||||||
netip.MustParsePrefix("192.168.0.0/16"),
|
netip.MustParsePrefix("192.168.0.0/16"),
|
||||||
netip.MustParsePrefix("172.16.0.0/12"),
|
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
|
// 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.
|
// 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()
|
il, err := interfaces.GetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -1240,11 +1239,11 @@ func internalAndExternalInterfaces() (internal, external []netaddr.IPPrefix, err
|
|||||||
return internalAndExternalInterfacesFrom(il, runtime.GOOS)
|
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
|
// We use an IPSetBuilder here to canonicalize the prefixes
|
||||||
// and to remove any duplicate entries.
|
// and to remove any duplicate entries.
|
||||||
var internalBuilder, externalBuilder netipx.IPSetBuilder
|
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()) {
|
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1286,9 +1285,9 @@ func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (interna
|
|||||||
return iSet.Prefixes(), eSet.Prefixes(), nil
|
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
|
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()) {
|
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1308,7 +1307,7 @@ func interfaceRoutes() (ips *netipx.IPSet, hostIPs []netaddr.IP, err error) {
|
|||||||
// shrinkDefaultRoute returns an IPSet representing the IPs in route,
|
// shrinkDefaultRoute returns an IPSet representing the IPs in route,
|
||||||
// minus those in removeFromDefaultRoute and localInterfaceRoutes,
|
// minus those in removeFromDefaultRoute and localInterfaceRoutes,
|
||||||
// plus the IPs in hostIPs.
|
// 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
|
var b netipx.IPSetBuilder
|
||||||
// Add the default route.
|
// Add the default route.
|
||||||
b.AddPrefix(route)
|
b.AddPrefix(route)
|
||||||
@ -1335,7 +1334,7 @@ func shrinkDefaultRoute(route netaddr.IPPrefix, localInterfaceRoutes *netipx.IPS
|
|||||||
|
|
||||||
// dnsCIDRsEqual determines whether two CIDR lists are equal
|
// dnsCIDRsEqual determines whether two CIDR lists are equal
|
||||||
// for DNS map construction purposes (that is, only the first entry counts).
|
// 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) {
|
if len(newAddr) != len(oldAddr) {
|
||||||
return false
|
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 {
|
if pingType == tailcfg.PingPeerAPI {
|
||||||
t0 := time.Now()
|
t0 := time.Now()
|
||||||
node, base, err := b.pingPeerAPI(ctx, ip)
|
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)
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
nm := b.NetMap()
|
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
|
// GetPeerAPIPort returns the port number for the peerapi server
|
||||||
// running on the provided IP.
|
// 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()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
for _, pln := range b.peerAPIListeners {
|
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).
|
// or IPv6 IP and the peerapi port for that address).
|
||||||
//
|
//
|
||||||
// The connection will be closed by ServePeerAPIConnection.
|
// 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()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
for _, pln := range b.peerAPIListeners {
|
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 {
|
func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Logf, versionOS string) *dns.Config {
|
||||||
dcfg := &dns.Config{
|
dcfg := &dns.Config{
|
||||||
Routes: map[dnsname.FQDN][]*dnstype.Resolver{},
|
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.
|
// 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
|
// isn't configured to make MagicDNS resolution truly
|
||||||
// magic. Details in
|
// magic. Details in
|
||||||
// https://github.com/tailscale/tailscale/issues/1886.
|
// 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 == "" {
|
if len(addrs) == 0 || name == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2311,7 +2310,7 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Log
|
|||||||
return // TODO: propagate error?
|
return // TODO: propagate error?
|
||||||
}
|
}
|
||||||
have4 := tsaddr.PrefixesContainsFunc(addrs, tsaddr.PrefixIs4)
|
have4 := tsaddr.PrefixesContainsFunc(addrs, tsaddr.PrefixIs4)
|
||||||
var ips []netaddr.IP
|
var ips []netip.Addr
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if selfV6Only {
|
if selfV6Only {
|
||||||
if addr.Addr().Is6() {
|
if addr.Addr().Is6() {
|
||||||
@ -2629,11 +2628,11 @@ func magicDNSRootDomains(nm *netmap.NetworkMap) []dnsname.FQDN {
|
|||||||
// peerRoutes returns the routerConfig.Routes to access peers.
|
// peerRoutes returns the routerConfig.Routes to access peers.
|
||||||
// If there are over cgnatThreshold CGNAT routes, one big CGNAT route
|
// If there are over cgnatThreshold CGNAT routes, one big CGNAT route
|
||||||
// is used instead.
|
// 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()
|
tsULA := tsaddr.TailscaleULARange()
|
||||||
cgNAT := tsaddr.CGNATRange()
|
cgNAT := tsaddr.CGNATRange()
|
||||||
var didULA bool
|
var didULA bool
|
||||||
var cgNATIPs []netaddr.IPPrefix
|
var cgNATIPs []netip.Prefix
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
for _, aip := range peer.AllowedIPs {
|
for _, aip := range peer.AllowedIPs {
|
||||||
aip = unmapIPPrefix(aip)
|
aip = unmapIPPrefix(aip)
|
||||||
@ -2665,7 +2664,7 @@ func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netaddr.IPPref
|
|||||||
return routes
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
func ipPrefixLess(ri, rj netaddr.IPPrefix) bool {
|
func ipPrefixLess(ri, rj netip.Prefix) bool {
|
||||||
if ri.Addr() == rj.Addr() {
|
if ri.Addr() == rj.Addr() {
|
||||||
return ri.Bits() < rj.Bits()
|
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) {
|
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
|
return rs
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmapIPPrefix(ipp netaddr.IPPrefix) netaddr.IPPrefix {
|
func unmapIPPrefix(ipp netip.Prefix) netip.Prefix {
|
||||||
return netip.PrefixFrom(ipp.Addr().Unmap(), ipp.Bits())
|
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 _, ipps := range ippsList {
|
||||||
for _, ipp := range ipps {
|
for _, ipp := range ipps {
|
||||||
ret = append(ret, unmapIPPrefix(ipp))
|
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
|
// 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
|
// Tailscale ULA's v6 "via" range embedding an IPv4 address to be forwarded to
|
||||||
// by Tailscale.
|
// by Tailscale.
|
||||||
func (b *LocalBackend) ShouldHandleViaIP(ip netaddr.IP) bool {
|
func (b *LocalBackend) ShouldHandleViaIP(ip netip.Addr) bool {
|
||||||
if f, ok := b.containsViaIPFuncAtomic.Load().(func(netaddr.IP) bool); ok {
|
if f, ok := b.containsViaIPFuncAtomic.Load().(func(netip.Addr) bool); ok {
|
||||||
return f(ip)
|
return f(ip)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -3107,7 +3106,7 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
|
|||||||
|
|
||||||
// Update the nodeByAddr index.
|
// Update the nodeByAddr index.
|
||||||
if b.nodeByAddr == nil {
|
if b.nodeByAddr == nil {
|
||||||
b.nodeByAddr = map[netaddr.IP]*tailcfg.Node{}
|
b.nodeByAddr = map[netip.Addr]*tailcfg.Node{}
|
||||||
}
|
}
|
||||||
// First pass, mark everything unwanted.
|
// First pass, mark everything unwanted.
|
||||||
for k := range b.nodeByAddr {
|
for k := range b.nodeByAddr {
|
||||||
@ -3313,12 +3312,12 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
|
|||||||
p6 = s.Port
|
p6 = s.Port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var ipp netaddr.IPPort
|
var ipp netip.AddrPort
|
||||||
switch {
|
switch {
|
||||||
case have4 && p4 != 0:
|
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:
|
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() {
|
if !ipp.Addr().IsValid() {
|
||||||
return ""
|
return ""
|
||||||
@ -3326,13 +3325,13 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
|
|||||||
return fmt.Sprintf("http://%v", ipp)
|
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 {
|
for _, a := range n.Addresses {
|
||||||
if a.IsSingleIP() && pred(a.Addr()) {
|
if a.IsSingleIP() && pred(a.Addr()) {
|
||||||
return a.Addr()
|
return a.Addr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return netaddr.IP{}
|
return netip.Addr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LocalBackend) CheckIPForwarding() error {
|
func (b *LocalBackend) CheckIPForwarding() error {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/store/mem"
|
"tailscale.com/ipn/store/mem"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -31,13 +30,13 @@ func TestNetworkMapCompare(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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")
|
prefix2, err := netip.ParsePrefix("10.0.0.0/8")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
node2 := &tailcfg.Node{Addresses: []netaddr.IPPrefix{prefix2}}
|
node2 := &tailcfg.Node{Addresses: []netip.Prefix{prefix2}}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
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 {
|
for _, pfx := range removeFromDefaultRoute {
|
||||||
if pfx.Contains(ip) {
|
if pfx.Contains(ip) {
|
||||||
return true
|
return true
|
||||||
@ -147,7 +146,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
|
|||||||
route string
|
route string
|
||||||
in []string
|
in []string
|
||||||
out []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",
|
route: "0.0.0.0/0",
|
||||||
@ -167,7 +166,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
|
|||||||
"fe80::",
|
"fe80::",
|
||||||
"2601::1",
|
"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",
|
route: "::/0",
|
||||||
@ -177,7 +176,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
|
|||||||
"ff00::1",
|
"ff00::1",
|
||||||
tsaddr.TailscaleULARange().Addr().String(),
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
hostIPs := []netaddr.IP{
|
hostIPs := []netip.Addr{
|
||||||
netip.MustParseAddr("127.0.0.1"),
|
netip.MustParseAddr("127.0.0.1"),
|
||||||
netip.MustParseAddr("192.168.9.39"),
|
netip.MustParseAddr("192.168.9.39"),
|
||||||
netip.MustParseAddr("fe80::1"),
|
netip.MustParseAddr("fe80::1"),
|
||||||
netip.MustParseAddr("fe80::437d:feff:feca:49a7"),
|
netip.MustParseAddr("fe80::437d:feff:feca:49a7"),
|
||||||
}
|
}
|
||||||
localAddresses := []netaddr.IP{
|
localAddresses := []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.9.39"),
|
netip.MustParseAddr("192.168.9.39"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,18 +232,18 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
peers []wgcfg.Peer
|
peers []wgcfg.Peer
|
||||||
want []netaddr.IPPrefix
|
want []netip.Prefix
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "small_v4",
|
name: "small_v4",
|
||||||
peers: []wgcfg.Peer{
|
peers: []wgcfg.Peer{
|
||||||
{
|
{
|
||||||
AllowedIPs: []netaddr.IPPrefix{
|
AllowedIPs: []netip.Prefix{
|
||||||
pp("100.101.102.103/32"),
|
pp("100.101.102.103/32"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: []netaddr.IPPrefix{
|
want: []netip.Prefix{
|
||||||
pp("100.101.102.103/32"),
|
pp("100.101.102.103/32"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -252,14 +251,14 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
name: "big_v4",
|
name: "big_v4",
|
||||||
peers: []wgcfg.Peer{
|
peers: []wgcfg.Peer{
|
||||||
{
|
{
|
||||||
AllowedIPs: []netaddr.IPPrefix{
|
AllowedIPs: []netip.Prefix{
|
||||||
pp("100.101.102.103/32"),
|
pp("100.101.102.103/32"),
|
||||||
pp("100.101.102.104/32"),
|
pp("100.101.102.104/32"),
|
||||||
pp("100.101.102.105/32"),
|
pp("100.101.102.105/32"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: []netaddr.IPPrefix{
|
want: []netip.Prefix{
|
||||||
pp("100.64.0.0/10"),
|
pp("100.64.0.0/10"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -267,12 +266,12 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
name: "has_1_v6",
|
name: "has_1_v6",
|
||||||
peers: []wgcfg.Peer{
|
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:b240/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: []netaddr.IPPrefix{
|
want: []netip.Prefix{
|
||||||
pp("fd7a:115c:a1e0::/48"),
|
pp("fd7a:115c:a1e0::/48"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -280,13 +279,13 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
name: "has_2_v6",
|
name: "has_2_v6",
|
||||||
peers: []wgcfg.Peer{
|
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:b240/128"),
|
||||||
pp("fd7a:115c:a1e0:ab12:4843:cd96:6258:b241/128"),
|
pp("fd7a:115c:a1e0:ab12:4843:cd96:6258:b241/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: []netaddr.IPPrefix{
|
want: []netip.Prefix{
|
||||||
pp("fd7a:115c:a1e0::/48"),
|
pp("fd7a:115c:a1e0::/48"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -294,7 +293,7 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
name: "big_v4_big_v6",
|
name: "big_v4_big_v6",
|
||||||
peers: []wgcfg.Peer{
|
peers: []wgcfg.Peer{
|
||||||
{
|
{
|
||||||
AllowedIPs: []netaddr.IPPrefix{
|
AllowedIPs: []netip.Prefix{
|
||||||
pp("100.101.102.103/32"),
|
pp("100.101.102.103/32"),
|
||||||
pp("100.101.102.104/32"),
|
pp("100.101.102.104/32"),
|
||||||
pp("100.101.102.105/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("100.64.0.0/10"),
|
||||||
pp("fd7a:115c:a1e0::/48"),
|
pp("fd7a:115c:a1e0::/48"),
|
||||||
},
|
},
|
||||||
@ -312,19 +311,19 @@ func TestPeerRoutes(t *testing.T) {
|
|||||||
name: "output-should-be-sorted",
|
name: "output-should-be-sorted",
|
||||||
peers: []wgcfg.Peer{
|
peers: []wgcfg.Peer{
|
||||||
{
|
{
|
||||||
AllowedIPs: []netaddr.IPPrefix{
|
AllowedIPs: []netip.Prefix{
|
||||||
pp("100.64.0.2/32"),
|
pp("100.64.0.2/32"),
|
||||||
pp("10.0.0.0/16"),
|
pp("10.0.0.0/16"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
AllowedIPs: []netaddr.IPPrefix{
|
AllowedIPs: []netip.Prefix{
|
||||||
pp("100.64.0.1/32"),
|
pp("100.64.0.1/32"),
|
||||||
pp("10.0.0.0/8"),
|
pp("10.0.0.0/8"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: []netaddr.IPPrefix{
|
want: []netip.Prefix{
|
||||||
pp("10.0.0.0/8"),
|
pp("10.0.0.0/8"),
|
||||||
pp("10.0.0.0/16"),
|
pp("10.0.0.0/16"),
|
||||||
pp("100.64.0.1/32"),
|
pp("100.64.0.1/32"),
|
||||||
@ -363,12 +362,12 @@ func TestPeerAPIBase(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "self_only_4_them_both",
|
name: "self_only_4_them_both",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.1/32"),
|
netip.MustParsePrefix("100.64.1.1/32"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
peer: &tailcfg.Node{
|
peer: &tailcfg.Node{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.2/32"),
|
netip.MustParsePrefix("100.64.1.2/32"),
|
||||||
netip.MustParsePrefix("fe70::2/128"),
|
netip.MustParsePrefix("fe70::2/128"),
|
||||||
},
|
},
|
||||||
@ -384,12 +383,12 @@ func TestPeerAPIBase(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "self_only_6_them_both",
|
name: "self_only_6_them_both",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("fe70::1/128"),
|
netip.MustParsePrefix("fe70::1/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
peer: &tailcfg.Node{
|
peer: &tailcfg.Node{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.2/32"),
|
netip.MustParsePrefix("100.64.1.2/32"),
|
||||||
netip.MustParsePrefix("fe70::2/128"),
|
netip.MustParsePrefix("fe70::2/128"),
|
||||||
},
|
},
|
||||||
@ -405,13 +404,13 @@ func TestPeerAPIBase(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "self_both_them_only_4",
|
name: "self_both_them_only_4",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.1/32"),
|
netip.MustParsePrefix("100.64.1.1/32"),
|
||||||
netip.MustParsePrefix("fe70::1/128"),
|
netip.MustParsePrefix("fe70::1/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
peer: &tailcfg.Node{
|
peer: &tailcfg.Node{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.2/32"),
|
netip.MustParsePrefix("100.64.1.2/32"),
|
||||||
netip.MustParsePrefix("fe70::2/128"),
|
netip.MustParsePrefix("fe70::2/128"),
|
||||||
},
|
},
|
||||||
@ -426,13 +425,13 @@ func TestPeerAPIBase(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "self_both_them_only_6",
|
name: "self_both_them_only_6",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.1/32"),
|
netip.MustParsePrefix("100.64.1.1/32"),
|
||||||
netip.MustParsePrefix("fe70::1/128"),
|
netip.MustParsePrefix("fe70::1/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
peer: &tailcfg.Node{
|
peer: &tailcfg.Node{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.2/32"),
|
netip.MustParsePrefix("100.64.1.2/32"),
|
||||||
netip.MustParsePrefix("fe70::2/128"),
|
netip.MustParsePrefix("fe70::2/128"),
|
||||||
},
|
},
|
||||||
@ -447,13 +446,13 @@ func TestPeerAPIBase(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "self_both_them_no_peerapi_service",
|
name: "self_both_them_no_peerapi_service",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.1/32"),
|
netip.MustParsePrefix("100.64.1.1/32"),
|
||||||
netip.MustParsePrefix("fe70::1/128"),
|
netip.MustParsePrefix("fe70::1/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
peer: &tailcfg.Node{
|
peer: &tailcfg.Node{
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
netip.MustParsePrefix("100.64.1.2/32"),
|
netip.MustParsePrefix("100.64.1.2/32"),
|
||||||
netip.MustParsePrefix("fe70::2/128"),
|
netip.MustParsePrefix("fe70::2/128"),
|
||||||
},
|
},
|
||||||
@ -543,10 +542,10 @@ func TestFileTargets(t *testing.T) {
|
|||||||
func TestInternalAndExternalInterfaces(t *testing.T) {
|
func TestInternalAndExternalInterfaces(t *testing.T) {
|
||||||
type interfacePrefix struct {
|
type interfacePrefix struct {
|
||||||
i interfaces.Interface
|
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 {
|
for _, ip := range ips {
|
||||||
pfxs = append(pfxs, ip.pfx.Masked())
|
pfxs = append(pfxs, ip.pfx.Masked())
|
||||||
}
|
}
|
||||||
@ -585,8 +584,8 @@ type interfacePrefix struct {
|
|||||||
name string
|
name string
|
||||||
goos string
|
goos string
|
||||||
il interfaces.List
|
il interfaces.List
|
||||||
wantInt []netaddr.IPPrefix
|
wantInt []netip.Prefix
|
||||||
wantExt []netaddr.IPPrefix
|
wantExt []netip.Prefix
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "single-interface",
|
name: "single-interface",
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
"tailscale.com/wgengine/filter"
|
"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
|
// addH2C is non-nil on platforms where we want to add H2C
|
||||||
// ("cleartext" HTTP/2) support to the peerAPI.
|
// ("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
|
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.
|
// 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
|
// 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
|
// 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 {
|
type peerAPIListener struct {
|
||||||
ps *peerAPIServer
|
ps *peerAPIServer
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
lb *LocalBackend
|
lb *LocalBackend
|
||||||
|
|
||||||
// ln is the Listener. It can be nil in netstack mode if there are more than
|
// 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
|
logf := pln.lb.logf
|
||||||
peerNode, peerUser, ok := pln.lb.WhoIs(src)
|
peerNode, peerUser, ok := pln.lb.WhoIs(src)
|
||||||
if !ok {
|
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.
|
// peerAPIHandler serves the Peer API for a source specific client.
|
||||||
type peerAPIHandler struct {
|
type peerAPIHandler struct {
|
||||||
ps *peerAPIServer
|
ps *peerAPIServer
|
||||||
remoteAddr netaddr.IPPort
|
remoteAddr netip.AddrPort
|
||||||
isSelf bool // whether peerNode is owned by same user as this node
|
isSelf bool // whether peerNode is owned by same user as this node
|
||||||
peerNode *tailcfg.Node // peerNode is who's making the request
|
peerNode *tailcfg.Node // peerNode is who's making the request
|
||||||
peerUser tailcfg.UserProfile // profile of peerNode
|
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.Fprintf(w, "<th>%v</th> ", v)
|
||||||
}
|
}
|
||||||
fmt.Fprint(w, "</tr>\n")
|
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>")
|
fmt.Fprint(w, "<tr>")
|
||||||
for _, v := range []any{iface.Index, iface.Name, iface.MTU, iface.Flags, ipps} {
|
for _, v := range []any{iface.Index, iface.Name, iface.MTU, iface.Flags, ipps} {
|
||||||
fmt.Fprintf(w, "<td>%v</td> ", v)
|
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.
|
// it's listening on the provided IP address and on TCP port 1.
|
||||||
//
|
//
|
||||||
// See docs on fakePeerAPIListener.
|
// See docs on fakePeerAPIListener.
|
||||||
func newFakePeerAPIListener(ip netaddr.IP) net.Listener {
|
func newFakePeerAPIListener(ip netip.Addr) net.Listener {
|
||||||
return &fakePeerAPIListener{
|
return &fakePeerAPIListener{
|
||||||
addr: net.TCPAddrFromAddrPort(netaddr.IPPortFrom(ip, 1)),
|
addr: net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, 1)),
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ func init() {
|
|||||||
// initListenConfigNetworkExtension configures nc for listening on IP
|
// initListenConfigNetworkExtension configures nc for listening on IP
|
||||||
// through the iOS/macOS Network/System Extension (Packet Tunnel
|
// through the iOS/macOS Network/System Extension (Packet Tunnel
|
||||||
// Provider) sandbox.
|
// 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]
|
tunIf, ok := st.Interface[tunIfName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("no interface with name %q", tunIfName)
|
return fmt.Errorf("no interface with name %q", tunIfName)
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
"go4.org/netipx"
|
"go4.org/netipx"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -596,7 +595,7 @@ func TestPeerAPIReplyToDNSQueries(t *testing.T) {
|
|||||||
t.Fatal("unexpectedly offering exit node")
|
t.Fatal("unexpectedly offering exit node")
|
||||||
}
|
}
|
||||||
h.ps.b.prefs = &ipn.Prefs{
|
h.ps.b.prefs = &ipn.Prefs{
|
||||||
AdvertiseRoutes: []netaddr.IPPrefix{
|
AdvertiseRoutes: []netip.Prefix{
|
||||||
netip.MustParsePrefix("0.0.0.0/0"),
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
netip.MustParsePrefix("::/0"),
|
netip.MustParsePrefix("::/0"),
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
"tailscale.com/ipn/localapi"
|
"tailscale.com/ipn/localapi"
|
||||||
"tailscale.com/logtail/backoff"
|
"tailscale.com/logtail/backoff"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netstat"
|
"tailscale.com/net/netstat"
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -1066,7 +1065,7 @@ func (s *Server) ServeHTMLStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
st.WriteHTML(w)
|
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 {
|
for _, e := range entries {
|
||||||
if e.Local == ra && e.Remote == la {
|
if e.Local == ra && e.Remote == la {
|
||||||
return e.Pid
|
return e.Pid
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
"html"
|
"html"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"net/netip"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/views"
|
"tailscale.com/types/views"
|
||||||
@ -35,7 +35,7 @@ type Status struct {
|
|||||||
BackendState string
|
BackendState string
|
||||||
|
|
||||||
AuthURL string // current URL provided by control to authorize client
|
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
|
Self *PeerStatus
|
||||||
|
|
||||||
// ExitNodeStatus describes the current exit node.
|
// ExitNodeStatus describes the current exit node.
|
||||||
@ -94,7 +94,7 @@ type ExitNodeStatus struct {
|
|||||||
Online bool
|
Online bool
|
||||||
|
|
||||||
// TailscaleIPs are the exit node's IP addresses assigned to the node.
|
// TailscaleIPs are the exit node's IP addresses assigned to the node.
|
||||||
TailscaleIPs []netaddr.IPPrefix
|
TailscaleIPs []netip.Prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Status) Peers() []key.NodePublic {
|
func (s *Status) Peers() []key.NodePublic {
|
||||||
@ -124,7 +124,7 @@ type PeerStatus struct {
|
|||||||
DNSName string
|
DNSName string
|
||||||
OS string // HostInfo.OS
|
OS string // HostInfo.OS
|
||||||
UserID tailcfg.UserID
|
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.
|
// Tags are the list of ACL tags applied to this node.
|
||||||
// See tailscale.com/tailcfg#Node.Tags for more information.
|
// 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.
|
// 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()
|
sb.mu.Lock()
|
||||||
defer sb.mu.Unlock()
|
defer sb.mu.Unlock()
|
||||||
if sb.locked {
|
if sb.locked {
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netutil"
|
"tailscale.com/net/netutil"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -223,7 +222,7 @@ func (h *Handler) serveWhoIs(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
b := h.b
|
b := h.b
|
||||||
var ipp netaddr.IPPort
|
var ipp netip.AddrPort
|
||||||
if v := r.FormValue("addr"); v != "" {
|
if v := r.FormValue("addr"); v != "" {
|
||||||
var err error
|
var err error
|
||||||
ipp, err = netip.ParseAddrPort(v)
|
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
|
// blackhole route will be installed on the local system to
|
||||||
// prevent any traffic escaping to the local network.
|
// prevent any traffic escaping to the local network.
|
||||||
ExitNodeID tailcfg.StableNodeID
|
ExitNodeID tailcfg.StableNodeID
|
||||||
ExitNodeIP netaddr.IP
|
ExitNodeIP netip.Addr
|
||||||
|
|
||||||
// ExitNodeAllowLANAccess indicates whether locally accessible subnets should be
|
// ExitNodeAllowLANAccess indicates whether locally accessible subnets should be
|
||||||
// routed directly or via the exit node.
|
// routed directly or via the exit node.
|
||||||
@ -168,7 +168,7 @@ type Prefs struct {
|
|||||||
// AdvertiseRoutes specifies CIDR prefixes to advertise into the
|
// AdvertiseRoutes specifies CIDR prefixes to advertise into the
|
||||||
// Tailscale network as reachable through the current
|
// Tailscale network as reachable through the current
|
||||||
// node.
|
// node.
|
||||||
AdvertiseRoutes []netaddr.IPPrefix
|
AdvertiseRoutes []netip.Prefix
|
||||||
|
|
||||||
// NoSNAT specifies whether to source NAT traffic going to
|
// NoSNAT specifies whether to source NAT traffic going to
|
||||||
// destinations in AdvertiseRoutes. The default is to apply source
|
// 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)
|
p.Persist.Equals(p2.Persist)
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareIPNets(a, b []netaddr.IPPrefix) bool {
|
func compareIPNets(a, b []netip.Prefix) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -478,13 +478,13 @@ func (p *Prefs) SetAdvertiseExitNode(runExit bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.AdvertiseRoutes = append(p.AdvertiseRoutes,
|
p.AdvertiseRoutes = append(p.AdvertiseRoutes,
|
||||||
netaddr.IPPrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
|
netip.PrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
|
||||||
netaddr.IPPrefixFrom(netip.IPv6Unspecified(), 0))
|
netip.PrefixFrom(netip.IPv6Unspecified(), 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
// peerWithTailscaleIP returns the peer in st with the provided
|
// peerWithTailscaleIP returns the peer in st with the provided
|
||||||
// Tailscale IP.
|
// 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 _, ps := range st.Peer {
|
||||||
for _, ip2 := range ps.TailscaleIPs {
|
for _, ip2 := range ps.TailscaleIPs {
|
||||||
if ip == ip2 {
|
if ip == ip2 {
|
||||||
@ -495,7 +495,7 @@ func peerWithTailscaleIP(st *ipnstate.Status, ip netaddr.IP) (ps *ipnstate.PeerS
|
|||||||
return nil, false
|
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 {
|
for _, selfIP := range st.TailscaleIPs {
|
||||||
if ip == selfIP {
|
if ip == selfIP {
|
||||||
return false
|
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.
|
// ClearExitNode sets the ExitNodeID and ExitNodeIP to their zero values.
|
||||||
func (p *Prefs) ClearExitNode() {
|
func (p *Prefs) ClearExitNode() {
|
||||||
p.ExitNodeID = ""
|
p.ExitNodeID = ""
|
||||||
p.ExitNodeIP = netaddr.IP{}
|
p.ExitNodeIP = netip.Addr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExitNodeLocalIPError is returned when the requested IP address for an exit
|
// 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)
|
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 == "" {
|
if s == "" {
|
||||||
return ip, os.ErrInvalid
|
return ip, os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func TestPrefsEqual(t *testing.T) {
|
|||||||
have, prefsHandles)
|
have, prefsHandles)
|
||||||
}
|
}
|
||||||
|
|
||||||
nets := func(strs ...string) (ns []netaddr.IPPrefix) {
|
nets := func(strs ...string) (ns []netip.Prefix) {
|
||||||
for _, s := range strs {
|
for _, s := range strs {
|
||||||
n, err := netip.ParsePrefix(s)
|
n, err := netip.ParsePrefix(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -227,12 +227,12 @@ func TestPrefsEqual(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
&Prefs{AdvertiseRoutes: nil},
|
&Prefs{AdvertiseRoutes: nil},
|
||||||
&Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
|
&Prefs{AdvertiseRoutes: []netip.Prefix{}},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
|
&Prefs{AdvertiseRoutes: []netip.Prefix{}},
|
||||||
&Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}},
|
&Prefs{AdvertiseRoutes: []netip.Prefix{}},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -659,7 +659,7 @@ func TestPrefsExitNode(t *testing.T) {
|
|||||||
if p.AdvertisesExitNode() {
|
if p.AdvertisesExitNode() {
|
||||||
t.Errorf("default shouldn't advertise exit node")
|
t.Errorf("default shouldn't advertise exit node")
|
||||||
}
|
}
|
||||||
p.AdvertiseRoutes = []netaddr.IPPrefix{
|
p.AdvertiseRoutes = []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.0.0/16"),
|
netip.MustParsePrefix("10.0.0.0/16"),
|
||||||
}
|
}
|
||||||
p.SetAdvertiseExitNode(true)
|
p.SetAdvertiseExitNode(true)
|
||||||
@ -688,7 +688,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
arg string
|
arg string
|
||||||
st *ipnstate.Status
|
st *ipnstate.Status
|
||||||
want netaddr.IP
|
want netip.Addr
|
||||||
wantErr string
|
wantErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -714,7 +714,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
|
|||||||
BackendState: "Running",
|
BackendState: "Running",
|
||||||
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
||||||
key.NewNode().Public(): {
|
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",
|
BackendState: "Running",
|
||||||
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
||||||
key.NewNode().Public(): {
|
key.NewNode().Public(): {
|
||||||
TailscaleIPs: []netaddr.IP{mustIP("1.2.3.4")},
|
TailscaleIPs: []netip.Addr{mustIP("1.2.3.4")},
|
||||||
ExitNodeOption: true,
|
ExitNodeOption: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -748,7 +748,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
|
|||||||
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
||||||
key.NewNode().Public(): {
|
key.NewNode().Public(): {
|
||||||
DNSName: "skippy.foo.",
|
DNSName: "skippy.foo.",
|
||||||
TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
|
TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
|
||||||
ExitNodeOption: true,
|
ExitNodeOption: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -763,7 +763,7 @@ func TestExitNodeIPOfArg(t *testing.T) {
|
|||||||
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
||||||
key.NewNode().Public(): {
|
key.NewNode().Public(): {
|
||||||
DNSName: "skippy.foo.",
|
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{
|
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
|
||||||
key.NewNode().Public(): {
|
key.NewNode().Public(): {
|
||||||
DNSName: "skippy.foo.",
|
DNSName: "skippy.foo.",
|
||||||
TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
|
TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
|
||||||
ExitNodeOption: true,
|
ExitNodeOption: true,
|
||||||
},
|
},
|
||||||
key.NewNode().Public(): {
|
key.NewNode().Public(): {
|
||||||
DNSName: "SKIPPY.foo.",
|
DNSName: "SKIPPY.foo.",
|
||||||
TailscaleIPs: []netaddr.IP{mustIP("1.0.0.2")},
|
TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
|
||||||
ExitNodeOption: true,
|
ExitNodeOption: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
@ -40,13 +40,13 @@ type Config struct {
|
|||||||
// Adding an entry to Hosts merely creates the record. If you want
|
// Adding an entry to Hosts merely creates the record. If you want
|
||||||
// it to resolve, you also need to add appropriate routes to
|
// it to resolve, you also need to add appropriate routes to
|
||||||
// Routes.
|
// Routes.
|
||||||
Hosts map[dnsname.FQDN][]netaddr.IP
|
Hosts map[dnsname.FQDN][]netip.Addr
|
||||||
// OnlyIPv6, if true, uses the IPv6 service IP (for MagicDNS)
|
// OnlyIPv6, if true, uses the IPv6 service IP (for MagicDNS)
|
||||||
// instead of the IPv4 version (100.100.100.100).
|
// instead of the IPv4 version (100.100.100.100).
|
||||||
OnlyIPv6 bool
|
OnlyIPv6 bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) serviceIP() netaddr.IP {
|
func (c *Config) serviceIP() netip.Addr {
|
||||||
if c.OnlyIPv6 {
|
if c.OnlyIPv6 {
|
||||||
return tsaddr.TailscaleServiceIPv6()
|
return tsaddr.TailscaleServiceIPv6()
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ func sameResolverNames(a, b []*dnstype.Resolver) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func sameIPs(a, b []netaddr.IP) bool {
|
func sameIPs(a, b []netip.Addr) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -21,7 +22,6 @@
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/dns/resolvconffile"
|
"tailscale.com/net/dns/resolvconffile"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
// writeResolvConf writes DNS configuration in resolv.conf format to the given writer.
|
// 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{
|
c := &resolvconffile.Config{
|
||||||
Nameservers: servers,
|
Nameservers: servers,
|
||||||
SearchDomains: domains,
|
SearchDomains: domains,
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ func testDirect(t *testing.T, fs wholeFileFS) {
|
|||||||
|
|
||||||
m := directManager{logf: t.Logf, fs: fs}
|
m := directManager{logf: t.Logf, fs: fs}
|
||||||
if err := m.SetDNS(OSConfig{
|
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."},
|
SearchDomains: []dnsname.FQDN{"ts.net.", "ts-dns.test."},
|
||||||
MatchDomains: []dnsname.FQDN{"ignored."},
|
MatchDomains: []dnsname.FQDN{"ignored."},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -109,7 +108,7 @@ func testDirect(t *testing.T, fs wholeFileFS) {
|
|||||||
assertBaseState(t)
|
assertBaseState(t)
|
||||||
|
|
||||||
// Test that Close cleans up resolv.conf.
|
// 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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := m.Close(); err != nil {
|
if err := m.Close(); err != nil {
|
||||||
@ -150,21 +149,21 @@ func TestReadResolve(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{in: `nameserver 192.168.0.100`,
|
{in: `nameserver 192.168.0.100`,
|
||||||
want: OSConfig{
|
want: OSConfig{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{in: `nameserver 192.168.0.100 # comment`,
|
{in: `nameserver 192.168.0.100 # comment`,
|
||||||
want: OSConfig{
|
want: OSConfig{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{in: `nameserver 192.168.0.100#`,
|
{in: `nameserver 192.168.0.100#`,
|
||||||
want: OSConfig{
|
want: OSConfig{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@ -67,7 +67,7 @@ func maxActiveQueries() int32 {
|
|||||||
|
|
||||||
type response struct {
|
type response struct {
|
||||||
pkt []byte
|
pkt []byte
|
||||||
to netaddr.IPPort // response destination (request source)
|
to netip.AddrPort // response destination (request source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manager manages system DNS settings.
|
// Manager manages system DNS settings.
|
||||||
@ -175,7 +175,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig
|
|||||||
// through quad-100.
|
// through quad-100.
|
||||||
rcfg.Routes = routes
|
rcfg.Routes = routes
|
||||||
rcfg.Routes["."] = cfg.DefaultResolvers
|
rcfg.Routes["."] = cfg.DefaultResolvers
|
||||||
ocfg.Nameservers = []netaddr.IP{cfg.serviceIP()}
|
ocfg.Nameservers = []netip.Addr{cfg.serviceIP()}
|
||||||
return rcfg, ocfg, nil
|
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
|
// or routes + MagicDNS, or just MagicDNS, or on an OS that cannot
|
||||||
// split-DNS. Install a split config pointing at quad-100.
|
// split-DNS. Install a split config pointing at quad-100.
|
||||||
rcfg.Routes = routes
|
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
|
// If the OS can't do native split-dns, read out the underlying
|
||||||
// resolver config and blend it into our config.
|
// 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.
|
// toIPsOnly returns only the IP portion of dnstype.Resolver.
|
||||||
// Only safe to use if the resolvers slice has been cleared of
|
// Only safe to use if the resolvers slice has been cleared of
|
||||||
// DoH or custom-port entries with something like hasDefaultIPResolversOnly.
|
// 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 {
|
for _, r := range resolvers {
|
||||||
if ipp, ok := r.IPPort(); ok && ipp.Port() == 53 {
|
if ipp, ok := r.IPPort(); ok && ipp.Port() == 53 {
|
||||||
ret = append(ret, ipp.Addr())
|
ret = append(ret, ipp.Addr())
|
||||||
@ -252,7 +252,7 @@ func toIPsOnly(resolvers []*dnstype.Resolver) (ret []netaddr.IP) {
|
|||||||
// called with a DNS request payload.
|
// called with a DNS request payload.
|
||||||
//
|
//
|
||||||
// TODO(tom): Rip out once all platforms use netstack.
|
// 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 {
|
if to.Port() != 53 || proto != ipproto.UDP {
|
||||||
return nil
|
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
|
// 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.
|
// provided in bs as a wire-encoded DNS query without any transport header.
|
||||||
// This method is called for requests arriving over UDP and TCP.
|
// 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 {
|
select {
|
||||||
case <-m.ctx.Done():
|
case <-m.ctx.Done():
|
||||||
return nil, net.ErrClosed
|
return nil, net.ErrClosed
|
||||||
@ -368,7 +368,7 @@ type dnsTCPSession struct {
|
|||||||
m *Manager
|
m *Manager
|
||||||
|
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
srcAddr netaddr.IPPort
|
srcAddr netip.AddrPort
|
||||||
|
|
||||||
readClosing chan struct{}
|
readClosing chan struct{}
|
||||||
responses chan []byte // DNS replies pending writing
|
responses chan []byte // DNS replies pending writing
|
||||||
@ -455,7 +455,7 @@ func (s *dnsTCPSession) handleReads() {
|
|||||||
|
|
||||||
// HandleTCPConn implements magicDNS over TCP, taking a connection and
|
// HandleTCPConn implements magicDNS over TCP, taking a connection and
|
||||||
// servicing DNS requests sent down it.
|
// 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{
|
s := dnsTCPSession{
|
||||||
m: m,
|
m: m,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
dns "golang.org/x/net/dns/dnsmessage"
|
dns "golang.org/x/net/dns/dnsmessage"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
@ -73,7 +73,7 @@ func TestDNSOverTCP(t *testing.T) {
|
|||||||
|
|
||||||
c, s := net.Pipe()
|
c, s := net.Pipe()
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
go m.HandleTCPConn(s, netaddr.IPPort{})
|
go m.HandleTCPConn(s, netip.AddrPort{})
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
wantResults := map[dnsname.FQDN]string{
|
wantResults := map[dnsname.FQDN]string{
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/util/dnsname"
|
"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() })
|
trIP := cmp.Transformer("ipStr", func(ip netip.Addr) string { return ip.String() })
|
||||||
trIPPort := cmp.Transformer("ippStr", func(ipp netaddr.IPPort) string {
|
trIPPort := cmp.Transformer("ippStr", func(ipp netip.AddrPort) string {
|
||||||
if ipp.Port() == 53 {
|
if ipp.Port() == 53 {
|
||||||
return ipp.Addr().String()
|
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 {
|
for _, s := range strs {
|
||||||
ret = append(ret, netip.MustParseAddr(s))
|
ret = append(ret, netip.MustParseAddr(s))
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustIPPs(strs ...string) (ret []netaddr.IPPort) {
|
func mustIPPs(strs ...string) (ret []netip.AddrPort) {
|
||||||
for _, s := range strs {
|
for _, s := range strs {
|
||||||
ret = append(ret, netip.MustParseAddrPort(s))
|
ret = append(ret, netip.MustParseAddrPort(s))
|
||||||
}
|
}
|
||||||
@ -456,9 +455,9 @@ func fqdns(strs ...string) (ret []dnsname.FQDN) {
|
|||||||
return ret
|
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
|
var key dnsname.FQDN
|
||||||
ret = map[dnsname.FQDN][]netaddr.IP{}
|
ret = map[dnsname.FQDN][]netip.Addr{}
|
||||||
for _, s := range strs {
|
for _, s := range strs {
|
||||||
if ip, err := netip.ParseAddr(s); err == nil {
|
if ip, err := netip.ParseAddr(s); err == nil {
|
||||||
if key == "" {
|
if key == "" {
|
||||||
|
@ -90,7 +90,7 @@ func delValue(key registry.Key, name string) error {
|
|||||||
// system's "primary" resolver.
|
// system's "primary" resolver.
|
||||||
//
|
//
|
||||||
// If no resolvers are provided, the Tailscale NRPT rules are deleted.
|
// 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 m.nrptDB == nil {
|
||||||
if resolvers == nil {
|
if resolvers == nil {
|
||||||
// Just a no-op in this case.
|
// Just a no-op in this case.
|
||||||
@ -118,7 +118,7 @@ func (m windowsManager) setSplitDNS(resolvers []netaddr.IP, domains []dnsname.FQ
|
|||||||
// "primary" resolvers.
|
// "primary" resolvers.
|
||||||
// domains can be set without resolvers, which just contributes new
|
// domains can be set without resolvers, which just contributes new
|
||||||
// paths to the global DNS search list.
|
// 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 ipsv4 []string
|
||||||
var ipsv6 []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
|
// 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
|
// what the "previous" primary resolver was. It might be wrong, or
|
||||||
// incomplete.
|
// 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)
|
tsGUID, err := windows.GUIDFromString(m.guid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -422,7 +422,7 @@ type candidate struct {
|
|||||||
return resolvers, nil
|
return resolvers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var siteLocalResolvers = []netaddr.IP{
|
var siteLocalResolvers = []netip.Addr{
|
||||||
netip.MustParseAddr("fec0:0:0:ffff::1"),
|
netip.MustParseAddr("fec0:0:0:ffff::1"),
|
||||||
netip.MustParseAddr("fec0:0:0:ffff::2"),
|
netip.MustParseAddr("fec0:0:0:ffff::2"),
|
||||||
netip.MustParseAddr("fec0:0:0:ffff::3"),
|
netip.MustParseAddr("fec0:0:0:ffff::3"),
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/util/winutil"
|
"tailscale.com/util/winutil"
|
||||||
)
|
)
|
||||||
@ -92,7 +91,7 @@ func TestManagerWindowsGPMove(t *testing.T) {
|
|||||||
// Upon initialization of cfg, we should not have any NRPT rules
|
// Upon initialization of cfg, we should not have any NRPT rules
|
||||||
ensureNoRules(t)
|
ensureNoRules(t)
|
||||||
|
|
||||||
resolvers := []netaddr.IP{netip.MustParseAddr("1.1.1.1")}
|
resolvers := []netip.Addr{netip.MustParseAddr("1.1.1.1")}
|
||||||
domains := genRandomSubdomains(t, 1)
|
domains := genRandomSubdomains(t, 1)
|
||||||
|
|
||||||
// 1. Populate local NRPT
|
// 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
|
// Upon initialization of cfg, we should not have any NRPT rules
|
||||||
ensureNoRules(t)
|
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)
|
domains := genRandomSubdomains(t, 2*nrptMaxDomainsPerRule+1)
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
"github.com/godbus/dbus/v5"
|
"github.com/godbus/dbus/v5"
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
"tailscale.com/util/endian"
|
"tailscale.com/util/endian"
|
||||||
)
|
)
|
||||||
@ -294,7 +293,7 @@ func (m *nmManager) GetBaseConfig() (OSConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type dnsPrio struct {
|
type dnsPrio struct {
|
||||||
resolvers []netaddr.IP
|
resolvers []netip.Addr
|
||||||
domains []string
|
domains []string
|
||||||
priority int32
|
priority int32
|
||||||
}
|
}
|
||||||
@ -342,7 +341,7 @@ type dnsPrio struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ret OSConfig
|
ret OSConfig
|
||||||
seenResolvers = map[netaddr.IP]bool{}
|
seenResolvers = map[netip.Addr]bool{}
|
||||||
seenSearch = map[string]bool{}
|
seenSearch = map[string]bool{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ type OSConfigurator interface {
|
|||||||
// OSConfig is an OS DNS configuration.
|
// OSConfig is an OS DNS configuration.
|
||||||
type OSConfig struct {
|
type OSConfig struct {
|
||||||
// Nameservers are the IP addresses of the nameservers to use.
|
// 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
|
// SearchDomains are the domain suffixes to use when expanding
|
||||||
// single-label name queries. SearchDomains is additive to
|
// single-label name queries. SearchDomains is additive to
|
||||||
// whatever non-Tailscale search domains the OS has.
|
// whatever non-Tailscale search domains the OS has.
|
||||||
|
@ -9,31 +9,29 @@
|
|||||||
import (
|
import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var knownDoH = map[netaddr.IP]string{} // 8.8.8.8 => "https://..."
|
var knownDoH = map[netip.Addr]string{} // 8.8.8.8 => "https://..."
|
||||||
var dohIPsOfBase = map[string][]netaddr.IP{}
|
var dohIPsOfBase = map[string][]netip.Addr{}
|
||||||
var populateOnce sync.Once
|
var populateOnce sync.Once
|
||||||
|
|
||||||
// KnownDoH returns a map of well-known public DNS IPs to their DoH URL.
|
// KnownDoH returns a map of well-known public DNS IPs to their DoH URL.
|
||||||
// The returned map should not be modified.
|
// The returned map should not be modified.
|
||||||
func KnownDoH() map[netaddr.IP]string {
|
func KnownDoH() map[netip.Addr]string {
|
||||||
populateOnce.Do(populate)
|
populateOnce.Do(populate)
|
||||||
return knownDoH
|
return knownDoH
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoHIPsOfBase returns a map of DNS server IP addresses keyed
|
// DoHIPsOfBase returns a map of DNS server IP addresses keyed
|
||||||
// by their DoH URL. It is the inverse of KnownDoH.
|
// 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)
|
populateOnce.Do(populate)
|
||||||
return dohIPsOfBase
|
return dohIPsOfBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoHV6 returns the first IPv6 DNS address from a given public DNS provider
|
// DoHV6 returns the first IPv6 DNS address from a given public DNS provider
|
||||||
// if found, along with a boolean indicating success.
|
// 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)
|
populateOnce.Do(populate)
|
||||||
for _, ip := range dohIPsOfBase[base] {
|
for _, ip := range dohIPsOfBase[base] {
|
||||||
if ip.Is6() {
|
if ip.Is6() {
|
||||||
@ -43,7 +41,7 @@ func DoHV6(base string) (ip netaddr.IP, ok bool) {
|
|||||||
return ip, false
|
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.
|
// adds it to both knownDoH and dohIPsOFBase maps.
|
||||||
func addDoH(ipStr, base string) {
|
func addDoH(ipStr, base string) {
|
||||||
ip := netip.MustParseAddr(ipStr)
|
ip := netip.MustParseAddr(ipStr)
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
import (
|
import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
@ -24,12 +22,12 @@ func TestInit(t *testing.T) {
|
|||||||
func TestDohV6(t *testing.T) {
|
func TestDohV6(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
in string
|
in string
|
||||||
firstIP netaddr.IP
|
firstIP netip.Addr
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"https://cloudflare-dns.com/dns-query", netip.MustParseAddr("2606:4700:4700::1111"), true},
|
{"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},
|
{"https://dns.google/dns-query", netip.MustParseAddr("2001:4860:4860::8888"), true},
|
||||||
{"bogus", netaddr.IP{}, false},
|
{"bogus", netip.Addr{}, false},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.in, func(t *testing.T) {
|
t.Run(test.in, func(t *testing.T) {
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,7 +29,7 @@
|
|||||||
// Config represents a resolv.conf(5) file.
|
// Config represents a resolv.conf(5) file.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Nameservers are the IP addresses of the nameservers to use.
|
// 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
|
// SearchDomains are the domain suffixes to use when expanding
|
||||||
// single-label name queries. SearchDomains is additive to
|
// single-label name queries. SearchDomains is additive to
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,21 +21,21 @@ func TestParse(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{in: `nameserver 192.168.0.100`,
|
{in: `nameserver 192.168.0.100`,
|
||||||
want: &Config{
|
want: &Config{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{in: `nameserver 192.168.0.100 # comment`,
|
{in: `nameserver 192.168.0.100 # comment`,
|
||||||
want: &Config{
|
want: &Config{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{in: `nameserver 192.168.0.100#`,
|
{in: `nameserver 192.168.0.100#`,
|
||||||
want: &Config{
|
want: &Config{
|
||||||
Nameservers: []netaddr.IP{
|
Nameservers: []netip.Addr{
|
||||||
netip.MustParseAddr("192.168.0.100"),
|
netip.MustParseAddr("192.168.0.100"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
@ -28,7 +29,6 @@
|
|||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/net/dns/publicdns"
|
"tailscale.com/net/dns/publicdns"
|
||||||
"tailscale.com/net/dnscache"
|
"tailscale.com/net/dnscache"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/neterror"
|
"tailscale.com/net/neterror"
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/tsdial"
|
"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))
|
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 {
|
if f.linkSel == nil || initListenConfig == nil {
|
||||||
return stdNetPacketListener, nil
|
return stdNetPacketListener, nil
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
type packet struct {
|
type packet struct {
|
||||||
bs []byte
|
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.
|
// Config is a resolver configuration.
|
||||||
@ -70,7 +70,7 @@ type Config struct {
|
|||||||
// To register a "default route", add an entry for ".".
|
// To register a "default route", add an entry for ".".
|
||||||
Routes map[dnsname.FQDN][]*dnstype.Resolver
|
Routes map[dnsname.FQDN][]*dnstype.Resolver
|
||||||
// LocalHosts is a map of FQDNs to corresponding IPs.
|
// 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
|
// LocalDomains is a list of DNS name suffixes that should not be
|
||||||
// routed to upstream resolvers.
|
// routed to upstream resolvers.
|
||||||
LocalDomains []dnsname.FQDN
|
LocalDomains []dnsname.FQDN
|
||||||
@ -106,7 +106,7 @@ func (c *Config) WriteToBufioWriter(w *bufio.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteIPPorts writes vv to w.
|
// WriteIPPorts writes vv to w.
|
||||||
func WriteIPPorts(w *bufio.Writer, vv []netaddr.IPPort) {
|
func WriteIPPorts(w *bufio.Writer, vv []netip.AddrPort) {
|
||||||
w.WriteByte('[')
|
w.WriteByte('[')
|
||||||
var b []byte
|
var b []byte
|
||||||
for i, v := range vv {
|
for i, v := range vv {
|
||||||
@ -193,15 +193,15 @@ type Resolver struct {
|
|||||||
// mu guards the following fields from being updated while used.
|
// mu guards the following fields from being updated while used.
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
localDomains []dnsname.FQDN
|
localDomains []dnsname.FQDN
|
||||||
hostToIP map[dnsname.FQDN][]netaddr.IP
|
hostToIP map[dnsname.FQDN][]netip.Addr
|
||||||
ipToHost map[netaddr.IP]dnsname.FQDN
|
ipToHost map[netip.Addr]dnsname.FQDN
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForwardLinkSelector interface {
|
type ForwardLinkSelector interface {
|
||||||
// PickLink returns which network device should be used to query
|
// PickLink returns which network device should be used to query
|
||||||
// the DNS server at the given IP.
|
// the DNS server at the given IP.
|
||||||
// The empty string means to use an unspecified default.
|
// The empty string means to use an unspecified default.
|
||||||
PickLink(netaddr.IP) (linkName string)
|
PickLink(netip.Addr) (linkName string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new resolver.
|
// 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: "),
|
logf: logger.WithPrefix(logf, "resolver: "),
|
||||||
linkMon: linkMon,
|
linkMon: linkMon,
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
hostToIP: map[dnsname.FQDN][]netaddr.IP{},
|
hostToIP: map[dnsname.FQDN][]netip.Addr{},
|
||||||
ipToHost: map[netaddr.IP]dnsname.FQDN{},
|
ipToHost: map[netip.Addr]dnsname.FQDN{},
|
||||||
dialer: dialer,
|
dialer: dialer,
|
||||||
}
|
}
|
||||||
r.forwarder = newForwarder(r.logf, linkMon, linkSel, dialer)
|
r.forwarder = newForwarder(r.logf, linkMon, linkSel, dialer)
|
||||||
@ -229,7 +229,7 @@ func (r *Resolver) SetConfig(cfg Config) error {
|
|||||||
r.saveConfigForTests(cfg)
|
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 host, ips := range cfg.Hosts {
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
@ -266,7 +266,7 @@ func (r *Resolver) Close() {
|
|||||||
// bound on per-query resource usage.
|
// bound on per-query resource usage.
|
||||||
const dnsQueryTimeout = 10 * time.Second
|
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)
|
metricDNSQueryLocal.Add(1)
|
||||||
select {
|
select {
|
||||||
case <-r.closed:
|
case <-r.closed:
|
||||||
@ -323,7 +323,7 @@ func parseExitNodeQuery(q []byte) *response {
|
|||||||
// still result in a response DNS packet (saying there's a failure)
|
// still result in a response DNS packet (saying there's a failure)
|
||||||
// and a nil error.
|
// and a nil error.
|
||||||
// TODO: figure out if we even need an error result.
|
// 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)
|
metricDNSExitProxyQuery.Add(1)
|
||||||
ch := make(chan packet, 1)
|
ch := make(chan packet, 1)
|
||||||
|
|
||||||
@ -489,7 +489,7 @@ func isGoNoSuchHostError(err error) bool {
|
|||||||
type resolvConfCache struct {
|
type resolvConfCache struct {
|
||||||
mod time.Time
|
mod time.Time
|
||||||
size int64
|
size int64
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
// TODO: inode/dev?
|
// TODO: inode/dev?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +501,10 @@ type resolvConfCache struct {
|
|||||||
|
|
||||||
// stubResolverForOS returns the IP address of the first nameserver in
|
// stubResolverForOS returns the IP address of the first nameserver in
|
||||||
// /etc/resolv.conf.
|
// /etc/resolv.conf.
|
||||||
func stubResolverForOS() (ip netaddr.IP, err error) {
|
func stubResolverForOS() (ip netip.Addr, err error) {
|
||||||
fi, err := os.Stat(resolvconffile.Path)
|
fi, err := os.Stat(resolvconffile.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IP{}, err
|
return netip.Addr{}, err
|
||||||
}
|
}
|
||||||
cur := resolvConfCache{
|
cur := resolvConfCache{
|
||||||
mod: fi.ModTime(),
|
mod: fi.ModTime(),
|
||||||
@ -515,10 +515,10 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
|
|||||||
}
|
}
|
||||||
conf, err := resolvconffile.ParseFile(resolvconffile.Path)
|
conf, err := resolvconffile.ParseFile(resolvconffile.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IP{}, err
|
return netip.Addr{}, err
|
||||||
}
|
}
|
||||||
if len(conf.Nameservers) == 0 {
|
if len(conf.Nameservers) == 0 {
|
||||||
return netaddr.IP{}, errEmptyResolvConf
|
return netip.Addr{}, errEmptyResolvConf
|
||||||
}
|
}
|
||||||
ip = conf.Nameservers[0]
|
ip = conf.Nameservers[0]
|
||||||
cur.ip = ip
|
cur.ip = ip
|
||||||
@ -531,12 +531,12 @@ func stubResolverForOS() (ip netaddr.IP, err error) {
|
|||||||
// typ (A, AAAA, ALL).
|
// typ (A, AAAA, ALL).
|
||||||
// Returns dns.RCodeRefused to indicate that the local map is not
|
// Returns dns.RCodeRefused to indicate that the local map is not
|
||||||
// authoritative for domain.
|
// 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)
|
metricDNSResolveLocal.Add(1)
|
||||||
// Reject .onion domains per RFC 7686.
|
// Reject .onion domains per RFC 7686.
|
||||||
if dnsname.HasSuffix(domain.WithoutTrailingDot(), ".onion") {
|
if dnsname.HasSuffix(domain.WithoutTrailingDot(), ".onion") {
|
||||||
metricDNSResolveLocalErrorOnion.Add(1)
|
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
|
// 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) {
|
if suffix.Contains(domain) {
|
||||||
// We are authoritative for the queried domain.
|
// We are authoritative for the queried domain.
|
||||||
metricDNSResolveLocalErrorMissing.Add(1)
|
metricDNSResolveLocalErrorMissing.Add(1)
|
||||||
return netaddr.IP{}, dns.RCodeNameError
|
return netip.Addr{}, dns.RCodeNameError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Not authoritative, signal that forwarding is advisable.
|
// 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,
|
// 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)
|
metricDNSResolveLocalNoA.Add(1)
|
||||||
return netaddr.IP{}, dns.RCodeSuccess
|
return netip.Addr{}, dns.RCodeSuccess
|
||||||
case dns.TypeAAAA:
|
case dns.TypeAAAA:
|
||||||
for _, ip := range addrs {
|
for _, ip := range addrs {
|
||||||
if ip.Is6() {
|
if ip.Is6() {
|
||||||
@ -597,14 +597,14 @@ func (r *Resolver) resolveLocal(domain dnsname.FQDN, typ dns.Type) (netaddr.IP,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
metricDNSResolveLocalNoAAAA.Add(1)
|
metricDNSResolveLocalNoAAAA.Add(1)
|
||||||
return netaddr.IP{}, dns.RCodeSuccess
|
return netip.Addr{}, dns.RCodeSuccess
|
||||||
case dns.TypeALL:
|
case dns.TypeALL:
|
||||||
// Answer with whatever we've got.
|
// Answer with whatever we've got.
|
||||||
// It could be IPv4, IPv6, or a zero addr.
|
// It could be IPv4, IPv6, or a zero addr.
|
||||||
// TODO: Return all available resolutions (A and AAAA, if we have them).
|
// TODO: Return all available resolutions (A and AAAA, if we have them).
|
||||||
if len(addrs) == 0 {
|
if len(addrs) == 0 {
|
||||||
metricDNSResolveLocalNoAll.Add(1)
|
metricDNSResolveLocalNoAll.Add(1)
|
||||||
return netaddr.IP{}, dns.RCodeSuccess
|
return netip.Addr{}, dns.RCodeSuccess
|
||||||
}
|
}
|
||||||
metricDNSResolveLocalOKAll.Add(1)
|
metricDNSResolveLocalOKAll.Add(1)
|
||||||
return addrs[0], dns.RCodeSuccess
|
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.
|
// DNS semantics and might be implemented in the future.
|
||||||
case dns.TypeNS, dns.TypeSOA, dns.TypeAXFR, dns.TypeHINFO:
|
case dns.TypeNS, dns.TypeSOA, dns.TypeAXFR, dns.TypeHINFO:
|
||||||
metricDNSResolveNotImplType.Add(1)
|
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.
|
// 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
|
// 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:
|
default:
|
||||||
metricDNSResolveNoRecordType.Add(1)
|
metricDNSResolveNoRecordType.Add(1)
|
||||||
// The name exists, but no records exist of the requested type.
|
// 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
|
// (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
|
// "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.
|
// 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())
|
fqdn := string(domain.WithoutTrailingDot())
|
||||||
if typ != dns.TypeAAAA {
|
if typ != dns.TypeAAAA {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
if len(fqdn) < len("via-X.0.0.0.0") {
|
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
|
var siteID string
|
||||||
@ -653,18 +653,18 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP
|
|||||||
if strings.HasPrefix(fqdn, "via-") {
|
if strings.HasPrefix(fqdn, "via-") {
|
||||||
firstDot := strings.Index(fqdn, ".")
|
firstDot := strings.Index(fqdn, ".")
|
||||||
if firstDot < 0 {
|
if firstDot < 0 {
|
||||||
return netaddr.IP{}, false // missing dot delimiters
|
return netip.Addr{}, false // missing dot delimiters
|
||||||
}
|
}
|
||||||
siteID = fqdn[len("via-"):firstDot]
|
siteID = fqdn[len("via-"):firstDot]
|
||||||
ip4Str = fqdn[firstDot+1:]
|
ip4Str = fqdn[firstDot+1:]
|
||||||
} else {
|
} else {
|
||||||
lastDot := strings.LastIndex(fqdn, ".")
|
lastDot := strings.LastIndex(fqdn, ".")
|
||||||
if lastDot < 0 {
|
if lastDot < 0 {
|
||||||
return netaddr.IP{}, false // missing dot delimiters
|
return netip.Addr{}, false // missing dot delimiters
|
||||||
}
|
}
|
||||||
suffix := fqdn[lastDot+1:]
|
suffix := fqdn[lastDot+1:]
|
||||||
if !strings.HasPrefix(suffix, "via-") {
|
if !strings.HasPrefix(suffix, "via-") {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
siteID = suffix[len("via-"):]
|
siteID = suffix[len("via-"):]
|
||||||
ip4Str = fqdn[:lastDot]
|
ip4Str = fqdn[:lastDot]
|
||||||
@ -672,22 +672,22 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP
|
|||||||
|
|
||||||
ip4, err := netip.ParseAddr(ip4Str)
|
ip4, err := netip.ParseAddr(ip4Str)
|
||||||
if err != nil {
|
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)
|
prefix, err := strconv.ParseUint(siteID, 0, 32)
|
||||||
if err != nil {
|
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()))
|
out, _ := tsaddr.MapVia(uint32(prefix), netip.PrefixFrom(ip4, ip4.BitLen()))
|
||||||
return out.Addr(), true
|
return out.Addr(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveReverse returns the unique domain name that maps to the given address.
|
// resolveReverse returns the unique domain name that maps to the given address.
|
||||||
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
|
func (r *Resolver) resolveLocalReverse(name dnsname.FQDN) (dnsname.FQDN, dns.RCode) {
|
||||||
var ip netaddr.IP
|
var ip netip.Addr
|
||||||
var ok bool
|
var ok bool
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(name.WithTrailingDot(), rdnsv4Suffix):
|
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.
|
// 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
|
// If someone curiously does a reverse lookup on the DNS IP, we
|
||||||
// return a domain that helps indicate that Tailscale is using
|
// return a domain that helps indicate that Tailscale is using
|
||||||
// this IP for a special purpose and it is not a node on their
|
// 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.
|
// IP and IPs are the responses to an A, AAAA, or ALL query.
|
||||||
// Either/both/neither can be populated.
|
// Either/both/neither can be populated.
|
||||||
IP netaddr.IP
|
IP netip.Addr
|
||||||
IPs []netaddr.IP
|
IPs []netip.Addr
|
||||||
|
|
||||||
// TXT is the response to a TXT query.
|
// TXT is the response to a TXT query.
|
||||||
// Each one is its own RR with one string.
|
// 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.
|
// marshalARecord serializes an A record into an active builder.
|
||||||
// The caller may continue using the builder following the call.
|
// 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
|
var answer dns.AResource
|
||||||
|
|
||||||
answerHeader := dns.ResourceHeader{
|
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.
|
// marshalAAAARecord serializes an AAAA record into an active builder.
|
||||||
// The caller may continue using the builder following the call.
|
// 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
|
var answer dns.AAAAResource
|
||||||
|
|
||||||
answerHeader := dns.ResourceHeader{
|
answerHeader := dns.ResourceHeader{
|
||||||
@ -839,7 +839,7 @@ func marshalAAAARecord(name dns.Name, ip netaddr.IP, builder *dns.Builder) error
|
|||||||
return builder.AAAAResource(answerHeader, answer)
|
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() {
|
if ip.Is4() {
|
||||||
return marshalARecord(name, ip, builder)
|
return marshalARecord(name, ip, builder)
|
||||||
}
|
}
|
||||||
@ -1066,14 +1066,14 @@ func rawNameToLower(name []byte) string {
|
|||||||
// 4.3.2.1.in-addr.arpa
|
// 4.3.2.1.in-addr.arpa
|
||||||
// is transformed to
|
// is transformed to
|
||||||
// 1.2.3.4
|
// 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)
|
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv4Suffix)
|
||||||
ip, err := netip.ParseAddr(s)
|
ip, err := netip.ParseAddr(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
if !ip.Is4() {
|
if !ip.Is4() {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
b := ip.As4()
|
b := ip.As4()
|
||||||
return netaddr.IPv4(b[3], b[2], b[1], b[0]), true
|
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.
|
// 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
|
// is transformed to
|
||||||
// 2001:db8::567:89ab
|
// 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 b [32]byte
|
||||||
var ipb [16]byte
|
var ipb [16]byte
|
||||||
|
|
||||||
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv6Suffix)
|
s := strings.TrimSuffix(name.WithTrailingDot(), rdnsv6Suffix)
|
||||||
// 32 nibbles and 31 dots between them.
|
// 32 nibbles and 31 dots between them.
|
||||||
if len(s) != 63 {
|
if len(s) != 63 {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dots and hex digits alternate.
|
// 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-- {
|
for i, j := len(s)-1, 0; i >= 0; i-- {
|
||||||
thisDot := (s[i] == '.')
|
thisDot := (s[i] == '.')
|
||||||
if prevDot == thisDot {
|
if prevDot == thisDot {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
prevDot = thisDot
|
prevDot = thisDot
|
||||||
|
|
||||||
@ -1115,7 +1115,7 @@ func rdnsNameToIPv6(name dnsname.FQDN) (ip netaddr.IP, ok bool) {
|
|||||||
|
|
||||||
_, err := hex.Decode(ipb[:], b[:])
|
_, err := hex.Decode(ipb[:], b[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return netaddr.IPFrom16(ipb), true
|
return netaddr.IPFrom16(ipb), true
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file exists to isolate the test infrastructure
|
// 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 A it receives with an A record containing ipv4,
|
||||||
// to queries of type AAAA with an AAAA record containing ipv6,
|
// to queries of type AAAA with an AAAA record containing ipv6,
|
||||||
// to queries of type NS with an NS record containing name.
|
// 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) {
|
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetReply(req)
|
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 A it receives with an A record containing ipv4,
|
||||||
// to queries of type AAAA with an AAAA record containing ipv6,
|
// to queries of type AAAA with an AAAA record containing ipv6,
|
||||||
// to queries of type NS with an NS record containing name.
|
// 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) {
|
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetReply(req)
|
m.SetReply(req)
|
||||||
@ -220,7 +220,7 @@ func weirdoGoCNAMEHandler(target string) dns.HandlerFunc {
|
|||||||
// dnsHandler returns a handler that replies with the answers/options
|
// dnsHandler returns a handler that replies with the answers/options
|
||||||
// provided.
|
// provided.
|
||||||
//
|
//
|
||||||
// Types supported: netaddr.IP.
|
// Types supported: netip.Addr.
|
||||||
func dnsHandler(answers ...any) dns.HandlerFunc {
|
func dnsHandler(answers ...any) dns.HandlerFunc {
|
||||||
return func(w dns.ResponseWriter, req *dns.Msg) {
|
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
@ -235,7 +235,7 @@ func dnsHandler(answers ...any) dns.HandlerFunc {
|
|||||||
switch a := a.(type) {
|
switch a := a.(type) {
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported dnsHandler arg %T", a))
|
panic(fmt.Sprintf("unsupported dnsHandler arg %T", a))
|
||||||
case netaddr.IP:
|
case netip.Addr:
|
||||||
ip := a
|
ip := a
|
||||||
if ip.Is4() {
|
if ip.Is4() {
|
||||||
m.Answer = append(m.Answer, &dns.A{
|
m.Answer = append(m.Answer, &dns.A{
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
var dnsCfg = Config{
|
var dnsCfg = Config{
|
||||||
Hosts: map[dnsname.FQDN][]netaddr.IP{
|
Hosts: map[dnsname.FQDN][]netip.Addr{
|
||||||
"test1.ipn.dev.": {testipv4},
|
"test1.ipn.dev.": {testipv4},
|
||||||
"test2.ipn.dev.": {testipv6},
|
"test2.ipn.dev.": {testipv6},
|
||||||
},
|
},
|
||||||
@ -92,7 +92,7 @@ func dnspacket(domain dnsname.FQDN, tp dns.Type, ednsSize uint16) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type dnsResponse struct {
|
type dnsResponse struct {
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
txt []string
|
txt []string
|
||||||
name dnsname.FQDN
|
name dnsname.FQDN
|
||||||
rcode dns.RCode
|
rcode dns.RCode
|
||||||
@ -157,7 +157,7 @@ func unpackResponse(payload []byte) (dnsResponse, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
response.ip = netaddr.IPv6Raw(res.AAAA)
|
response.ip = netip.AddrFrom16(res.AAAA)
|
||||||
case dns.TypeTXT:
|
case dns.TypeTXT:
|
||||||
res, err := parser.TXTResource()
|
res, err := parser.TXTResource()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -234,10 +234,10 @@ func unpackResponse(payload []byte) (dnsResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func syncRespond(r *Resolver, query []byte) ([]byte, 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)
|
ip, err := netip.ParseAddr(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -249,13 +249,13 @@ func TestRDNSNameToIPv4(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
input dnsname.FQDN
|
input dnsname.FQDN
|
||||||
wantIP netaddr.IP
|
wantIP netip.Addr
|
||||||
wantOK bool
|
wantOK bool
|
||||||
}{
|
}{
|
||||||
{"valid", "4.123.24.1.in-addr.arpa.", netaddr.IPv4(1, 24, 123, 4), true},
|
{"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},
|
{"double_dot", "1..2.3.in-addr.arpa.", netip.Addr{}, false},
|
||||||
{"overflow", "1.256.3.4.in-addr.arpa.", netaddr.IP{}, false},
|
{"overflow", "1.256.3.4.in-addr.arpa.", netip.Addr{}, false},
|
||||||
{"not_ip", "sub.do.ma.in.in-addr.arpa.", netaddr.IP{}, false},
|
{"not_ip", "sub.do.ma.in.in-addr.arpa.", netip.Addr{}, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -274,7 +274,7 @@ func TestRDNSNameToIPv6(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
input dnsname.FQDN
|
input dnsname.FQDN
|
||||||
wantIP netaddr.IP
|
wantIP netip.Addr
|
||||||
wantOK bool
|
wantOK bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -286,19 +286,19 @@ func TestRDNSNameToIPv6(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"double_dot",
|
"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.",
|
"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,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"double_hex",
|
"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.",
|
"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,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"not_hex",
|
"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.",
|
"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,
|
false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -329,27 +329,27 @@ func TestResolveLocal(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
qname dnsname.FQDN
|
qname dnsname.FQDN
|
||||||
qtype dns.Type
|
qtype dns.Type
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
code dns.RCode
|
code dns.RCode
|
||||||
}{
|
}{
|
||||||
{"ipv4", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
|
{"ipv4", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
|
||||||
{"ipv6", "test2.ipn.dev.", dns.TypeAAAA, testipv6, dns.RCodeSuccess},
|
{"ipv6", "test2.ipn.dev.", dns.TypeAAAA, testipv6, dns.RCodeSuccess},
|
||||||
{"no-ipv6", "test1.ipn.dev.", dns.TypeAAAA, netaddr.IP{}, dns.RCodeSuccess},
|
{"no-ipv6", "test1.ipn.dev.", dns.TypeAAAA, netip.Addr{}, dns.RCodeSuccess},
|
||||||
{"nxdomain", "test3.ipn.dev.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
|
{"nxdomain", "test3.ipn.dev.", dns.TypeA, netip.Addr{}, dns.RCodeNameError},
|
||||||
{"foreign domain", "google.com.", dns.TypeA, netaddr.IP{}, dns.RCodeRefused},
|
{"foreign domain", "google.com.", dns.TypeA, netip.Addr{}, dns.RCodeRefused},
|
||||||
{"all", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
|
{"all", "test1.ipn.dev.", dns.TypeA, testipv4, dns.RCodeSuccess},
|
||||||
{"mx-ipv4", "test1.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeSuccess},
|
{"mx-ipv4", "test1.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeSuccess},
|
||||||
{"mx-ipv6", "test2.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeSuccess},
|
{"mx-ipv6", "test2.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeSuccess},
|
||||||
{"mx-nxdomain", "test3.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeNameError},
|
{"mx-nxdomain", "test3.ipn.dev.", dns.TypeMX, netip.Addr{}, dns.RCodeNameError},
|
||||||
{"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netaddr.IP{}, dns.RCodeNameError},
|
{"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netip.Addr{}, dns.RCodeNameError},
|
||||||
{"onion-domain", "footest.onion.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError},
|
{"onion-domain", "footest.onion.", dns.TypeA, netip.Addr{}, dns.RCodeNameError},
|
||||||
{"magicdns", dnsSymbolicFQDN, dns.TypeA, netip.MustParseAddr("100.100.100.100"), dns.RCodeSuccess},
|
{"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_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},
|
{"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_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},
|
{"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", dnsname.FQDN("via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||||
{"via_invalid_2", dnsname.FQDN("2.3.4.5.via-."), dns.TypeAAAA, netaddr.IP{}, dns.RCodeRefused},
|
{"via_invalid_2", dnsname.FQDN("2.3.4.5.via-."), dns.TypeAAAA, netip.Addr{}, dns.RCodeRefused},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -1003,7 +1003,7 @@ func TestForwardLinkSelection(t *testing.T) {
|
|||||||
// routes differently.
|
// routes differently.
|
||||||
specialIP := netaddr.IPv4(1, 2, 3, 4)
|
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) {
|
if ip == netaddr.IPv4(1, 2, 3, 4) {
|
||||||
return "special"
|
return "special"
|
||||||
}
|
}
|
||||||
@ -1011,7 +1011,7 @@ func TestForwardLinkSelection(t *testing.T) {
|
|||||||
}), new(tsdial.Dialer))
|
}), new(tsdial.Dialer))
|
||||||
|
|
||||||
// Test non-special IP.
|
// 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)
|
t.Fatal(err)
|
||||||
} else if got != stdNetPacketListener {
|
} else if got != stdNetPacketListener {
|
||||||
t.Errorf("for IP zero value, didn't get expected packet listener")
|
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) {
|
func TestHandleExitNodeDNSQueryWithNetPkg(t *testing.T) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -62,7 +63,7 @@ type Resolver struct {
|
|||||||
|
|
||||||
// LookupIPFallback optionally provides a backup DNS mechanism
|
// LookupIPFallback optionally provides a backup DNS mechanism
|
||||||
// to use if Forward returns an error or no results.
|
// 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
|
// 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
|
// 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
|
// by Resolver.LookupIP for any hostname. When non-nil, SingleHost must also be
|
||||||
// set with the expected name.
|
// set with the expected name.
|
||||||
SingleHostStaticResult []netaddr.IP
|
SingleHostStaticResult []netip.Addr
|
||||||
|
|
||||||
// SingleHost is the hostname that SingleHostStaticResult is for.
|
// SingleHost is the hostname that SingleHostStaticResult is for.
|
||||||
// It is required when SingleHostStaticResult is present.
|
// 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 {
|
if (err != nil || len(ips) == 0) && r.LookupIPFallback != nil {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var fips []netaddr.IP
|
var fips []netip.Addr
|
||||||
fips, err = r.LookupIPFallback(ctx, host)
|
fips, err = r.LookupIPFallback(ctx, host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ips = nil
|
ips = nil
|
||||||
@ -344,7 +345,7 @@ func Dialer(fwd DialContextFunc, dnsCache *Resolver) DialContextFunc {
|
|||||||
d := &dialer{
|
d := &dialer{
|
||||||
fwd: fwd,
|
fwd: fwd,
|
||||||
dnsCache: dnsCache,
|
dnsCache: dnsCache,
|
||||||
pastConnect: map[netaddr.IP]time.Time{},
|
pastConnect: map[netip.Addr]time.Time{},
|
||||||
}
|
}
|
||||||
return d.DialContext
|
return d.DialContext
|
||||||
}
|
}
|
||||||
@ -355,7 +356,7 @@ type dialer struct {
|
|||||||
dnsCache *Resolver
|
dnsCache *Resolver
|
||||||
|
|
||||||
mu sync.Mutex
|
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) {
|
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
|
network, address, host, port string
|
||||||
|
|
||||||
mu sync.Mutex // lock ordering: dialer.mu, then dialCall.mu
|
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
|
// dnsWasTrustworthy reports whether we think the IP address(es) we
|
||||||
@ -453,7 +454,7 @@ func (dc *dialCall) dnsWasTrustworthy() bool {
|
|||||||
return false
|
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))
|
c, err := dc.d.fwd(ctx, dc.network, net.JoinHostPort(ip.String(), dc.port))
|
||||||
dc.noteDialResult(ip, err)
|
dc.noteDialResult(ip, err)
|
||||||
return c, 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
|
// noteDialResult records that a dial to ip either succeeded or
|
||||||
// failed.
|
// failed.
|
||||||
func (dc *dialCall) noteDialResult(ip netaddr.IP, err error) {
|
func (dc *dialCall) noteDialResult(ip netip.Addr, err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
d := dc.d
|
d := dc.d
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
@ -472,17 +473,17 @@ func (dc *dialCall) noteDialResult(ip netaddr.IP, err error) {
|
|||||||
dc.mu.Lock()
|
dc.mu.Lock()
|
||||||
defer dc.mu.Unlock()
|
defer dc.mu.Unlock()
|
||||||
if dc.fails == nil {
|
if dc.fails == nil {
|
||||||
dc.fails = map[netaddr.IP]error{}
|
dc.fails = map[netip.Addr]error{}
|
||||||
}
|
}
|
||||||
dc.fails[ip] = err
|
dc.fails[ip] = err
|
||||||
}
|
}
|
||||||
|
|
||||||
// uniqueIPs returns a possibly-mutated subslice of ips, filtering out
|
// uniqueIPs returns a possibly-mutated subslice of ips, filtering out
|
||||||
// dups and ones that have already failed previously.
|
// 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()
|
dc.mu.Lock()
|
||||||
defer dc.mu.Unlock()
|
defer dc.mu.Unlock()
|
||||||
seen := map[netaddr.IP]bool{}
|
seen := map[netip.Addr]bool{}
|
||||||
ret = ips[:0]
|
ret = ips[:0]
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if seen[ip] {
|
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
|
// raceDial tries to dial port on each ip in ips, starting a new race
|
||||||
// dial every fallbackDelay apart, returning whichever completes first.
|
// 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)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -536,7 +537,7 @@ type res struct {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
go func(ip netaddr.IP) {
|
go func(ip netip.Addr) {
|
||||||
c, err := dc.dialOne(ctx, ip)
|
c, err := dc.dialOne(ctx, ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Best effort wake-up a pending dial.
|
// 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 {
|
for _, a := range aa {
|
||||||
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is4() {
|
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is4() {
|
||||||
ret = append(ret, ip)
|
ret = append(ret, ip)
|
||||||
@ -589,7 +590,7 @@ func v4addrs(aa []net.IPAddr) (ret []netaddr.IP) {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func v6addrs(aa []net.IPAddr) (ret []netaddr.IP) {
|
func v6addrs(aa []net.IPAddr) (ret []netip.Addr) {
|
||||||
for _, a := range aa {
|
for _, a := range aa {
|
||||||
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is6() {
|
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is6() {
|
||||||
ret = append(ret, ip)
|
ret = append(ret, ip)
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var dialTest = flag.String("dial-test", "", "if non-empty, addr:port to test dial")
|
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) {
|
func TestDialCall_DNSWasTrustworthy(t *testing.T) {
|
||||||
type step struct {
|
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
|
err error // the dial error or nil for success
|
||||||
}
|
}
|
||||||
mustIP := netip.MustParseAddr
|
mustIP := netip.MustParseAddr
|
||||||
@ -73,7 +71,7 @@ type step struct {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
d := &dialer{
|
d := &dialer{
|
||||||
pastConnect: map[netaddr.IP]time.Time{},
|
pastConnect: map[netip.Addr]time.Time{},
|
||||||
}
|
}
|
||||||
dc := &dialCall{
|
dc := &dialCall{
|
||||||
d: d,
|
d: d,
|
||||||
@ -95,7 +93,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
|
|||||||
errFail := errors.New("some connect failure")
|
errFail := errors.New("some connect failure")
|
||||||
dc.noteDialResult(mustIP("2003::1"), errFail)
|
dc.noteDialResult(mustIP("2003::1"), errFail)
|
||||||
dc.noteDialResult(mustIP("2003::2"), errFail)
|
dc.noteDialResult(mustIP("2003::2"), errFail)
|
||||||
got := dc.uniqueIPs([]netaddr.IP{
|
got := dc.uniqueIPs([]netip.Addr{
|
||||||
mustIP("2003::1"),
|
mustIP("2003::1"),
|
||||||
mustIP("2003::2"),
|
mustIP("2003::2"),
|
||||||
mustIP("2003::2"),
|
mustIP("2003::2"),
|
||||||
@ -104,7 +102,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
|
|||||||
mustIP("2003::4"),
|
mustIP("2003::4"),
|
||||||
mustIP("2003::4"),
|
mustIP("2003::4"),
|
||||||
})
|
})
|
||||||
want := []netaddr.IP{
|
want := []netip.Addr{
|
||||||
mustIP("2003::3"),
|
mustIP("2003::3"),
|
||||||
mustIP("2003::4"),
|
mustIP("2003::4"),
|
||||||
}
|
}
|
||||||
@ -116,7 +114,7 @@ func TestDialCall_uniqueIPs(t *testing.T) {
|
|||||||
func TestResolverAllHostStaticResult(t *testing.T) {
|
func TestResolverAllHostStaticResult(t *testing.T) {
|
||||||
r := &Resolver{
|
r := &Resolver{
|
||||||
SingleHost: "foo.bar",
|
SingleHost: "foo.bar",
|
||||||
SingleHostStaticResult: []netaddr.IP{
|
SingleHostStaticResult: []netip.Addr{
|
||||||
netip.MustParseAddr("2001:4860:4860::8888"),
|
netip.MustParseAddr("2001:4860:4860::8888"),
|
||||||
netip.MustParseAddr("2001:4860:4860::8844"),
|
netip.MustParseAddr("2001:4860:4860::8844"),
|
||||||
netip.MustParseAddr("8.8.8.8"),
|
netip.MustParseAddr("8.8.8.8"),
|
||||||
|
@ -22,21 +22,20 @@
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/net/tlsdial"
|
"tailscale.com/net/tlsdial"
|
||||||
"tailscale.com/net/tshttpproxy"
|
"tailscale.com/net/tshttpproxy"
|
||||||
"tailscale.com/tailcfg"
|
"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() {
|
if ip, err := netip.ParseAddr(host); err == nil && ip.IsValid() {
|
||||||
return []netaddr.IP{ip}, nil
|
return []netip.Addr{ip}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nameIP struct {
|
type nameIP struct {
|
||||||
dnsName string
|
dnsName string
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
dm := getDERPMap()
|
dm := getDERPMap()
|
||||||
@ -94,7 +93,7 @@ type nameIP struct {
|
|||||||
|
|
||||||
// serverName and serverIP of are, say, "derpN.tailscale.com".
|
// serverName and serverIP of are, say, "derpN.tailscale.com".
|
||||||
// queryName is the name being sought (e.g. "controlplane.tailscale.com"), passed as hint.
|
// 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)
|
dialer := netns.NewDialer(log.Printf)
|
||||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
tr.Proxy = tshttpproxy.ProxyFromEnvironment
|
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:
|
// dnsMap is the JSON type returned by the DERP /bootstrap-dns handler:
|
||||||
// https://derp10.tailscale.com/bootstrap-dns
|
// 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
|
// getDERPMap returns some DERP map. The DERP servers also run a fallback
|
||||||
// DNS server.
|
// DNS server.
|
||||||
|
@ -13,16 +13,16 @@
|
|||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tuple is a 5-tuple of proto, source and destination IP and port.
|
// Tuple is a 5-tuple of proto, source and destination IP and port.
|
||||||
type Tuple struct {
|
type Tuple struct {
|
||||||
Proto ipproto.Proto
|
Proto ipproto.Proto
|
||||||
Src netaddr.IPPort
|
Src netip.AddrPort
|
||||||
Dst netaddr.IPPort
|
Dst netip.AddrPort
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Tuple) String() string {
|
func (t Tuple) String() string {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
// Tailscale returns the current machine's Tailscale interface, if any.
|
// Tailscale returns the current machine's Tailscale interface, if any.
|
||||||
// If none is found, all zero values are returned.
|
// If none is found, all zero values are returned.
|
||||||
// A non-nil error is only returned on a problem listing the system interfaces.
|
// 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()
|
ifs, err := netInterfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -41,7 +41,7 @@ func Tailscale() ([]netaddr.IP, *net.Interface, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var tsIPs []netaddr.IP
|
var tsIPs []netip.Addr
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
if ipnet, ok := a.(*net.IPNet); ok {
|
if ipnet, ok := a.(*net.IPNet); ok {
|
||||||
nip, ok := netaddr.FromStdIP(ipnet.IP)
|
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
|
// whether they're loopback addresses. If there are no regular addresses
|
||||||
// it will return any IPv4 linklocal or IPv6 unique local addresses because we
|
// 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.
|
// 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
|
// TODO(crawshaw): don't serve interface addresses that we are routing
|
||||||
ifaces, err := netInterfaces()
|
ifaces, err := netInterfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
var regular4, regular6, linklocal4, ula6 []netaddr.IP
|
var regular4, regular6, linklocal4, ula6 []netip.Addr
|
||||||
for _, iface := range ifaces {
|
for _, iface := range ifaces {
|
||||||
stdIf := iface.Interface
|
stdIf := iface.Interface
|
||||||
if !isUp(stdIf) || isProblematicInterface(stdIf) {
|
if !isUp(stdIf) || isProblematicInterface(stdIf) {
|
||||||
@ -165,7 +165,7 @@ func LocalAddresses() (regular, loopback []netaddr.IP, err error) {
|
|||||||
return regular, loopback, nil
|
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]) })
|
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
|
// ForeachInterfaceAddress is a wrapper for GetList, then
|
||||||
// List.ForeachInterfaceAddress.
|
// List.ForeachInterfaceAddress.
|
||||||
func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
|
func ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
|
||||||
ifaces, err := GetList()
|
ifaces, err := GetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -198,7 +198,7 @@ func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
|
|||||||
// ForeachInterfaceAddress calls fn for each interface in ifaces, with
|
// ForeachInterfaceAddress calls fn for each interface in ifaces, with
|
||||||
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
||||||
// the interface, and Bits are the subnet mask.
|
// 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 {
|
for _, iface := range ifaces {
|
||||||
addrs, err := iface.Addrs()
|
addrs, err := iface.Addrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -218,7 +218,7 @@ func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix))
|
|||||||
|
|
||||||
// ForeachInterface is a wrapper for GetList, then
|
// ForeachInterface is a wrapper for GetList, then
|
||||||
// List.ForeachInterface.
|
// List.ForeachInterface.
|
||||||
func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
|
func ForeachInterface(fn func(Interface, []netip.Prefix)) error {
|
||||||
ifaces, err := GetList()
|
ifaces, err := GetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -229,7 +229,7 @@ func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
|
|||||||
// ForeachInterface calls fn for each interface in ifaces, with
|
// ForeachInterface calls fn for each interface in ifaces, with
|
||||||
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
||||||
// the interface, and Bits are the subnet mask.
|
// 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()
|
ifaces, err := GetList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -239,7 +239,7 @@ func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var pfxs []netaddr.IPPrefix
|
var pfxs []netip.Prefix
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
switch v := a.(type) {
|
switch v := a.(type) {
|
||||||
case *net.IPNet:
|
case *net.IPNet:
|
||||||
@ -264,7 +264,7 @@ type State struct {
|
|||||||
// configured on that interface. Each address is represented as an
|
// configured on that interface. Each address is represented as an
|
||||||
// IPPrefix, where the IP is the interface IP address and Bits is
|
// IPPrefix, where the IP is the interface IP address and Bits is
|
||||||
// the subnet mask.
|
// the subnet mask.
|
||||||
InterfaceIPs map[string][]netaddr.IPPrefix
|
InterfaceIPs map[string][]netip.Prefix
|
||||||
Interface map[string]Interface
|
Interface map[string]Interface
|
||||||
|
|
||||||
// HaveV6 is whether this machine has an IPv6 Global or Unique Local Address
|
// 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.
|
// An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal.
|
||||||
// ips are all the IPPrefixes associated with i.
|
// 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.
|
// 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.
|
// 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,
|
// EqualFiltered reports whether s and s2 are equal,
|
||||||
// considering only interfaces in s for which filter returns true,
|
// 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))
|
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
|
// 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 {
|
for _, ipp := range ipps {
|
||||||
if useIP(ipp.Addr()) {
|
if useIP(ipp.Addr()) {
|
||||||
x = append(x, ipp)
|
x = append(x, ipp)
|
||||||
@ -421,11 +421,11 @@ func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
|
|||||||
return x
|
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))
|
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) {
|
if len(a) != len(b) {
|
||||||
return false
|
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.
|
// 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.
|
// 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.
|
// 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)
|
return !isTailscaleInterface(i.Name, ips) && anyInterestingIP(ips)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseInterestingIPs is an IPFilter that reports whether ip is an interesting IP address.
|
// 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.
|
// 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)
|
return isInterestingIP(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseAllInterfaces is an InterfaceFilter that includes all interfaces.
|
// 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.
|
// 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 != "" }
|
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)
|
return s != nil && (s.HaveV4 || s.HaveV6)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
|
func hasTailscaleIP(pfxs []netip.Prefix) bool {
|
||||||
for _, pfx := range pfxs {
|
for _, pfx := range pfxs {
|
||||||
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||||
return true
|
return true
|
||||||
@ -475,7 +475,7 @@ func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
|
|||||||
return false
|
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) {
|
if runtime.GOOS == "darwin" && strings.HasPrefix(name, "utun") && hasTailscaleIP(ips) {
|
||||||
// On macOS in the sandboxed app (at least as of
|
// On macOS in the sandboxed app (at least as of
|
||||||
// 2021-02-25), we often see two utun devices
|
// 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.
|
// It does not set the returned State.IsExpensive. The caller can populate that.
|
||||||
func GetState() (*State, error) {
|
func GetState() (*State, error) {
|
||||||
s := &State{
|
s := &State{
|
||||||
InterfaceIPs: make(map[string][]netaddr.IPPrefix),
|
InterfaceIPs: make(map[string][]netip.Prefix),
|
||||||
Interface: make(map[string]Interface),
|
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()
|
ifUp := ni.IsUp()
|
||||||
s.Interface[ni.Name] = ni
|
s.Interface[ni.Name] = ni
|
||||||
s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...)
|
s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...)
|
||||||
@ -556,7 +556,7 @@ func HTTPOfListener(ln net.Listener) string {
|
|||||||
|
|
||||||
var goodIP string
|
var goodIP string
|
||||||
var privateIP string
|
var privateIP string
|
||||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
|
||||||
ip := pfx.Addr()
|
ip := pfx.Addr()
|
||||||
if ip.IsPrivate() {
|
if ip.IsPrivate() {
|
||||||
if privateIP == "" {
|
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,
|
// LikelyHomeRouterIP returns the likely IP of the residential router,
|
||||||
// which will always be an IPv4 private address, if found.
|
// which will always be an IPv4 private address, if found.
|
||||||
// In addition, it returns the IP address of the current machine on
|
// In addition, it returns the IP address of the current machine on
|
||||||
// the LAN using that gateway.
|
// the LAN using that gateway.
|
||||||
// This is used as the destination for UPnP, NAT-PMP, PCP, etc queries.
|
// 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 {
|
if likelyHomeRouterIP != nil {
|
||||||
gateway, ok = likelyHomeRouterIP()
|
gateway, ok = likelyHomeRouterIP()
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -593,7 +593,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
|
||||||
ip := pfx.Addr()
|
ip := pfx.Addr()
|
||||||
if !i.IsUp() || !ip.IsValid() || myIP.IsValid() {
|
if !i.IsUp() || !ip.IsValid() || myIP.IsValid() {
|
||||||
return
|
return
|
||||||
@ -611,7 +611,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
|||||||
// conceivably be used to get Internet connectivity. Globally routable and
|
// conceivably be used to get Internet connectivity. Globally routable and
|
||||||
// private IPv4 addresses are always Usable, and link local 169.254.x.x
|
// private IPv4 addresses are always Usable, and link local 169.254.x.x
|
||||||
// addresses are in some environments.
|
// addresses are in some environments.
|
||||||
func isUsableV4(ip netaddr.IP) bool {
|
func isUsableV4(ip netip.Addr) bool {
|
||||||
if !ip.Is4() || ip.IsLoopback() {
|
if !ip.Is4() || ip.IsLoopback() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -625,7 +625,7 @@ func isUsableV4(ip netaddr.IP) bool {
|
|||||||
// conceivably be used to get Internet connectivity. Globally routable
|
// conceivably be used to get Internet connectivity. Globally routable
|
||||||
// IPv6 addresses are always Usable, and Unique Local Addresses
|
// IPv6 addresses are always Usable, and Unique Local Addresses
|
||||||
// (fc00::/7) are in some environments used with address translation.
|
// (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) ||
|
return v6Global1.Contains(ip) ||
|
||||||
(ip.Is6() && ip.IsPrivate() && !tsaddr.TailscaleULARange().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
|
// anyInterestingIP reports whether pfxs contains any IP that matches
|
||||||
// isInterestingIP.
|
// isInterestingIP.
|
||||||
func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
|
func anyInterestingIP(pfxs []netip.Prefix) bool {
|
||||||
for _, pfx := range pfxs {
|
for _, pfx := range pfxs {
|
||||||
if isInterestingIP(pfx.Addr()) {
|
if isInterestingIP(pfx.Addr()) {
|
||||||
return true
|
return true
|
||||||
@ -648,7 +648,7 @@ func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
|
|||||||
// isInterestingIP reports whether ip is an interesting IP that we
|
// isInterestingIP reports whether ip is an interesting IP that we
|
||||||
// should log in interfaces.State logging. We don't need to show
|
// should log in interfaces.State logging. We don't need to show
|
||||||
// localhost or link-local addresses.
|
// localhost or link-local addresses.
|
||||||
func isInterestingIP(ip netaddr.IP) bool {
|
func isInterestingIP(ip netip.Addr) bool {
|
||||||
return !ip.IsLoopback() && !ip.IsLinkLocalUnicast()
|
return !ip.IsLoopback() && !ip.IsLinkLocalUnicast()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +727,7 @@ func DefaultRoute() (DefaultRouteDetails, error) {
|
|||||||
func HasCGNATInterface() (bool, error) {
|
func HasCGNATInterface() (bool, error) {
|
||||||
hasCGNATInterface := false
|
hasCGNATInterface := false
|
||||||
cgnatRange := tsaddr.CGNATRange()
|
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) {
|
if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/net/route"
|
"golang.org/x/net/route"
|
||||||
@ -95,7 +96,7 @@ func init() {
|
|||||||
likelyHomeRouterIP = likelyHomeRouterIPBSDFetchRIB
|
likelyHomeRouterIP = likelyHomeRouterIPBSDFetchRIB
|
||||||
}
|
}
|
||||||
|
|
||||||
func likelyHomeRouterIPBSDFetchRIB() (ret netaddr.IP, ok bool) {
|
func likelyHomeRouterIPBSDFetchRIB() (ret netip.Addr, ok bool) {
|
||||||
rib, err := fetchRoutingTable()
|
rib, err := fetchRoutingTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("routerIP/FetchRIB: %v", err)
|
log.Printf("routerIP/FetchRIB: %v", err)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/net/route"
|
"golang.org/x/net/route"
|
||||||
@ -89,7 +90,7 @@ func init() {
|
|||||||
likelyHomeRouterIP = likelyHomeRouterIPDarwinFetchRIB
|
likelyHomeRouterIP = likelyHomeRouterIPDarwinFetchRIB
|
||||||
}
|
}
|
||||||
|
|
||||||
func likelyHomeRouterIPDarwinFetchRIB() (ret netaddr.IP, ok bool) {
|
func likelyHomeRouterIPDarwinFetchRIB() (ret netip.Addr, ok bool) {
|
||||||
rib, err := fetchRoutingTable()
|
rib, err := fetchRoutingTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("routerIP/FetchRIB: %v", err)
|
log.Printf("routerIP/FetchRIB: %v", err)
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/util/lineread"
|
"tailscale.com/util/lineread"
|
||||||
"tailscale.com/version"
|
"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() {
|
if version.IsMobile() {
|
||||||
// Don't try to do subprocesses on iOS. Ends up with log spam like:
|
// Don't try to do subprocesses on iOS. Ends up with log spam like:
|
||||||
// kernel: "Sandbox: IPNExtension(86580) deny(1) process-fork"
|
// 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 00000000 0100000A 0003 0 0 0 00000000 0 0 0
|
||||||
ens18 0000000A 00000000 0001 0 0 0 0000FFFF 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 procNetRouteErr.Get() {
|
||||||
// If we failed to read /proc/net/route previously, don't keep trying.
|
// If we failed to read /proc/net/route previously, don't keep trying.
|
||||||
// But if we're on Android, go into the Android path.
|
// 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
|
// Android apps don't have permission to read /proc/net/route, at
|
||||||
// least on Google devices and the Android emulator.
|
// 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")
|
cmd := exec.Command("/system/bin/ip", "route", "show", "table", "0")
|
||||||
out, err := cmd.StdoutPipe()
|
out, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetState(t *testing.T) {
|
func TestGetState(t *testing.T) {
|
||||||
@ -76,7 +74,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
|
|||||||
// has gained an "uninteresting" IP address.
|
// has gained an "uninteresting" IP address.
|
||||||
|
|
||||||
s1 := &State{
|
s1 := &State{
|
||||||
InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
|
InterfaceIPs: map[string][]netip.Prefix{"x": {
|
||||||
netip.MustParsePrefix("42.0.0.0/8"),
|
netip.MustParsePrefix("42.0.0.0/8"),
|
||||||
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
||||||
}},
|
}},
|
||||||
@ -84,7 +82,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s2 := &State{
|
s2 := &State{
|
||||||
InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
|
InterfaceIPs: map[string][]netip.Prefix{"x": {
|
||||||
netip.MustParsePrefix("42.0.0.0/8"),
|
netip.MustParsePrefix("42.0.0.0/8"),
|
||||||
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
||||||
netip.MustParsePrefix("127.0.0.0/8"), // loopback (added)
|
netip.MustParsePrefix("127.0.0.0/8"), // loopback (added)
|
||||||
@ -126,8 +124,8 @@ func TestStateString(t *testing.T) {
|
|||||||
Interface: &net.Interface{},
|
Interface: &net.Interface{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
InterfaceIPs: map[string][]netaddr.IPPrefix{
|
InterfaceIPs: map[string][]netip.Prefix{
|
||||||
"eth0": []netaddr.IPPrefix{
|
"eth0": []netip.Prefix{
|
||||||
netip.MustParsePrefix("10.0.0.2/8"),
|
netip.MustParsePrefix("10.0.0.2/8"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -27,7 +28,7 @@ func init() {
|
|||||||
getPAC = getPACWindows
|
getPAC = getPACWindows
|
||||||
}
|
}
|
||||||
|
|
||||||
func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
|
func likelyHomeRouterIPWindows() (ret netip.Addr, ok bool) {
|
||||||
rs, err := winipcfg.GetIPForwardTable2(windows.AF_INET)
|
rs, err := winipcfg.GetIPForwardTable2(windows.AF_INET)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("routerIP/GetIPForwardTable2 error: %v", err)
|
log.Printf("routerIP/GetIPForwardTable2 error: %v", err)
|
||||||
@ -94,7 +95,7 @@ func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
|
|||||||
|
|
||||||
if ret.IsValid() && !ret.IsPrivate() {
|
if ret.IsValid() && !ret.IsPrivate() {
|
||||||
// Default route has a non-private gateway
|
// Default route has a non-private gateway
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, ret.IsValid()
|
return ret, ret.IsValid()
|
||||||
|
@ -15,14 +15,8 @@
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
IP = netip.Addr
|
|
||||||
IPPort = netip.AddrPort
|
|
||||||
IPPrefix = netip.Prefix
|
|
||||||
)
|
|
||||||
|
|
||||||
// IPv4 returns the IP of the IPv4 address a.b.c.d.
|
// 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})
|
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.
|
// v6-mapped IPv4 address.
|
||||||
//
|
//
|
||||||
// It is equivalent to calling IPv6Raw(addr).Unmap().
|
// 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()
|
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.
|
// FromStdIP returns an IP from the standard library's IP type.
|
||||||
//
|
//
|
||||||
// If std is invalid, ok is false.
|
// 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
|
// returned, without the IPv6 wrapper. This is the common form returned by
|
||||||
// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
|
// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
|
||||||
// To convert a standard library IP without the implicit unmapping, use
|
// To convert a standard library IP without the implicit unmapping, use
|
||||||
// FromStdIPRaw.
|
// netip.AddrFromSlice.
|
||||||
func FromStdIP(std net.IP) (ip IP, ok bool) {
|
func FromStdIP(std net.IP) (ip netip.Addr, ok bool) {
|
||||||
ret, ok := FromStdIPRaw(std)
|
ret, ok := netip.AddrFromSlice(std)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ret, false
|
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.
|
// FromStdIPNet returns an IPPrefix from the standard library's IPNet type.
|
||||||
// If std is invalid, ok is false.
|
// 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)
|
ip, ok := FromStdIP(std.IP)
|
||||||
if !ok {
|
if !ok {
|
||||||
return IPPrefix{}, false
|
return netip.Prefix{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
|
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
|
||||||
// Invalid mask.
|
// Invalid mask.
|
||||||
return IPPrefix{}, false
|
return netip.Prefix{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
ones, bits := std.Mask.Size()
|
ones, bits := std.Mask.Size()
|
||||||
if ones == 0 && bits == 0 {
|
if ones == 0 && bits == 0 {
|
||||||
// IPPrefix does not support non-contiguous masks.
|
// IPPrefix does not support non-contiguous masks.
|
||||||
return IPPrefix{}, false
|
return netip.Prefix{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return netip.PrefixFrom(ip, ones), true
|
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
|
// FromStdAddr maps the components of a standard library TCPAddr or
|
||||||
// UDPAddr into an IPPort.
|
// 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)
|
ip, ok := FromStdIP(stdIP)
|
||||||
if !ok || port < 0 || port > math.MaxUint16 {
|
if !ok || port < 0 || port > math.MaxUint16 {
|
||||||
return
|
return
|
||||||
|
@ -211,7 +211,7 @@ func (c *Client) vlogf(format string, a ...any) {
|
|||||||
|
|
||||||
// handleHairSTUN reports whether pkt (from src) was our magic hairpin
|
// handleHairSTUN reports whether pkt (from src) was our magic hairpin
|
||||||
// probe packet that we sent to ourselves.
|
// 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
|
rs := c.curState
|
||||||
if rs == nil {
|
if rs == nil {
|
||||||
return false
|
return false
|
||||||
@ -234,7 +234,7 @@ func (c *Client) MakeNextReportFull() {
|
|||||||
c.nextFull = true
|
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)
|
c.vlogf("received STUN packet from %s", src)
|
||||||
|
|
||||||
if src.Addr().Is4() {
|
if src.Addr().Is4() {
|
||||||
@ -526,7 +526,7 @@ func (c *Client) readPackets(ctx context.Context, pc net.PacketConn) {
|
|||||||
type reportState struct {
|
type reportState struct {
|
||||||
c *Client
|
c *Client
|
||||||
hairTX stun.TxID
|
hairTX stun.TxID
|
||||||
gotHairSTUN chan netaddr.IPPort
|
gotHairSTUN chan netip.AddrPort
|
||||||
hairTimeout chan struct{} // closed on timeout
|
hairTimeout chan struct{} // closed on timeout
|
||||||
pc4 STUNConn
|
pc4 STUNConn
|
||||||
pc6 STUNConn
|
pc6 STUNConn
|
||||||
@ -538,7 +538,7 @@ type reportState struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
sentHairCheck bool
|
sentHairCheck bool
|
||||||
report *Report // to be returned by GetReport
|
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
|
gotEP4 string
|
||||||
timers []*time.Timer
|
timers []*time.Timer
|
||||||
}
|
}
|
||||||
@ -590,7 +590,7 @@ func (rs *reportState) probeWouldHelp(probe probe, node *tailcfg.DERPNode) bool
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *reportState) startHairCheckLocked(dst netaddr.IPPort) {
|
func (rs *reportState) startHairCheckLocked(dst netip.AddrPort) {
|
||||||
if rs.sentHairCheck || rs.incremental {
|
if rs.sentHairCheck || rs.incremental {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -642,9 +642,9 @@ func (rs *reportState) stopTimers() {
|
|||||||
// addNodeLatency updates rs to note that node's latency is d. If ipp
|
// 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
|
// is non-zero (for all but HTTPS replies), it's recorded as our UDP
|
||||||
// IP:port.
|
// 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
|
var ipPortStr string
|
||||||
if ipp != (netaddr.IPPort{}) {
|
if ipp != (netip.AddrPort{}) {
|
||||||
ipPortStr = net.JoinHostPort(ipp.Addr().String(), fmt.Sprint(ipp.Port()))
|
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{
|
rs := &reportState{
|
||||||
c: c,
|
c: c,
|
||||||
report: newReport(),
|
report: newReport(),
|
||||||
inFlight: map[stun.TxID]func(netaddr.IPPort){},
|
inFlight: map[stun.TxID]func(netip.AddrPort){},
|
||||||
hairTX: stun.NewTxID(), // random payload
|
hairTX: stun.NewTxID(), // random payload
|
||||||
gotHairSTUN: make(chan netaddr.IPPort, 1),
|
gotHairSTUN: make(chan netip.AddrPort, 1),
|
||||||
hairTimeout: make(chan struct{}),
|
hairTimeout: make(chan struct{}),
|
||||||
stopProbeCh: make(chan struct{}, 1),
|
stopProbeCh: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
@ -1008,20 +1008,20 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
d := c.timeNow().Sub(t0)
|
d := c.timeNow().Sub(t0)
|
||||||
rs.addNodeLatency(node, netaddr.IPPort{}, d)
|
rs.addNodeLatency(node, netip.AddrPort{}, d)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return nil
|
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)
|
metricHTTPSend.Add(1)
|
||||||
var result httpstat.Result
|
var result httpstat.Result
|
||||||
ctx, cancel := context.WithTimeout(httpstat.WithHTTPStat(ctx, &result), overallProbeTimeout)
|
ctx, cancel := context.WithTimeout(httpstat.WithHTTPStat(ctx, &result), overallProbeTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
var ip netaddr.IP
|
var ip netip.Addr
|
||||||
|
|
||||||
dc := derphttp.NewNetcheckClient(c.logf)
|
dc := derphttp.NewNetcheckClient(c.logf)
|
||||||
tlsConn, tcpConn, node, err := dc.DialRegionTLS(ctx, reg)
|
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 {
|
if ta, ok := tlsConn.RemoteAddr().(*net.TCPAddr); ok {
|
||||||
ip, _ = netaddr.FromStdIP(ta.IP)
|
ip, _ = netaddr.FromStdIP(ta.IP)
|
||||||
}
|
}
|
||||||
if ip == (netaddr.IP{}) {
|
if ip == (netip.Addr{}) {
|
||||||
return 0, ip, fmt.Errorf("no unexpected RemoteAddr %#v", tlsConn.RemoteAddr())
|
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
|
sent := time.Now() // after DNS lookup above
|
||||||
|
|
||||||
rs.mu.Lock()
|
rs.mu.Lock()
|
||||||
rs.inFlight[txID] = func(ipp netaddr.IPPort) {
|
rs.inFlight[txID] = func(ipp netip.AddrPort) {
|
||||||
rs.addNodeLatency(node, ipp, time.Since(sent))
|
rs.addNodeLatency(node, ipp, time.Since(sent))
|
||||||
cancelSet() // abort other nodes in this set
|
cancelSet() // abort other nodes in this set
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -17,7 +18,6 @@
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/stun"
|
"tailscale.com/net/stun"
|
||||||
"tailscale.com/net/stun/stuntest"
|
"tailscale.com/net/stun/stuntest"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -28,14 +28,14 @@ func TestHairpinSTUN(t *testing.T) {
|
|||||||
c := &Client{
|
c := &Client{
|
||||||
curState: &reportState{
|
curState: &reportState{
|
||||||
hairTX: tx,
|
hairTX: tx,
|
||||||
gotHairSTUN: make(chan netaddr.IPPort, 1),
|
gotHairSTUN: make(chan netip.AddrPort, 1),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
req := stun.Request(tx)
|
req := stun.Request(tx)
|
||||||
if !stun.Is(req) {
|
if !stun.Is(req) {
|
||||||
t.Fatal("expected STUN message")
|
t.Fatal("expected STUN message")
|
||||||
}
|
}
|
||||||
if !c.handleHairSTUNLocked(req, netaddr.IPPort{}) {
|
if !c.handleHairSTUNLocked(req, netip.AddrPort{}) {
|
||||||
t.Fatal("expected true")
|
t.Fatal("expected true")
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
@ -7,15 +7,14 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)
|
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)
|
||||||
|
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
Local, Remote netaddr.IPPort
|
Local, Remote netip.AddrPort
|
||||||
Pid int
|
Pid int
|
||||||
State string // TODO: type?
|
State string // TODO: type?
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
"net/netip"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -153,22 +154,22 @@ func state(v uint32) string {
|
|||||||
return fmt.Sprintf("unknown-state-%d", v)
|
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 {
|
if !endian.Big {
|
||||||
addr = bits.ReverseBytes32(addr)
|
addr = bits.ReverseBytes32(addr)
|
||||||
}
|
}
|
||||||
return netaddr.IPPortFrom(
|
return netip.AddrPortFrom(
|
||||||
netaddr.IPv4(byte(addr>>24), byte(addr>>16), byte(addr>>8), byte(addr)),
|
netaddr.IPv4(byte(addr>>24), byte(addr>>16), byte(addr>>8), byte(addr)),
|
||||||
port)
|
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)
|
ip := netaddr.IPFrom16(addr)
|
||||||
if scope != 0 {
|
if scope != 0 {
|
||||||
// TODO: something better here?
|
// TODO: something better here?
|
||||||
ip = ip.WithZone(fmt.Sprint(scope))
|
ip = ip.WithZone(fmt.Sprint(scope))
|
||||||
}
|
}
|
||||||
return netaddr.IPPortFrom(ip, port)
|
return netip.AddrPortFrom(ip, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
func port(v *uint32) uint16 {
|
func port(v *uint32) uint16 {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -16,19 +17,18 @@
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are
|
// protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are
|
||||||
// required to forward the specified routes.
|
// required to forward the specified routes.
|
||||||
// The state param must be specified.
|
// 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 {
|
if len(routes) == 0 {
|
||||||
// Nothing to route, so no need to warn.
|
// Nothing to route, so no need to warn.
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
localIPs := make(map[netaddr.IP]bool)
|
localIPs := make(map[netip.Addr]bool)
|
||||||
for _, addrs := range state.InterfaceIPs {
|
for _, addrs := range state.InterfaceIPs {
|
||||||
for _, pfx := range addrs {
|
for _, pfx := range addrs {
|
||||||
localIPs[pfx.Addr()] = true
|
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 an error if it is unable to determine if IP forwarding is enabled.
|
||||||
// It returns a warning describing configuration issues if IP forwarding is
|
// It returns a warning describing configuration issues if IP forwarding is
|
||||||
// non-functional or partly functional.
|
// 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" {
|
if runtime.GOOS != "linux" {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "dragonfly", "freebsd", "netbsd", "openbsd":
|
case "dragonfly", "freebsd", "netbsd", "openbsd":
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,8 +19,8 @@
|
|||||||
type IP4Header struct {
|
type IP4Header struct {
|
||||||
IPProto ipproto.Proto
|
IPProto ipproto.Proto
|
||||||
IPID uint16
|
IPID uint16
|
||||||
Src netaddr.IP
|
Src netip.Addr
|
||||||
Dst netaddr.IP
|
Dst netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len implements Header.
|
// Len implements Header.
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,8 +18,8 @@
|
|||||||
type IP6Header struct {
|
type IP6Header struct {
|
||||||
IPProto ipproto.Proto
|
IPProto ipproto.Proto
|
||||||
IPID uint32 // only lower 20 bits used
|
IPID uint32 // only lower 20 bits used
|
||||||
Src netaddr.IP
|
Src netip.Addr
|
||||||
Dst netaddr.IP
|
Dst netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len implements Header.
|
// Len implements Header.
|
||||||
|
@ -54,9 +54,9 @@ type Parsed struct {
|
|||||||
IPProto ipproto.Proto
|
IPProto ipproto.Proto
|
||||||
// SrcIP4 is the source address. Family matches IPVersion. Port is
|
// SrcIP4 is the source address. Family matches IPVersion. Port is
|
||||||
// valid iff IPProto == TCP || IPProto == UDP.
|
// valid iff IPProto == TCP || IPProto == UDP.
|
||||||
Src netaddr.IPPort
|
Src netip.AddrPort
|
||||||
// DstIP4 is the destination address. Family matches IPVersion.
|
// 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 is the packet's TCP flag bits. Valid iff IPProto == TCP.
|
||||||
TCPFlags TCPFlag
|
TCPFlags TCPFlag
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
)
|
)
|
||||||
@ -27,7 +26,7 @@
|
|||||||
Fragment = ipproto.Fragment
|
Fragment = ipproto.Fragment
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustIPPort(s string) netaddr.IPPort {
|
func mustIPPort(s string) netip.AddrPort {
|
||||||
ipp, err := netip.ParseAddrPort(s)
|
ipp, err := netip.ParseAddrPort(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"tailscale.com/net/flowtrack"
|
"tailscale.com/net/flowtrack"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/ipproto"
|
"tailscale.com/types/ipproto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,10 +36,10 @@
|
|||||||
// In the future it might also accept 16 byte IP flow src/dst IPs
|
// 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.
|
// after the header, if they're different than the IP-level ones.
|
||||||
type TailscaleRejectedHeader struct {
|
type TailscaleRejectedHeader struct {
|
||||||
IPSrc netaddr.IP // IPv4 or IPv6 header's src IP
|
IPSrc netip.Addr // IPv4 or IPv6 header's src IP
|
||||||
IPDst netaddr.IP // IPv4 or IPv6 header's dst IP
|
IPDst netip.Addr // IPv4 or IPv6 header's dst IP
|
||||||
Src netaddr.IPPort // rejected flow's src
|
Src netip.AddrPort // rejected flow's src
|
||||||
Dst netaddr.IPPort // rejected flow's dst
|
Dst netip.AddrPort // rejected flow's dst
|
||||||
Proto ipproto.Proto // proto that was rejected (TCP or UDP)
|
Proto ipproto.Proto // proto that was rejected (TCP or UDP)
|
||||||
Reason TailscaleRejectReason // why the connection was rejected
|
Reason TailscaleRejectReason // why the connection was rejected
|
||||||
|
|
||||||
@ -192,8 +192,8 @@ func (pp *Parsed) AsTailscaleRejectedHeader() (h TailscaleRejectedHeader, ok boo
|
|||||||
Reason: TailscaleRejectReason(p[2]),
|
Reason: TailscaleRejectReason(p[2]),
|
||||||
IPSrc: pp.Src.Addr(),
|
IPSrc: pp.Src.Addr(),
|
||||||
IPDst: pp.Dst.Addr(),
|
IPDst: pp.Dst.Addr(),
|
||||||
Src: netaddr.IPPortFrom(pp.Dst.Addr(), binary.BigEndian.Uint16(p[3:5])),
|
Src: netip.AddrPortFrom(pp.Dst.Addr(), binary.BigEndian.Uint16(p[3:5])),
|
||||||
Dst: netaddr.IPPortFrom(pp.Src.Addr(), binary.BigEndian.Uint16(p[5:7])),
|
Dst: netip.AddrPortFrom(pp.Src.Addr(), binary.BigEndian.Uint16(p[5:7])),
|
||||||
}
|
}
|
||||||
if len(p) > 7 {
|
if len(p) > 7 {
|
||||||
flags := p[7]
|
flags := p[7]
|
||||||
|
@ -9,8 +9,7 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/netip"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type upnpClient any
|
type upnpClient any
|
||||||
@ -23,9 +22,9 @@ func parseUPnPDiscoResponse([]byte) (uPnPDiscoResponse, error) {
|
|||||||
|
|
||||||
func (c *Client) getUPnPPortMapping(
|
func (c *Client) getUPnPPortMapping(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gw netaddr.IP,
|
gw netip.Addr,
|
||||||
internal netaddr.IPPort,
|
internal netip.AddrPort,
|
||||||
prevPort uint16,
|
prevPort uint16,
|
||||||
) (external netaddr.IPPort, ok bool) {
|
) (external netip.AddrPort, ok bool) {
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ func (d *TestIGD) TestUPnPPort() uint16 {
|
|||||||
return uint16(d.upnpConn.LocalAddr().(*net.UDPAddr).Port)
|
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
|
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)
|
d.inc(&d.counters.numPMPRecv)
|
||||||
if len(pkt) < 2 {
|
if len(pkt) < 2 {
|
||||||
return
|
return
|
||||||
@ -205,7 +206,7 @@ func (d *TestIGD) handlePMPQuery(pkt []byte, src netaddr.IPPort) {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *TestIGD) handlePCPQuery(pkt []byte, src netaddr.IPPort) {
|
func (d *TestIGD) handlePCPQuery(pkt []byte, src netip.AddrPort) {
|
||||||
d.inc(&d.counters.numPCPRecv)
|
d.inc(&d.counters.numPCPRecv)
|
||||||
if len(pkt) < 24 {
|
if len(pkt) < 24 {
|
||||||
return
|
return
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
"tailscale.com/net/netaddr"
|
||||||
@ -49,9 +50,9 @@
|
|||||||
|
|
||||||
type pcpMapping struct {
|
type pcpMapping struct {
|
||||||
c *Client
|
c *Client
|
||||||
gw netaddr.IPPort
|
gw netip.AddrPort
|
||||||
internal netaddr.IPPort
|
internal netip.AddrPort
|
||||||
external netaddr.IPPort
|
external netip.AddrPort
|
||||||
|
|
||||||
renewAfter time.Time
|
renewAfter time.Time
|
||||||
goodUntil time.Time
|
goodUntil time.Time
|
||||||
@ -62,7 +63,7 @@ type pcpMapping struct {
|
|||||||
|
|
||||||
func (p *pcpMapping) GoodUntil() time.Time { return p.goodUntil }
|
func (p *pcpMapping) GoodUntil() time.Time { return p.goodUntil }
|
||||||
func (p *pcpMapping) RenewAfter() time.Time { return p.renewAfter }
|
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) {
|
func (p *pcpMapping) Release(ctx context.Context) {
|
||||||
uc, err := p.c.listenPacket(ctx, "udp4", ":0")
|
uc, err := p.c.listenPacket(ctx, "udp4", ":0")
|
||||||
if err != nil {
|
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 prevPort is not known, it should be set to 0.
|
||||||
// If prevExternalIP is not known, it should be set to 0.0.0.0.
|
// If prevExternalIP is not known, it should be set to 0.0.0.0.
|
||||||
func buildPCPRequestMappingPacket(
|
func buildPCPRequestMappingPacket(
|
||||||
myIP netaddr.IP,
|
myIP netip.Addr,
|
||||||
localPort, prevPort uint16,
|
localPort, prevPort uint16,
|
||||||
lifetimeSec uint32,
|
lifetimeSec uint32,
|
||||||
prevExternalIP netaddr.IP,
|
prevExternalIP netip.Addr,
|
||||||
) (pkt []byte) {
|
) (pkt []byte) {
|
||||||
// 24 byte common PCP header + 36 bytes of MAP-specific fields
|
// 24 byte common PCP header + 36 bytes of MAP-specific fields
|
||||||
pkt = make([]byte, 24+36)
|
pkt = make([]byte, 24+36)
|
||||||
@ -127,7 +128,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
|
|||||||
copy(externalIPBytes[:], resp[44:])
|
copy(externalIPBytes[:], resp[44:])
|
||||||
externalIP := netaddr.IPFrom16(externalIPBytes)
|
externalIP := netaddr.IPFrom16(externalIPBytes)
|
||||||
|
|
||||||
external := netaddr.IPPortFrom(externalIP, externalPort)
|
external := netip.AddrPortFrom(externalIP, externalPort)
|
||||||
|
|
||||||
lifetime := time.Second * time.Duration(res.Lifetime)
|
lifetime := time.Second * time.Duration(res.Lifetime)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -141,7 +142,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pcpAnnounceRequest generates a PCP packet with an ANNOUNCE opcode.
|
// 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
|
// See https://tools.ietf.org/html/rfc6887#section-7.1
|
||||||
pkt := make([]byte, 24)
|
pkt := make([]byte, 24)
|
||||||
pkt[0] = pcpVersion
|
pkt[0] = pcpVersion
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
// Client is a port mapping client.
|
// Client is a port mapping client.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
ipAndGateway func() (gw, ip netaddr.IP, ok bool)
|
ipAndGateway func() (gw, ip netip.Addr, ok bool)
|
||||||
onChange func() // or nil
|
onChange func() // or nil
|
||||||
testPxPPort uint16 // if non-zero, pxpPort to use for tests
|
testPxPPort uint16 // if non-zero, pxpPort to use for tests
|
||||||
testUPnPPort uint16 // if non-zero, uPnPPort 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).
|
// off a createMapping goroutine).
|
||||||
runningCreate bool
|
runningCreate bool
|
||||||
|
|
||||||
lastMyIP netaddr.IP
|
lastMyIP netip.Addr
|
||||||
lastGW netaddr.IP
|
lastGW netip.Addr
|
||||||
closed bool
|
closed bool
|
||||||
|
|
||||||
lastProbe time.Time
|
lastProbe time.Time
|
||||||
|
|
||||||
pmpPubIP netaddr.IP // non-zero if known
|
pmpPubIP netip.Addr // non-zero if known
|
||||||
pmpPubIPTime time.Time // time pmpPubIP last verified
|
pmpPubIPTime time.Time // time pmpPubIP last verified
|
||||||
pmpLastEpoch uint32
|
pmpLastEpoch uint32
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ type mapping interface {
|
|||||||
// renewAfter returns the earliest time that the mapping should be renewed.
|
// renewAfter returns the earliest time that the mapping should be renewed.
|
||||||
RenewAfter() time.Time
|
RenewAfter() time.Time
|
||||||
// externalIPPort indicates what port the mapping can be reached from on the outside.
|
// 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.
|
// HaveMapping reports whether we have a current valid mapping.
|
||||||
@ -120,9 +120,9 @@ func (c *Client) HaveMapping() bool {
|
|||||||
// All fields are immutable once created.
|
// All fields are immutable once created.
|
||||||
type pmpMapping struct {
|
type pmpMapping struct {
|
||||||
c *Client
|
c *Client
|
||||||
gw netaddr.IPPort
|
gw netip.AddrPort
|
||||||
external netaddr.IPPort
|
external netip.AddrPort
|
||||||
internal netaddr.IPPort
|
internal netip.AddrPort
|
||||||
renewAfter time.Time // the time at which we want to renew the mapping
|
renewAfter time.Time // the time at which we want to renew the mapping
|
||||||
goodUntil time.Time // the mapping's total lifetime
|
goodUntil time.Time // the mapping's total lifetime
|
||||||
epoch uint32
|
epoch uint32
|
||||||
@ -135,7 +135,7 @@ func (m *pmpMapping) externalValid() bool {
|
|||||||
|
|
||||||
func (p *pmpMapping) GoodUntil() time.Time { return p.goodUntil }
|
func (p *pmpMapping) GoodUntil() time.Time { return p.goodUntil }
|
||||||
func (p *pmpMapping) RenewAfter() time.Time { return p.renewAfter }
|
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.
|
// Release does a best effort fire-and-forget release of the PMP mapping m.
|
||||||
func (m *pmpMapping) Release(ctx context.Context) {
|
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
|
// 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.
|
// the primary IP address for that gateway. It must be called before the client is used.
|
||||||
// If not called, interfaces.LikelyHomeRouterIP 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
|
c.ipAndGateway = f
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,11 +203,11 @@ func (c *Client) SetLocalPort(localPort uint16) {
|
|||||||
c.invalidateMappingsLocked(true)
|
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()
|
gw, myIP, ok = c.ipAndGateway()
|
||||||
if !ok {
|
if !ok {
|
||||||
gw = netaddr.IP{}
|
gw = netip.Addr{}
|
||||||
myIP = netaddr.IP{}
|
myIP = netip.Addr{}
|
||||||
}
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
@ -273,7 +273,7 @@ func (c *Client) invalidateMappingsLocked(releaseOld bool) {
|
|||||||
}
|
}
|
||||||
c.mapping = nil
|
c.mapping = nil
|
||||||
}
|
}
|
||||||
c.pmpPubIP = netaddr.IP{}
|
c.pmpPubIP = netip.Addr{}
|
||||||
c.pmpPubIPTime = time.Time{}
|
c.pmpPubIPTime = time.Time{}
|
||||||
c.pcpSawTime = time.Time{}
|
c.pcpSawTime = time.Time{}
|
||||||
c.uPnPSawTime = 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 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
|
// If the background goroutine ends up creating one, the onChange hook registered with the
|
||||||
// NewClient constructor (if any) will fire.
|
// 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()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ func (c *Client) GetCachedMappingOrStartCreatingOne() (external netaddr.IPPort,
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.maybeStartMappingLocked()
|
c.maybeStartMappingLocked()
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybeStartMappingLocked starts a createMapping goroutine up, if one isn't already running.
|
// 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
|
// If no mapping is available, the error will be of type
|
||||||
// NoMappingError; see IsNoMappingError.
|
// 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 {
|
if DisableUPnP && DisablePCP && DisablePMP {
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
|
return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
|
||||||
}
|
}
|
||||||
gw, myIP, ok := c.gatewayAndSelfIP()
|
gw, myIP, ok := c.gatewayAndSelfIP()
|
||||||
if !ok {
|
if !ok {
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrGatewayRange}
|
return netip.AddrPort{}, NoMappingError{ErrGatewayRange}
|
||||||
}
|
}
|
||||||
if gw.Is6() {
|
if gw.Is6() {
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrGatewayIPv6}
|
return netip.AddrPort{}, NoMappingError{ErrGatewayIPv6}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
localPort := c.localPort
|
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
|
// 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.
|
// 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 {
|
if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
|
||||||
return external, nil
|
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
|
// 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.
|
// construct it upon receiving that packet.
|
||||||
m := &pmpMapping{
|
m := &pmpMapping{
|
||||||
c: c,
|
c: c,
|
||||||
gw: netaddr.IPPortFrom(gw, c.pxpPort()),
|
gw: netip.AddrPortFrom(gw, c.pxpPort()),
|
||||||
internal: internalAddr,
|
internal: internalAddr,
|
||||||
}
|
}
|
||||||
if haveRecentPMP {
|
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 {
|
if external, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
|
||||||
return external, nil
|
return external, nil
|
||||||
}
|
}
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
|
return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
|
||||||
}
|
}
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|
||||||
uc, err := c.listenPacket(ctx, "udp4", ":0")
|
uc, err := c.listenPacket(ctx, "udp4", ":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
defer uc.Close()
|
defer uc.Close()
|
||||||
|
|
||||||
uc.SetReadDeadline(time.Now().Add(portMapServiceTimeout))
|
uc.SetReadDeadline(time.Now().Add(portMapServiceTimeout))
|
||||||
defer closeCloserOnContextDone(ctx, uc)()
|
defer closeCloserOnContextDone(ctx, uc)()
|
||||||
|
|
||||||
pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
|
pxpAddr := netip.AddrPortFrom(gw, c.pxpPort())
|
||||||
|
|
||||||
preferPCP := !DisablePCP && (DisablePMP || (!haveRecentPMP && haveRecentPCP))
|
preferPCP := !DisablePCP && (DisablePMP || (!haveRecentPMP && haveRecentPCP))
|
||||||
|
|
||||||
@ -495,7 +495,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
|||||||
if neterror.TreatAsLostUDP(err) {
|
if neterror.TreatAsLostUDP(err) {
|
||||||
err = NoMappingError{ErrNoPortMappingServices}
|
err = NoMappingError{ErrNoPortMappingServices}
|
||||||
}
|
}
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ask for our external address if needed.
|
// 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) {
|
if neterror.TreatAsLostUDP(err) {
|
||||||
err = NoMappingError{ErrNoPortMappingServices}
|
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) {
|
if neterror.TreatAsLostUDP(err) {
|
||||||
err = NoMappingError{ErrNoPortMappingServices}
|
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)
|
n, srci, err := uc.ReadFrom(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ctx.Err() == context.Canceled {
|
if ctx.Err() == context.Canceled {
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
// fallback to UPnP portmapping
|
// fallback to UPnP portmapping
|
||||||
if mapping, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
|
if mapping, ok := c.getUPnPPortMapping(ctx, gw, internalAddr, prevPort); ok {
|
||||||
return mapping, nil
|
return mapping, nil
|
||||||
}
|
}
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
|
return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
|
||||||
}
|
}
|
||||||
srcu := srci.(*net.UDPAddr)
|
srcu := srci.(*net.UDPAddr)
|
||||||
src, ok := netaddr.FromStdAddr(srcu.IP, srcu.Port, srcu.Zone)
|
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
|
continue
|
||||||
}
|
}
|
||||||
if pres.ResultCode != 0 {
|
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 {
|
if pres.OpCode == pmpOpReply|pmpOpMapPublicAddr {
|
||||||
m.external = netip.AddrPortFrom(pres.PublicAddr, m.external.Port())
|
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 {
|
if err != nil {
|
||||||
c.logf("failed to get PCP mapping: %v", err)
|
c.logf("failed to get PCP mapping: %v", err)
|
||||||
// PCP should only have a single packet response
|
// PCP should only have a single packet response
|
||||||
return netaddr.IPPort{}, NoMappingError{ErrNoPortMappingServices}
|
return netip.AddrPort{}, NoMappingError{ErrNoPortMappingServices}
|
||||||
}
|
}
|
||||||
pcpMapping.c = c
|
pcpMapping.c = c
|
||||||
pcpMapping.internal = m.internal
|
pcpMapping.internal = m.internal
|
||||||
pcpMapping.gw = netaddr.IPPortFrom(gw, c.pxpPort())
|
pcpMapping.gw = netip.AddrPortFrom(gw, c.pxpPort())
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
c.mapping = pcpMapping
|
c.mapping = pcpMapping
|
||||||
return pcpMapping.external, nil
|
return pcpMapping.external, nil
|
||||||
default:
|
default:
|
||||||
c.logf("unknown PMP/PCP version number: %d %v", version, res[:n])
|
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
|
ExternalPort uint16
|
||||||
|
|
||||||
// For public addr ops:
|
// For public addr ops:
|
||||||
PublicAddr netaddr.IP
|
PublicAddr netip.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePMPResponse(pkt []byte) (res pmpResponse, ok bool) {
|
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 cancel()
|
||||||
defer closeCloserOnContextDone(ctx, uc)()
|
defer closeCloserOnContextDone(ctx, uc)()
|
||||||
|
|
||||||
pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
|
pxpAddr := netip.AddrPortFrom(gw, c.pxpPort())
|
||||||
upnpAddr := netaddr.IPPortFrom(gw, c.upnpPort())
|
upnpAddr := netip.AddrPortFrom(gw, c.upnpPort())
|
||||||
upnpMulticastAddr := netaddr.IPPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort())
|
upnpMulticastAddr := netip.AddrPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort())
|
||||||
|
|
||||||
// Don't send probes to services that we recently learned (for
|
// Don't send probes to services that we recently learned (for
|
||||||
// the same gw/myIP) are available. See
|
// the same gw/myIP) are available. See
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
"github.com/tailscale/goupnp"
|
"github.com/tailscale/goupnp"
|
||||||
"github.com/tailscale/goupnp/dcps/internetgateway2"
|
"github.com/tailscale/goupnp/dcps/internetgateway2"
|
||||||
"tailscale.com/control/controlknobs"
|
"tailscale.com/control/controlknobs"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/netns"
|
"tailscale.com/net/netns"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
@ -36,9 +35,9 @@
|
|||||||
// upnpMapping is a port mapping over the upnp protocol. After being created it is immutable,
|
// 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.
|
// but the client field may be shared across mapping instances.
|
||||||
type upnpMapping struct {
|
type upnpMapping struct {
|
||||||
gw netaddr.IP
|
gw netip.Addr
|
||||||
external netaddr.IPPort
|
external netip.AddrPort
|
||||||
internal netaddr.IPPort
|
internal netip.AddrPort
|
||||||
goodUntil time.Time
|
goodUntil time.Time
|
||||||
renewAfter time.Time
|
renewAfter time.Time
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ type upnpMapping struct {
|
|||||||
|
|
||||||
func (u *upnpMapping) GoodUntil() time.Time { return u.goodUntil }
|
func (u *upnpMapping) GoodUntil() time.Time { return u.goodUntil }
|
||||||
func (u *upnpMapping) RenewAfter() time.Time { return u.renewAfter }
|
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) {
|
func (u *upnpMapping) Release(ctx context.Context) {
|
||||||
u.client.DeletePortMapping(ctx, "", u.external.Port(), "udp")
|
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
|
// The provided ctx is not retained in the returned upnpClient, but
|
||||||
// its associated HTTP client is (if set via goupnp.WithHTTPClient).
|
// 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 {
|
if controlknobs.DisableUPnP() || DisableUPnP {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -233,12 +232,12 @@ func (c *Client) upnpHTTPClientLocked() *http.Client {
|
|||||||
// port and an error.
|
// port and an error.
|
||||||
func (c *Client) getUPnPPortMapping(
|
func (c *Client) getUPnPPortMapping(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
gw netaddr.IP,
|
gw netip.Addr,
|
||||||
internal netaddr.IPPort,
|
internal netip.AddrPort,
|
||||||
prevPort uint16,
|
prevPort uint16,
|
||||||
) (external netaddr.IPPort, ok bool) {
|
) (external netip.AddrPort, ok bool) {
|
||||||
if controlknobs.DisableUPnP() || DisableUPnP {
|
if controlknobs.DisableUPnP() || DisableUPnP {
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
upnp := &upnpMapping{
|
upnp := &upnpMapping{
|
||||||
@ -262,11 +261,11 @@ func (c *Client) getUPnPPortMapping(
|
|||||||
c.logf("getUPnPClient: %T, %v", client, err)
|
c.logf("getUPnPClient: %T, %v", client, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
var newPort uint16
|
var newPort uint16
|
||||||
@ -282,7 +281,7 @@ func (c *Client) getUPnPPortMapping(
|
|||||||
c.logf("addAnyPortMapping: %v, %v", newPort, err)
|
c.logf("addAnyPortMapping: %v, %v", newPort, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
// TODO cache this ip somewhere?
|
// TODO cache this ip somewhere?
|
||||||
extIP, err := client.GetExternalIPAddress(ctx)
|
extIP, err := client.GetExternalIPAddress(ctx)
|
||||||
@ -291,14 +290,14 @@ func (c *Client) getUPnPPortMapping(
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO this doesn't seem right
|
// TODO this doesn't seem right
|
||||||
return netaddr.IPPort{}, false
|
return netip.AddrPort{}, false
|
||||||
}
|
}
|
||||||
externalIP, err := netip.ParseAddr(extIP)
|
externalIP, err := netip.ParseAddr(extIP)
|
||||||
if err != nil {
|
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
|
d := time.Duration(pmpMapLifetimeSec) * time.Second
|
||||||
upnp.goodUntil = now.Add(d)
|
upnp.goodUntil = now.Add(d)
|
||||||
upnp.renewAfter = now.Add(d / 2)
|
upnp.renewAfter = now.Add(d / 2)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
|
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
|
||||||
// ChromeOS to interconnect the host OS to containers and VMs. We
|
// ChromeOS to interconnect the host OS to containers and VMs. We
|
||||||
// avoid allocating Tailscale IPs from it, to avoid conflicts.
|
// 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") })
|
chromeOSRange.Do(func() { mustPrefix(&chromeOSRange.v, "100.115.92.0/23") })
|
||||||
return chromeOSRange.v
|
return chromeOSRange.v
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ func ChromeOSVMRange() netaddr.IPPrefix {
|
|||||||
// is the superset range that Tailscale assigns out of.
|
// is the superset range that Tailscale assigns out of.
|
||||||
// See https://tailscale.com/kb/1015/100.x-addresses.
|
// See https://tailscale.com/kb/1015/100.x-addresses.
|
||||||
// Note that Tailscale does not assign out of the ChromeOSVMRange.
|
// 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") })
|
cgnatRange.Do(func() { mustPrefix(&cgnatRange.v, "100.64.0.0/10") })
|
||||||
return cgnatRange.v
|
return cgnatRange.v
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ func CGNATRange() netaddr.IPPrefix {
|
|||||||
// provided by Tailscale itself such as the MagicDNS proxy.
|
// provided by Tailscale itself such as the MagicDNS proxy.
|
||||||
//
|
//
|
||||||
// For IPv6, use TailscaleServiceIPv6.
|
// 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
|
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.
|
// provided by Tailscale itself such as the MagicDNS proxy.
|
||||||
//
|
//
|
||||||
// For IPv4, use TailscaleServiceIP.
|
// For IPv4, use TailscaleServiceIP.
|
||||||
func TailscaleServiceIPv6() netaddr.IP {
|
func TailscaleServiceIPv6() netip.Addr {
|
||||||
serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, "fd7a:115c:a1e0::53/128") })
|
serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, "fd7a:115c:a1e0::53/128") })
|
||||||
return serviceIPv6.v.Addr()
|
return serviceIPv6.v.Addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTailscaleIP reports whether ip is an IP address in a range that
|
// IsTailscaleIP reports whether ip is an IP address in a range that
|
||||||
// Tailscale assigns from.
|
// Tailscale assigns from.
|
||||||
func IsTailscaleIP(ip netaddr.IP) bool {
|
func IsTailscaleIP(ip netip.Addr) bool {
|
||||||
if ip.Is4() {
|
if ip.Is4() {
|
||||||
return CGNATRange().Contains(ip) && !ChromeOSVMRange().Contains(ip)
|
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
|
// TailscaleULARange returns the IPv6 Unique Local Address range that
|
||||||
// is the superset range that Tailscale assigns out of.
|
// 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") })
|
tsUlaRange.Do(func() { mustPrefix(&tsUlaRange.v, "fd7a:115c:a1e0::/48") })
|
||||||
return tsUlaRange.v
|
return tsUlaRange.v
|
||||||
}
|
}
|
||||||
|
|
||||||
// TailscaleViaRange returns the IPv6 Unique Local Address subset range
|
// TailscaleViaRange returns the IPv6 Unique Local Address subset range
|
||||||
// TailscaleULARange that's used for IPv4 tunneling via IPv6.
|
// TailscaleULARange that's used for IPv4 tunneling via IPv6.
|
||||||
func TailscaleViaRange() netaddr.IPPrefix {
|
func TailscaleViaRange() netip.Prefix {
|
||||||
// Mnemonic: "b1a" sounds like "via".
|
// Mnemonic: "b1a" sounds like "via".
|
||||||
tsViaRange.Do(func() { mustPrefix(&tsViaRange.v, "fd7a:115c:a1e0:b1a::/64") })
|
tsViaRange.Do(func() { mustPrefix(&tsViaRange.v, "fd7a:115c:a1e0:b1a::/64") })
|
||||||
return tsViaRange.v
|
return tsViaRange.v
|
||||||
@ -86,7 +86,7 @@ func TailscaleViaRange() netaddr.IPPrefix {
|
|||||||
|
|
||||||
// Tailscale4To6Range returns the subset of TailscaleULARange used for
|
// Tailscale4To6Range returns the subset of TailscaleULARange used for
|
||||||
// auto-translated Tailscale ipv4 addresses.
|
// auto-translated Tailscale ipv4 addresses.
|
||||||
func Tailscale4To6Range() netaddr.IPPrefix {
|
func Tailscale4To6Range() netip.Prefix {
|
||||||
// This IP range has no significance, beyond being a subset of
|
// This IP range has no significance, beyond being a subset of
|
||||||
// TailscaleULARange. The bits from /48 to /104 were picked at
|
// TailscaleULARange. The bits from /48 to /104 were picked at
|
||||||
// random.
|
// random.
|
||||||
@ -96,7 +96,7 @@ func Tailscale4To6Range() netaddr.IPPrefix {
|
|||||||
|
|
||||||
// TailscaleEphemeral6Range returns the subset of TailscaleULARange
|
// TailscaleEphemeral6Range returns the subset of TailscaleULARange
|
||||||
// used for ephemeral IPv6-only Tailscale nodes.
|
// 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
|
// This IP range has no significance, beyond being a subset of
|
||||||
// TailscaleULARange. The bits from /48 to /64 were picked at
|
// TailscaleULARange. The bits from /48 to /64 were picked at
|
||||||
// random, with the only criterion being to not be the conflict
|
// 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
|
// Currently used to work around a Windows limitation when programming
|
||||||
// IPv6 routes in corner cases.
|
// IPv6 routes in corner cases.
|
||||||
func Tailscale4To6Placeholder() netaddr.IP {
|
func Tailscale4To6Placeholder() netip.Addr {
|
||||||
return Tailscale4To6Range().Addr()
|
return Tailscale4To6Range().Addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tailscale4To6 returns a Tailscale IPv6 address that maps 1:1 to the
|
// 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
|
// given Tailscale IPv4 address. Returns a zero IP if ipv4 isn't a
|
||||||
// Tailscale IPv4 address.
|
// Tailscale IPv4 address.
|
||||||
func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
|
func Tailscale4To6(ipv4 netip.Addr) netip.Addr {
|
||||||
if !ipv4.Is4() || !IsTailscaleIP(ipv4) {
|
if !ipv4.Is4() || !IsTailscaleIP(ipv4) {
|
||||||
return netaddr.IP{}
|
return netip.Addr{}
|
||||||
}
|
}
|
||||||
ret := Tailscale4To6Range().Addr().As16()
|
ret := Tailscale4To6Range().Addr().As16()
|
||||||
v4 := ipv4.As4()
|
v4 := ipv4.As4()
|
||||||
@ -133,15 +133,15 @@ func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
|
|||||||
// tailscale IPv6 address within the 4To6 range. The IPv4 address
|
// tailscale IPv6 address within the 4To6 range. The IPv4 address
|
||||||
// and true are returned if the given address was in the correct range,
|
// and true are returned if the given address was in the correct range,
|
||||||
// false if not.
|
// 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) {
|
if !ipv6.Is6() || !Tailscale4To6Range().Contains(ipv6) {
|
||||||
return netaddr.IP{}, false
|
return netip.Addr{}, false
|
||||||
}
|
}
|
||||||
v6 := ipv6.As16()
|
v6 := ipv6.As16()
|
||||||
return netaddr.IPv4(100, v6[13], v6[14], v6[15]), true
|
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
|
var err error
|
||||||
*v, err = netip.ParsePrefix(prefix)
|
*v, err = netip.ParsePrefix(prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -151,7 +151,7 @@ func mustPrefix(v *netaddr.IPPrefix, prefix string) {
|
|||||||
|
|
||||||
type oncePrefix struct {
|
type oncePrefix struct {
|
||||||
sync.Once
|
sync.Once
|
||||||
v netaddr.IPPrefix
|
v netip.Prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContainsIPFunc returns a func that reports whether ip is in addrs.
|
// NewContainsIPFunc returns a func that reports whether ip is in addrs.
|
||||||
@ -161,11 +161,11 @@ type oncePrefix struct {
|
|||||||
// one IPv6 address).
|
// one IPv6 address).
|
||||||
//
|
//
|
||||||
// Otherwise the implementation is somewhat slow.
|
// 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
|
// Specialize the three common cases: no address, just IPv4
|
||||||
// (or just IPv6), and both IPv4 and IPv6.
|
// (or just IPv6), and both IPv4 and IPv6.
|
||||||
if len(addrs) == 0 {
|
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
|
// If any addr is more than a single IP, then just do the slow
|
||||||
// linear thing until
|
// linear thing until
|
||||||
@ -174,8 +174,8 @@ func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
|
|||||||
if a.IsSingleIP() {
|
if a.IsSingleIP() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
acopy := append([]netaddr.IPPrefix(nil), addrs...)
|
acopy := append([]netip.Prefix(nil), addrs...)
|
||||||
return func(ip netaddr.IP) bool {
|
return func(ip netip.Addr) bool {
|
||||||
for _, a := range acopy {
|
for _, a := range acopy {
|
||||||
if a.Contains(ip) {
|
if a.Contains(ip) {
|
||||||
return true
|
return true
|
||||||
@ -187,23 +187,23 @@ func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
|
|||||||
// Fast paths for 1 and 2 IPs:
|
// Fast paths for 1 and 2 IPs:
|
||||||
if len(addrs) == 1 {
|
if len(addrs) == 1 {
|
||||||
a := addrs[0]
|
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 {
|
if len(addrs) == 2 {
|
||||||
a, b := addrs[0], addrs[1]
|
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:
|
// General case:
|
||||||
m := map[netaddr.IP]bool{}
|
m := map[netip.Addr]bool{}
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
m[a.Addr()] = true
|
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
|
// PrefixesContainsFunc reports whether f is true for any IPPrefix in
|
||||||
// ipp.
|
// 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 {
|
for _, v := range ipp {
|
||||||
if f(v) {
|
if f(v) {
|
||||||
return true
|
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.
|
// 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 {
|
for _, r := range ipp {
|
||||||
if r.Contains(ip) {
|
if r.Contains(ip) {
|
||||||
return true
|
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.
|
// 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 {
|
for _, v := range ips {
|
||||||
if f(v) {
|
if f(v) {
|
||||||
return true
|
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.
|
// 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.
|
// 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
|
// ContainsExitRoutes reports whether rr contains both the IPv4 and
|
||||||
// IPv6 /0 route.
|
// IPv6 /0 route.
|
||||||
func ContainsExitRoutes(rr []netaddr.IPPrefix) bool {
|
func ContainsExitRoutes(rr []netip.Prefix) bool {
|
||||||
var v4, v6 bool
|
var v4, v6 bool
|
||||||
for _, r := range rr {
|
for _, r := range rr {
|
||||||
if r == allIPv4 {
|
if r == allIPv4 {
|
||||||
@ -258,18 +258,18 @@ func ContainsExitRoutes(rr []netaddr.IPPrefix) bool {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// AllIPv4 returns 0.0.0.0/0.
|
// AllIPv4 returns 0.0.0.0/0.
|
||||||
func AllIPv4() netaddr.IPPrefix { return allIPv4 }
|
func AllIPv4() netip.Prefix { return allIPv4 }
|
||||||
|
|
||||||
// AllIPv6 returns ::/0.
|
// AllIPv6 returns ::/0.
|
||||||
func AllIPv6() netaddr.IPPrefix { return allIPv6 }
|
func AllIPv6() netip.Prefix { return allIPv6 }
|
||||||
|
|
||||||
// ExitRoutes returns a slice containing AllIPv4 and 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
|
// FilterPrefixes returns a new slice, not aliasing in, containing elements of
|
||||||
// in that match f.
|
// in that match f.
|
||||||
func FilterPrefixesCopy(in []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool) []netaddr.IPPrefix {
|
func FilterPrefixesCopy(in []netip.Prefix, f func(netip.Prefix) bool) []netip.Prefix {
|
||||||
var out []netaddr.IPPrefix
|
var out []netip.Prefix
|
||||||
for _, v := range in {
|
for _, v := range in {
|
||||||
if f(v) {
|
if f(v) {
|
||||||
out = append(out, 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.
|
// IsViaPrefix reports whether p is a CIDR in the Tailscale "via" range.
|
||||||
// See TailscaleViaRange.
|
// See TailscaleViaRange.
|
||||||
func IsViaPrefix(p netaddr.IPPrefix) bool {
|
func IsViaPrefix(p netip.Prefix) bool {
|
||||||
return TailscaleViaRange().Contains(p.Addr())
|
return TailscaleViaRange().Contains(p.Addr())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,16 +288,16 @@ func IsViaPrefix(p netaddr.IPPrefix) bool {
|
|||||||
// "via" IPv4-in-IPv6 address.
|
// "via" IPv4-in-IPv6 address.
|
||||||
//
|
//
|
||||||
// If ip is not a via address, it returns ip unchanged.
|
// 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) {
|
if TailscaleViaRange().Contains(ip) {
|
||||||
a := ip.As16()
|
a := ip.As16()
|
||||||
return netaddr.IPFrom4(*(*[4]byte)(a[12:16]))
|
return netip.AddrFrom4(*(*[4]byte)(a[12:16]))
|
||||||
}
|
}
|
||||||
return ip
|
return ip
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapVia returns an IPv6 "via" route for an IPv4 CIDR in a given siteID.
|
// 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() {
|
if !v4.Addr().Is4() {
|
||||||
return via, errors.New("want IPv4 CIDR with a site ID")
|
return via, errors.New("want IPv4 CIDR with a site ID")
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
func TestInCrostiniRange(t *testing.T) {
|
func TestInCrostiniRange(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
ip netaddr.IP
|
ip netip.Addr
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{netaddr.IPv4(192, 168, 0, 1), false},
|
{netaddr.IPv4(192, 168, 0, 1), false},
|
||||||
@ -53,25 +53,25 @@ func TestCGNATRange(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewContainsIPFunc(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")) {
|
if f(netip.MustParseAddr("8.8.8.8")) {
|
||||||
t.Fatal("bad")
|
t.Fatal("bad")
|
||||||
}
|
}
|
||||||
if !f(netip.MustParseAddr("10.1.2.3")) {
|
if !f(netip.MustParseAddr("10.1.2.3")) {
|
||||||
t.Fatal("bad")
|
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")) {
|
if !f(netip.MustParseAddr("10.1.2.3")) {
|
||||||
t.Fatal("bad")
|
t.Fatal("bad")
|
||||||
}
|
}
|
||||||
f = NewContainsIPFunc([]netaddr.IPPrefix{
|
f = NewContainsIPFunc([]netip.Prefix{
|
||||||
netip.MustParsePrefix("10.1.2.3/32"),
|
netip.MustParsePrefix("10.1.2.3/32"),
|
||||||
netip.MustParsePrefix("::2/128"),
|
netip.MustParsePrefix("::2/128"),
|
||||||
})
|
})
|
||||||
if !f(netip.MustParseAddr("::2")) {
|
if !f(netip.MustParseAddr("::2")) {
|
||||||
t.Fatal("bad")
|
t.Fatal("bad")
|
||||||
}
|
}
|
||||||
f = NewContainsIPFunc([]netaddr.IPPrefix{
|
f = NewContainsIPFunc([]netip.Prefix{
|
||||||
netip.MustParsePrefix("10.1.2.3/32"),
|
netip.MustParsePrefix("10.1.2.3/32"),
|
||||||
netip.MustParsePrefix("10.1.2.4/32"),
|
netip.MustParsePrefix("10.1.2.4/32"),
|
||||||
netip.MustParsePrefix("::2/128"),
|
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) {
|
func BenchmarkTailscaleServiceAddr(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
@ -23,7 +22,7 @@
|
|||||||
//
|
//
|
||||||
// Example keys are "foo.domain.tld.beta.tailscale.net" and "foo",
|
// Example keys are "foo.domain.tld.beta.tailscale.net" and "foo",
|
||||||
// both without trailing dots, and both always lowercase.
|
// 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.
|
// canonMapKey canonicalizes its input s to be a dnsMap map key.
|
||||||
func canonMapKey(s string) string {
|
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
|
// The error is [exactly] errUnresolved if the addr is a name that isn't known
|
||||||
// in the map.
|
// 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)
|
host, port, err := splitHostPort(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// addr malformed or invalid port.
|
// addr malformed or invalid port.
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
if ip, err := netip.ParseAddr(host); err == nil {
|
if ip, err := netip.ParseAddr(host); err == nil {
|
||||||
// addr was literal ip:port.
|
// 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.
|
// 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.
|
// Try MagicDNS first, otherwise a real DNS lookup.
|
||||||
ip := m[canonMapKey(host)]
|
ip := m[canonMapKey(host)]
|
||||||
if ip.IsValid() {
|
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"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
)
|
)
|
||||||
@ -26,7 +25,7 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
|
|||||||
name: "self",
|
name: "self",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Name: "foo.tailnet",
|
Name: "foo.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100.102.103.104/32"),
|
pfx("100.102.103.104/32"),
|
||||||
pfx("100::123/128"),
|
pfx("100::123/128"),
|
||||||
},
|
},
|
||||||
@ -40,21 +39,21 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
|
|||||||
name: "self_and_peers",
|
name: "self_and_peers",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Name: "foo.tailnet",
|
Name: "foo.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100.102.103.104/32"),
|
pfx("100.102.103.104/32"),
|
||||||
pfx("100::123/128"),
|
pfx("100::123/128"),
|
||||||
},
|
},
|
||||||
Peers: []*tailcfg.Node{
|
Peers: []*tailcfg.Node{
|
||||||
{
|
{
|
||||||
Name: "a.tailnet",
|
Name: "a.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100.0.0.201/32"),
|
pfx("100.0.0.201/32"),
|
||||||
pfx("100::201/128"),
|
pfx("100::201/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "b.tailnet",
|
Name: "b.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100::202/128"),
|
pfx("100::202/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -73,20 +72,20 @@ func TestDNSMapFromNetworkMap(t *testing.T) {
|
|||||||
name: "self_has_v6_only",
|
name: "self_has_v6_only",
|
||||||
nm: &netmap.NetworkMap{
|
nm: &netmap.NetworkMap{
|
||||||
Name: "foo.tailnet",
|
Name: "foo.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100::123/128"),
|
pfx("100::123/128"),
|
||||||
},
|
},
|
||||||
Peers: []*tailcfg.Node{
|
Peers: []*tailcfg.Node{
|
||||||
{
|
{
|
||||||
Name: "a.tailnet",
|
Name: "a.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100.0.0.201/32"),
|
pfx("100.0.0.201/32"),
|
||||||
pfx("100::201/128"),
|
pfx("100::201/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "b.tailnet",
|
Name: "b.tailnet",
|
||||||
Addresses: []netaddr.IPPrefix{
|
Addresses: []netip.Prefix{
|
||||||
pfx("100::202/128"),
|
pfx("100::202/128"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -38,11 +38,11 @@ type Dialer struct {
|
|||||||
Logf logger.Logf
|
Logf logger.Logf
|
||||||
// UseNetstackForIP if non-nil is whether NetstackDialTCP (if
|
// UseNetstackForIP if non-nil is whether NetstackDialTCP (if
|
||||||
// it's non-nil) should be used to dial the provided IP.
|
// 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.
|
// NetstackDialTCP dials the provided IPPort using netstack.
|
||||||
// If nil, it's not used.
|
// 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
|
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
|
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()
|
d.mu.Lock()
|
||||||
dns := d.dns
|
dns := d.dns
|
||||||
exitDNSDoH := d.exitDNSDoHBase
|
exitDNSDoH := d.exitDNSDoHBase
|
||||||
@ -227,7 +227,7 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
|
|||||||
host, port, err := splitHostPort(addr)
|
host, port, err := splitHostPort(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// addr is malformed.
|
// addr is malformed.
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r net.Resolver
|
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)
|
ips, err := r.LookupIP(ctx, ipNetOfNetwork(network), host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netaddr.IPPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
if len(ips) == 0 {
|
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])
|
ip, _ := netaddr.FromStdIP(ips[0])
|
||||||
return netaddr.IPPortFrom(ip, port), nil
|
return netip.AddrPortFrom(ip, port), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding
|
// ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
@ -246,8 +247,8 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
|
|||||||
pkt := packLayer2UDP(
|
pkt := packLayer2UDP(
|
||||||
offer.ToBytes(),
|
offer.ToBytes(),
|
||||||
ourMAC, ethSrcMAC,
|
ourMAC, ethSrcMAC,
|
||||||
netaddr.IPPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
|
netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
|
||||||
netaddr.IPPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
|
netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
|
||||||
)
|
)
|
||||||
n, err := t.tdev.Write(pkt, 0)
|
n, err := t.tdev.Write(pkt, 0)
|
||||||
if tapDebug {
|
if tapDebug {
|
||||||
@ -273,8 +274,8 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
|
|||||||
pkt := packLayer2UDP(
|
pkt := packLayer2UDP(
|
||||||
ack.ToBytes(),
|
ack.ToBytes(),
|
||||||
ourMAC, ethSrcMAC,
|
ourMAC, ethSrcMAC,
|
||||||
netaddr.IPPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
|
netip.AddrPortFrom(netaddr.IPv4(100, 100, 100, 100), 67), // src
|
||||||
netaddr.IPPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
|
netip.AddrPortFrom(netaddr.IPv4(255, 255, 255, 255), 68), // dst
|
||||||
)
|
)
|
||||||
n, err := t.tdev.Write(pkt, 0)
|
n, err := t.tdev.Write(pkt, 0)
|
||||||
if tapDebug {
|
if tapDebug {
|
||||||
@ -288,7 +289,7 @@ func (t *Wrapper) handleDHCPRequest(ethBuf []byte) bool {
|
|||||||
return consumePacket
|
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))
|
buf := make([]byte, header.EthernetMinimumSize+header.UDPMinimumSize+header.IPv4MinimumSize+len(payload))
|
||||||
payloadStart := len(buf) - len(payload)
|
payloadStart := len(buf) - len(payload)
|
||||||
copy(buf[payloadStart:], payload)
|
copy(buf[payloadStart:], payload)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -21,7 +22,6 @@
|
|||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||||
"tailscale.com/disco"
|
"tailscale.com/disco"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/packet"
|
"tailscale.com/net/packet"
|
||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/tstime/mono"
|
"tailscale.com/tstime/mono"
|
||||||
@ -82,7 +82,7 @@ type Wrapper struct {
|
|||||||
// you might need to add a pad32.Four field here.
|
// you might need to add a pad32.Four field here.
|
||||||
lastActivityAtomic mono.Time // time of last send or receive
|
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
|
destMACAtomic atomic.Value // of [6]byte
|
||||||
discoKey atomic.Value // of key.DiscoPublic
|
discoKey atomic.Value // of key.DiscoPublic
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ type Wrapper struct {
|
|||||||
|
|
||||||
// PeerAPIPort, if non-nil, returns the peerapi port that's
|
// PeerAPIPort, if non-nil, returns the peerapi port that's
|
||||||
// running for the given IP address.
|
// 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 disables all filtering when set. This should only be used in tests.
|
||||||
disableFilter bool
|
disableFilter bool
|
||||||
@ -222,7 +222,7 @@ func wrap(logf logger.Logf, tdev tun.Device, isTAP bool) *Wrapper {
|
|||||||
// destination (the map keys).
|
// destination (the map keys).
|
||||||
//
|
//
|
||||||
// The map ownership passes to the Wrapper. It must be non-nil.
|
// 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)
|
t.destIPActivity.Store(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,8 +429,8 @@ func (t *Wrapper) sendOutbound(r tunReadResult) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
magicDNSIPPort = netaddr.IPPortFrom(tsaddr.TailscaleServiceIP(), 0) // 100.100.100.100:0
|
magicDNSIPPort = netip.AddrPortFrom(tsaddr.TailscaleServiceIP(), 0) // 100.100.100.100:0
|
||||||
magicDNSIPPortv6 = netaddr.IPPortFrom(tsaddr.TailscaleServiceIPv6(), 0)
|
magicDNSIPPortv6 = netip.AddrPortFrom(tsaddr.TailscaleServiceIPv6(), 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response {
|
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)
|
defer parsedPacketPool.Put(p)
|
||||||
p.Decode(buf[offset : offset+n])
|
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 {
|
if fn := m[p.Dst.Addr()]; fn != nil {
|
||||||
fn()
|
fn()
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ func tcp4syn(src, dst string, sport, dport uint16) []byte {
|
|||||||
return both
|
return both
|
||||||
}
|
}
|
||||||
|
|
||||||
func nets(nets ...string) (ret []netaddr.IPPrefix) {
|
func nets(nets ...string) (ret []netip.Prefix) {
|
||||||
for _, s := range nets {
|
for _, s := range nets {
|
||||||
if i := strings.IndexByte(s, '/'); i == -1 {
|
if i := strings.IndexByte(s, '/'); i == -1 {
|
||||||
ip, err := netip.ParseAddr(s)
|
ip, err := netip.ParseAddr(s)
|
||||||
@ -88,7 +88,7 @@ func nets(nets ...string) (ret []netaddr.IPPrefix) {
|
|||||||
if ip.Is6() {
|
if ip.Is6() {
|
||||||
bits = 128
|
bits = 128
|
||||||
}
|
}
|
||||||
ret = append(ret, netaddr.IPPrefixFrom(ip, bits))
|
ret = append(ret, netip.PrefixFrom(ip, int(bits)))
|
||||||
} else {
|
} else {
|
||||||
pfx, err := netip.ParsePrefix(s)
|
pfx, err := netip.ParsePrefix(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -428,7 +428,7 @@ func TestAtomic64Alignment(t *testing.T) {
|
|||||||
|
|
||||||
func TestPeerAPIBypass(t *testing.T) {
|
func TestPeerAPIBypass(t *testing.T) {
|
||||||
wrapperWithPeerAPI := &Wrapper{
|
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") {
|
if ip == netip.MustParseAddr("100.64.1.2") {
|
||||||
return 60000, true
|
return 60000, true
|
||||||
}
|
}
|
||||||
@ -446,7 +446,7 @@ func TestPeerAPIBypass(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "reject_nil_filter",
|
name: "reject_nil_filter",
|
||||||
w: &Wrapper{
|
w: &Wrapper{
|
||||||
PeerAPIPort: func(netaddr.IP) (port uint16, ok bool) {
|
PeerAPIPort: func(netip.Addr) (port uint16, ok bool) {
|
||||||
return 60000, true
|
return 60000, true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -405,7 +405,7 @@ func (c *conn) sshPolicy() (_ *tailcfg.SSHPolicy, ok bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func toIPPort(a net.Addr) (ipp netaddr.IPPort) {
|
func toIPPort(a net.Addr) (ipp netip.AddrPort) {
|
||||||
ta, ok := a.(*net.TCPAddr)
|
ta, ok := a.(*net.TCPAddr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@ -414,7 +414,7 @@ func toIPPort(a net.Addr) (ipp netaddr.IPPort) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return netaddr.IPPortFrom(tanetaddr, uint16(ta.Port))
|
return netip.AddrPortFrom(tanetaddr, uint16(ta.Port))
|
||||||
}
|
}
|
||||||
|
|
||||||
// connInfo returns a populated sshConnInfo from the provided arguments,
|
// connInfo returns a populated sshConnInfo from the provided arguments,
|
||||||
@ -1103,10 +1103,10 @@ type sshConnInfo struct {
|
|||||||
sshUser string
|
sshUser string
|
||||||
|
|
||||||
// src is the Tailscale IP and port that the connection came from.
|
// 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 is the Tailscale IP and port that the connection came for.
|
||||||
dst netaddr.IPPort
|
dst netip.AddrPort
|
||||||
|
|
||||||
// node is srcIP's node.
|
// node is srcIP's node.
|
||||||
node *tailcfg.Node
|
node *tailcfg.Node
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/opt"
|
"tailscale.com/types/opt"
|
||||||
@ -170,10 +170,10 @@ type Node struct {
|
|||||||
KeyExpiry time.Time
|
KeyExpiry time.Time
|
||||||
Machine key.MachinePublic
|
Machine key.MachinePublic
|
||||||
DiscoKey key.DiscoPublic
|
DiscoKey key.DiscoPublic
|
||||||
Addresses []netaddr.IPPrefix // IP addresses of this Node directly
|
Addresses []netip.Prefix // IP addresses of this Node directly
|
||||||
AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node
|
AllowedIPs []netip.Prefix // range of IP addresses to route to this node
|
||||||
Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs)
|
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
|
DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint
|
||||||
Hostinfo HostinfoView
|
Hostinfo HostinfoView
|
||||||
Created time.Time
|
Created time.Time
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ type Node struct {
|
|||||||
// is currently the primary subnet router for, as determined
|
// is currently the primary subnet router for, as determined
|
||||||
// by the control plane. It does not include the self address
|
// by the control plane. It does not include the self address
|
||||||
// values from Addresses that are in AllowedIPs.
|
// 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
|
// LastSeen is when the node was last online. It is not
|
||||||
// updated when Online is true. It is nil if the current
|
// 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
|
// Because it contains pointers (slices), this type should not be used
|
||||||
// as a value type.
|
// as a value type.
|
||||||
type Hostinfo struct {
|
type Hostinfo struct {
|
||||||
IPNVersion string `json:",omitempty"` // version of this code
|
IPNVersion string `json:",omitempty"` // version of this code
|
||||||
FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance
|
FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance
|
||||||
BackendLogID string `json:",omitempty"` // logtail ID of backend instance
|
BackendLogID string `json:",omitempty"` // logtail ID of backend instance
|
||||||
OS string `json:",omitempty"` // operating system the client runs on (a version.OS value)
|
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")
|
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
|
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)
|
Package string `json:",omitempty"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown)
|
||||||
DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3")
|
DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3")
|
||||||
Hostname string `json:",omitempty"` // name of the host the client runs on
|
Hostname string `json:",omitempty"` // name of the host the client runs on
|
||||||
ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections
|
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
|
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)
|
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
|
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
|
RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim
|
||||||
Services []Service `json:",omitempty"` // services advertised by this machine
|
Services []Service `json:",omitempty"` // services advertised by this machine
|
||||||
NetInfo *NetInfo `json:",omitempty"`
|
NetInfo *NetInfo `json:",omitempty"`
|
||||||
SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised
|
SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised
|
||||||
Cloud string `json:",omitempty"`
|
Cloud string `json:",omitempty"`
|
||||||
|
|
||||||
// NOTE: any new fields containing pointers in this type
|
// NOTE: any new fields containing pointers in this type
|
||||||
// require changes to Hostinfo.Equal.
|
// require changes to Hostinfo.Equal.
|
||||||
@ -854,7 +854,7 @@ func (et EndpointType) String() string {
|
|||||||
// broken up into two parallel slices in MapRequest, for compatibility
|
// broken up into two parallel slices in MapRequest, for compatibility
|
||||||
// reasons. But this type is used in the codebase.
|
// reasons. But this type is used in the codebase.
|
||||||
type Endpoint struct {
|
type Endpoint struct {
|
||||||
Addr netaddr.IPPort
|
Addr netip.AddrPort
|
||||||
Type EndpointType
|
Type EndpointType
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,7 +946,7 @@ type NetPortRange struct {
|
|||||||
type CapGrant struct {
|
type CapGrant struct {
|
||||||
// Dsts are the destination IP ranges that this capabilty
|
// Dsts are the destination IP ranges that this capabilty
|
||||||
// grant matches.
|
// grant matches.
|
||||||
Dsts []netaddr.IPPrefix
|
Dsts []netip.Prefix
|
||||||
|
|
||||||
// Caps are the capabilities the source IP matched by
|
// Caps are the capabilities the source IP matched by
|
||||||
// FilterRule.SrcIPs are granted to the destination IP,
|
// FilterRule.SrcIPs are granted to the destination IP,
|
||||||
@ -1059,7 +1059,7 @@ type DNSConfig struct {
|
|||||||
// MapRequest.Version >=9 and <14.
|
// MapRequest.Version >=9 and <14.
|
||||||
|
|
||||||
// Nameservers are the IP addresses of the nameservers to use.
|
// 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 is not set by the control server, and does nothing.
|
||||||
PerDomain bool `json:",omitempty"`
|
PerDomain bool `json:",omitempty"`
|
||||||
@ -1149,7 +1149,7 @@ type PingRequest struct {
|
|||||||
|
|
||||||
// IP is the ping target.
|
// 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.
|
// 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.
|
// PingResponse provides result information for a TSMP or Disco PingRequest.
|
||||||
@ -1446,7 +1446,7 @@ func eqStrings(a, b []string) bool {
|
|||||||
return true
|
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)) {
|
if len(a) != len(b) || ((a == nil) != (b == nil)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
@ -40,7 +39,7 @@ func TestHostinfoEqual(t *testing.T) {
|
|||||||
have, hiHandles)
|
have, hiHandles)
|
||||||
}
|
}
|
||||||
|
|
||||||
nets := func(strs ...string) (ns []netaddr.IPPrefix) {
|
nets := func(strs ...string) (ns []netip.Prefix) {
|
||||||
for _, s := range strs {
|
for _, s := range strs {
|
||||||
n, err := netip.ParsePrefix(s)
|
n, err := netip.ParsePrefix(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -225,12 +224,12 @@ func TestHostinfoHowEqual(t *testing.T) {
|
|||||||
a: &Hostinfo{
|
a: &Hostinfo{
|
||||||
IPNVersion: "1",
|
IPNVersion: "1",
|
||||||
ShieldsUp: false,
|
ShieldsUp: false,
|
||||||
RoutableIPs: []netaddr.IPPrefix{netip.MustParsePrefix("1.2.3.0/24")},
|
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("1.2.3.0/24")},
|
||||||
},
|
},
|
||||||
b: &Hostinfo{
|
b: &Hostinfo{
|
||||||
IPNVersion: "2",
|
IPNVersion: "2",
|
||||||
ShieldsUp: true,
|
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"},
|
want: []string{"IPNVersion", "ShieldsUp", "RoutableIPs"},
|
||||||
},
|
},
|
||||||
@ -403,23 +402,23 @@ func TestNodeEqual(t *testing.T) {
|
|||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&Node{Addresses: []netaddr.IPPrefix{}},
|
&Node{Addresses: []netip.Prefix{}},
|
||||||
&Node{Addresses: nil},
|
&Node{Addresses: nil},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&Node{Addresses: []netaddr.IPPrefix{}},
|
&Node{Addresses: []netip.Prefix{}},
|
||||||
&Node{Addresses: []netaddr.IPPrefix{}},
|
&Node{Addresses: []netip.Prefix{}},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&Node{AllowedIPs: []netaddr.IPPrefix{}},
|
&Node{AllowedIPs: []netip.Prefix{}},
|
||||||
&Node{AllowedIPs: nil},
|
&Node{AllowedIPs: nil},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&Node{Addresses: []netaddr.IPPrefix{}},
|
&Node{Addresses: []netip.Prefix{}},
|
||||||
&Node{Addresses: []netaddr.IPPrefix{}},
|
&Node{Addresses: []netip.Prefix{}},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -566,8 +565,8 @@ func TestCloneNode(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"nil_fields", &Node{}},
|
{"nil_fields", &Node{}},
|
||||||
{"zero_fields", &Node{
|
{"zero_fields", &Node{
|
||||||
Addresses: make([]netaddr.IPPrefix, 0),
|
Addresses: make([]netip.Prefix, 0),
|
||||||
AllowedIPs: make([]netaddr.IPPrefix, 0),
|
AllowedIPs: make([]netip.Prefix, 0),
|
||||||
Endpoints: make([]string, 0),
|
Endpoints: make([]string, 0),
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -32,7 +33,6 @@
|
|||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
"tailscale.com/logtail/filch"
|
"tailscale.com/logtail/filch"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/net/nettest"
|
"tailscale.com/net/nettest"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/smallzstd"
|
"tailscale.com/smallzstd"
|
||||||
@ -272,11 +272,11 @@ func (s *Server) start() error {
|
|||||||
if err := ns.Start(); err != nil {
|
if err := ns.Start(); err != nil {
|
||||||
return fmt.Errorf("failed to start netstack: %w", err)
|
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)
|
_, ok := eng.PeerForIP(ip)
|
||||||
return ok
|
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)
|
return ns.DialContextTCP(ctx, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/ipn/store"
|
"tailscale.com/ipn/store"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
"tailscale.com/safesocket"
|
"tailscale.com/safesocket"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/tstest"
|
"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 := n.env.t
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var addrs []netaddr.IP
|
var addrs []netip.Addr
|
||||||
if err := tstest.WaitFor(20*time.Second, func() error {
|
if err := tstest.WaitFor(20*time.Second, func() error {
|
||||||
cmd := n.Tailscale("ip")
|
cmd := n.Tailscale("ip")
|
||||||
cmd.Stdout = nil // in case --verbose-tailscale was set
|
cmd.Stdout = nil // in case --verbose-tailscale was set
|
||||||
@ -828,7 +827,7 @@ func (n *testNode) AwaitIPs() []netaddr.IP {
|
|||||||
}
|
}
|
||||||
ips := string(out)
|
ips := string(out)
|
||||||
ipslice := strings.Fields(ips)
|
ipslice := strings.Fields(ips)
|
||||||
addrs = make([]netaddr.IP, len(ipslice))
|
addrs = make([]netip.Addr, len(ipslice))
|
||||||
|
|
||||||
for i, ip := range ipslice {
|
for i, ip := range ipslice {
|
||||||
netIP, err := netip.ParseAddr(ip)
|
netIP, err := netip.ParseAddr(ip)
|
||||||
@ -848,7 +847,7 @@ func (n *testNode) AwaitIPs() []netaddr.IP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AwaitIP returns the IP address of n.
|
// AwaitIP returns the IP address of n.
|
||||||
func (n *testNode) AwaitIP() netaddr.IP {
|
func (n *testNode) AwaitIP() netip.Addr {
|
||||||
t := n.env.t
|
t := n.env.t
|
||||||
t.Helper()
|
t.Helper()
|
||||||
ips := n.AwaitIPs()
|
ips := n.AwaitIPs()
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
_ "tailscale.com/logtail"
|
_ "tailscale.com/logtail"
|
||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
_ "tailscale.com/net/netaddr"
|
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/portmapper"
|
_ "tailscale.com/net/portmapper"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
_ "tailscale.com/logtail"
|
_ "tailscale.com/logtail"
|
||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
_ "tailscale.com/net/netaddr"
|
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/portmapper"
|
_ "tailscale.com/net/portmapper"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
_ "tailscale.com/logtail"
|
_ "tailscale.com/logtail"
|
||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
_ "tailscale.com/net/netaddr"
|
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/portmapper"
|
_ "tailscale.com/net/portmapper"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
_ "tailscale.com/logtail"
|
_ "tailscale.com/logtail"
|
||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
_ "tailscale.com/net/netaddr"
|
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/portmapper"
|
_ "tailscale.com/net/portmapper"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
_ "tailscale.com/logtail/backoff"
|
_ "tailscale.com/logtail/backoff"
|
||||||
_ "tailscale.com/net/dns"
|
_ "tailscale.com/net/dns"
|
||||||
_ "tailscale.com/net/interfaces"
|
_ "tailscale.com/net/interfaces"
|
||||||
_ "tailscale.com/net/netaddr"
|
|
||||||
_ "tailscale.com/net/netns"
|
_ "tailscale.com/net/netns"
|
||||||
_ "tailscale.com/net/portmapper"
|
_ "tailscale.com/net/portmapper"
|
||||||
_ "tailscale.com/net/proxymux"
|
_ "tailscale.com/net/proxymux"
|
||||||
|
@ -312,7 +312,7 @@ func (s *Server) AddFakeNode() {
|
|||||||
r := nk.Raw32()
|
r := nk.Raw32()
|
||||||
id := int64(binary.LittleEndian.Uint64(r[:]))
|
id := int64(binary.LittleEndian.Uint64(r[:]))
|
||||||
ip := netaddr.IPv4(r[0], r[1], r[2], r[3])
|
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{
|
s.nodes[nk] = &tailcfg.Node{
|
||||||
ID: tailcfg.NodeID(id),
|
ID: tailcfg.NodeID(id),
|
||||||
StableID: tailcfg.StableNodeID(fmt.Sprintf("TESTCTRL%08x", id)),
|
StableID: tailcfg.StableNodeID(fmt.Sprintf("TESTCTRL%08x", id)),
|
||||||
@ -321,8 +321,8 @@ func (s *Server) AddFakeNode() {
|
|||||||
Key: nk,
|
Key: nk,
|
||||||
MachineAuthorized: true,
|
MachineAuthorized: true,
|
||||||
DiscoKey: dk,
|
DiscoKey: dk,
|
||||||
Addresses: []netaddr.IPPrefix{addr},
|
Addresses: []netip.Prefix{addr},
|
||||||
AllowedIPs: []netaddr.IPPrefix{addr},
|
AllowedIPs: []netip.Prefix{addr},
|
||||||
}
|
}
|
||||||
// TODO: send updates to other (non-fake?) nodes
|
// 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
|
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)
|
v4Prefix := netip.PrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
|
||||||
v6Prefix := netaddr.IPPrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
|
v6Prefix := netip.PrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
|
||||||
|
|
||||||
allowedIPs := []netaddr.IPPrefix{
|
allowedIPs := []netip.Prefix{
|
||||||
v4Prefix,
|
v4Prefix,
|
||||||
v6Prefix,
|
v6Prefix,
|
||||||
}
|
}
|
||||||
@ -761,10 +761,10 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
|
|||||||
return res.Peers[i].ID < res.Peers[j].ID
|
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)
|
v4Prefix := netip.PrefixFrom(netaddr.IPv4(100, 64, uint8(tailcfg.NodeID(user.ID)>>8), uint8(tailcfg.NodeID(user.ID))), 32)
|
||||||
v6Prefix := netaddr.IPPrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
|
v6Prefix := netip.PrefixFrom(tsaddr.Tailscale4To6(v4Prefix.Addr()), 128)
|
||||||
|
|
||||||
res.Node.Addresses = []netaddr.IPPrefix{
|
res.Node.Addresses = []netip.Prefix{
|
||||||
v4Prefix,
|
v4Prefix,
|
||||||
v6Prefix,
|
v6Prefix,
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"tailscale.com/net/interfaces"
|
"tailscale.com/net/interfaces"
|
||||||
"tailscale.com/net/netaddr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func deriveBindhost(t *testing.T) string {
|
func deriveBindhost(t *testing.T) string {
|
||||||
@ -22,7 +22,7 @@ func deriveBindhost(t *testing.T) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ret 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 {
|
if ret != "" || i.Name != ifName {
|
||||||
return
|
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