all: migrate more code code to net/netip directly

Instead of going through the tailscale.com/net/netaddr transitional
wrappers.

Updates #5162

Change-Id: I3dafd1c2effa1a6caa9b7151ecf6edd1a3fda3dd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-08-02 13:38:11 -07:00 committed by Brad Fitzpatrick
parent eb32847d85
commit 8725b14056
27 changed files with 65 additions and 92 deletions

View File

@ -57,7 +57,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
tailscale.com/net/dnsfallback from tailscale.com/control/controlhttp
tailscale.com/net/flowtrack from tailscale.com/wgengine/filter+
💣 tailscale.com/net/interfaces from tailscale.com/cmd/tailscale/cli+
tailscale.com/net/netaddr from tailscale.com/disco+
tailscale.com/net/netaddr from tailscale.com/ipn+
tailscale.com/net/netcheck from tailscale.com/cmd/tailscale/cli
tailscale.com/net/neterror from tailscale.com/net/netcheck+
tailscale.com/net/netknob from tailscale.com/net/netns

View File

@ -219,7 +219,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/net/dnsfallback from tailscale.com/control/controlclient+
tailscale.com/net/flowtrack from tailscale.com/net/packet+
💣 tailscale.com/net/interfaces from tailscale.com/control/controlclient+
tailscale.com/net/netaddr from tailscale.com/disco+
tailscale.com/net/netaddr from tailscale.com/ipn+
tailscale.com/net/netcheck from tailscale.com/wgengine/magicsock
tailscale.com/net/neterror from tailscale.com/net/dns/resolver+
tailscale.com/net/netknob from tailscale.com/net/netns+

View File

@ -28,7 +28,6 @@
"net/netip"
"go4.org/mem"
"tailscale.com/net/netaddr"
"tailscale.com/types/key"
)
@ -200,7 +199,7 @@ func parseCallMeMaybe(ver uint8, p []byte) (m *CallMeMaybe, err error) {
var a [16]byte
copy(a[:], p)
m.MyNumber = append(m.MyNumber, netip.AddrPortFrom(
netaddr.IPFrom16(a),
netip.AddrFrom16(a).Unmap(),
binary.BigEndian.Uint16(p[16:18])))
p = p[epLength:]
}
@ -235,10 +234,10 @@ func parsePong(ver uint8, p []byte) (m *Pong, err error) {
copy(m.TxID[:], p)
p = p[12:]
srcIP, _ := netaddr.FromStdIP(net.IP(p[:16]))
srcIP, _ := netip.AddrFromSlice(net.IP(p[:16]))
p = p[16:]
port := binary.BigEndian.Uint16(p)
m.Src = netip.AddrPortFrom(srcIP, port)
m.Src = netip.AddrPortFrom(srcIP.Unmap(), port)
return m, nil
}

View File

@ -18,7 +18,6 @@
"golang.org/x/sys/windows/registry"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"tailscale.com/envknob"
"tailscale.com/net/netaddr"
"tailscale.com/types/logger"
"tailscale.com/util/dnsname"
)
@ -394,10 +393,11 @@ type candidate struct {
ipLoop:
for _, stdip := range ips {
ip, ok := netaddr.FromStdIP(stdip)
ip, ok := netip.AddrFromSlice(stdip)
if !ok {
continue
}
ip = ip.Unmap()
// Skip IPv6 site-local resolvers. These are an ancient
// and obsolete IPv6 RFC, which Windows still faithfully
// implements. The net result is that some low-metric

View File

@ -428,8 +428,8 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
return handleError(err)
}
for _, stdIP := range ips {
if ip, ok := netaddr.FromStdIP(stdIP); ok {
resp.IPs = append(resp.IPs, ip)
if ip, ok := netip.AddrFromSlice(stdIP); ok {
resp.IPs = append(resp.IPs, ip.Unmap())
}
}
case dns.TypeTXT:
@ -1124,7 +1124,7 @@ func rdnsNameToIPv6(name dnsname.FQDN) (ip netip.Addr, ok bool) {
return netip.Addr{}, false
}
return netaddr.IPFrom16(ipb), true
return netip.AddrFrom16(ipb), true
}
// respondReverse returns a DNS response to a PTR query.
@ -1221,7 +1221,7 @@ func unARPA(a string) (ipStr string, ok bool) {
}
}
hex.Decode(a16[:], hx[:])
return netaddr.IPFrom16(a16).String(), true
return netip.AddrFrom16(a16).Unmap().String(), true
}
return "", false

