mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
net/netaddr: start migrating to net/netip via new netaddr adapter package
Updates #5162 Change-Id: Id7bdec303b25471f69d542f8ce43805328d56c12 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
7b1a91dfd3
commit
7eaf5e509f
@ -14,7 +14,7 @@
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
// ACLRow defines a rule that grants access by a set of users or groups to a set
|
||||
|
@ -28,10 +28,10 @@
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/paths"
|
||||
"tailscale.com/safesocket"
|
||||
|
@ -14,7 +14,7 @@
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
// Routes contains the lists of subnet routes that are currently advertised by a device,
|
||||
@ -60,7 +60,7 @@ type postRoutesParams struct {
|
||||
}
|
||||
|
||||
// SetRoutes updates the list of subnets that are enabled for a device.
|
||||
// Subnets must be parsable by inet.af/netaddr.ParseIPPrefix.
|
||||
// Subnets must be parsable by tailscale.com/net/netaddr.ParseIPPrefix.
|
||||
// Subnets do not have to be currently advertised by a device, they may be pre-enabled.
|
||||
// Returns the updated list of enabled and advertised subnet routes in a *Routes object.
|
||||
func (c *Client) SetRoutes(ctx context.Context, deviceID string, subnets []netaddr.IPPrefix) (routes *Routes, err error) {
|
||||
|
@ -135,13 +135,13 @@ func tailscaleIP(who *apitype.WhoIsResponse) string {
|
||||
return ""
|
||||
}
|
||||
for _, nodeIP := range who.Node.Addresses {
|
||||
if nodeIP.IP().Is4() && nodeIP.IsSingleIP() {
|
||||
return nodeIP.IP().String()
|
||||
if nodeIP.Addr().Is4() && nodeIP.IsSingleIP() {
|
||||
return nodeIP.Addr().String()
|
||||
}
|
||||
}
|
||||
for _, nodeIP := range who.Node.Addresses {
|
||||
if nodeIP.IsSingleIP() {
|
||||
return nodeIP.IP().String()
|
||||
return nodeIP.Addr().String()
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
@ -15,9 +15,9 @@
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/persist"
|
||||
"tailscale.com/types/preftype"
|
||||
|
@ -17,6 +17,7 @@
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@ -24,10 +25,10 @@
|
||||
"time"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/control/controlhttp"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/paths"
|
||||
"tailscale.com/safesocket"
|
||||
@ -408,19 +409,19 @@ func runVia(ctx context.Context, args []string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ipp.IP().Is6() {
|
||||
if !ipp.Addr().Is6() {
|
||||
return errors.New("with one argument, expect an IPv6 CIDR")
|
||||
}
|
||||
if !tsaddr.TailscaleViaRange().Contains(ipp.IP()) {
|
||||
if !tsaddr.TailscaleViaRange().Contains(ipp.Addr()) {
|
||||
return errors.New("not a via route")
|
||||
}
|
||||
if ipp.Bits() < 96 {
|
||||
return errors.New("short length, want /96 or more")
|
||||
}
|
||||
v4 := tsaddr.UnmapVia(ipp.IP())
|
||||
a := ipp.IP().As16()
|
||||
v4 := tsaddr.UnmapVia(ipp.Addr())
|
||||
a := ipp.Addr().As16()
|
||||
siteID := binary.BigEndian.Uint32(a[8:12])
|
||||
fmt.Printf("site %v (0x%x), %v\n", siteID, siteID, netaddr.IPPrefixFrom(v4, ipp.Bits()-96))
|
||||
fmt.Printf("site %v (0x%x), %v\n", siteID, siteID, netip.PrefixFrom(v4, ipp.Bits()-96))
|
||||
case 2:
|
||||
siteID, err := strconv.ParseUint(args[0], 0, 32)
|
||||
if err != nil {
|
||||
|
@ -23,10 +23,10 @@
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"golang.org/x/time/rate"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/version"
|
||||
@ -179,7 +179,7 @@ func getTargetStableID(ctx context.Context, ipStr string) (id tailcfg.StableNode
|
||||
for _, ft := range fts {
|
||||
n := ft.Node
|
||||
for _, a := range n.Addresses {
|
||||
if a.IP() != ip {
|
||||
if a.Addr() != ip {
|
||||
continue
|
||||
}
|
||||
isOffline = n.Online != nil && !*n.Online
|
||||
@ -281,7 +281,7 @@ func runCpTargets(ctx context.Context, args []string) error {
|
||||
if detail != "" {
|
||||
detail = "\t" + detail
|
||||
}
|
||||
printf("%s\t%s%s\n", n.Addresses[0].IP(), n.ComputedName, detail)
|
||||
printf("%s\t%s%s\n", n.Addresses[0].Addr(), n.ComputedName, detail)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
"fmt"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var ipCmd = &ffcli.Command{
|
||||
|
@ -16,8 +16,8 @@
|
||||
"time"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
|
@ -17,9 +17,9 @@
|
||||
"strings"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
@ -166,7 +166,7 @@ func nodeDNSNameFromArg(st *ipnstate.Status, arg string) (dnsName string, ok boo
|
||||
argIP, _ := netaddr.ParseIP(arg)
|
||||
for _, ps := range st.Peer {
|
||||
dnsName = ps.DNSName
|
||||
if !argIP.IsZero() {
|
||||
if argIP.IsValid() {
|
||||
for _, ip := range ps.TailscaleIPs {
|
||||
if ip == argIP {
|
||||
return dnsName, true
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"github.com/toqueteos/webbrowser"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -24,9 +24,9 @@
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
qrcode "github.com/skip2/go-qrcode"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/safesocket"
|
||||
"tailscale.com/tailcfg"
|
||||
@ -210,7 +210,7 @@ func validateViaPrefix(ipp netaddr.IPPrefix) error {
|
||||
if ipp.Bits() < (128 - 32) {
|
||||
return fmt.Errorf("%v 4-in-6 prefix must be at least a /%v", ipp, 128-32)
|
||||
}
|
||||
a := ipp.IP().As16()
|
||||
a := ipp.Addr().As16()
|
||||
// The first 64 bits of a are the via prefix.
|
||||
// The next 32 bits are the "site ID".
|
||||
// The last 32 bits are the IPv4.
|
||||
@ -266,7 +266,7 @@ func calcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]
|
||||
if routes[i].Bits() != routes[j].Bits() {
|
||||
return routes[i].Bits() < routes[j].Bits()
|
||||
}
|
||||
return routes[i].IP().Less(routes[j].IP())
|
||||
return routes[i].Addr().Less(routes[j].Addr())
|
||||
})
|
||||
return routes, nil
|
||||
}
|
||||
@ -913,10 +913,10 @@ func prefsToFlags(env upCheckEnv, prefs *ipn.Prefs) (flagVal map[string]any) {
|
||||
ret := make(map[string]any)
|
||||
|
||||
exitNodeIPStr := func() string {
|
||||
if !prefs.ExitNodeIP.IsZero() {
|
||||
if prefs.ExitNodeIP.IsValid() {
|
||||
return prefs.ExitNodeIP.String()
|
||||
}
|
||||
if prefs.ExitNodeID.IsZero() || env.curExitNodeIP.IsZero() {
|
||||
if prefs.ExitNodeID.IsZero() || !env.curExitNodeIP.IsValid() {
|
||||
return ""
|
||||
}
|
||||
return env.curExitNodeIP.String()
|
||||
@ -995,9 +995,9 @@ func hasExitNodeRoutes(rr []netaddr.IPPrefix) bool {
|
||||
var v4, v6 bool
|
||||
for _, r := range rr {
|
||||
if r.Bits() == 0 {
|
||||
if r.IP().Is4() {
|
||||
if r.Addr().Is4() {
|
||||
v4 = true
|
||||
} else if r.IP().Is6() {
|
||||
} else if r.Addr().Is6() {
|
||||
v6 = true
|
||||
}
|
||||
}
|
||||
@ -1027,7 +1027,7 @@ func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netaddr.IP) {
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
if !p.ExitNodeIP.IsZero() {
|
||||
if p.ExitNodeIP.IsValid() {
|
||||
return p.ExitNodeIP
|
||||
}
|
||||
id := p.ExitNodeID
|
||||
|
@ -27,8 +27,8 @@
|
||||
"strings"
|
||||
|
||||
"github.com/peterbourgon/ff/v3/ffcli"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/preftype"
|
||||
"tailscale.com/util/groupmember"
|
||||
|
@ -26,11 +26,9 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
github.com/tailscale/goupnp/ssdp from github.com/tailscale/goupnp
|
||||
github.com/tcnksm/go-httpstat from tailscale.com/net/netcheck
|
||||
github.com/toqueteos/webbrowser from tailscale.com/cmd/tailscale/cli
|
||||
💣 go4.org/intern from inet.af/netaddr
|
||||
💣 go4.org/mem from tailscale.com/derp+
|
||||
go4.org/unsafe/assume-no-moving-gc from go4.org/intern
|
||||
go4.org/netipx from tailscale.com/wgengine/filter
|
||||
W 💣 golang.zx2c4.com/wireguard/windows/tunnel/winipcfg from tailscale.com/net/interfaces+
|
||||
inet.af/netaddr from tailscale.com/cmd/tailscale/cli+
|
||||
nhooyr.io/websocket from tailscale.com/derp/derphttp+
|
||||
nhooyr.io/websocket/internal/errd from nhooyr.io/websocket
|
||||
nhooyr.io/websocket/internal/xsync from nhooyr.io/websocket
|
||||
@ -54,6 +52,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
tailscale.com/net/dnsfallback from tailscale.com/control/controlhttp
|
||||
tailscale.com/net/flowtrack from tailscale.com/wgengine/filter+
|
||||
💣 tailscale.com/net/interfaces from tailscale.com/cmd/tailscale/cli+
|
||||
tailscale.com/net/netaddr from tailscale.com/client/tailscale+
|
||||
tailscale.com/net/netcheck from tailscale.com/cmd/tailscale/cli
|
||||
tailscale.com/net/neterror from tailscale.com/net/netcheck+
|
||||
tailscale.com/net/netknob from tailscale.com/net/netns
|
||||
@ -78,6 +77,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
tailscale.com/types/key from tailscale.com/derp+
|
||||
tailscale.com/types/logger from tailscale.com/cmd/tailscale/cli+
|
||||
tailscale.com/types/netmap from tailscale.com/ipn
|
||||
tailscale.com/types/nettype from tailscale.com/net/netcheck+
|
||||
tailscale.com/types/opt from tailscale.com/net/netcheck+
|
||||
tailscale.com/types/pad32 from tailscale.com/derp
|
||||
tailscale.com/types/persist from tailscale.com/ipn
|
||||
@ -190,7 +190,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
|
||||
net/http/cgi from tailscale.com/cmd/tailscale/cli
|
||||
net/http/httptrace from github.com/tcnksm/go-httpstat+
|
||||
net/http/internal from net/http
|
||||
net/netip from net
|
||||
net/netip from net+
|
||||
net/textproto from golang.org/x/net/http/httpguts+
|
||||
net/url from crypto/x509+
|
||||
os from crypto/rand+
|
||||
|
@ -25,11 +25,11 @@
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/derp/derphttp"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/portmapper"
|
||||
"tailscale.com/net/tshttpproxy"
|
||||
"tailscale.com/tailcfg"
|
||||
|
@ -113,9 +113,10 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
L github.com/u-root/uio/uio from github.com/insomniacslk/dhcp/dhcpv4+
|
||||
L 💣 github.com/vishvananda/netlink/nl from github.com/tailscale/netlink
|
||||
L github.com/vishvananda/netns from github.com/tailscale/netlink+
|
||||
💣 go4.org/intern from inet.af/netaddr
|
||||
W 💣 go4.org/intern from inet.af/netaddr
|
||||
💣 go4.org/mem from tailscale.com/control/controlbase+
|
||||
go4.org/unsafe/assume-no-moving-gc from go4.org/intern
|
||||
go4.org/netipx from tailscale.com/ipn/ipnlocal+
|
||||
W go4.org/unsafe/assume-no-moving-gc from go4.org/intern
|
||||
W 💣 golang.zx2c4.com/wintun from golang.zx2c4.com/wireguard/tun
|
||||
💣 golang.zx2c4.com/wireguard/conn from golang.zx2c4.com/wireguard/device+
|
||||
W 💣 golang.zx2c4.com/wireguard/conn/winrio from golang.zx2c4.com/wireguard/conn
|
||||
@ -168,7 +169,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
gvisor.dev/gvisor/pkg/tcpip/transport/tcpconntrack from gvisor.dev/gvisor/pkg/tcpip/stack
|
||||
gvisor.dev/gvisor/pkg/tcpip/transport/udp from tailscale.com/net/tstun+
|
||||
gvisor.dev/gvisor/pkg/waiter from gvisor.dev/gvisor/pkg/context+
|
||||
inet.af/netaddr from tailscale.com/control/controlclient+
|
||||
W inet.af/netaddr from inet.af/wf
|
||||
inet.af/peercred from tailscale.com/ipn/ipnserver
|
||||
W 💣 inet.af/wf from tailscale.com/wf
|
||||
nhooyr.io/websocket from tailscale.com/derp/derphttp+
|
||||
@ -216,6 +217,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
tailscale.com/net/dnsfallback from tailscale.com/control/controlclient+
|
||||
tailscale.com/net/flowtrack from tailscale.com/net/packet+
|
||||
💣 tailscale.com/net/interfaces from tailscale.com/control/controlclient+
|
||||
tailscale.com/net/netaddr from tailscale.com/client/tailscale+
|
||||
tailscale.com/net/netcheck from tailscale.com/wgengine/magicsock
|
||||
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
|
||||
tailscale.com/net/netknob from tailscale.com/net/netns+
|
||||
@ -252,7 +254,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
tailscale.com/types/key from tailscale.com/control/controlbase+
|
||||
tailscale.com/types/logger from tailscale.com/control/controlclient+
|
||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||
tailscale.com/types/nettype from tailscale.com/wgengine/magicsock
|
||||
tailscale.com/types/nettype from tailscale.com/wgengine/magicsock+
|
||||
tailscale.com/types/opt from tailscale.com/control/controlclient+
|
||||
tailscale.com/types/pad32 from tailscale.com/derp
|
||||
tailscale.com/types/persist from tailscale.com/control/controlclient+
|
||||
@ -269,7 +271,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
||||
tailscale.com/util/lineread from tailscale.com/hostinfo+
|
||||
tailscale.com/util/mak from tailscale.com/control/controlclient+
|
||||
tailscale.com/util/multierr from tailscale.com/control/controlclient+
|
||||
tailscale.com/util/netconv from tailscale.com/wgengine/magicsock
|
||||
tailscale.com/util/osshare from tailscale.com/ipn/ipnlocal+
|
||||
tailscale.com/util/pidowner from tailscale.com/ipn/ipnserver
|
||||
tailscale.com/util/racebuild from tailscale.com/logpolicy
|
||||
|
@ -29,7 +29,6 @@
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/cmd/tailscaled/childproc"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/envknob"
|
||||
@ -39,6 +38,7 @@
|
||||
"tailscale.com/logpolicy"
|
||||
"tailscale.com/logtail"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/proxymux"
|
||||
"tailscale.com/net/socks5"
|
||||
|
@ -32,12 +32,12 @@
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn/ipnserver"
|
||||
"tailscale.com/ipn/store"
|
||||
"tailscale.com/logpolicy"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/net/tstun"
|
||||
"tailscale.com/safesocket"
|
||||
|
@ -24,12 +24,12 @@
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/ipnserver"
|
||||
"tailscale.com/ipn/store/mem"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/safesocket"
|
||||
@ -175,7 +175,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
|
||||
Self: jsNetMapSelfNode{
|
||||
jsNetMapNode: jsNetMapNode{
|
||||
Name: nm.Name,
|
||||
Addresses: mapSlice(nm.Addresses, func(a netaddr.IPPrefix) string { return a.IP().String() }),
|
||||
Addresses: mapSlice(nm.Addresses, func(a netaddr.IPPrefix) string { return a.Addr().String() }),
|
||||
NodeKey: nm.NodeKey.String(),
|
||||
MachineKey: nm.MachineKey.String(),
|
||||
},
|
||||
@ -185,7 +185,7 @@ func (i *jsIPN) run(jsCallbacks js.Value) {
|
||||
return jsNetMapPeerNode{
|
||||
jsNetMapNode: jsNetMapNode{
|
||||
Name: p.Name,
|
||||
Addresses: mapSlice(p.Addresses, func(a netaddr.IPPrefix) string { return a.IP().String() }),
|
||||
Addresses: mapSlice(p.Addresses, func(a netaddr.IPPrefix) string { return a.Addr().String() }),
|
||||
MachineKey: p.Machine.String(),
|
||||
NodeKey: p.Key.String(),
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
//go:generate go run tailscale.com/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices
|
||||
|
@ -7,7 +7,7 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"inet.af/netaddr"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// Clone makes a deep copy of StructWithPtrs.
|
||||
@ -50,7 +50,7 @@ func (src *StructWithoutPtrs) Clone() *StructWithoutPtrs {
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _StructWithoutPtrsCloneNeedsRegeneration = StructWithoutPtrs(struct {
|
||||
Int int
|
||||
Pfx netaddr.IPPrefix
|
||||
Pfx netip.Prefix
|
||||
}{})
|
||||
|
||||
// Clone makes a deep copy of Map.
|
||||
@ -178,6 +178,6 @@ func (src *StructWithSlices) Clone() *StructWithSlices {
|
||||
Structs []StructWithPtrs
|
||||
Ints []*int
|
||||
Slice []string
|
||||
Prefixes []netaddr.IPPrefix
|
||||
Prefixes []netip.Prefix
|
||||
Data []byte
|
||||
}{})
|
||||
|
@ -9,9 +9,9 @@
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/netip"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/types/views"
|
||||
)
|
||||
|
||||
@ -135,12 +135,12 @@ func (v *StructWithoutPtrsView) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
func (v StructWithoutPtrsView) Int() int { return v.ж.Int }
|
||||
func (v StructWithoutPtrsView) Pfx() netaddr.IPPrefix { return v.ж.Pfx }
|
||||
func (v StructWithoutPtrsView) Pfx() netip.Prefix { return v.ж.Pfx }
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _StructWithoutPtrsViewNeedsRegeneration = StructWithoutPtrs(struct {
|
||||
Int int
|
||||
Pfx netaddr.IPPrefix
|
||||
Pfx netip.Prefix
|
||||
}{})
|
||||
|
||||
// View returns a readonly view of Map.
|
||||
@ -311,6 +311,6 @@ func (v StructWithSlicesView) Data() mem.RO { return mem.B(v.ж.Data) }
|
||||
Structs []StructWithPtrs
|
||||
Ints []*int
|
||||
Slice []string
|
||||
Prefixes []netaddr.IPPrefix
|
||||
Prefixes []netip.Prefix
|
||||
Data []byte
|
||||
}{})
|
||||
|
@ -177,7 +177,7 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, thi
|
||||
case "byte":
|
||||
it.Import("go4.org/mem")
|
||||
writeTemplate("byteSliceField")
|
||||
case "inet.af/netaddr.IPPrefix":
|
||||
case "inet.af/netaddr.IPPrefix", "net/netip.Prefix":
|
||||
it.Import("tailscale.com/types/views")
|
||||
writeTemplate("ipPrefixSliceField")
|
||||
default:
|
||||
|
@ -26,7 +26,6 @@
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/control/controlknobs"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/health"
|
||||
@ -37,6 +36,7 @@
|
||||
"tailscale.com/net/dnscache"
|
||||
"tailscale.com/net/dnsfallback"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/net/tlsdial"
|
||||
"tailscale.com/net/tsdial"
|
||||
@ -1408,7 +1408,7 @@ func (c *Direct) DoNoiseRequest(req *http.Request) (*http.Response, error) {
|
||||
// doPingerPing sends a Ping to pr.IP using pinger, and sends an http request back to
|
||||
// pr.URL with ping response data.
|
||||
func doPingerPing(logf logger.Logf, c *http.Client, pr *tailcfg.PingRequest, pinger Pinger, pingType tailcfg.PingType) {
|
||||
if pr.URL == "" || pr.IP.IsZero() || pinger == nil {
|
||||
if pr.URL == "" || !pr.IP.IsValid() || pinger == nil {
|
||||
logf("invalid ping request: missing url, ip or pinger")
|
||||
return
|
||||
}
|
||||
|
@ -11,9 +11,9 @@
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
|
@ -9,8 +9,8 @@
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
@ -309,7 +309,7 @@ func filterSelfAddresses(in []netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
|
||||
return in
|
||||
case debugSelfIPv6Only:
|
||||
for _, a := range in {
|
||||
if a.IP().Is6() {
|
||||
if a.Addr().Is6() {
|
||||
ret = append(ret, a)
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
"go4.org/mem"
|
||||
"golang.org/x/time/rate"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
)
|
||||
|
@ -36,11 +36,11 @@
|
||||
"go4.org/mem"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"golang.org/x/time/rate"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale"
|
||||
"tailscale.com/disco"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/metrics"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
|
@ -30,10 +30,10 @@
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/derp"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/dnscache"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/tlsdial"
|
||||
"tailscale.com/net/tshttpproxy"
|
||||
|
@ -26,7 +26,7 @@
|
||||
"net"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
@ -180,7 +180,7 @@ type CallMeMaybe struct {
|
||||
func (m *CallMeMaybe) AppendMarshal(b []byte) []byte {
|
||||
ret, p := appendMsgHeader(b, TypeCallMeMaybe, v0, epLength*len(m.MyNumber))
|
||||
for _, ipp := range m.MyNumber {
|
||||
a := ipp.IP().As16()
|
||||
a := ipp.Addr().As16()
|
||||
copy(p[:], a[:])
|
||||
binary.BigEndian.PutUint16(p[16:], ipp.Port())
|
||||
p = p[epLength:]
|
||||
@ -219,7 +219,7 @@ type Pong struct {
|
||||
func (m *Pong) AppendMarshal(b []byte) []byte {
|
||||
ret, d := appendMsgHeader(b, TypePong, v0, pongLen)
|
||||
d = d[copy(d, m.TxID[:]):]
|
||||
ip16 := m.Src.IP().As16()
|
||||
ip16 := m.Src.Addr().As16()
|
||||
d = d[copy(d, ip16[:]):]
|
||||
binary.BigEndian.PutUint16(d, m.Src.Port())
|
||||
return ret
|
||||
|
@ -11,7 +11,7 @@
|
||||
"testing"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
|
1
go.mod
1
go.mod
@ -54,6 +54,7 @@ require (
|
||||
github.com/u-root/u-root v0.8.0
|
||||
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54
|
||||
go4.org/mem v0.0.0-20210711025021-927187094b94
|
||||
go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf
|
||||
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
|
||||
|
2
go.sum
2
go.sum
@ -1248,6 +1248,8 @@ go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3m
|
||||
go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
|
||||
go4.org/mem v0.0.0-20210711025021-927187094b94 h1:OAAkygi2Js191AJP1Ds42MhJRgeofeKGjuoUqNp1QC4=
|
||||
go4.org/mem v0.0.0-20210711025021-927187094b94/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g=
|
||||
go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf h1:IdwJUzqoIo5lkr2EOyKoe5qipUaEjbOKKY5+fzPBZ3A=
|
||||
go4.org/netipx v0.0.0-20220725152314-7e7bdc8411bf/go.mod h1:+QXzaoURFd0rGDIjDNpyIkv+F9R7EmeKorvlKRnhqgA=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
|
@ -8,7 +8,7 @@
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/netmap"
|
||||
|
@ -7,7 +7,8 @@
|
||||
package ipn
|
||||
|
||||
import (
|
||||
"inet.af/netaddr"
|
||||
"net/netip"
|
||||
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/persist"
|
||||
"tailscale.com/types/preftype"
|
||||
@ -36,7 +37,7 @@ func (src *Prefs) Clone() *Prefs {
|
||||
RouteAll bool
|
||||
AllowSingleHosts bool
|
||||
ExitNodeID tailcfg.StableNodeID
|
||||
ExitNodeIP netaddr.IP
|
||||
ExitNodeIP netip.Addr
|
||||
ExitNodeAllowLANAccess bool
|
||||
CorpDNS bool
|
||||
RunSSH bool
|
||||
@ -47,7 +48,7 @@ func (src *Prefs) Clone() *Prefs {
|
||||
Hostname string
|
||||
NotepadURLs bool
|
||||
ForceDaemon bool
|
||||
AdvertiseRoutes []netaddr.IPPrefix
|
||||
AdvertiseRoutes []netip.Prefix
|
||||
NoSNAT bool
|
||||
NetfilterMode preftype.NetfilterMode
|
||||
OperatorUser string
|
||||
|
@ -6,12 +6,13 @@
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/netip"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/dnstype"
|
||||
@ -23,7 +24,7 @@
|
||||
func ipps(ippStrs ...string) (ipps []netaddr.IPPrefix) {
|
||||
for _, s := range ippStrs {
|
||||
if ip, err := netaddr.ParseIP(s); err == nil {
|
||||
ipps = append(ipps, netaddr.IPPrefixFrom(ip, ip.BitLen()))
|
||||
ipps = append(ipps, netip.PrefixFrom(ip, ip.BitLen()))
|
||||
continue
|
||||
}
|
||||
ipps = append(ipps, netaddr.MustParseIPPrefix(s))
|
||||
|
@ -11,6 +11,7 @@
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
@ -22,7 +23,7 @@
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"go4.org/netipx"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/envknob"
|
||||
@ -33,6 +34,7 @@
|
||||
"tailscale.com/ipn/policy"
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
@ -231,7 +233,7 @@ func NewLocalBackend(logf logger.Logf, logid string, store ipn.StateStore, diale
|
||||
}
|
||||
|
||||
// Default filter blocks everything and logs nothing, until Start() is called.
|
||||
b.setFilter(filter.NewAllowNone(logf, &netaddr.IPSet{}))
|
||||
b.setFilter(filter.NewAllowNone(logf, &netipx.IPSet{}))
|
||||
|
||||
b.statusChanged = sync.NewCond(&b.statusLock)
|
||||
b.e.SetStatusCallback(b.setWgengineStatus)
|
||||
@ -498,8 +500,8 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
|
||||
}
|
||||
var tailscaleIPs = make([]netaddr.IP, 0, len(p.Addresses))
|
||||
for _, addr := range p.Addresses {
|
||||
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.IP()) {
|
||||
tailscaleIPs = append(tailscaleIPs, addr.IP())
|
||||
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
|
||||
tailscaleIPs = append(tailscaleIPs, addr.Addr())
|
||||
}
|
||||
}
|
||||
exitNodeOption := tsaddr.PrefixesContainsFunc(p.AllowedIPs, func(r netaddr.IPPrefix) bool {
|
||||
@ -543,7 +545,7 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
|
||||
func (b *LocalBackend) WhoIs(ipp netaddr.IPPort) (n *tailcfg.Node, u tailcfg.UserProfile, ok bool) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
n, ok = b.nodeByAddr[ipp.IP()]
|
||||
n, ok = b.nodeByAddr[ipp.Addr()]
|
||||
if !ok {
|
||||
var ip netaddr.IP
|
||||
if ipp.Port() != 0 {
|
||||
@ -580,9 +582,9 @@ func (b *LocalBackend) PeerCaps(src netaddr.IP) []string {
|
||||
if !a.IsSingleIP() {
|
||||
continue
|
||||
}
|
||||
dstIP := a.IP()
|
||||
dstIP := a.Addr()
|
||||
if dstIP.BitLen() == src.BitLen() {
|
||||
return filt.AppendCaps(nil, src, a.IP())
|
||||
return filt.AppendCaps(nil, src, a.Addr())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -750,7 +752,7 @@ func (b *LocalBackend) findExitNodeIDLocked(nm *netmap.NetworkMap) (prefsChanged
|
||||
|
||||
// If we have a desired IP on file, try to find the corresponding
|
||||
// node.
|
||||
if b.prefs.ExitNodeIP.IsZero() {
|
||||
if !b.prefs.ExitNodeIP.IsValid() {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -762,7 +764,7 @@ func (b *LocalBackend) findExitNodeIDLocked(nm *netmap.NetworkMap) (prefsChanged
|
||||
|
||||
for _, peer := range nm.Peers {
|
||||
for _, addr := range peer.Addresses {
|
||||
if !addr.IsSingleIP() || addr.IP() != b.prefs.ExitNodeIP {
|
||||
if !addr.IsSingleIP() || addr.Addr() != b.prefs.ExitNodeIP {
|
||||
continue
|
||||
}
|
||||
// Found the node being referenced, upgrade prefs to
|
||||
@ -1123,8 +1125,8 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs *ipn.
|
||||
haveNetmap = netMap != nil
|
||||
addrs []netaddr.IPPrefix
|
||||
packetFilter []filter.Match
|
||||
localNetsB netaddr.IPSetBuilder
|
||||
logNetsB netaddr.IPSetBuilder
|
||||
localNetsB netipx.IPSetBuilder
|
||||
logNetsB netipx.IPSetBuilder
|
||||
shieldsUp = prefs == nil || prefs.ShieldsUp // Be conservative when not ready
|
||||
)
|
||||
// Log traffic for Tailscale IPs.
|
||||
@ -1241,9 +1243,9 @@ func internalAndExternalInterfaces() (internal, external []netaddr.IPPrefix, err
|
||||
func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (internal, external []netaddr.IPPrefix, err error) {
|
||||
// We use an IPSetBuilder here to canonicalize the prefixes
|
||||
// and to remove any duplicate entries.
|
||||
var internalBuilder, externalBuilder netaddr.IPSetBuilder
|
||||
var internalBuilder, externalBuilder netipx.IPSetBuilder
|
||||
if err := il.ForeachInterfaceAddress(func(iface interfaces.Interface, pfx netaddr.IPPrefix) {
|
||||
if tsaddr.IsTailscaleIP(pfx.IP()) {
|
||||
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||
return
|
||||
}
|
||||
if pfx.IsSingleIP() {
|
||||
@ -1284,16 +1286,16 @@ func internalAndExternalInterfacesFrom(il interfaces.List, goos string) (interna
|
||||
return iSet.Prefixes(), eSet.Prefixes(), nil
|
||||
}
|
||||
|
||||
func interfaceRoutes() (ips *netaddr.IPSet, hostIPs []netaddr.IP, err error) {
|
||||
var b netaddr.IPSetBuilder
|
||||
func interfaceRoutes() (ips *netipx.IPSet, hostIPs []netaddr.IP, err error) {
|
||||
var b netipx.IPSetBuilder
|
||||
if err := interfaces.ForeachInterfaceAddress(func(_ interfaces.Interface, pfx netaddr.IPPrefix) {
|
||||
if tsaddr.IsTailscaleIP(pfx.IP()) {
|
||||
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||
return
|
||||
}
|
||||
if pfx.IsSingleIP() {
|
||||
return
|
||||
}
|
||||
hostIPs = append(hostIPs, pfx.IP())
|
||||
hostIPs = append(hostIPs, pfx.Addr())
|
||||
b.AddPrefix(pfx)
|
||||
}); err != nil {
|
||||
return nil, nil, err
|
||||
@ -1306,8 +1308,8 @@ func interfaceRoutes() (ips *netaddr.IPSet, hostIPs []netaddr.IP, err error) {
|
||||
// shrinkDefaultRoute returns an IPSet representing the IPs in route,
|
||||
// minus those in removeFromDefaultRoute and localInterfaceRoutes,
|
||||
// plus the IPs in hostIPs.
|
||||
func shrinkDefaultRoute(route netaddr.IPPrefix, localInterfaceRoutes *netaddr.IPSet, hostIPs []netaddr.IP) (*netaddr.IPSet, error) {
|
||||
var b netaddr.IPSetBuilder
|
||||
func shrinkDefaultRoute(route netaddr.IPPrefix, localInterfaceRoutes *netipx.IPSet, hostIPs []netaddr.IP) (*netipx.IPSet, error) {
|
||||
var b netipx.IPSetBuilder
|
||||
// Add the default route.
|
||||
b.AddPrefix(route)
|
||||
// Remove the local interface routes.
|
||||
@ -2089,7 +2091,7 @@ func (b *LocalBackend) ServePeerAPIConnection(remote, local netaddr.IPPort, c ne
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
for _, pln := range b.peerAPIListeners {
|
||||
if pln.ip == local.IP() {
|
||||
if pln.ip == local.Addr() {
|
||||
go pln.ServeConn(remote, c)
|
||||
return
|
||||
}
|
||||
@ -2312,8 +2314,8 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Log
|
||||
var ips []netaddr.IP
|
||||
for _, addr := range addrs {
|
||||
if selfV6Only {
|
||||
if addr.IP().Is6() {
|
||||
ips = append(ips, addr.IP())
|
||||
if addr.Addr().Is6() {
|
||||
ips = append(ips, addr.Addr())
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -2325,10 +2327,10 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, prefs *ipn.Prefs, logf logger.Log
|
||||
// https://github.com/tailscale/tailscale/issues/1152
|
||||
// tracks adding the right capability reporting to
|
||||
// enable AAAA in MagicDNS.
|
||||
if addr.IP().Is6() && have4 {
|
||||
if addr.Addr().Is6() && have4 {
|
||||
continue
|
||||
}
|
||||
ips = append(ips, addr.IP())
|
||||
ips = append(ips, addr.Addr())
|
||||
}
|
||||
dcfg.Hosts[fqdn] = ips
|
||||
}
|
||||
@ -2520,7 +2522,7 @@ func (b *LocalBackend) initPeerAPIListener() {
|
||||
if len(b.netMap.Addresses) == len(b.peerAPIListeners) {
|
||||
allSame := true
|
||||
for i, pln := range b.peerAPIListeners {
|
||||
if pln.ip != b.netMap.Addresses[i].IP() {
|
||||
if pln.ip != b.netMap.Addresses[i].Addr() {
|
||||
allSame = false
|
||||
break
|
||||
}
|
||||
@ -2563,20 +2565,20 @@ func (b *LocalBackend) initPeerAPIListener() {
|
||||
var err error
|
||||
skipListen := i > 0 && isNetstack
|
||||
if !skipListen {
|
||||
ln, err = ps.listen(a.IP(), b.prevIfState)
|
||||
ln, err = ps.listen(a.Addr(), b.prevIfState)
|
||||
if err != nil {
|
||||
if peerAPIListenAsync {
|
||||
// Expected. But we fix it later in linkChange
|
||||
// ("peerAPIListeners too low").
|
||||
continue
|
||||
}
|
||||
b.logf("[unexpected] peerapi listen(%q) error: %v", a.IP(), err)
|
||||
b.logf("[unexpected] peerapi listen(%q) error: %v", a.Addr(), err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
pln := &peerAPIListener{
|
||||
ps: ps,
|
||||
ip: a.IP(),
|
||||
ip: a.Addr(),
|
||||
ln: ln, // nil for 2nd+ on netstack
|
||||
lb: b,
|
||||
}
|
||||
@ -2585,7 +2587,7 @@ func (b *LocalBackend) initPeerAPIListener() {
|
||||
} else {
|
||||
pln.port = ln.Addr().(*net.TCPAddr).Port
|
||||
}
|
||||
pln.urlStr = "http://" + net.JoinHostPort(a.IP().String(), strconv.Itoa(pln.port))
|
||||
pln.urlStr = "http://" + net.JoinHostPort(a.Addr().String(), strconv.Itoa(pln.port))
|
||||
b.logf("peerapi: serving on %s", pln.urlStr)
|
||||
go pln.serve()
|
||||
b.peerAPIListeners = append(b.peerAPIListeners, pln)
|
||||
@ -2636,14 +2638,14 @@ func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netaddr.IPPref
|
||||
for _, aip := range peer.AllowedIPs {
|
||||
aip = unmapIPPrefix(aip)
|
||||
// Only add the Tailscale IPv6 ULA once, if we see anybody using part of it.
|
||||
if aip.IP().Is6() && aip.IsSingleIP() && tsULA.Contains(aip.IP()) {
|
||||
if aip.Addr().Is6() && aip.IsSingleIP() && tsULA.Contains(aip.Addr()) {
|
||||
if !didULA {
|
||||
didULA = true
|
||||
routes = append(routes, tsULA)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if aip.IsSingleIP() && cgNAT.Contains(aip.IP()) {
|
||||
if aip.IsSingleIP() && cgNAT.Contains(aip.Addr()) {
|
||||
cgNATIPs = append(cgNATIPs, aip)
|
||||
} else {
|
||||
routes = append(routes, aip)
|
||||
@ -2664,10 +2666,10 @@ func peerRoutes(peers []wgcfg.Peer, cgnatThreshold int) (routes []netaddr.IPPref
|
||||
}
|
||||
|
||||
func ipPrefixLess(ri, rj netaddr.IPPrefix) bool {
|
||||
if ri.IP() == rj.IP() {
|
||||
if ri.Addr() == rj.Addr() {
|
||||
return ri.Bits() < rj.Bits()
|
||||
}
|
||||
return ri.IP().Less(rj.IP())
|
||||
return ri.Addr().Less(rj.Addr())
|
||||
}
|
||||
|
||||
// routerConfig produces a router.Config from a wireguard config and IPN prefs.
|
||||
@ -2695,7 +2697,7 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs *ipn.Prefs, oneCGNA
|
||||
// likely to break some functionality, but if the user expressed a
|
||||
// preference for routing remotely, we want to avoid leaking
|
||||
// traffic at the expense of functionality.
|
||||
if prefs.ExitNodeID != "" || !prefs.ExitNodeIP.IsZero() {
|
||||
if prefs.ExitNodeID != "" || prefs.ExitNodeIP.IsValid() {
|
||||
var default4, default6 bool
|
||||
for _, route := range rs.Routes {
|
||||
switch route {
|
||||
@ -2741,7 +2743,7 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs *ipn.Prefs, oneCGNA
|
||||
}
|
||||
|
||||
func unmapIPPrefix(ipp netaddr.IPPrefix) netaddr.IPPrefix {
|
||||
return netaddr.IPPrefixFrom(ipp.IP().Unmap(), ipp.Bits())
|
||||
return netip.PrefixFrom(ipp.Addr().Unmap(), ipp.Bits())
|
||||
}
|
||||
|
||||
func unmapIPPrefixes(ippsList ...[]netaddr.IPPrefix) (ret []netaddr.IPPrefix) {
|
||||
@ -2828,7 +2830,7 @@ func (b *LocalBackend) enterState(newState ipn.State) {
|
||||
case ipn.Running:
|
||||
var addrs []string
|
||||
for _, addr := range netMap.Addresses {
|
||||
addrs = append(addrs, addr.IP().String())
|
||||
addrs = append(addrs, addr.Addr().String())
|
||||
}
|
||||
systemd.Status("Connected; %s; %s", activeLogin, strings.Join(addrs, " "))
|
||||
default:
|
||||
@ -3114,7 +3116,7 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
|
||||
addNode := func(n *tailcfg.Node) {
|
||||
for _, ipp := range n.Addresses {
|
||||
if ipp.IsSingleIP() {
|
||||
b.nodeByAddr[ipp.IP()] = n
|
||||
b.nodeByAddr[ipp.Addr()] = n
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3294,9 +3296,9 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case a.IP().Is4():
|
||||
case a.Addr().Is4():
|
||||
have4 = true
|
||||
case a.IP().Is6():
|
||||
case a.Addr().Is6():
|
||||
have6 = true
|
||||
}
|
||||
}
|
||||
@ -3318,7 +3320,7 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
|
||||
case have6 && p6 != 0:
|
||||
ipp = netaddr.IPPortFrom(nodeIP(peer, netaddr.IP.Is6), p6)
|
||||
}
|
||||
if ipp.IP().IsZero() {
|
||||
if !ipp.Addr().IsValid() {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("http://%v", ipp)
|
||||
@ -3326,8 +3328,8 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
|
||||
|
||||
func nodeIP(n *tailcfg.Node, pred func(netaddr.IP) bool) netaddr.IP {
|
||||
for _, a := range n.Addresses {
|
||||
if a.IsSingleIP() && pred(a.IP()) {
|
||||
return a.IP()
|
||||
if a.IsSingleIP() && pred(a.Addr()) {
|
||||
return a.Addr()
|
||||
}
|
||||
}
|
||||
return netaddr.IP{}
|
||||
@ -3369,9 +3371,9 @@ func (b *LocalBackend) OfferingExitNode() bool {
|
||||
if r.Bits() != 0 {
|
||||
continue
|
||||
}
|
||||
if r.IP().Is4() {
|
||||
if r.Addr().Is4() {
|
||||
def4 = true
|
||||
} else if r.IP().Is6() {
|
||||
} else if r.Addr().Is6() {
|
||||
def6 = true
|
||||
}
|
||||
}
|
||||
@ -3543,7 +3545,7 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
io.WriteString(w, "<p>Local addresses:</p><ul>\n")
|
||||
for _, ipp := range b.netMap.Addresses {
|
||||
fmt.Fprintf(w, "<li>%v</li>\n", ipp.IP())
|
||||
fmt.Fprintf(w, "<li>%v</li>\n", ipp.Addr())
|
||||
}
|
||||
io.WriteString(w, "</ul>\n")
|
||||
}
|
||||
|
@ -12,10 +12,11 @@
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"go4.org/netipx"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/store/mem"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
@ -173,7 +174,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
|
||||
out: []string{
|
||||
"fe80::1",
|
||||
"ff00::1",
|
||||
tsaddr.TailscaleULARange().IP().String(),
|
||||
tsaddr.TailscaleULARange().Addr().String(),
|
||||
},
|
||||
localIPFn: func(ip netaddr.IP) bool { return !inRemove(ip) && ip.Is6() },
|
||||
},
|
||||
@ -182,7 +183,7 @@ func TestShrinkDefaultRoute(t *testing.T) {
|
||||
// Construct a fake local network environment to make this test hermetic.
|
||||
// localInterfaceRoutes and hostIPs would normally come from calling interfaceRoutes,
|
||||
// and localAddresses would normally come from calling interfaces.LocalAddresses.
|
||||
var b netaddr.IPSetBuilder
|
||||
var b netipx.IPSetBuilder
|
||||
for _, c := range []string{"127.0.0.0/8", "192.168.9.0/24", "fe80::/32"} {
|
||||
p := netaddr.MustParseIPPrefix(c)
|
||||
b.AddPrefix(p)
|
||||
@ -561,7 +562,7 @@ type interfacePrefix struct {
|
||||
ip := interfaces.Interface{
|
||||
Interface: &net.Interface{},
|
||||
AltAddrs: []net.Addr{
|
||||
ippfx.IPNet(),
|
||||
netipx.PrefixIPNet(ippfx),
|
||||
},
|
||||
}
|
||||
if loopback {
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
"github.com/kortschak/wol"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/hostinfo"
|
||||
@ -39,6 +38,7 @@
|
||||
"tailscale.com/logtail/backoff"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/tailcfg"
|
||||
@ -577,7 +577,7 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
<body>
|
||||
<h1>Hello, %s (%v)</h1>
|
||||
This is my Tailscale device. Your device is %v.
|
||||
`, html.EscapeString(who), h.remoteAddr.IP(), html.EscapeString(h.peerNode.ComputedName))
|
||||
`, html.EscapeString(who), h.remoteAddr.Addr(), html.EscapeString(h.peerNode.ComputedName))
|
||||
|
||||
if h.isSelf {
|
||||
fmt.Fprintf(w, "<p>You are the owner of this node.\n")
|
||||
@ -693,7 +693,7 @@ func (h *peerAPIHandler) canWakeOnLAN() bool {
|
||||
}
|
||||
|
||||
func (h *peerAPIHandler) peerHasCap(wantCap string) bool {
|
||||
for _, hasCap := range h.ps.b.PeerCaps(h.remoteAddr.IP()) {
|
||||
for _, hasCap := range h.ps.b.PeerCaps(h.remoteAddr.Addr()) {
|
||||
if hasCap == wantCap {
|
||||
return true
|
||||
}
|
||||
@ -801,7 +801,7 @@ func (h *peerAPIHandler) handlePeerPut(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
d := time.Since(t0).Round(time.Second / 10)
|
||||
h.logf("got put of %s in %v from %v/%v", approxSize(finalSize), d, h.remoteAddr.IP, h.peerNode.ComputedName)
|
||||
h.logf("got put of %s in %v from %v/%v", approxSize(finalSize), d, h.remoteAddr.Addr(), h.peerNode.ComputedName)
|
||||
|
||||
// TODO: set modtime
|
||||
// TODO: some real response
|
||||
@ -925,12 +925,11 @@ func (h *peerAPIHandler) handleWakeOnLAN(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
for ifName, ips := range st.InterfaceIPs {
|
||||
for _, ip := range ips {
|
||||
if ip.IP().IsLoopback() || ip.IP().Is6() {
|
||||
if ip.Addr().IsLoopback() || ip.Addr().Is6() {
|
||||
continue
|
||||
}
|
||||
ipa := ip.IP().IPAddr()
|
||||
local := &net.UDPAddr{
|
||||
IP: ipa.IP,
|
||||
IP: ip.Addr().AsSlice(),
|
||||
Port: 0,
|
||||
}
|
||||
remote := &net.UDPAddr{
|
||||
@ -982,7 +981,7 @@ func (h *peerAPIHandler) replyToDNSQueries() bool {
|
||||
// arbitrary. DNS runs over TCP and UDP, so sure... we check
|
||||
// TCP.
|
||||
dstIP := netaddr.IPv4(0, 0, 0, 0)
|
||||
remoteIP := h.remoteAddr.IP()
|
||||
remoteIP := h.remoteAddr.Addr()
|
||||
if remoteIP.Is6() {
|
||||
// autogroup:internet for IPv6 is defined to start with 2000::/3,
|
||||
// so use 2000::0 as the probe "the internet" address.
|
||||
@ -1171,7 +1170,7 @@ func writePrettyDNSReply(w io.Writer, res []byte) (err error) {
|
||||
// See docs on fakePeerAPIListener.
|
||||
func newFakePeerAPIListener(ip netaddr.IP) net.Listener {
|
||||
return &fakePeerAPIListener{
|
||||
addr: netaddr.IPPortFrom(ip, 1).TCPAddr(),
|
||||
addr: net.TCPAddrFromAddrPort(netaddr.IPPortFrom(ip, 1)),
|
||||
closed: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
)
|
||||
|
||||
|
@ -19,8 +19,9 @@
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"go4.org/netipx"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/logger"
|
||||
@ -607,7 +608,7 @@ func TestPeerAPIReplyToDNSQueries(t *testing.T) {
|
||||
t.Errorf("unexpectedly doing DNS without filter")
|
||||
}
|
||||
|
||||
h.ps.b.setFilter(filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)))
|
||||
h.ps.b.setFilter(filter.NewAllowNone(logger.Discard, new(netipx.IPSet)))
|
||||
if h.replyToDNSQueries() {
|
||||
t.Errorf("unexpectedly doing DNS without filter")
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"inet.af/peercred"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/envknob"
|
||||
@ -37,6 +36,7 @@
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/localapi"
|
||||
"tailscale.com/logtail/backoff"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netstat"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/net/tsdial"
|
||||
@ -154,7 +154,7 @@ func (s *Server) getConnIdentity(c net.Conn) (ci connIdentity, err error) {
|
||||
if err != nil {
|
||||
return ci, fmt.Errorf("parsing local remote: %w", err)
|
||||
}
|
||||
if !la.IP().IsLoopback() || !ra.IP().IsLoopback() {
|
||||
if !la.Addr().IsLoopback() || !ra.Addr().IsLoopback() {
|
||||
return ci, errors.New("non-loopback connection")
|
||||
}
|
||||
tab, err := netstat.Get()
|
||||
|
@ -17,7 +17,7 @@
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/views"
|
||||
|
@ -24,11 +24,11 @@
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
@ -242,7 +242,7 @@ func (h *Handler) serveWhoIs(w http.ResponseWriter, r *http.Request) {
|
||||
res := &apitype.WhoIsResponse{
|
||||
Node: n,
|
||||
UserProfile: &u,
|
||||
Caps: b.PeerCaps(ipp.IP()),
|
||||
Caps: b.PeerCaps(ipp.Addr()),
|
||||
}
|
||||
j, err := json.MarshalIndent(res, "", "\t")
|
||||
if err != nil {
|
||||
|
@ -11,15 +11,16 @@
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/atomicfile"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/persist"
|
||||
@ -308,7 +309,7 @@ func (p *Prefs) pretty(goos string) string {
|
||||
if p.ShieldsUp {
|
||||
sb.WriteString("shields=true ")
|
||||
}
|
||||
if !p.ExitNodeIP.IsZero() {
|
||||
if p.ExitNodeIP.IsValid() {
|
||||
fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeIP, p.ExitNodeAllowLANAccess)
|
||||
} else if !p.ExitNodeID.IsZero() {
|
||||
fmt.Fprintf(&sb, "exit=%v lan=%t ", p.ExitNodeID, p.ExitNodeAllowLANAccess)
|
||||
@ -478,7 +479,7 @@ func (p *Prefs) SetAdvertiseExitNode(runExit bool) {
|
||||
}
|
||||
p.AdvertiseRoutes = append(p.AdvertiseRoutes,
|
||||
netaddr.IPPrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0),
|
||||
netaddr.IPPrefixFrom(netaddr.IPv6Unspecified(), 0))
|
||||
netaddr.IPPrefixFrom(netip.IPv6Unspecified(), 0))
|
||||
}
|
||||
|
||||
// peerWithTailscaleIP returns the peer in st with the provided
|
||||
|
@ -16,8 +16,8 @@
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/key"
|
||||
|
@ -9,8 +9,8 @@
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/util/dnsname"
|
||||
|
@ -20,8 +20,8 @@
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/dns/resolvconffile"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/version/distro"
|
||||
|
@ -15,7 +15,7 @@
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
@ -242,7 +242,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig
|
||||
func toIPsOnly(resolvers []*dnstype.Resolver) (ret []netaddr.IP) {
|
||||
for _, r := range resolvers {
|
||||
if ipp, ok := r.IPPort(); ok && ipp.Port() == 53 {
|
||||
ret = append(ret, ipp.IP())
|
||||
ret = append(ret, ipp.Addr())
|
||||
}
|
||||
}
|
||||
return ret
|
||||
@ -299,11 +299,11 @@ func (m *Manager) NextPacket() ([]byte, error) {
|
||||
|
||||
var buf []byte
|
||||
switch {
|
||||
case resp.to.IP().Is4():
|
||||
case resp.to.Addr().Is4():
|
||||
h := packet.UDP4Header{
|
||||
IP4Header: packet.IP4Header{
|
||||
Src: magicDNSIP,
|
||||
Dst: resp.to.IP(),
|
||||
Dst: resp.to.Addr(),
|
||||
},
|
||||
SrcPort: 53,
|
||||
DstPort: resp.to.Port(),
|
||||
@ -312,11 +312,11 @@ func (m *Manager) NextPacket() ([]byte, error) {
|
||||
buf = make([]byte, offset+hlen+len(resp.pkt))
|
||||
copy(buf[offset+hlen:], resp.pkt)
|
||||
h.Marshal(buf[offset:])
|
||||
case resp.to.IP().Is6():
|
||||
case resp.to.Addr().Is6():
|
||||
h := packet.UDP6Header{
|
||||
IP6Header: packet.IP6Header{
|
||||
Src: magicDNSIPv6,
|
||||
Dst: resp.to.IP(),
|
||||
Dst: resp.to.Addr(),
|
||||
},
|
||||
SrcPort: 53,
|
||||
DstPort: resp.to.Port(),
|
||||
|
@ -13,8 +13,8 @@
|
||||
"time"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/cmpver"
|
||||
)
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/dns/resolver"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/util/dnsname"
|
||||
@ -396,7 +396,7 @@ func TestManager(t *testing.T) {
|
||||
trIP := cmp.Transformer("ipStr", func(ip netaddr.IP) string { return ip.String() })
|
||||
trIPPort := cmp.Transformer("ippStr", func(ipp netaddr.IPPort) string {
|
||||
if ipp.Port() == 53 {
|
||||
return ipp.IP().String()
|
||||
return ipp.Addr().String()
|
||||
}
|
||||
return ipp.String()
|
||||
})
|
||||
|
@ -16,8 +16,8 @@
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/winutil"
|
||||
)
|
||||
|
@ -14,8 +14,8 @@
|
||||
"time"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/endian"
|
||||
)
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var knownDoH = map[netaddr.IP]string{} // 8.8.8.8 => "https://..."
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@ -15,11 +15,11 @@
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"tailscale.com/logtail/backoff"
|
||||
"github.com/godbus/dbus/v5"
|
||||
"golang.org/x/sys/unix"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/health"
|
||||
"tailscale.com/logtail/backoff"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
@ -78,7 +78,7 @@ type resolvedLinkDomain struct {
|
||||
// changeRequest tracks latest OSConfig and related error responses to update.
|
||||
type changeRequest struct {
|
||||
config OSConfig // configs OSConfigs, one per each SetDNS call
|
||||
res chan <- error // response channel
|
||||
res chan<- error // response channel
|
||||
}
|
||||
|
||||
// resolvedManager is an OSConfigurator which uses the systemd-resolved DBus API.
|
||||
|
@ -24,16 +24,17 @@
|
||||
"time"
|
||||
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/net/dns/publicdns"
|
||||
"tailscale.com/net/dnscache"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/neterror"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/nettype"
|
||||
"tailscale.com/util/cloudenv"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/wgengine/monitor"
|
||||
@ -267,7 +268,7 @@ func resolversWithDelays(resolvers []*dnstype.Resolver) []resolverAndDelay {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
dohBase, ok := publicdns.KnownDoH()[ipp.IP()]
|
||||
dohBase, ok := publicdns.KnownDoH()[ipp.Addr()]
|
||||
if !ok || didDoH[dohBase] {
|
||||
continue
|
||||
}
|
||||
@ -288,12 +289,12 @@ type hostAndFam struct {
|
||||
rr = append(rr, resolverAndDelay{name: r})
|
||||
continue
|
||||
}
|
||||
ip := ipp.IP()
|
||||
ip := ipp.Addr()
|
||||
var startDelay time.Duration
|
||||
if host, ok := publicdns.KnownDoH()[ip]; ok {
|
||||
// We already did the DoH query early. These
|
||||
startDelay = dohHeadStart
|
||||
key := hostAndFam{host, ip.BitLen()}
|
||||
key := hostAndFam{host, uint8(ip.BitLen())}
|
||||
if done[key] > 0 {
|
||||
startDelay += wellKnownHostBackupDelay
|
||||
}
|
||||
@ -364,13 +365,9 @@ func (f *forwarder) setRoutes(routesBySuffix map[dnsname.FQDN][]*dnstype.Resolve
|
||||
f.cloudHostFallback = cloudHostFallback
|
||||
}
|
||||
|
||||
var stdNetPacketListener packetListener = new(net.ListenConfig)
|
||||
var stdNetPacketListener nettype.PacketListenerWithNetIP = nettype.MakePacketListenerWithNetIP(new(net.ListenConfig))
|
||||
|
||||
type packetListener interface {
|
||||
ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error)
|
||||
}
|
||||
|
||||
func (f *forwarder) packetListener(ip netaddr.IP) (packetListener, error) {
|
||||
func (f *forwarder) packetListener(ip netaddr.IP) (nettype.PacketListenerWithNetIP, error) {
|
||||
if f.linkSel == nil || initListenConfig == nil {
|
||||
return stdNetPacketListener, nil
|
||||
}
|
||||
@ -382,7 +379,7 @@ func (f *forwarder) packetListener(ip netaddr.IP) (packetListener, error) {
|
||||
if err := initListenConfig(lc, f.linkMon, linkName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lc, nil
|
||||
return nettype.MakePacketListenerWithNetIP(lc), nil
|
||||
}
|
||||
|
||||
// getKnownDoHClientForProvider returns an HTTP client for a specific DoH
|
||||
@ -528,11 +525,17 @@ func (f *forwarder) sendUDP(ctx context.Context, fq *forwardQuery, rr resolverAn
|
||||
}
|
||||
metricDNSFwdUDP.Add(1)
|
||||
|
||||
ln, err := f.packetListener(ipp.IP())
|
||||
ln, err := f.packetListener(ipp.Addr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn, err := ln.ListenPacket(ctx, "udp", ":0")
|
||||
|
||||
// Specify the exact UDP family to work around https://github.com/golang/go/issues/52264
|
||||
udpFam := "udp4"
|
||||
if ipp.Addr().Is6() {
|
||||
udpFam = "udp6"
|
||||
}
|
||||
conn, err := ln.ListenPacket(ctx, udpFam, ":0")
|
||||
if err != nil {
|
||||
f.logf("ListenPacket failed: %v", err)
|
||||
return nil, err
|
||||
@ -542,7 +545,7 @@ func (f *forwarder) sendUDP(ctx context.Context, fq *forwardQuery, rr resolverAn
|
||||
fq.closeOnCtxDone.Add(conn)
|
||||
defer fq.closeOnCtxDone.Remove(conn)
|
||||
|
||||
if _, err := conn.WriteTo(fq.packet, ipp.UDPAddr()); err != nil {
|
||||
if _, err := conn.WriteToUDPAddrPort(fq.packet, ipp); err != nil {
|
||||
metricDNSFwdUDPErrorWrite.Add(1)
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
|
@ -14,6 +14,7 @@
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
@ -24,8 +25,8 @@
|
||||
"time"
|
||||
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/dns/resolvconffile"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/types/dnstype"
|
||||
@ -680,8 +681,8 @@ func (r *Resolver) parseViaDomain(domain dnsname.FQDN, typ dns.Type) (netaddr.IP
|
||||
}
|
||||
|
||||
// MapVia will never error when given an ipv4 netaddr.IPPrefix.
|
||||
out, _ := tsaddr.MapVia(uint32(prefix), netaddr.IPPrefixFrom(ip4, ip4.BitLen()))
|
||||
return out.IP(), true
|
||||
out, _ := tsaddr.MapVia(uint32(prefix), netip.PrefixFrom(ip4, ip4.BitLen()))
|
||||
return out.Addr(), true
|
||||
}
|
||||
|
||||
// resolveReverse returns the unique domain name that maps to the given address.
|
||||
|
@ -11,7 +11,7 @@
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
// This file exists to isolate the test infrastructure
|
||||
@ -41,7 +41,7 @@ func resolveToIP(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
A: ipv4.IPAddr().IP,
|
||||
A: ipv4.AsSlice(),
|
||||
}
|
||||
case dns.TypeAAAA:
|
||||
ans = &dns.AAAA{
|
||||
@ -50,7 +50,7 @@ func resolveToIP(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
AAAA: ipv6.IPAddr().IP,
|
||||
AAAA: ipv6.AsSlice(),
|
||||
}
|
||||
case dns.TypeNS:
|
||||
ans = &dns.NS{
|
||||
@ -93,7 +93,7 @@ func resolveToIPLowercase(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
A: ipv4.IPAddr().IP,
|
||||
A: ipv4.AsSlice(),
|
||||
}
|
||||
case dns.TypeAAAA:
|
||||
ans = &dns.AAAA{
|
||||
@ -102,7 +102,7 @@ func resolveToIPLowercase(ipv4, ipv6 netaddr.IP, ns string) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
AAAA: ipv6.IPAddr().IP,
|
||||
AAAA: ipv6.AsSlice(),
|
||||
}
|
||||
case dns.TypeNS:
|
||||
ans = &dns.NS{
|
||||
@ -244,7 +244,7 @@ func dnsHandler(answers ...any) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
A: ip.IPAddr().IP,
|
||||
A: ip.AsSlice(),
|
||||
})
|
||||
} else if ip.Is6() {
|
||||
m.Answer = append(m.Answer, &dns.AAAA{
|
||||
@ -253,7 +253,7 @@ func dnsHandler(answers ...any) dns.HandlerFunc {
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
AAAA: ip.IPAddr().IP,
|
||||
AAAA: ip.AsSlice(),
|
||||
})
|
||||
}
|
||||
case dns.PTR:
|
||||
|
@ -23,7 +23,7 @@
|
||||
miekdns "github.com/miekg/dns"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
dns "golang.org/x/net/dns/dnsmessage"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/dnstype"
|
||||
|
@ -19,8 +19,8 @@
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/cloudenv"
|
||||
"tailscale.com/util/singleflight"
|
||||
)
|
||||
@ -153,7 +153,10 @@ func (r *Resolver) LookupIP(ctx context.Context, host string) (ip, v6 net.IP, al
|
||||
return nil, nil, nil, fmt.Errorf("dnscache: unexpected hostname %q doesn't match expected %q", host, r.SingleHost)
|
||||
}
|
||||
for _, naIP := range r.SingleHostStaticResult {
|
||||
ipa := naIP.IPAddr()
|
||||
ipa := &net.IPAddr{
|
||||
IP: naIP.AsSlice(),
|
||||
Zone: naIP.Zone(),
|
||||
}
|
||||
if ip == nil && naIP.Is4() {
|
||||
ip = ipa.IP
|
||||
}
|
||||
@ -273,7 +276,10 @@ func (r *Resolver) lookupIP(host string) (ip, ip6 net.IP, allIPs []net.IPAddr, e
|
||||
if err == nil {
|
||||
ips = nil
|
||||
for _, fip := range fips {
|
||||
ips = append(ips, *fip.IPAddr())
|
||||
ips = append(ips, net.IPAddr{
|
||||
IP: fip.AsSlice(),
|
||||
Zone: fip.Zone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var dialTest = flag.String("dial-test", "", "if non-empty, addr:port to test dial")
|
||||
|
@ -90,18 +90,25 @@
|
||||
"RegionName": "r2",
|
||||
"Nodes": [
|
||||
{
|
||||
"Name": "2a",
|
||||
"Name": "2d",
|
||||
"RegionID": 2,
|
||||
"HostName": "derp2.tailscale.com",
|
||||
"IPv4": "167.172.206.31",
|
||||
"IPv6": "2604:a880:2:d1::c5:7001"
|
||||
"HostName": "derp2d.tailscale.com",
|
||||
"IPv4": "192.73.252.65",
|
||||
"IPv6": "2607:f740:0:3f::287"
|
||||
},
|
||||
{
|
||||
"Name": "2b",
|
||||
"Name": "2e",
|
||||
"RegionID": 2,
|
||||
"HostName": "derp2b.tailscale.com",
|
||||
"IPv4": "64.227.106.23",
|
||||
"IPv6": "2604:a880:4:1d0::29:9000"
|
||||
"HostName": "derp2e.tailscale.com",
|
||||
"IPv4": "192.73.252.134",
|
||||
"IPv6": "2607:f740:0:3f::44c"
|
||||
},
|
||||
{
|
||||
"Name": "2f",
|
||||
"RegionID": 2,
|
||||
"HostName": "derp2f.tailscale.com",
|
||||
"IPv4": "208.111.34.178",
|
||||
"IPv6": "2607:f740:0:3f::f4"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -21,7 +21,7 @@
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/tlsdial"
|
||||
"tailscale.com/net/tshttpproxy"
|
||||
@ -29,7 +29,7 @@
|
||||
)
|
||||
|
||||
func Lookup(ctx context.Context, host string) ([]netaddr.IP, error) {
|
||||
if ip, err := netaddr.ParseIP(host); err == nil && !ip.IsZero() {
|
||||
if ip, err := netaddr.ParseIP(host); err == nil && ip.IsValid() {
|
||||
return []netaddr.IP{ip}, nil
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
)
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/hostinfo"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tshttpproxy"
|
||||
)
|
||||
@ -248,7 +248,7 @@ func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) erro
|
||||
}
|
||||
}
|
||||
sort.Slice(pfxs, func(i, j int) bool {
|
||||
return pfxs[i].IP().Less(pfxs[j].IP())
|
||||
return pfxs[i].Addr().Less(pfxs[j].Addr())
|
||||
})
|
||||
fn(iface, pfxs)
|
||||
}
|
||||
@ -326,7 +326,7 @@ func (s *State) String() string {
|
||||
fmt.Fprintf(&sb, "%s:[", ifName)
|
||||
needSpace := false
|
||||
for _, pfx := range s.InterfaceIPs[ifName] {
|
||||
if !isInterestingIP(pfx.IP()) {
|
||||
if !isInterestingIP(pfx.Addr()) {
|
||||
continue
|
||||
}
|
||||
if needSpace {
|
||||
@ -413,7 +413,7 @@ func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
|
||||
// TODO: rewrite prefixesEqualFiltered to avoid making copies
|
||||
x := make([]netaddr.IPPrefix, 0, len(ipps))
|
||||
for _, ipp := range ipps {
|
||||
if useIP(ipp.IP()) {
|
||||
if useIP(ipp.Addr()) {
|
||||
x = append(x, ipp)
|
||||
}
|
||||
}
|
||||
@ -467,7 +467,7 @@ func (s *State) AnyInterfaceUp() bool {
|
||||
|
||||
func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
|
||||
for _, pfx := range pfxs {
|
||||
if tsaddr.IsTailscaleIP(pfx.IP()) {
|
||||
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -507,11 +507,11 @@ func GetState() (*State, error) {
|
||||
return
|
||||
}
|
||||
for _, pfx := range pfxs {
|
||||
if pfx.IP().IsLoopback() {
|
||||
if pfx.Addr().IsLoopback() {
|
||||
continue
|
||||
}
|
||||
s.HaveV6 = s.HaveV6 || isUsableV6(pfx.IP())
|
||||
s.HaveV4 = s.HaveV4 || isUsableV4(pfx.IP())
|
||||
s.HaveV6 = s.HaveV6 || isUsableV6(pfx.Addr())
|
||||
s.HaveV4 = s.HaveV4 || isUsableV4(pfx.Addr())
|
||||
}
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
@ -556,7 +556,7 @@ func HTTPOfListener(ln net.Listener) string {
|
||||
var goodIP string
|
||||
var privateIP string
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
||||
ip := pfx.IP()
|
||||
ip := pfx.Addr()
|
||||
if ip.IsPrivate() {
|
||||
if privateIP == "" {
|
||||
privateIP = ip.String()
|
||||
@ -593,8 +593,8 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
||||
return
|
||||
}
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
||||
ip := pfx.IP()
|
||||
if !i.IsUp() || ip.IsZero() || !myIP.IsZero() {
|
||||
ip := pfx.Addr()
|
||||
if !i.IsUp() || !ip.IsValid() || myIP.IsValid() {
|
||||
return
|
||||
}
|
||||
if gateway.IsPrivate() && ip.IsPrivate() {
|
||||
@ -603,7 +603,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
||||
return
|
||||
}
|
||||
})
|
||||
return gateway, myIP, !myIP.IsZero()
|
||||
return gateway, myIP, myIP.IsValid()
|
||||
}
|
||||
|
||||
// isUsableV4 reports whether ip is a usable IPv4 address which could
|
||||
@ -637,7 +637,7 @@ func isUsableV6(ip netaddr.IP) bool {
|
||||
// isInterestingIP.
|
||||
func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
|
||||
for _, pfx := range pfxs {
|
||||
if isInterestingIP(pfx.IP()) {
|
||||
if isInterestingIP(pfx.Addr()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
"golang.org/x/net/route"
|
||||
"golang.org/x/sys/unix"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func defaultRoute() (d DefaultRouteDetails, err error) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
"golang.org/x/net/route"
|
||||
"golang.org/x/sys/unix"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func defaultRoute() (d DefaultRouteDetails, err error) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
"testing"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/lineread"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
@ -80,7 +80,7 @@ func likelyHomeRouterIPDarwinExec() (ret netaddr.IP, ok bool) {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return ret, !ret.IsZero()
|
||||
return ret, ret.IsValid()
|
||||
}
|
||||
|
||||
func TestFetchRoutingTable(t *testing.T) {
|
||||
|
@ -21,7 +21,7 @@
|
||||
"github.com/mdlayher/netlink"
|
||||
"go4.org/mem"
|
||||
"golang.org/x/sys/unix"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/util/lineread"
|
||||
)
|
||||
@ -98,7 +98,7 @@ func likelyHomeRouterIPLinux() (ret netaddr.IP, ok bool) {
|
||||
}
|
||||
log.Printf("interfaces: failed to read /proc/net/route: %v", err)
|
||||
}
|
||||
return ret, !ret.IsZero()
|
||||
return ret, ret.IsValid()
|
||||
}
|
||||
|
||||
// Android apps don't have permission to read /proc/net/route, at
|
||||
@ -133,7 +133,7 @@ func likelyHomeRouterIPAndroid() (ret netaddr.IP, ok bool) {
|
||||
})
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
return ret, !ret.IsZero()
|
||||
return ret, ret.IsValid()
|
||||
}
|
||||
|
||||
func defaultRoute() (d DefaultRouteDetails, err error) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestGetState(t *testing.T) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tsconst"
|
||||
)
|
||||
|
||||
@ -92,12 +92,12 @@ func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if !ret.IsZero() && !ret.IsPrivate() {
|
||||
if ret.IsValid() && !ret.IsPrivate() {
|
||||
// Default route has a non-private gateway
|
||||
return netaddr.IP{}, false
|
||||
}
|
||||
|
||||
return ret, !ret.IsZero()
|
||||
return ret, ret.IsValid()
|
||||
}
|
||||
|
||||
// NonTailscaleMTUs returns a map of interface LUID to interface MTU,
|
||||
|
135
net/netaddr/netaddr.go
Normal file
135
net/netaddr/netaddr.go
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package netaddr is a transitional package while we finish migrating from inet.af/netaddr
|
||||
// to Go 1.18's net/netip.
|
||||
//
|
||||
// TODO(bradfitz): delete this package eventually. Tracking bug is
|
||||
// https://github.com/tailscale/tailscale/issues/5162
|
||||
package netaddr
|
||||
|
||||
import (
|
||||
"math"
|
||||
"net"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type (
|
||||
IP = netip.Addr
|
||||
IPPort = netip.AddrPort
|
||||
IPPrefix = netip.Prefix
|
||||
)
|
||||
|
||||
// IPv4 returns the IP of the IPv4 address a.b.c.d.
|
||||
func IPv4(a, b, c, d uint8) IP {
|
||||
return netip.AddrFrom4([4]byte{a, b, c, d})
|
||||
}
|
||||
|
||||
// IPFrom16 returns the IP address given by the bytes in addr, unmapping any
|
||||
// v6-mapped IPv4 address.
|
||||
//
|
||||
// It is equivalent to calling IPv6Raw(addr).Unmap().
|
||||
func IPFrom16(a [16]byte) IP {
|
||||
return netip.AddrFrom16(a).Unmap()
|
||||
}
|
||||
|
||||
// IPv6Raw returns the IPv6 address given by the bytes in addr, without an
|
||||
// implicit Unmap call to unmap any v6-mapped IPv4 address.
|
||||
func IPv6Raw(a [16]byte) IP {
|
||||
return netip.AddrFrom16(a) // no implicit unmapping
|
||||
}
|
||||
|
||||
// IPFrom4 returns the IPv4 address given by the bytes in addr. It is equivalent
|
||||
// to calling IPv4(addr[0], addr[1], addr[2], addr[3]).
|
||||
func IPFrom4(a [4]byte) IP {
|
||||
return netip.AddrFrom4(a)
|
||||
}
|
||||
|
||||
// IPPrefixFrom returns an IPPrefix with IP ip and provided bits prefix length.
|
||||
// It does not allocate.
|
||||
func IPPrefixFrom(ip IP, bits uint8) IPPrefix {
|
||||
return netip.PrefixFrom(ip, int(bits))
|
||||
}
|
||||
|
||||
// IPPortFrom returns an IPPort with IP ip and port port. It does not allocate.
|
||||
func IPPortFrom(ip IP, port uint16) IPPort {
|
||||
return netip.AddrPortFrom(ip, port)
|
||||
}
|
||||
|
||||
// FromStdIPRaw returns an IP from the standard library's IP type.
|
||||
// If std is invalid, ok is false.
|
||||
// Unlike FromStdIP, FromStdIPRaw does not do an implicit Unmap if
|
||||
// len(std) == 16 and contains an IPv6-mapped IPv4 address.
|
||||
func FromStdIPRaw(std net.IP) (ip IP, ok bool) {
|
||||
return netip.AddrFromSlice(std)
|
||||
}
|
||||
|
||||
// FromStdIP returns an IP from the standard library's IP type.
|
||||
//
|
||||
// If std is invalid, ok is false.
|
||||
//
|
||||
// FromStdIP implicitly unmaps IPv6-mapped IPv4 addresses. That is, if
|
||||
// len(std) == 16 and contains an IPv4 address, only the IPv4 part is
|
||||
// returned, without the IPv6 wrapper. This is the common form returned by
|
||||
// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
|
||||
// To convert a standard library IP without the implicit unmapping, use
|
||||
// FromStdIPRaw.
|
||||
func FromStdIP(std net.IP) (ip IP, ok bool) {
|
||||
ret, ok := FromStdIPRaw(std)
|
||||
if !ok {
|
||||
return ret, false
|
||||
}
|
||||
if ret.Is4In6() {
|
||||
return ret.Unmap(), true
|
||||
}
|
||||
return ret, true
|
||||
}
|
||||
|
||||
// FromStdIPNet returns an IPPrefix from the standard library's IPNet type.
|
||||
// If std is invalid, ok is false.
|
||||
func FromStdIPNet(std *net.IPNet) (prefix IPPrefix, ok bool) {
|
||||
ip, ok := FromStdIP(std.IP)
|
||||
if !ok {
|
||||
return IPPrefix{}, false
|
||||
}
|
||||
|
||||
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
|
||||
// Invalid mask.
|
||||
return IPPrefix{}, false
|
||||
}
|
||||
|
||||
ones, bits := std.Mask.Size()
|
||||
if ones == 0 && bits == 0 {
|
||||
// IPPrefix does not support non-contiguous masks.
|
||||
return IPPrefix{}, false
|
||||
}
|
||||
|
||||
return netip.PrefixFrom(ip, ones), true
|
||||
}
|
||||
|
||||
// FromStdAddr maps the components of a standard library TCPAddr or
|
||||
// UDPAddr into an IPPort.
|
||||
func FromStdAddr(stdIP net.IP, port int, zone string) (_ IPPort, ok bool) {
|
||||
ip, ok := FromStdIP(stdIP)
|
||||
if !ok || port < 0 || port > math.MaxUint16 {
|
||||
return
|
||||
}
|
||||
ip = ip.Unmap()
|
||||
if zone != "" {
|
||||
if ip.Is4() {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
ip = ip.WithZone(zone)
|
||||
}
|
||||
return netip.AddrPortFrom(ip, uint16(port)), true
|
||||
}
|
||||
|
||||
func ParseIP(s string) (IP, error) { return netip.ParseAddr(s) }
|
||||
func ParseIPPrefix(s string) (IPPrefix, error) { return netip.ParsePrefix(s) }
|
||||
func ParseIPPort(s string) (IPPort, error) { return netip.ParseAddrPort(s) }
|
||||
|
||||
func MustParseIP(s string) IP { return netip.MustParseAddr(s) }
|
||||
func MustParseIPPrefix(s string) IPPrefix { return netip.MustParsePrefix(s) }
|
||||
func MustParseIPPort(s string) IPPort { return netip.MustParseAddrPort(s) }
|
@ -16,16 +16,17 @@
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/tcnksm/go-httpstat"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/derp/derphttp"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/neterror"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/portmapper"
|
||||
@ -33,6 +34,7 @@
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/nettype"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/util/clientmetric"
|
||||
)
|
||||
@ -179,6 +181,7 @@ type Client struct {
|
||||
// STUNConn is the interface required by the netcheck Client when
|
||||
// reusing an existing UDP connection.
|
||||
type STUNConn interface {
|
||||
WriteToUDPAddrPort([]byte, netip.AddrPort) (int, error)
|
||||
WriteTo([]byte, net.Addr) (int, error)
|
||||
ReadFrom([]byte) (int, net.Addr, error)
|
||||
}
|
||||
@ -234,9 +237,9 @@ func (c *Client) MakeNextReportFull() {
|
||||
func (c *Client) ReceiveSTUNPacket(pkt []byte, src netaddr.IPPort) {
|
||||
c.vlogf("received STUN packet from %s", src)
|
||||
|
||||
if src.IP().Is4() {
|
||||
if src.Addr().Is4() {
|
||||
metricSTUNRecv4.Add(1)
|
||||
} else if src.IP().Is6() {
|
||||
} else if src.Addr().Is6() {
|
||||
metricSTUNRecv6.Add(1)
|
||||
}
|
||||
|
||||
@ -527,7 +530,7 @@ type reportState struct {
|
||||
hairTimeout chan struct{} // closed on timeout
|
||||
pc4 STUNConn
|
||||
pc6 STUNConn
|
||||
pc4Hair net.PacketConn
|
||||
pc4Hair nettype.PacketConn
|
||||
incremental bool // doing a lite, follow-up netcheck
|
||||
stopProbeCh chan struct{}
|
||||
waitPortMap sync.WaitGroup
|
||||
@ -592,9 +595,8 @@ func (rs *reportState) startHairCheckLocked(dst netaddr.IPPort) {
|
||||
return
|
||||
}
|
||||
rs.sentHairCheck = true
|
||||
ua := dst.UDPAddr()
|
||||
rs.pc4Hair.WriteTo(stun.Request(rs.hairTX), ua)
|
||||
rs.c.vlogf("sent haircheck to %v", ua)
|
||||
rs.pc4Hair.WriteToUDPAddrPort(stun.Request(rs.hairTX), dst)
|
||||
rs.c.vlogf("sent haircheck to %v", dst)
|
||||
time.AfterFunc(hairpinCheckTimeout, func() { close(rs.hairTimeout) })
|
||||
}
|
||||
|
||||
@ -643,7 +645,7 @@ func (rs *reportState) stopTimers() {
|
||||
func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netaddr.IPPort, d time.Duration) {
|
||||
var ipPortStr string
|
||||
if ipp != (netaddr.IPPort{}) {
|
||||
ipPortStr = net.JoinHostPort(ipp.IP().String(), fmt.Sprint(ipp.Port()))
|
||||
ipPortStr = net.JoinHostPort(ipp.Addr().String(), fmt.Sprint(ipp.Port()))
|
||||
}
|
||||
|
||||
rs.mu.Lock()
|
||||
@ -668,13 +670,13 @@ func (rs *reportState) addNodeLatency(node *tailcfg.DERPNode, ipp netaddr.IPPort
|
||||
}
|
||||
|
||||
switch {
|
||||
case ipp.IP().Is6():
|
||||
case ipp.Addr().Is6():
|
||||
updateLatency(ret.RegionV6Latency, node.RegionID, d)
|
||||
ret.IPv6 = true
|
||||
ret.GlobalV6 = ipPortStr
|
||||
// TODO: track MappingVariesByDestIP for IPv6
|
||||
// too? Would be sad if so, but who knows.
|
||||
case ipp.IP().Is4():
|
||||
case ipp.Addr().Is4():
|
||||
updateLatency(ret.RegionV4Latency, node.RegionID, d)
|
||||
ret.IPv4 = true
|
||||
if rs.gotEP4 == "" {
|
||||
@ -809,14 +811,14 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (_ *Report,
|
||||
|
||||
// See if IPv6 works at all, or if it's been hard disabled at the
|
||||
// OS level.
|
||||
v6udp, err := netns.Listener(c.logf).ListenPacket(ctx, "udp6", "[::1]:0")
|
||||
v6udp, err := nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf)).ListenPacket(ctx, "udp6", "[::1]:0")
|
||||
if err == nil {
|
||||
rs.report.OSHasIPv6 = true
|
||||
v6udp.Close()
|
||||
}
|
||||
|
||||
// Create a UDP4 socket used for sending to our discovered IPv4 address.
|
||||
rs.pc4Hair, err = netns.Listener(c.logf).ListenPacket(ctx, "udp4", ":0")
|
||||
rs.pc4Hair, err = nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf)).ListenPacket(ctx, "udp4", ":0")
|
||||
if err != nil {
|
||||
c.logf("udp4: %v", err)
|
||||
return nil, err
|
||||
@ -844,7 +846,7 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (_ *Report,
|
||||
if f := c.GetSTUNConn4; f != nil {
|
||||
rs.pc4 = f()
|
||||
} else {
|
||||
u4, err := netns.Listener(c.logf).ListenPacket(ctx, "udp4", c.udpBindAddr())
|
||||
u4, err := nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf)).ListenPacket(ctx, "udp4", c.udpBindAddr())
|
||||
if err != nil {
|
||||
c.logf("udp4: %v", err)
|
||||
return nil, err
|
||||
@ -857,7 +859,7 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap) (_ *Report,
|
||||
if f := c.GetSTUNConn6; f != nil {
|
||||
rs.pc6 = f()
|
||||
} else {
|
||||
u6, err := netns.Listener(c.logf).ListenPacket(ctx, "udp6", c.udpBindAddr())
|
||||
u6, err := nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf)).ListenPacket(ctx, "udp6", c.udpBindAddr())
|
||||
if err != nil {
|
||||
c.logf("udp6: %v", err)
|
||||
} else {
|
||||
@ -1238,7 +1240,7 @@ func (rs *reportState) runProbe(ctx context.Context, dm *tailcfg.DERPMap, probe
|
||||
}
|
||||
|
||||
addr := c.nodeAddr(ctx, node, probe.proto)
|
||||
if addr == nil {
|
||||
if !addr.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1257,7 +1259,7 @@ func (rs *reportState) runProbe(ctx context.Context, dm *tailcfg.DERPMap, probe
|
||||
switch probe.proto {
|
||||
case probeIPv4:
|
||||
metricSTUNSend4.Add(1)
|
||||
n, err := rs.pc4.WriteTo(req, addr)
|
||||
n, err := rs.pc4.WriteToUDPAddrPort(req, addr)
|
||||
if n == len(req) && err == nil || neterror.TreatAsLostUDP(err) {
|
||||
rs.mu.Lock()
|
||||
rs.report.IPv4CanSend = true
|
||||
@ -1265,7 +1267,7 @@ func (rs *reportState) runProbe(ctx context.Context, dm *tailcfg.DERPMap, probe
|
||||
}
|
||||
case probeIPv6:
|
||||
metricSTUNSend6.Add(1)
|
||||
n, err := rs.pc6.WriteTo(req, addr)
|
||||
n, err := rs.pc6.WriteToUDPAddrPort(req, addr)
|
||||
if n == len(req) && err == nil || neterror.TreatAsLostUDP(err) {
|
||||
rs.mu.Lock()
|
||||
rs.report.IPv6CanSend = true
|
||||
@ -1279,26 +1281,26 @@ func (rs *reportState) runProbe(ctx context.Context, dm *tailcfg.DERPMap, probe
|
||||
|
||||
// proto is 4 or 6
|
||||
// If it returns nil, the node is skipped.
|
||||
func (c *Client) nodeAddr(ctx context.Context, n *tailcfg.DERPNode, proto probeProto) *net.UDPAddr {
|
||||
func (c *Client) nodeAddr(ctx context.Context, n *tailcfg.DERPNode, proto probeProto) (ap netip.AddrPort) {
|
||||
port := n.STUNPort
|
||||
if port == 0 {
|
||||
port = 3478
|
||||
}
|
||||
if port < 0 || port > 1<<16-1 {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
if n.STUNTestIP != "" {
|
||||
ip, err := netaddr.ParseIP(n.STUNTestIP)
|
||||
if err != nil {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
if proto == probeIPv4 && ip.Is6() {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
if proto == probeIPv6 && ip.Is4() {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
return netaddr.IPPortFrom(ip, uint16(port)).UDPAddr()
|
||||
return netip.AddrPortFrom(ip, uint16(port))
|
||||
}
|
||||
|
||||
switch proto {
|
||||
@ -1306,30 +1308,31 @@ func (c *Client) nodeAddr(ctx context.Context, n *tailcfg.DERPNode, proto probeP
|
||||
if n.IPv4 != "" {
|
||||
ip, _ := netaddr.ParseIP(n.IPv4)
|
||||
if !ip.Is4() {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
return netaddr.IPPortFrom(ip, uint16(port)).UDPAddr()
|
||||
return netip.AddrPortFrom(ip, uint16(port))
|
||||
}
|
||||
case probeIPv6:
|
||||
if n.IPv6 != "" {
|
||||
ip, _ := netaddr.ParseIP(n.IPv6)
|
||||
if !ip.Is6() {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
return netaddr.IPPortFrom(ip, uint16(port)).UDPAddr()
|
||||
return netip.AddrPortFrom(ip, uint16(port))
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(bradfitz): add singleflight+dnscache here.
|
||||
addrs, _ := net.DefaultResolver.LookupIPAddr(ctx, n.HostName)
|
||||
for _, a := range addrs {
|
||||
if (a.IP.To4() != nil) == (proto == probeIPv4) {
|
||||
return &net.UDPAddr{IP: a.IP, Port: port}
|
||||
na, _ := netaddr.FromStdIP(a.IP.To4())
|
||||
return netip.AddrPortFrom(na, uint16(port))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
func regionHasDERPNode(r *tailcfg.DERPRegion) bool {
|
||||
|
@ -16,8 +16,8 @@
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/stun"
|
||||
"tailscale.com/net/stun/stuntest"
|
||||
"tailscale.com/tailcfg"
|
||||
|
@ -18,7 +18,7 @@
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netknob"
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/types/logger"
|
||||
|
@ -9,7 +9,7 @@
|
||||
"errors"
|
||||
"runtime"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)
|
||||
|
@ -13,7 +13,7 @@
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/endian"
|
||||
)
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
// protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are
|
||||
@ -31,7 +31,7 @@ func protocolsRequiredForForwarding(routes []netaddr.IPPrefix, state *interfaces
|
||||
localIPs := make(map[netaddr.IP]bool)
|
||||
for _, addrs := range state.InterfaceIPs {
|
||||
for _, pfx := range addrs {
|
||||
localIPs[pfx.IP()] = true
|
||||
localIPs[pfx.Addr()] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +39,10 @@ func protocolsRequiredForForwarding(routes []netaddr.IPPrefix, state *interfaces
|
||||
// It's possible to advertise a route to one of the local
|
||||
// machine's local IPs. IP forwarding isn't required for this
|
||||
// to work, so we shouldn't warn for such exports.
|
||||
if r.IsSingleIP() && localIPs[r.IP()] {
|
||||
if r.IsSingleIP() && localIPs[r.Addr()] {
|
||||
continue
|
||||
}
|
||||
if r.IP().Is4() {
|
||||
if r.Addr().Is4() {
|
||||
v4 = true
|
||||
} else {
|
||||
v6 = true
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@ -8,9 +8,10 @@
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
@ -126,8 +127,8 @@ func (q *Parsed) decode4(b []byte) {
|
||||
}
|
||||
|
||||
// If it's valid IPv4, then the IP addresses are valid
|
||||
q.Src = q.Src.WithIP(netaddr.IPv4(b[12], b[13], b[14], b[15]))
|
||||
q.Dst = q.Dst.WithIP(netaddr.IPv4(b[16], b[17], b[18], b[19]))
|
||||
q.Src = withIP(q.Src, netaddr.IPv4(b[12], b[13], b[14], b[15]))
|
||||
q.Dst = withIP(q.Dst, netaddr.IPv4(b[16], b[17], b[18], b[19]))
|
||||
|
||||
q.subofs = int((b[0] & 0x0F) << 2)
|
||||
if q.subofs > q.length {
|
||||
@ -169,8 +170,8 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(0)
|
||||
q.Dst = q.Dst.WithPort(0)
|
||||
q.Src = withPort(q.Src, 0)
|
||||
q.Dst = withPort(q.Dst, 0)
|
||||
q.dataofs = q.subofs + icmp4HeaderLength
|
||||
return
|
||||
case ipproto.IGMP:
|
||||
@ -182,8 +183,8 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.TCPFlags = TCPFlag(sub[13])
|
||||
headerLength := (sub[12] & 0xF0) >> 2
|
||||
q.dataofs = q.subofs + int(headerLength)
|
||||
@ -193,8 +194,8 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.dataofs = q.subofs + udpHeaderLength
|
||||
return
|
||||
case ipproto.SCTP:
|
||||
@ -202,8 +203,8 @@ func (q *Parsed) decode4(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
return
|
||||
case ipproto.TSMP:
|
||||
// Inter-tailscale messages.
|
||||
@ -251,8 +252,8 @@ func (q *Parsed) decode6(b []byte) {
|
||||
// always well-formed stdlib IPs.
|
||||
srcIP, _ := netaddr.FromStdIP(net.IP(b[8:24]))
|
||||
dstIP, _ := netaddr.FromStdIP(net.IP(b[24:40]))
|
||||
q.Src = q.Src.WithIP(srcIP)
|
||||
q.Dst = q.Dst.WithIP(dstIP)
|
||||
q.Src = withIP(q.Src, srcIP)
|
||||
q.Dst = withIP(q.Dst, dstIP)
|
||||
|
||||
// We don't support any IPv6 extension headers. Don't try to
|
||||
// be clever. Therefore, the IP subprotocol always starts at
|
||||
@ -276,16 +277,16 @@ func (q *Parsed) decode6(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(0)
|
||||
q.Dst = q.Dst.WithPort(0)
|
||||
q.Src = withPort(q.Src, 0)
|
||||
q.Dst = withPort(q.Dst, 0)
|
||||
q.dataofs = q.subofs + icmp6HeaderLength
|
||||
case ipproto.TCP:
|
||||
if len(sub) < tcpHeaderLength {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.TCPFlags = TCPFlag(sub[13])
|
||||
headerLength := (sub[12] & 0xF0) >> 2
|
||||
q.dataofs = q.subofs + int(headerLength)
|
||||
@ -295,16 +296,16 @@ func (q *Parsed) decode6(b []byte) {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.dataofs = q.subofs + udpHeaderLength
|
||||
case ipproto.SCTP:
|
||||
if len(sub) < sctpHeaderLength {
|
||||
q.IPProto = unknown
|
||||
return
|
||||
}
|
||||
q.Src = q.Src.WithPort(binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = q.Dst.WithPort(binary.BigEndian.Uint16(sub[2:4]))
|
||||
q.Src = withPort(q.Src, binary.BigEndian.Uint16(sub[0:2]))
|
||||
q.Dst = withPort(q.Dst, binary.BigEndian.Uint16(sub[2:4]))
|
||||
return
|
||||
case ipproto.TSMP:
|
||||
// Inter-tailscale messages.
|
||||
@ -324,8 +325,8 @@ func (q *Parsed) IP4Header() IP4Header {
|
||||
return IP4Header{
|
||||
IPID: ipid,
|
||||
IPProto: q.IPProto,
|
||||
Src: q.Src.IP(),
|
||||
Dst: q.Dst.IP(),
|
||||
Src: q.Src.Addr(),
|
||||
Dst: q.Dst.Addr(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,8 +338,8 @@ func (q *Parsed) IP6Header() IP6Header {
|
||||
return IP6Header{
|
||||
IPID: ipid,
|
||||
IPProto: q.IPProto,
|
||||
Src: q.Src.IP(),
|
||||
Dst: q.Dst.IP(),
|
||||
Src: q.Src.Addr(),
|
||||
Dst: q.Dst.Addr(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,3 +489,11 @@ func Hexdump(b []byte) string {
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func withIP(ap netip.AddrPort, ip netip.Addr) netip.AddrPort {
|
||||
return netip.AddrPortFrom(ip, ap.Port())
|
||||
}
|
||||
|
||||
func withPort(ap netip.AddrPort, port uint16) netip.AddrPort {
|
||||
return netip.AddrPortFrom(ap.Addr(), port)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
@ -15,8 +15,8 @@
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/flowtrack"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
@ -143,7 +143,7 @@ func (h TailscaleRejectedHeader) Marshal(buf []byte) error {
|
||||
if len(buf) > maxPacketLength {
|
||||
return errLargePacket
|
||||
}
|
||||
if h.Src.IP().Is4() {
|
||||
if h.Src.Addr().Is4() {
|
||||
iph := IP4Header{
|
||||
IPProto: ipproto.TSMP,
|
||||
Src: h.IPSrc,
|
||||
@ -151,7 +151,7 @@ func (h TailscaleRejectedHeader) Marshal(buf []byte) error {
|
||||
}
|
||||
iph.Marshal(buf)
|
||||
buf = buf[ip4HeaderLength:]
|
||||
} else if h.Src.IP().Is6() {
|
||||
} else if h.Src.Addr().Is6() {
|
||||
iph := IP6Header{
|
||||
IPProto: ipproto.TSMP,
|
||||
Src: h.IPSrc,
|
||||
@ -190,10 +190,10 @@ func (pp *Parsed) AsTailscaleRejectedHeader() (h TailscaleRejectedHeader, ok boo
|
||||
h = TailscaleRejectedHeader{
|
||||
Proto: ipproto.Proto(p[1]),
|
||||
Reason: TailscaleRejectReason(p[2]),
|
||||
IPSrc: pp.Src.IP(),
|
||||
IPDst: pp.Dst.IP(),
|
||||
Src: netaddr.IPPortFrom(pp.Dst.IP(), binary.BigEndian.Uint16(p[3:5])),
|
||||
Dst: netaddr.IPPortFrom(pp.Src.IP(), binary.BigEndian.Uint16(p[5:7])),
|
||||
IPSrc: pp.Src.Addr(),
|
||||
IPDst: pp.Dst.Addr(),
|
||||
Src: netaddr.IPPortFrom(pp.Dst.Addr(), binary.BigEndian.Uint16(p[3:5])),
|
||||
Dst: netaddr.IPPortFrom(pp.Src.Addr(), binary.BigEndian.Uint16(p[5:7])),
|
||||
}
|
||||
if len(p) > 7 {
|
||||
flags := p[7]
|
||||
|
@ -7,7 +7,7 @@
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestTailscaleRejectedHeader(t *testing.T) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
import (
|
||||
"context"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
type upnpClient any
|
||||
|
@ -13,7 +13,7 @@
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/syncs"
|
||||
"tailscale.com/types/logger"
|
||||
)
|
||||
@ -214,10 +214,10 @@ func (d *TestIGD) handlePCPQuery(pkt []byte, src netaddr.IPPort) {
|
||||
pktSrcBytes := [16]byte{}
|
||||
copy(pktSrcBytes[:], pkt[8:24])
|
||||
pktSrc := netaddr.IPFrom16(pktSrcBytes)
|
||||
if pktSrc != src.IP() {
|
||||
if pktSrc != src.Addr() {
|
||||
// TODO this error isn't fatal but should be rejected by server.
|
||||
// Since it's a test it's difficult to get them the same though.
|
||||
d.logf("mismatch of packet source and source IP: got %v, expected %v", pktSrc, src.IP())
|
||||
d.logf("mismatch of packet source and source IP: got %v, expected %v", pktSrc, src.Addr())
|
||||
}
|
||||
switch op {
|
||||
case pcpOpAnnounce:
|
||||
@ -226,7 +226,7 @@ func (d *TestIGD) handlePCPQuery(pkt []byte, src netaddr.IPPort) {
|
||||
return
|
||||
}
|
||||
resp := buildPCPDiscoResponse(pkt)
|
||||
if _, err := d.pxpConn.WriteTo(resp, src.UDPAddr()); err != nil {
|
||||
if _, err := d.pxpConn.WriteTo(resp, net.UDPAddrFromAddrPort(src)); err != nil {
|
||||
d.inc(&d.counters.numFailedWrites)
|
||||
}
|
||||
case pcpOpMap:
|
||||
@ -240,7 +240,7 @@ func (d *TestIGD) handlePCPQuery(pkt []byte, src netaddr.IPPort) {
|
||||
return
|
||||
}
|
||||
resp := buildPCPMapResponse(pkt)
|
||||
d.pxpConn.WriteTo(resp, src.UDPAddr())
|
||||
d.pxpConn.WriteTo(resp, net.UDPAddrFromAddrPort(src))
|
||||
default:
|
||||
// unknown op code, ignore it for now.
|
||||
d.inc(&d.counters.numPCPOtherRecv)
|
||||
|
@ -11,7 +11,7 @@
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
// References:
|
||||
@ -69,8 +69,8 @@ func (p *pcpMapping) Release(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
defer uc.Close()
|
||||
pkt := buildPCPRequestMappingPacket(p.internal.IP(), p.internal.Port(), p.external.Port(), 0, p.external.IP())
|
||||
uc.WriteTo(pkt, p.gw.UDPAddr())
|
||||
pkt := buildPCPRequestMappingPacket(p.internal.Addr(), p.internal.Port(), p.external.Port(), 0, p.external.Addr())
|
||||
uc.WriteToUDPAddrPort(pkt, p.gw)
|
||||
}
|
||||
|
||||
// buildPCPRequestMappingPacket generates a PCP packet with a MAP opcode.
|
||||
|
@ -8,7 +8,7 @@
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var examplePCPMapResponse = []byte{2, 129, 0, 0, 0, 0, 28, 32, 0, 2, 155, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 112, 9, 24, 241, 208, 251, 45, 157, 76, 10, 188, 17, 0, 0, 0, 4, 210, 4, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 135, 180, 175, 246}
|
||||
|
@ -14,15 +14,17 @@
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/interfaces"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/neterror"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/nettype"
|
||||
"tailscale.com/util/clientmetric"
|
||||
)
|
||||
|
||||
@ -128,7 +130,7 @@ type pmpMapping struct {
|
||||
|
||||
// externalValid reports whether m.external is valid, with both its IP and Port populated.
|
||||
func (m *pmpMapping) externalValid() bool {
|
||||
return !m.external.IP().IsZero() && m.external.Port() != 0
|
||||
return m.external.Addr().IsValid() && m.external.Port() != 0
|
||||
}
|
||||
|
||||
func (p *pmpMapping) GoodUntil() time.Time { return p.goodUntil }
|
||||
@ -143,7 +145,7 @@ func (m *pmpMapping) Release(ctx context.Context) {
|
||||
}
|
||||
defer uc.Close()
|
||||
pkt := buildPMPRequestMappingPacket(m.internal.Port(), m.external.Port(), pmpMapLifetimeDelete)
|
||||
uc.WriteTo(pkt, m.gw.UDPAddr())
|
||||
uc.WriteToUDPAddrPort(pkt, m.gw)
|
||||
}
|
||||
|
||||
// NewClient returns a new portmapping client.
|
||||
@ -236,7 +238,7 @@ func (c *Client) upnpPort() uint16 {
|
||||
return upnpDefaultPort
|
||||
}
|
||||
|
||||
func (c *Client) listenPacket(ctx context.Context, network, addr string) (net.PacketConn, error) {
|
||||
func (c *Client) listenPacket(ctx context.Context, network, addr string) (nettype.PacketConn, error) {
|
||||
// When running under testing conditions, we bind the IGD server
|
||||
// to localhost, and may be running in an environment where our
|
||||
// netns code would decide that binding the portmapper client
|
||||
@ -251,9 +253,17 @@ func (c *Client) listenPacket(ctx context.Context, network, addr string) (net.Pa
|
||||
// so we don't care.
|
||||
if c.testPxPPort != 0 || c.testUPnPPort != 0 {
|
||||
var lc net.ListenConfig
|
||||
return lc.ListenPacket(ctx, network, addr)
|
||||
pc, err := lc.ListenPacket(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return netns.Listener(c.logf).ListenPacket(ctx, network, addr)
|
||||
return pc.(*net.UDPConn), nil
|
||||
}
|
||||
pc, err := netns.Listener(c.logf).ListenPacket(ctx, network, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pc.(*net.UDPConn), nil
|
||||
}
|
||||
|
||||
func (c *Client) invalidateMappingsLocked(releaseOld bool) {
|
||||
@ -277,7 +287,7 @@ func (c *Client) sawPMPRecently() bool {
|
||||
}
|
||||
|
||||
func (c *Client) sawPMPRecentlyLocked() bool {
|
||||
return !c.pmpPubIP.IsZero() && c.pmpPubIPTime.After(time.Now().Add(-trustServiceStillAvailableDuration))
|
||||
return c.pmpPubIP.IsValid() && c.pmpPubIPTime.After(time.Now().Add(-trustServiceStillAvailableDuration))
|
||||
}
|
||||
|
||||
func (c *Client) sawPCPRecently() bool {
|
||||
@ -333,6 +343,7 @@ func IsNoMappingError(err error) bool {
|
||||
var (
|
||||
ErrNoPortMappingServices = errors.New("no port mapping services were found")
|
||||
ErrGatewayRange = errors.New("skipping portmap; gateway range likely lacks support")
|
||||
ErrGatewayIPv6 = errors.New("skipping portmap; no IPv6 support for portmapping")
|
||||
)
|
||||
|
||||
// GetCachedMappingOrStartCreatingOne quickly returns with our current cached portmapping, if any.
|
||||
@ -401,6 +412,9 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
if !ok {
|
||||
return netaddr.IPPort{}, NoMappingError{ErrGatewayRange}
|
||||
}
|
||||
if gw.Is6() {
|
||||
return netaddr.IPPort{}, NoMappingError{ErrGatewayIPv6}
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
localPort := c.localPort
|
||||
@ -447,7 +461,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
internal: internalAddr,
|
||||
}
|
||||
if haveRecentPMP {
|
||||
m.external = m.external.WithIP(c.pmpPubIP)
|
||||
m.external = netip.AddrPortFrom(c.pmpPubIP, m.external.Port())
|
||||
}
|
||||
if c.lastProbe.After(now.Add(-5*time.Second)) && !haveRecentPMP && !haveRecentPCP {
|
||||
c.mu.Unlock()
|
||||
@ -469,7 +483,6 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
defer closeCloserOnContextDone(ctx, uc)()
|
||||
|
||||
pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
|
||||
pxpAddru := pxpAddr.UDPAddr()
|
||||
|
||||
preferPCP := !DisablePCP && (DisablePMP || (!haveRecentPMP && haveRecentPCP))
|
||||
|
||||
@ -478,7 +491,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
// TODO replace wildcardIP here with previous external if known.
|
||||
// Only do PCP mapping in the case when PMP did not appear to be available recently.
|
||||
pkt := buildPCPRequestMappingPacket(myIP, localPort, prevPort, pcpMapLifetimeSec, wildcardIP)
|
||||
if _, err := uc.WriteTo(pkt, pxpAddru); err != nil {
|
||||
if _, err := uc.WriteToUDPAddrPort(pkt, pxpAddr); err != nil {
|
||||
if neterror.TreatAsLostUDP(err) {
|
||||
err = NoMappingError{ErrNoPortMappingServices}
|
||||
}
|
||||
@ -486,8 +499,8 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
}
|
||||
} else {
|
||||
// Ask for our external address if needed.
|
||||
if m.external.IP().IsZero() {
|
||||
if _, err := uc.WriteTo(pmpReqExternalAddrPacket, pxpAddru); err != nil {
|
||||
if !m.external.Addr().IsValid() {
|
||||
if _, err := uc.WriteToUDPAddrPort(pmpReqExternalAddrPacket, pxpAddr); err != nil {
|
||||
if neterror.TreatAsLostUDP(err) {
|
||||
err = NoMappingError{ErrNoPortMappingServices}
|
||||
}
|
||||
@ -496,7 +509,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
}
|
||||
|
||||
pkt := buildPMPRequestMappingPacket(localPort, prevPort, pmpMapLifetimeSec)
|
||||
if _, err := uc.WriteTo(pkt, pxpAddru); err != nil {
|
||||
if _, err := uc.WriteToUDPAddrPort(pkt, pxpAddr); err != nil {
|
||||
if neterror.TreatAsLostUDP(err) {
|
||||
err = NoMappingError{ErrNoPortMappingServices}
|
||||
}
|
||||
@ -535,10 +548,10 @@ func (c *Client) createOrGetMapping(ctx context.Context) (external netaddr.IPPor
|
||||
return netaddr.IPPort{}, NoMappingError{fmt.Errorf("PMP response Op=0x%x,Res=0x%x", pres.OpCode, pres.ResultCode)}
|
||||
}
|
||||
if pres.OpCode == pmpOpReply|pmpOpMapPublicAddr {
|
||||
m.external = m.external.WithIP(pres.PublicAddr)
|
||||
m.external = netip.AddrPortFrom(pres.PublicAddr, m.external.Port())
|
||||
}
|
||||
if pres.OpCode == pmpOpReply|pmpOpMapUDP {
|
||||
m.external = m.external.WithPort(pres.ExternalPort)
|
||||
m.external = netip.AddrPortFrom(m.external.Addr(), pres.ExternalPort)
|
||||
d := time.Duration(pres.MappingValidSeconds) * time.Second
|
||||
now := time.Now()
|
||||
m.goodUntil = now.Add(d)
|
||||
@ -688,9 +701,9 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
|
||||
defer cancel()
|
||||
defer closeCloserOnContextDone(ctx, uc)()
|
||||
|
||||
pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort()).UDPAddr()
|
||||
upnpAddr := netaddr.IPPortFrom(gw, c.upnpPort()).UDPAddr()
|
||||
upnpMulticastAddr := netaddr.IPPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort()).UDPAddr()
|
||||
pxpAddr := netaddr.IPPortFrom(gw, c.pxpPort())
|
||||
upnpAddr := netaddr.IPPortFrom(gw, c.upnpPort())
|
||||
upnpMulticastAddr := netaddr.IPPortFrom(netaddr.IPv4(239, 255, 255, 250), c.upnpPort())
|
||||
|
||||
// Don't send probes to services that we recently learned (for
|
||||
// the same gw/myIP) are available. See
|
||||
@ -699,13 +712,13 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
|
||||
res.PMP = true
|
||||
} else if !DisablePMP {
|
||||
metricPMPSent.Add(1)
|
||||
uc.WriteTo(pmpReqExternalAddrPacket, pxpAddr)
|
||||
uc.WriteToUDPAddrPort(pmpReqExternalAddrPacket, pxpAddr)
|
||||
}
|
||||
if c.sawPCPRecently() {
|
||||
res.PCP = true
|
||||
} else if !DisablePCP {
|
||||
metricPCPSent.Add(1)
|
||||
uc.WriteTo(pcpAnnounceRequest(myIP), pxpAddr)
|
||||
uc.WriteToUDPAddrPort(pcpAnnounceRequest(myIP), pxpAddr)
|
||||
}
|
||||
if c.sawUPnPRecently() {
|
||||
res.UPnP = true
|
||||
@ -756,9 +769,9 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
|
||||
// their first descriptor (like urn:schemas-wifialliance-org:device:WFADevice:1)
|
||||
// in response to ssdp:all. https://github.com/tailscale/tailscale/issues/3557
|
||||
metricUPnPSent.Add(1)
|
||||
uc.WriteTo(uPnPPacket, upnpAddr)
|
||||
uc.WriteTo(uPnPPacket, upnpMulticastAddr)
|
||||
uc.WriteTo(uPnPIGDPacket, upnpMulticastAddr)
|
||||
uc.WriteToUDPAddrPort(uPnPPacket, upnpAddr)
|
||||
uc.WriteToUDPAddrPort(uPnPPacket, upnpMulticastAddr)
|
||||
uc.WriteToUDPAddrPort(uPnPIGDPacket, upnpMulticastAddr)
|
||||
}
|
||||
|
||||
buf := make([]byte, 1500)
|
||||
|
@ -116,7 +116,7 @@ func TestPCPIntegration(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get mapping: %v", err)
|
||||
}
|
||||
if external.IsZero() {
|
||||
if !external.IsValid() {
|
||||
t.Errorf("got zero IP, expected non-zero")
|
||||
}
|
||||
if c.mapping == nil {
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
"github.com/tailscale/goupnp"
|
||||
"github.com/tailscale/goupnp/dcps/internetgateway2"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/control/controlknobs"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/types/logger"
|
||||
)
|
||||
@ -174,7 +174,7 @@ func getUPnPClient(ctx context.Context, logf logger.Logf, gw netaddr.IP, meta uP
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected host %q in %q", u.Host, meta.Location)
|
||||
}
|
||||
if ipp.IP() != gw {
|
||||
if ipp.Addr() != gw {
|
||||
return nil, fmt.Errorf("UPnP discovered root %q does not match gateway IP %v; ignoring UPnP",
|
||||
meta.Location, gw)
|
||||
}
|
||||
@ -274,7 +274,7 @@ func (c *Client) getUPnPPortMapping(
|
||||
client,
|
||||
prevPort,
|
||||
internal.Port(),
|
||||
internal.IP().String(),
|
||||
internal.Addr().String(),
|
||||
time.Second*pmpMapLifetimeSec,
|
||||
)
|
||||
if VerboseLogs {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user