mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-23 03:17:43 +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:

committed by
Brad Fitzpatrick

parent
7b1a91dfd3
commit
7eaf5e509f
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@@ -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(),
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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()
|
||||
})
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -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"
|
||||
)
|
||||
|
@@ -7,7 +7,7 @@ package dns
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@@ -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://..."
|
||||
|
@@ -7,7 +7,7 @@ package publicdns
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
|
@@ -19,7 +19,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/dnsname"
|
||||
)
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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:
|
||||
|
@@ -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"
|
||||
|
@@ -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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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")
|
||||
|
@@ -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 @@ 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
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,7 @@ import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@@ -7,7 +7,7 @@ package flowtrack
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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) {
|
||||
|
@@ -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) {
|
||||
|
@@ -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) {
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestGetState(t *testing.T) {
|
||||
|
@@ -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
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 @@ 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 {
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"errors"
|
||||
"runtime"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
var ErrNotImplemented = errors.New("not implemented for GOOS=" + runtime.GOOS)
|
||||
|
@@ -13,7 +13,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/endian"
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -7,7 +7,7 @@ package packet
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@@ -7,7 +7,7 @@ package packet
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/ipproto"
|
||||
)
|
||||
|
@@ -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]
|
||||
|
@@ -7,7 +7,7 @@ package packet
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestTailscaleRejectedHeader(t *testing.T) {
|
||||
|
@@ -10,7 +10,7 @@ package portmapper
|
||||
import (
|
||||
"context"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
type upnpClient any
|
||||
|
@@ -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)
|
||||
|
@@ -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.
|
||||
|
@@ -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}
|
||||
|
@@ -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)
|
||||
|
@@ -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 @@ 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 {
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tstest"
|
||||
)
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ package tsaddr
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestInCrostiniRange(t *testing.T) {
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/netmap"
|
||||
)
|
||||
|
@@ -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")
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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:
|
||||
|
@@ -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,
|
||||
},
|
||||
|
Reference in New Issue
Block a user