View File

@ -21,7 +21,6 @@
"time"
"tailscale.com/envknob"
"tailscale.com/net/netaddr"
"tailscale.com/util/cloudenv"
"tailscale.com/util/singleflight"
)
@ -312,7 +311,7 @@ func (r *Resolver) lookupIP(host string) (ip, ip6 net.IP, allIPs []net.IPAddr, e
}
func (r *Resolver) addIPCache(host string, ip, ip6 net.IP, allIPs []net.IPAddr, d time.Duration) {
if naIP, _ := netaddr.FromStdIP(ip); naIP.IsPrivate() {
if ip.IsPrivate() {
// Don't cache obviously wrong entries from captive portals.
// TODO: use DoH or DoT for the forwarding resolver?
if debug {
@ -400,16 +399,16 @@ func (d *dialer) DialContext(ctx context.Context, network, address string) (retC
if debug {
log.Printf("dnscache: dialing %s, %s for %s", network, ip, address)
}
ipNA, ok := netaddr.FromStdIP(ip)
ipNA, ok := netip.AddrFromSlice(ip)
if !ok {
return nil, fmt.Errorf("invalid IP %q", ip)
}
c, err := dc.dialOne(ctx, ipNA)
c, err := dc.dialOne(ctx, ipNA.Unmap())
if err == nil || ctx.Err() != nil {
return c, err
}
// Fall back to trying IPv6, if any.
ip6NA, ok := netaddr.FromStdIP(ip6)
ip6NA, ok := netip.AddrFromSlice(ip6)
if !ok {
return nil, err
}
@ -583,7 +582,9 @@ type res struct {
func v4addrs(aa []net.IPAddr) (ret []netip.Addr) {
for _, a := range aa {
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is4() {
ip, ok := netip.AddrFromSlice(a.IP)
ip = ip.Unmap()
if ok {
ret = append(ret, ip)
}
}
@ -592,7 +593,7 @@ func v4addrs(aa []net.IPAddr) (ret []netip.Addr) {
func v6addrs(aa []net.IPAddr) (ret []netip.Addr) {
for _, a := range aa {
if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is6() {
if ip, ok := netip.AddrFromSlice(a.IP); ok && ip.Is6() {
ret = append(ret, ip)
}
}

View File

@ -44,7 +44,8 @@ func Tailscale() ([]netip.Addr, *net.Interface, error) {
var tsIPs []netip.Addr
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok {
nip, ok := netaddr.FromStdIP(ipnet.IP)
nip, ok := netip.AddrFromSlice(ipnet.IP)
nip = nip.Unmap()
if ok && tsaddr.IsTailscaleIP(nip) {
tsIPs = append(tsIPs, nip)
}
@ -110,10 +111,11 @@ func LocalAddresses() (regular, loopback []netip.Addr, err error) {
for _, a := range addrs {
switch v := a.(type) {
case *net.IPNet:
ip, ok := netaddr.FromStdIP(v.IP)
ip, ok := netip.AddrFromSlice(v.IP)
if !ok {
continue
}
ip = ip.Unmap()
// TODO(apenwarr): don't special case cgNAT.
// In the general wireguard case, it might
// very well be something we can route to

View File

@ -15,7 +15,6 @@
"golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"tailscale.com/net/netaddr"
"tailscale.com/tsconst"
)
@ -65,11 +64,12 @@ func likelyHomeRouterIPWindows() (ret netip.Addr, ok bool) {
continue
}
ip, ok := netaddr.FromStdIP(r.NextHop.IP())
ip, ok := netip.AddrFromSlice(r.NextHop.IP())
if !ok {
// Not a valid gateway, so skip (won't happen though)
continue
}
ip = ip.Unmap()
if best == nil {
best = r

View File

@ -20,42 +20,14 @@ func IPv4(a, b, c, d uint8) netip.Addr {
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) netip.Addr {
return netip.AddrFrom16(a).Unmap()
}
// 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
// netip.AddrFromSlice.
func FromStdIP(std net.IP) (ip netip.Addr, ok bool) {
ret, ok := netip.AddrFromSlice(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 netip.Prefix, ok bool) {
ip, ok := FromStdIP(std.IP)
ip, ok := netip.AddrFromSlice(std.IP)
if !ok {
return netip.Prefix{}, false
}
ip = ip.Unmap()
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
// Invalid mask.
@ -74,7 +46,7 @@ func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
// FromStdAddr maps the components of a standard library TCPAddr or
// UDPAddr into an IPPort.
func FromStdAddr(stdIP net.IP, port int, zone string) (_ netip.AddrPort, ok bool) {
ip, ok := FromStdIP(stdIP)
ip, ok := netip.AddrFromSlice(stdIP)
if !ok || port < 0 || port > math.MaxUint16 {
return
}

View File

@ -1031,7 +1031,8 @@ func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegio
defer tcpConn.Close()
if ta, ok := tlsConn.RemoteAddr().(*net.TCPAddr); ok {
ip, _ = netaddr.FromStdIP(ta.IP)
ip, _ = netip.AddrFromSlice(ta.IP)
ip = ip.Unmap()
}
if ip == (netip.Addr{}) {
return 0, ip, fmt.Errorf("no unexpected RemoteAddr %#v", tlsConn.RemoteAddr())
@ -1328,8 +1329,8 @@ func (c *Client) nodeAddr(ctx context.Context, n *tailcfg.DERPNode, proto probeP
addrs, _ := net.DefaultResolver.LookupIPAddr(ctx, n.HostName)
for _, a := range addrs {
if (a.IP.To4() != nil) == (proto == probeIPv4) {
na, _ := netaddr.FromStdIP(a.IP.To4())
return netip.AddrPortFrom(na, uint16(port))
na, _ := netip.AddrFromSlice(a.IP.To4())
return netip.AddrPortFrom(na.Unmap(), uint16(port))
}
}
return

View File

@ -164,7 +164,7 @@ func ipport4(addr uint32, port uint16) netip.AddrPort {
}
func ipport6(addr [16]byte, scope uint32, port uint16) netip.AddrPort {
ip := netaddr.IPFrom16(addr)
ip := netip.AddrFrom16(addr).Unmap()
if scope != 0 {
// TODO: something better here?
ip = ip.WithZone(fmt.Sprint(scope))

View File

@ -250,8 +250,8 @@ func (q *Parsed) decode6(b []byte) {
// okay to ignore `ok` here, because IPs pulled from packets are
// always well-formed stdlib IPs.
srcIP, _ := netaddr.FromStdIP(net.IP(b[8:24]))
dstIP, _ := netaddr.FromStdIP(net.IP(b[24:40]))
srcIP, _ := netip.AddrFromSlice(net.IP(b[8:24]))
dstIP, _ := netip.AddrFromSlice(net.IP(b[24:40]))
q.Src = withIP(q.Src, srcIP)
q.Dst = withIP(q.Dst, dstIP)

View File

@ -214,7 +214,7 @@ func (d *TestIGD) handlePCPQuery(pkt []byte, src netip.AddrPort) {
op := pkt[1]
pktSrcBytes := [16]byte{}
copy(pktSrcBytes[:], pkt[8:24])
pktSrc := netaddr.IPFrom16(pktSrcBytes)
pktSrc := netip.AddrFrom16(pktSrcBytes).Unmap()
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.

View File

@ -11,8 +11,6 @@
"fmt"
"net/netip"
"time"
"tailscale.com/net/netaddr"
)
// References:
@ -126,7 +124,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
externalPort := binary.BigEndian.Uint16(resp[42:44])
externalIPBytes := [16]byte{}
copy(externalIPBytes[:], resp[44:])
externalIP := netaddr.IPFrom16(externalIPBytes)
externalIP := netip.AddrFrom16(externalIPBytes).Unmap()
external := netip.AddrPortFrom(externalIP, externalPort)

View File

@ -788,10 +788,11 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
}
return res, err
}
ip, ok := netaddr.FromStdIP(addr.(*net.UDPAddr).IP)
ip, ok := netip.AddrFromSlice(addr.(*net.UDPAddr).IP)
if !ok {
continue
}
ip = ip.Unmap()
port := uint16(addr.(*net.UDPAddr).Port)
switch port {
case c.upnpPort():

View File

@ -11,11 +11,11 @@
"net"
"net/http"
"net/http/httptest"
"net/netip"
"reflect"
"regexp"
"testing"
"tailscale.com/net/netaddr"
"tailscale.com/tstest"
)
@ -106,7 +106,8 @@ func TestGetUPnPClient(t *testing.T) {
http.NotFound(w, r)
}))
defer ts.Close()
gw, _ := netaddr.FromStdIP(ts.Listener.Addr().(*net.TCPAddr).IP)
gw, _ := netip.AddrFromSlice(ts.Listener.Addr().(*net.TCPAddr).IP)
gw = gw.Unmap()
var logBuf tstest.MemLogger
c, err := getUPnPClient(context.Background(), logBuf.Logf, gw, uPnPDiscoResponse{
Location: ts.URL + "/rootDesc.xml",

View File

@ -126,7 +126,7 @@ func Tailscale4To6(ipv4 netip.Addr) netip.Addr {
ret := Tailscale4To6Range().Addr().As16()
v4 := ipv4.As4()
copy(ret[13:], v4[1:])
return netaddr.IPFrom16(ret)
return netip.AddrFrom16(ret)
}
// Tailscale6to4 returns the IPv4 address corresponding to the given
@ -138,7 +138,7 @@ func Tailscale6to4(ipv6 netip.Addr) (netip.Addr, bool) {
return netip.Addr{}, false
}
v6 := ipv6.As16()
return netaddr.IPv4(100, v6[13], v6[14], v6[15]), true
return netip.AddrFrom4([4]byte{100, v6[13], v6[14], v6[15]}), true
}
func mustPrefix(v *netip.Prefix, prefix string) {
@ -307,5 +307,5 @@ func MapVia(siteID uint32, v4 netip.Prefix) (via netip.Prefix, err error) {
binary.BigEndian.PutUint32(a[8:], siteID)
ip4a := v4.Addr().As4()
copy(a[12:], ip4a[:])
return netip.PrefixFrom(netaddr.IPFrom16(a), v4.Bits()+64+32), nil
return netip.PrefixFrom(netip.AddrFrom16(a), v4.Bits()+64+32), nil
}

View File

@ -21,7 +21,6 @@
"tailscale.com/net/dnscache"
"tailscale.com/net/interfaces"
"tailscale.com/net/netaddr"
"tailscale.com/net/netknob"
"tailscale.com/net/netns"
"tailscale.com/types/logger"
@ -250,8 +249,8 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
if len(ips) == 0 {
return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
}
ip, _ := netaddr.FromStdIP(ips[0])
return netip.AddrPortFrom(ip, port), nil
ip, _ := netip.AddrFromSlice(ips[0])
return netip.AddrPortFrom(ip.Unmap(), port), nil
}
// ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding

View File

@ -36,7 +36,6 @@
"tailscale.com/envknob"
"tailscale.com/ipn/ipnlocal"
"tailscale.com/logtail/backoff"
"tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/syncs"
"tailscale.com/tailcfg"
@ -410,11 +409,11 @@ func toIPPort(a net.Addr) (ipp netip.AddrPort) {
if !ok {
return
}
tanetaddr, ok := netaddr.FromStdIP(ta.IP)
tanetaddr, ok := netip.AddrFromSlice(ta.IP)
if !ok {
return
}
return netip.AddrPortFrom(tanetaddr, uint16(ta.Port))
return netip.AddrPortFrom(tanetaddr.Unmap(), uint16(ta.Port))
}
// connInfo returns a populated sshConnInfo from the provided arguments,

View File

@ -140,7 +140,7 @@ func (n *Network) allocIPv4(iface *Interface) netip.Addr {
}
a := n.lastV4.As16()
addOne(&a, 15)
n.lastV4 = netaddr.IPFrom16(a)
n.lastV4 = netip.AddrFrom16(a).Unmap()
if !n.Prefix4.Contains(n.lastV4) {
panic("pool exhausted")
}
@ -159,7 +159,7 @@ func (n *Network) allocIPv6(iface *Interface) netip.Addr {
}
a := n.lastV6.As16()
addOne(&a, 15)
n.lastV6 = netaddr.IPFrom16(a)
n.lastV6 = netip.AddrFrom16(a).Unmap()
if !n.Prefix6.Contains(n.lastV6) {
panic("pool exhausted")
}

View File

@ -22,7 +22,6 @@
"unsafe"
"go4.org/mem"
"tailscale.com/net/netaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/dnstype"
"tailscale.com/types/ipproto"
@ -192,7 +191,7 @@ func getVal() []any {
return []any{
&wgcfg.Config{
Name: "foo",
Addresses: []netip.Prefix{netip.PrefixFrom(netaddr.IPFrom16([16]byte{3: 3}), 5)},
Addresses: []netip.Prefix{netip.PrefixFrom(netip.AddrFrom16([16]byte{3: 3}).Unmap(), 5)},
Peers: []wgcfg.Peer{
{
PublicKey: key.NodePublic{},

View File

@ -109,7 +109,7 @@ func (r Response) IsDrop() bool {
// attacks to reach the OS network stack.
func NewAllowAllForTest(logf logger.Logf) *Filter {
any4 := netip.PrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0)
any6 := netip.PrefixFrom(netaddr.IPFrom16([16]byte{}), 0)
any6 := netip.PrefixFrom(netip.AddrFrom16([16]byte{}), 0)
ms := []Match{
{
IPProto: []ipproto.Proto{ipproto.TCP, ipproto.UDP, ipproto.ICMPv4},

View File

@ -97,7 +97,7 @@ func MatchesFromFilterRules(pf []tailcfg.FilterRule) ([]Match, error) {
var (
zeroIP4 = netaddr.IPv4(0, 0, 0, 0)
zeroIP6 = netaddr.IPFrom16([16]byte{})
zeroIP6 = netip.AddrFrom16([16]byte{})
)
// parseIPSet parses arg as one:

View File

@ -3425,7 +3425,7 @@ func (de *endpoint) initFakeUDPAddr() {
addr[0] = 0xfd
addr[1] = 0x00
binary.BigEndian.PutUint64(addr[2:], uint64(reflect.ValueOf(de).Pointer()))
de.fakeWGAddr = netip.AddrPortFrom(netaddr.IPFrom16(addr), 12345)
de.fakeWGAddr = netip.AddrPortFrom(netip.AddrFrom16(addr).Unmap(), 12345)
}
// noteRecvActivity records receive activity on de, and invokes

View File

@ -16,7 +16,6 @@
"github.com/mdlayher/netlink"
"golang.org/x/sys/unix"
"tailscale.com/envknob"
"tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/types/logger"
)
@ -237,13 +236,13 @@ func (c *nlConn) Receive() (message, error) {
}
func netaddrIP(std net.IP) netip.Addr {
ip, _ := netaddr.FromStdIP(std)
return ip
ip, _ := netip.AddrFromSlice(std)
return ip.Unmap()
}
func netaddrIPPrefix(std net.IP, bits uint8) netip.Prefix {
ip, _ := netaddr.FromStdIP(std)
return netip.PrefixFrom(ip, int(bits))
ip, _ := netip.AddrFromSlice(std)
return netip.PrefixFrom(ip.Unmap(), int(bits))
}
func condNetAddrPrefix(ipp netip.Prefix) string {

View File

@ -7,6 +7,7 @@
import (
"context"
"errors"
"net/netip"
"strings"
"sync"
"time"
@ -132,7 +133,7 @@ func (m *winMon) Receive() (message, error) {
// unicastAddressChanged is the callback we register with Windows to call when unicast address changes.
func (m *winMon) unicastAddressChanged(_ winipcfg.MibNotificationType, row *winipcfg.MibUnicastIPAddressRow) {
what := "addr"
if ip, ok := netaddr.FromStdIP(row.Address.IP()); ok && tsaddr.IsTailscaleIP(ip) {
if ip, ok := netip.AddrFromSlice(row.Address.IP()); ok && tsaddr.IsTailscaleIP(ip.Unmap()) {
what = "tsaddr"
}

View File

@ -218,11 +218,12 @@ func (ns *Impl) SetLocalBackend(lb *ipnlocal.LocalBackend) {
func (ns *Impl) wrapProtoHandler(h func(stack.TransportEndpointID, *stack.PacketBuffer) bool) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
return func(tei stack.TransportEndpointID, pb *stack.PacketBuffer) bool {
addr := tei.LocalAddress
ip, ok := netaddr.FromStdIP(net.IP(addr))
ip, ok := netip.AddrFromSlice(net.IP(addr))
if !ok {
ns.logf("netstack: could not parse local address for incoming connection")
return false
}
ip = ip.Unmap()
if !ns.isLocalIP(ip) {
ns.addSubnetAddress(ip)
}
@ -486,7 +487,7 @@ func (ns *Impl) inject() {
}
case 6:
if len(b) >= 40 { // min ipv6 header
if srcIP, ok := netaddr.FromStdIP(net.IP(b[8:24])); ok && magicDNSIPv6 == srcIP {
if srcIP, ok := netip.AddrFromSlice(net.IP(b[8:24])); ok && magicDNSIPv6 == srcIP {
sendToHost = true
}
}
@ -710,7 +711,7 @@ func netaddrIPFromNetstackIP(s tcpip.Address) netip.Addr {
case 16:
var a [16]byte
copy(a[:], s)
return netaddr.IPFrom16(a)
return netip.AddrFrom16(a).Unmap()
}
return netip.Addr{}
}