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:
Brad Fitzpatrick
2022-07-24 20:08:42 -07:00
committed by Brad Fitzpatrick
parent 7b1a91dfd3
commit 7eaf5e509f
191 changed files with 1009 additions and 888 deletions

View File

@@ -9,8 +9,8 @@ import (
"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"

View File

@@ -20,8 +20,8 @@ import (
"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"

View File

@@ -15,7 +15,7 @@ import (
"testing"
qt "github.com/frankban/quicktest"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)

View File

@@ -15,9 +15,9 @@ import (
"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(),

View File

@@ -13,8 +13,8 @@ import (
"time"
"github.com/godbus/dbus/v5"
"inet.af/netaddr"
"tailscale.com/health"
"tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/util/cmpver"
)

View File

@@ -12,7 +12,7 @@ import (
"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"
)

View File

@@ -11,8 +11,8 @@ import (
"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()
})

View File

@@ -16,8 +16,8 @@ import (
"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"
)

View File

@@ -14,7 +14,7 @@ import (
"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"
)

View File

@@ -14,8 +14,8 @@ import (
"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"
)

View File

@@ -7,7 +7,7 @@ package dns
import (
"errors"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)

View File

@@ -9,7 +9,7 @@ package publicdns
import (
"sync"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
var knownDoH = map[netaddr.IP]string{} // 8.8.8.8 => "https://..."

View File

@@ -7,7 +7,7 @@ package publicdns
import (
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func TestInit(t *testing.T) {

View File

@@ -19,7 +19,7 @@ import (
"os"
"strings"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)

View File

@@ -9,7 +9,7 @@ import (
"strings"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/util/dnsname"
)

View File

@@ -15,11 +15,11 @@ import (
"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.
@@ -139,8 +139,8 @@ func (m *resolvedManager) SetDNS(config OSConfig) error {
func (m *resolvedManager) run(ctx context.Context) {
var (
conn *dbus.Conn
signals chan *dbus.Signal
conn *dbus.Conn
signals chan *dbus.Signal
rManager dbus.BusObject // rManager is the Resolved DBus connection
)
bo := backoff.NewBackoff("resolved-dbus", m.logf, 30*time.Second)

View File

@@ -24,16 +24,17 @@ import (
"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 @@ func resolversWithDelays(resolvers []*dnstype.Resolver) []resolverAndDelay {
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

View File

@@ -14,6 +14,7 @@ import (
"fmt"
"io"
"net"
"net/netip"
"os"
"runtime"
"sort"
@@ -24,8 +25,8 @@ import (
"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.

View File

@@ -11,7 +11,7 @@ import (
"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:

View File

@@ -23,7 +23,7 @@ import (
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"

View File

@@ -19,8 +19,8 @@ import (
"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(),
})
}
}
}

View File

@@ -14,7 +14,7 @@ import (
"testing"
"time"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
var dialTest = flag.String("dial-test", "", "if non-empty, addr:port to test dial")

View File

@@ -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"
}
]
},

View File

@@ -21,7 +21,7 @@ import (
"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 @@ import (
)
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
}

View File

@@ -14,7 +14,7 @@ import (
"container/list"
"fmt"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)

View File

@@ -7,7 +7,7 @@ package flowtrack
import (
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/tstest"
)

View File

@@ -14,8 +14,8 @@ import (
"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 @@ var (
// isInterestingIP.
func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
for _, pfx := range pfxs {
if isInterestingIP(pfx.IP()) {
if isInterestingIP(pfx.Addr()) {
return true
}
}

View File

@@ -19,7 +19,7 @@ import (
"golang.org/x/net/route"
"golang.org/x/sys/unix"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func defaultRoute() (d DefaultRouteDetails, err error) {

View File

@@ -13,7 +13,7 @@ import (
"golang.org/x/net/route"
"golang.org/x/sys/unix"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func defaultRoute() (d DefaultRouteDetails, err error) {

View File

@@ -10,7 +10,7 @@ import (
"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) {

View File

@@ -21,7 +21,7 @@ import (
"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) {

View File

@@ -9,7 +9,7 @@ import (
"net"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func TestGetState(t *testing.T) {

View File

@@ -14,7 +14,7 @@ import (
"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
View 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) }

View File

@@ -16,16 +16,17 @@ import (
"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 @@ import (
"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 {

View File

@@ -16,8 +16,8 @@ import (
"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"

View File

@@ -18,7 +18,7 @@ import (
"context"
"net"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/net/netknob"
"tailscale.com/syncs"
"tailscale.com/types/logger"

View File

@@ -9,7 +9,7 @@ import (
"errors"
"runtime"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)

View File

@@ -13,7 +13,7 @@ import (
"unsafe"
"golang.org/x/sys/windows"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/util/endian"
)

View File

@@ -15,8 +15,8 @@ import (
"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

View File

@@ -7,7 +7,7 @@ package packet
import (
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)

View File

@@ -8,7 +8,7 @@ import (
"encoding/binary"
"errors"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)

View File

@@ -7,7 +7,7 @@ package packet
import (
"encoding/binary"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/types/ipproto"
)

View File

@@ -8,9 +8,10 @@ import (
"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)
}

View File

@@ -9,7 +9,7 @@ import (
"reflect"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/tstest"
"tailscale.com/types/ipproto"
)

View File

@@ -15,8 +15,8 @@ import (
"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]

View File

@@ -7,7 +7,7 @@ package packet
import (
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func TestTailscaleRejectedHeader(t *testing.T) {

View File

@@ -10,7 +10,7 @@ package portmapper
import (
"context"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
type upnpClient any

View File

@@ -13,7 +13,7 @@ import (
"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)

View File

@@ -11,7 +11,7 @@ import (
"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.

View File

@@ -8,7 +8,7 @@ import (
"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}

View File

@@ -14,15 +14,17 @@ import (
"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 pc.(*net.UDPConn), nil
}
return netns.Listener(c.logf).ListenPacket(ctx, network, addr)
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)

View File

@@ -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 {

View File

@@ -22,8 +22,8 @@ import (
"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 {

View File

@@ -15,7 +15,7 @@ import (
"regexp"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/tstest"
)

View File

@@ -19,7 +19,7 @@ func socks5Server(listener net.Listener) {
if err != nil {
panic(err)
}
listener.Close()
listener.Close()
}
func backendServer(listener net.Listener) {
@@ -29,7 +29,7 @@ func backendServer(listener net.Listener) {
}
conn.Write([]byte("Test"))
conn.Close()
listener.Close()
listener.Close()
}
func TestRead(t *testing.T) {

View File

@@ -14,7 +14,7 @@ import (
"sync"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/net/stun"
"tailscale.com/tailcfg"
"tailscale.com/types/nettype"

View File

@@ -8,9 +8,10 @@ package tsaddr
import (
"encoding/binary"
"errors"
"net/netip"
"sync"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
@@ -56,7 +57,7 @@ func TailscaleServiceIP() netaddr.IP {
// For IPv4, use TailscaleServiceIP.
func TailscaleServiceIPv6() netaddr.IP {
serviceIPv6.Do(func() { mustPrefix(&serviceIPv6.v, "fd7a:115c:a1e0::53/128") })
return serviceIPv6.v.IP()
return serviceIPv6.v.Addr()
}
// IsTailscaleIP reports whether ip is an IP address in a range that
@@ -112,7 +113,7 @@ func TailscaleEphemeral6Range() netaddr.IPPrefix {
// Currently used to work around a Windows limitation when programming
// IPv6 routes in corner cases.
func Tailscale4To6Placeholder() netaddr.IP {
return Tailscale4To6Range().IP()
return Tailscale4To6Range().Addr()
}
// Tailscale4To6 returns a Tailscale IPv6 address that maps 1:1 to the
@@ -122,7 +123,7 @@ func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
if !ipv4.Is4() || !IsTailscaleIP(ipv4) {
return netaddr.IP{}
}
ret := Tailscale4To6Range().IP().As16()
ret := Tailscale4To6Range().Addr().As16()
v4 := ipv4.As4()
copy(ret[13:], v4[1:])
return netaddr.IPFrom16(ret)
@@ -186,16 +187,16 @@ func NewContainsIPFunc(addrs []netaddr.IPPrefix) func(ip netaddr.IP) bool {
// Fast paths for 1 and 2 IPs:
if len(addrs) == 1 {
a := addrs[0]
return func(ip netaddr.IP) bool { return ip == a.IP() }
return func(ip netaddr.IP) bool { return ip == a.Addr() }
}
if len(addrs) == 2 {
a, b := addrs[0], addrs[1]
return func(ip netaddr.IP) bool { return ip == a.IP() || ip == b.IP() }
return func(ip netaddr.IP) bool { return ip == a.Addr() || ip == b.Addr() }
}
// General case:
m := map[netaddr.IP]bool{}
for _, a := range addrs {
m[a.IP()] = true
m[a.Addr()] = true
}
return func(ip netaddr.IP) bool { return m[ip] }
}
@@ -232,10 +233,10 @@ func IPsContainsFunc(ips []netaddr.IP, f func(netaddr.IP) bool) bool {
}
// PrefixIs4 reports whether p is an IPv4 prefix.
func PrefixIs4(p netaddr.IPPrefix) bool { return p.IP().Is4() }
func PrefixIs4(p netaddr.IPPrefix) bool { return p.Addr().Is4() }
// PrefixIs6 reports whether p is an IPv6 prefix.
func PrefixIs6(p netaddr.IPPrefix) bool { return p.IP().Is6() }
func PrefixIs6(p netaddr.IPPrefix) bool { return p.Addr().Is6() }
// ContainsExitRoutes reports whether rr contains both the IPv4 and
// IPv6 /0 route.
@@ -280,7 +281,7 @@ func FilterPrefixesCopy(in []netaddr.IPPrefix, f func(netaddr.IPPrefix) bool) []
// IsViaPrefix reports whether p is a CIDR in the Tailscale "via" range.
// See TailscaleViaRange.
func IsViaPrefix(p netaddr.IPPrefix) bool {
return TailscaleViaRange().Contains(p.IP())
return TailscaleViaRange().Contains(p.Addr())
}
// UnmapVia returns the IPv4 address that corresponds to the provided Tailscale
@@ -297,14 +298,14 @@ func UnmapVia(ip netaddr.IP) netaddr.IP {
// MapVia returns an IPv6 "via" route for an IPv4 CIDR in a given siteID.
func MapVia(siteID uint32, v4 netaddr.IPPrefix) (via netaddr.IPPrefix, err error) {
if !v4.IP().Is4() {
if !v4.Addr().Is4() {
return via, errors.New("want IPv4 CIDR with a site ID")
}
viaRange16 := TailscaleViaRange().IP().As16()
viaRange16 := TailscaleViaRange().Addr().As16()
var a [16]byte
copy(a[:], viaRange16[:8])
binary.BigEndian.PutUint32(a[8:], siteID)
ip4a := v4.IP().As4()
ip4a := v4.Addr().As4()
copy(a[12:], ip4a[:])
return netaddr.IPPrefixFrom(netaddr.IPFrom16(a), v4.Bits()+64+32), nil
return netip.PrefixFrom(netaddr.IPFrom16(a), v4.Bits()+64+32), nil
}

View File

@@ -7,7 +7,7 @@ package tsaddr
import (
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
)
func TestInCrostiniRange(t *testing.T) {

View File

@@ -12,7 +12,7 @@ import (
"strconv"
"strings"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/types/netmap"
"tailscale.com/util/dnsname"
)
@@ -37,13 +37,13 @@ func dnsMapFromNetworkMap(nm *netmap.NetworkMap) dnsMap {
suffix := nm.MagicDNSSuffix()
have4 := false
if nm.Name != "" && len(nm.Addresses) > 0 {
ip := nm.Addresses[0].IP()
ip := nm.Addresses[0].Addr()
ret[canonMapKey(nm.Name)] = ip
if dnsname.HasSuffix(nm.Name, suffix) {
ret[canonMapKey(dnsname.TrimSuffix(nm.Name, suffix))] = ip
}
for _, a := range nm.Addresses {
if a.IP().Is4() {
if a.Addr().Is4() {
have4 = true
}
}
@@ -53,7 +53,7 @@ func dnsMapFromNetworkMap(nm *netmap.NetworkMap) dnsMap {
continue
}
for _, a := range p.Addresses {
ip := a.IP()
ip := a.Addr()
if ip.Is4() && !have4 {
continue
}
@@ -112,7 +112,7 @@ func (m dnsMap) resolveMemory(ctx context.Context, network, addr string) (_ neta
// Try MagicDNS first, otherwise a real DNS lookup.
ip := m[canonMapKey(host)]
if !ip.IsZero() {
if ip.IsValid() {
return netaddr.IPPortFrom(ip, port), nil
}

View File

@@ -8,7 +8,7 @@ import (
"reflect"
"testing"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/netmap"
)

View File

@@ -18,9 +18,9 @@ import (
"syscall"
"time"
"inet.af/netaddr"
"tailscale.com/net/dnscache"
"tailscale.com/net/interfaces"
"tailscale.com/net/netaddr"
"tailscale.com/net/netknob"
"tailscale.com/net/netns"
"tailscale.com/types/logger"
@@ -309,7 +309,7 @@ func (d *Dialer) UserDial(ctx context.Context, network, addr string) (net.Conn,
if err != nil {
return nil, err
}
if d.UseNetstackForIP != nil && d.UseNetstackForIP(ipp.IP()) {
if d.UseNetstackForIP != nil && d.UseNetstackForIP(ipp.Addr()) {
if d.NetstackDialTCP == nil {
return nil, errors.New("Dialer not initialized correctly")
}
@@ -334,7 +334,7 @@ func (d *Dialer) dialPeerAPI(ctx context.Context, network, addr string) (net.Con
if err != nil {
return nil, fmt.Errorf("peerAPI dial requires ip:port, not name resolution: %w", err)
}
if d.UseNetstackForIP != nil && d.UseNetstackForIP(ipp.IP()) {
if d.UseNetstackForIP != nil && d.UseNetstackForIP(ipp.Addr()) {
if d.NetstackDialTCP == nil {
return nil, errors.New("Dialer not initialized correctly")
}

View File

@@ -17,7 +17,7 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
"inet.af/netaddr"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/types/ipproto"
)
@@ -292,9 +292,9 @@ func packLayer2UDP(payload []byte, srcMAC, dstMAC net.HardwareAddr, src, dst net
buf := make([]byte, header.EthernetMinimumSize+header.UDPMinimumSize+header.IPv4MinimumSize+len(payload))
payloadStart := len(buf) - len(payload)
copy(buf[payloadStart:], payload)
srcB := src.IP().As4()
srcB := src.Addr().As4()
srcIP := tcpip.Address(srcB[:])
dstB := dst.IP().As4()
dstB := dst.Addr().As4()
dstIP := tcpip.Address(dstB[:])
// Ethernet header
eth := header.Ethernet(buf)

View File

@@ -20,8 +20,8 @@ import (
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"inet.af/netaddr"
"tailscale.com/disco"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/net/tsaddr"
"tailscale.com/tstime/mono"
@@ -545,7 +545,7 @@ func (t *Wrapper) Read(buf []byte, offset int) (int, error) {
p.Decode(buf[offset : offset+n])
if m, ok := t.destIPActivity.Load().(map[netaddr.IP]func()); ok {
if fn := m[p.Dst.IP()]; fn != nil {
if fn := m[p.Dst.Addr()]; fn != nil {
fn()
}
}
@@ -620,7 +620,7 @@ func (t *Wrapper) filterIn(buf []byte) filter.Response {
p.IPProto == ipproto.TCP &&
p.TCPFlags&packet.TCPSyn != 0 &&
t.PeerAPIPort != nil {
if port, ok := t.PeerAPIPort(p.Dst.IP()); ok && port == p.Dst.Port() {
if port, ok := t.PeerAPIPort(p.Dst.Addr()); ok && port == p.Dst.Port() {
outcome = filter.Accept
}
}
@@ -634,8 +634,8 @@ func (t *Wrapper) filterIn(buf []byte) filter.Response {
// can show them a rejection history with reasons.
if p.IPVersion == 4 && p.IPProto == ipproto.TCP && p.TCPFlags&packet.TCPSyn != 0 && !t.disableTSMPRejected {
rj := packet.TailscaleRejectedHeader{
IPSrc: p.Dst.IP(),
IPDst: p.Src.IP(),
IPSrc: p.Dst.Addr(),
IPDst: p.Src.Addr(),
Src: p.Src,
Dst: p.Dst,
Proto: p.IPProto,
@@ -775,7 +775,7 @@ func (t *Wrapper) injectOutboundPong(pp *packet.Parsed, req packet.TSMPPingReque
Data: req.Data,
}
if t.PeerAPIPort != nil {
pong.PeerAPIPort, _ = t.PeerAPIPort(pp.Dst.IP())
pong.PeerAPIPort, _ = t.PeerAPIPort(pp.Dst.Addr())
}
switch pp.IPVersion {
case 4:

View File

@@ -14,9 +14,10 @@ import (
"unsafe"
"go4.org/mem"
"go4.org/netipx"
"golang.zx2c4.com/wireguard/tun/tuntest"
"inet.af/netaddr"
"tailscale.com/disco"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/tstest"
"tailscale.com/tstime/mono"
@@ -148,7 +149,7 @@ func setfilter(logf logger.Logf, tun *Wrapper) {
{IPProto: protos, Srcs: nets("5.6.7.8"), Dsts: netports("1.2.3.4:89-90")},
{IPProto: protos, Srcs: nets("1.2.3.4"), Dsts: netports("5.6.7.8:98")},
}
var sb netaddr.IPSetBuilder
var sb netipx.IPSetBuilder
sb.AddPrefix(netaddr.MustParseIPPrefix("1.2.0.0/16"))
ipSet, _ := sb.IPSet()
tun.SetFilter(filter.New(matches, ipSet, ipSet, nil, logf))
@@ -454,28 +455,28 @@ func TestPeerAPIBypass(t *testing.T) {
{
name: "reject_with_filter",
w: &Wrapper{},
filter: filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)),
filter: filter.NewAllowNone(logger.Discard, new(netipx.IPSet)),
pkt: tcp4syn("1.2.3.4", "100.64.1.2", 1234, 60000),
want: filter.Drop,
},
{
name: "peerapi_bypass_filter",
w: wrapperWithPeerAPI,
filter: filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)),
filter: filter.NewAllowNone(logger.Discard, new(netipx.IPSet)),
pkt: tcp4syn("1.2.3.4", "100.64.1.2", 1234, 60000),
want: filter.Accept,
},
{
name: "peerapi_dont_bypass_filter_wrong_port",
w: wrapperWithPeerAPI,
filter: filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)),
filter: filter.NewAllowNone(logger.Discard, new(netipx.IPSet)),
pkt: tcp4syn("1.2.3.4", "100.64.1.2", 1234, 60001),
want: filter.Drop,
},
{
name: "peerapi_dont_bypass_filter_wrong_dst_ip",
w: wrapperWithPeerAPI,
filter: filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)),
filter: filter.NewAllowNone(logger.Discard, new(netipx.IPSet)),
pkt: tcp4syn("1.2.3.4", "100.64.1.3", 1234, 60000),
want: filter.Drop,
},