diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go index 08b326913..f3da419e4 100644 --- a/cmd/tailscale/cli/up.go +++ b/cmd/tailscale/cli/up.go @@ -19,7 +19,6 @@ "sync" "github.com/peterbourgon/ff/v2/ffcli" - "github.com/tailscale/wireguard-go/wgcfg" "inet.af/netaddr" "tailscale.com/ipn" "tailscale.com/tailcfg" @@ -85,29 +84,6 @@ func defaultNetfilterMode() string { hostname string } -// parseIPOrCIDR parses an IP address or a CIDR prefix. If the input -// is an IP address, it is returned in CIDR form with a /32 mask for -// IPv4 or a /128 mask for IPv6. -func parseIPOrCIDR(s string) (wgcfg.CIDR, bool) { - if strings.Contains(s, "/") { - ret, err := wgcfg.ParseCIDR(s) - if err != nil { - return wgcfg.CIDR{}, false - } - return ret, true - } - - ip, ok := wgcfg.ParseIP(s) - if !ok { - return wgcfg.CIDR{}, false - } - if ip.Is4() { - return wgcfg.CIDR{IP: ip, Mask: 32}, true - } else { - return wgcfg.CIDR{IP: ip, Mask: 128}, true - } -} - func isBSD(s string) bool { return s == "dragonfly" || s == "freebsd" || s == "netbsd" || s == "openbsd" } @@ -162,19 +138,18 @@ func runUp(ctx context.Context, args []string) error { } } - var routes []wgcfg.CIDR + var routes []netaddr.IPPrefix if upArgs.advertiseRoutes != "" { advroutes := strings.Split(upArgs.advertiseRoutes, ",") for _, s := range advroutes { - cidr, ok := parseIPOrCIDR(s) - ipp, err := netaddr.ParseIPPrefix(s) // parse it with other pawith both packages - if !ok || err != nil { + ipp, err := netaddr.ParseIPPrefix(s) + if err != nil { fatalf("%q is not a valid IP address or CIDR prefix", s) } if ipp != ipp.Masked() { fatalf("%s has non-address bits set; expected %s", ipp, ipp.Masked()) } - routes = append(routes, cidr) + routes = append(routes, ipp) } checkIPForwarding() } diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 7daf323c9..911d2f1e5 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -761,7 +761,7 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM nm.MachineStatus = tailcfg.MachineUnauthorized } if len(resp.DNS) > 0 { - nm.DNS.Nameservers = wgIPToNetaddr(resp.DNS) + nm.DNS.Nameservers = resp.DNS } if len(resp.SearchPaths) > 0 { nm.DNS.Domains = resp.SearchPaths @@ -922,17 +922,6 @@ func loadServerKey(ctx context.Context, httpc *http.Client, serverURL string) (w return key, nil } -func wgIPToNetaddr(ips []wgcfg.IP) (ret []netaddr.IP) { - for _, ip := range ips { - nip, ok := netaddr.FromStdIP(ip.IP()) - if !ok { - panic(fmt.Sprintf("conversion of %s from wgcfg to netaddr IP failed", ip)) - } - ret = append(ret, nip.Unmap()) - } - return ret -} - // Debug contains temporary internal-only debug knobs. // They're unexported to not draw attention to them. var Debug = initDebug() @@ -1091,7 +1080,7 @@ func TrimWGConfig() opt.Bool { // and will definitely not work for the routes provided. // // It should not return false positives. -func ipForwardingBroken(routes []wgcfg.CIDR) bool { +func ipForwardingBroken(routes []netaddr.IPPrefix) bool { if len(routes) == 0 { // Nothing to route, so no need to warn. return false diff --git a/control/controlclient/netmap.go b/control/controlclient/netmap.go index 024fff27f..cda3239e4 100644 --- a/control/controlclient/netmap.go +++ b/control/controlclient/netmap.go @@ -14,6 +14,7 @@ "time" "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/logger" "tailscale.com/wgengine/filter" @@ -27,7 +28,7 @@ type NetworkMap struct { Expiry time.Time // Name is the DNS name assigned to this node. Name string - Addresses []wgcfg.CIDR + Addresses []netaddr.IPPrefix LocalPort uint16 // used for debugging MachineStatus tailcfg.MachineStatus MachineKey tailcfg.MachineKey @@ -278,7 +279,7 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi } } for _, allowedIP := range peer.AllowedIPs { - if allowedIP.Mask == 0 { + if allowedIP.Bits == 0 { if (flags & AllowDefaultRoute) == 0 { logf("[v1] wgcfg: %v skipping default route", peer.Key.ShortString()) continue @@ -298,17 +299,11 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi // cidrIsSubnet reports whether cidr is a non-default-route subnet // exported by node that is not one of its own self addresses. -func cidrIsSubnet(node *tailcfg.Node, cidr wgcfg.CIDR) bool { - if cidr.Mask == 0 { +func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool { + if cidr.Bits == 0 { return false } - if cidr.Mask < 32 { - // Fast path for IPv4, to avoid loop below. - // - // TODO: if cidr.IP is an IPv6 address, we could do "< 128" - // to avoid the range over node.Addresses. Or we could - // just remove this fast path and unconditionally do the range - // loop. + if !cidr.IsSingleIP() { return true } for _, selfCIDR := range node.Addresses { @@ -351,7 +346,7 @@ func eqStringsIgnoreNil(a, b []string) bool { // eqCIDRsIgnoreNil reports whether a and b have the same length and // contents, but ignore whether a or b are nil. -func eqCIDRsIgnoreNil(a, b []wgcfg.CIDR) bool { +func eqCIDRsIgnoreNil(a, b []netaddr.IPPrefix) bool { if len(a) != len(b) { return false } diff --git a/control/controlclient/netmap_test.go b/control/controlclient/netmap_test.go index c9a422cec..5bb529ab0 100644 --- a/control/controlclient/netmap_test.go +++ b/control/controlclient/netmap_test.go @@ -9,7 +9,7 @@ "encoding/json" "testing" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/tailcfg" ) @@ -251,7 +251,7 @@ func TestConciseDiffFrom(t *testing.T) { DERP: "127.3.3.40:2", Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"}, DiscoKey: testDiscoKey("f00f00f00f"), - AllowedIPs: []wgcfg.CIDR{{IP: wgcfg.IPv4(100, 102, 103, 104), Mask: 32}}, + AllowedIPs: []netaddr.IPPrefix{{IP: netaddr.IPv4(100, 102, 103, 104), Bits: 32}}, }, }, }, @@ -264,7 +264,7 @@ func TestConciseDiffFrom(t *testing.T) { DERP: "127.3.3.40:2", Endpoints: []string{"192.168.0.100:41641", "1.1.1.1:41641"}, DiscoKey: testDiscoKey("ba4ba4ba4b"), - AllowedIPs: []wgcfg.CIDR{{IP: wgcfg.IPv4(100, 102, 103, 104), Mask: 32}}, + AllowedIPs: []netaddr.IPPrefix{{IP: netaddr.IPv4(100, 102, 103, 104), Bits: 32}}, }, }, }, diff --git a/go.mod b/go.mod index ad492a9bb..1bbaf9479 100644 --- a/go.mod +++ b/go.mod @@ -24,10 +24,12 @@ require ( github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3 github.com/peterbourgon/ff/v2 v2.0.0 github.com/tailscale/depaware v0.0.0-20201214215404-77d1e9757027 - github.com/tailscale/wireguard-go v0.0.0-20201220011020-db78fad0bebf + github.com/tailscale/wireguard-go v0.0.20201119-0.20201228205120-066446d1733a github.com/tcnksm/go-httpstat v0.2.0 github.com/toqueteos/webbrowser v1.2.0 + go4.org/intern v0.0.0-20201223061701-969c7e87e7cb // indirect go4.org/mem v0.0.0-20201119185036-c04c5a6ff174 + go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 // indirect golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 golang.org/x/net v0.0.0-20201216054612-986b41b23924 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d @@ -38,6 +40,6 @@ require ( golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 golang.zx2c4.com/wireguard/windows v0.1.2-0.20201113162609-9b85be97fdf8 honnef.co/go/tools v0.1.0 - inet.af/netaddr v0.0.0-20201222221711-c9bc69c385b2 + inet.af/netaddr v0.0.0-20201226233944-2d1876c01610 rsc.io/goversion v1.2.0 ) diff --git a/go.sum b/go.sum index 91ed09136..af3ac705c 100644 --- a/go.sum +++ b/go.sum @@ -118,25 +118,26 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofm github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go4.org/intern v0.0.0-20201222181806-763bd24e33ab h1:0V+gA+DKQSvINBzmFW6tc0Tz8/U7w3ZmhWP7Q+3wjhg= -go4.org/intern v0.0.0-20201222181806-763bd24e33ab/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= +go4.org/intern v0.0.0-20201223054237-ef8cbcb8edd7 h1:yeDrXaQ3VRXbTN7lHj70DxW4LdPow83MVwPPRjpP70U= +go4.org/intern v0.0.0-20201223054237-ef8cbcb8edd7/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= +go4.org/intern v0.0.0-20201223061701-969c7e87e7cb h1:yuqO0E4bHRsTPUocDpRKXfLE40lwWplVxENQ2WOV7Gc= +go4.org/intern v0.0.0-20201223061701-969c7e87e7cb/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= go4.org/mem v0.0.0-20201119185036-c04c5a6ff174 h1:vSug/WNOi2+4jrKdivxayTN/zd8EA1UrStjpWvvo1jk= go4.org/mem v0.0.0-20201119185036-c04c5a6ff174/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e h1:ExUmGi0ZsQmiVo9giDQqXkr7vreeXPMkOGIusfsfbzI= go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 h1:xYJJ3S178yv++9zXV/hnr29plCAGO9vAFG9dorqaFQc= golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -178,11 +179,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201202213521-69691e467435 h1:25AvDqqB9PrNqj1FLf2/70I4W0L19qqoaFq3gjNwbKk= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -191,7 +190,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b h1:a0ErnNnPKmhDyIXQvdZr+Lq8dc8xpMeqkF8y5PgQU4Q= golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -208,15 +206,11 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.20200321-0.20201111175144-60b3766b89b9 h1:qowcZ56hhpeoESmWzI4Exhx4Y78TpCyXUJur4/c0CoE= golang.zx2c4.com/wireguard v0.0.20200321-0.20201111175144-60b3766b89b9/go.mod h1:LMeNfjlcPZTrBC1juwgbQyA4Zy2XVcsrdO/fIJxwyuA= -golang.zx2c4.com/wireguard/windows v0.1.2-0.20201113162609-9b85be97fdf8 h1:nlXPqGA98n+qcq1pwZ28KjM5EsFQvamKS00A+VUeVjs= golang.zx2c4.com/wireguard/windows v0.1.2-0.20201113162609-9b85be97fdf8/go.mod h1:psva4yDnAHLuh7lUzOK7J7bLYxNFfo0iKWz+mi9gzkA= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -225,9 +219,11 @@ gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.1.0 h1:AWNL1W1i7f0wNZ8VwOKNJ0sliKvOF/adn0EHenfUh+c= honnef.co/go/tools v0.1.0/go.mod h1:XtegFAyX/PfluP4921rXU5IkjkqBCDnUq4W8VCIoKvM= -inet.af/netaddr v0.0.0-20201218162718-658fec415e52 h1:M3x8SO1eBn5526cVLtdQHVbQVzNcq6/zq2RDGCSuULc= -inet.af/netaddr v0.0.0-20201218162718-658fec415e52/go.mod h1:qqYzz/2whtrbWJvt+DNWQyvekNN4ePQZcg2xc2/Yjww= -inet.af/netaddr v0.0.0-20201222221711-c9bc69c385b2 h1:BS647ZMTpjIVt5mX2GUEq5NQTSv511tQZTeTmXQLRa0= -inet.af/netaddr v0.0.0-20201222221711-c9bc69c385b2/go.mod h1:UIsIj3CkLdrPSbDjO+yQO1TFLO2VUS0qNSqAw+aqQDE= +inet.af/netaddr v0.0.0-20201223185330-97d366981fac h1:aqMW8vft7VmOIhtQhsTWhAuZzOBGYBv+Otyvwj+VGSU= +inet.af/netaddr v0.0.0-20201223185330-97d366981fac/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o= +inet.af/netaddr v0.0.0-20201224214825-a55841caa437 h1:Li2QBwaT/hU3wE7GdyoqaX+TzIlI+V1zs/CuWrjX8e4= +inet.af/netaddr v0.0.0-20201224214825-a55841caa437/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o= +inet.af/netaddr v0.0.0-20201226233944-2d1876c01610 h1:9Nnw3NS9SL4SlFtBWSdv7onMbdY+B8nflRNZvhgxuMY= +inet.af/netaddr v0.0.0-20201226233944-2d1876c01610/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o= rsc.io/goversion v1.2.0 h1:SPn+NLTiAG7w30IRK/DKp1BjvpWabYgxlLp/+kx5J8w= rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo= diff --git a/internal/deepprint/deepprint_test.go b/internal/deepprint/deepprint_test.go index d88541f67..5512c1e11 100644 --- a/internal/deepprint/deepprint_test.go +++ b/internal/deepprint/deepprint_test.go @@ -37,7 +37,7 @@ func getVal() []interface{} { return []interface{}{ &wgcfg.Config{ Name: "foo", - Addresses: []wgcfg.CIDR{{Mask: 5, IP: wgcfg.IP{Addr: [16]byte{3: 3}}}}, + Addresses: []netaddr.IPPrefix{{Bits: 5, IP: netaddr.IPFrom16([16]byte{3: 3})}}, ListenPort: 5, Peers: []wgcfg.Peer{ { diff --git a/ipn/handle.go b/ipn/handle.go index c9f761b4c..b79eea8e2 100644 --- a/ipn/handle.go +++ b/ipn/handle.go @@ -8,8 +8,8 @@ "sync" "time" - "github.com/tailscale/wireguard-go/wgcfg" "golang.org/x/oauth2" + "inet.af/netaddr" "tailscale.com/control/controlclient" "tailscale.com/types/logger" ) @@ -118,7 +118,7 @@ func (h *Handle) EngineStatus() EngineStatus { return h.engineStatusCache } -func (h *Handle) LocalAddrs() []wgcfg.CIDR { +func (h *Handle) LocalAddrs() []netaddr.IPPrefix { h.mu.Lock() defer h.mu.Unlock() @@ -126,7 +126,7 @@ func (h *Handle) LocalAddrs() []wgcfg.CIDR { if nm != nil { return nm.Addresses } - return []wgcfg.CIDR{} + return []netaddr.IPPrefix{} } func (h *Handle) NetMap() *controlclient.NetworkMap { diff --git a/ipn/local.go b/ipn/local.go index 4c36b31d6..d2b2f3c78 100644 --- a/ipn/local.go +++ b/ipn/local.go @@ -213,7 +213,7 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) { // The peer struct currently only allows a single // Tailscale IP address. For compatibility with the // old display, make sure it's the IPv4 address. - if addr.IP.Is4() && addr.Mask == 32 && tsaddr.IsTailscaleIP(netaddr.IPFrom16(addr.IP.Addr)) { + if addr.IP.Is4() && addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.IP) { tailAddr = addr.IP.String() break } @@ -534,9 +534,9 @@ func (b *LocalBackend) updateFilter(netMap *controlclient.NetworkMap, prefs *Pre // quite hard to debug, so save yourself the trouble. var ( haveNetmap = netMap != nil - addrs []wgcfg.CIDR + addrs []netaddr.IPPrefix packetFilter []filter.Match - advRoutes []wgcfg.CIDR + advRoutes []netaddr.IPPrefix shieldsUp = prefs == nil || prefs.ShieldsUp // Be conservative when not ready ) if haveNetmap { @@ -558,7 +558,7 @@ func (b *LocalBackend) updateFilter(netMap *controlclient.NetworkMap, prefs *Pre return } - localNets := wgCIDRsToNetaddr(netMap.Addresses, advRoutes) + localNets := unmapIPPrefixes(netMap.Addresses, advRoutes) if shieldsUp { b.logf("netmap packet filter: (shields up)") @@ -572,7 +572,7 @@ func (b *LocalBackend) updateFilter(netMap *controlclient.NetworkMap, prefs *Pre // dnsCIDRsEqual determines whether two CIDR lists are equal // for DNS map construction purposes (that is, only the first entry counts). -func dnsCIDRsEqual(newAddr, oldAddr []wgcfg.CIDR) bool { +func dnsCIDRsEqual(newAddr, oldAddr []netaddr.IPPrefix) bool { if len(newAddr) != len(oldAddr) { return false } @@ -626,11 +626,11 @@ func (b *LocalBackend) updateDNSMap(netMap *controlclient.NetworkMap) { } nameToIP := make(map[string]netaddr.IP) - set := func(name string, addrs []wgcfg.CIDR) { + set := func(name string, addrs []netaddr.IPPrefix) { if len(addrs) == 0 || name == "" { return } - nameToIP[name] = netaddr.IPFrom16(addrs[0].IP.Addr) + nameToIP[name] = addrs[0].IP } for _, peer := range netMap.Peers { @@ -1064,7 +1064,7 @@ func (b *LocalBackend) SetPrefs(newp *Prefs) { oldHi := b.hostinfo newHi := oldHi.Clone() - newHi.RoutableIPs = append([]wgcfg.CIDR(nil), b.prefs.AdvertiseRoutes...) + newHi.RoutableIPs = append([]netaddr.IPPrefix(nil), b.prefs.AdvertiseRoutes...) applyPrefsToHostinfo(newHi, newp) b.hostinfo = newHi hostInfoChanged := !oldHi.Equal(newHi) @@ -1264,23 +1264,15 @@ func domainsForProxying(nm *controlclient.NetworkMap) []string { // routerConfig produces a router.Config from a wireguard config and IPN prefs. func routerConfig(cfg *wgcfg.Config, prefs *Prefs) *router.Config { - var addrs []wgcfg.CIDR - for _, addr := range cfg.Addresses { - addrs = append(addrs, wgcfg.CIDR{ - IP: addr.IP, - Mask: addr.Mask, - }) - } - rs := &router.Config{ - LocalAddrs: wgCIDRsToNetaddr(addrs), - SubnetRoutes: wgCIDRsToNetaddr(prefs.AdvertiseRoutes), + LocalAddrs: unmapIPPrefixes(cfg.Addresses), + SubnetRoutes: unmapIPPrefixes(prefs.AdvertiseRoutes), SNATSubnetRoutes: !prefs.NoSNAT, NetfilterMode: prefs.NetfilterMode, } for _, peer := range cfg.Peers { - rs.Routes = append(rs.Routes, wgCIDRsToNetaddr(peer.AllowedIPs)...) + rs.Routes = append(rs.Routes, unmapIPPrefixes(peer.AllowedIPs)...) } rs.Routes = append(rs.Routes, netaddr.IPPrefix{ @@ -1291,15 +1283,10 @@ func routerConfig(cfg *wgcfg.Config, prefs *Prefs) *router.Config { return rs } -func wgCIDRsToNetaddr(cidrLists ...[]wgcfg.CIDR) (ret []netaddr.IPPrefix) { - for _, cidrs := range cidrLists { - for _, cidr := range cidrs { - ncidr, ok := netaddr.FromStdIPNet(cidr.IPNet()) - if !ok { - panic(fmt.Sprintf("conversion of %s from wgcfg to netaddr IPNet failed", cidr)) - } - ncidr.IP = ncidr.IP.Unmap() - ret = append(ret, ncidr) +func unmapIPPrefixes(ippsList ...[]netaddr.IPPrefix) (ret []netaddr.IPPrefix) { + for _, ipps := range ippsList { + for _, ipp := range ipps { + ret = append(ret, netaddr.IPPrefix{IP: ipp.IP.Unmap(), Bits: ipp.Bits}) } } return ret diff --git a/ipn/prefs.go b/ipn/prefs.go index c65ca6095..970d08a9a 100644 --- a/ipn/prefs.go +++ b/ipn/prefs.go @@ -15,7 +15,7 @@ "runtime" "strings" - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/atomicfile" "tailscale.com/control/controlclient" "tailscale.com/wgengine/router" @@ -100,7 +100,7 @@ type Prefs struct { // AdvertiseRoutes specifies CIDR prefixes to advertise into the // Tailscale network as reachable through the current // node. - AdvertiseRoutes []wgcfg.CIDR + AdvertiseRoutes []netaddr.IPPrefix // NoSNAT specifies whether to source NAT traffic going to // destinations in AdvertiseRoutes. The default is to apply source @@ -206,12 +206,12 @@ func (p *Prefs) Equals(p2 *Prefs) bool { p.Persist.Equals(p2.Persist) } -func compareIPNets(a, b []wgcfg.CIDR) bool { +func compareIPNets(a, b []netaddr.IPPrefix) bool { if len(a) != len(b) { return false } for i := range a { - if !a[i].IP.Equal(b[i].IP) || a[i].Mask != b[i].Mask { + if a[i] != b[i] { return false } } diff --git a/ipn/prefs_clone.go b/ipn/prefs_clone.go index 051c75c4c..c0e11f8f8 100644 --- a/ipn/prefs_clone.go +++ b/ipn/prefs_clone.go @@ -7,7 +7,7 @@ package ipn import ( - "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/control/controlclient" "tailscale.com/wgengine/router" ) @@ -44,7 +44,7 @@ func (src *Prefs) Clone() *Prefs { DeviceModel string NotepadURLs bool ForceDaemon bool - AdvertiseRoutes []wgcfg.CIDR + AdvertiseRoutes []netaddr.IPPrefix NoSNAT bool NetfilterMode router.NetfilterMode Persist *controlclient.Persist diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go index 105683511..47fc02f6c 100644 --- a/ipn/prefs_test.go +++ b/ipn/prefs_test.go @@ -14,6 +14,7 @@ "time" "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" "tailscale.com/control/controlclient" "tailscale.com/tstest" "tailscale.com/wgengine/router" @@ -35,9 +36,9 @@ func TestPrefsEqual(t *testing.T) { have, prefsHandles) } - nets := func(strs ...string) (ns []wgcfg.CIDR) { + nets := func(strs ...string) (ns []netaddr.IPPrefix) { for _, s := range strs { - n, err := wgcfg.ParseCIDR(s) + n, err := netaddr.ParseIPPrefix(s) if err != nil { panic(err) } @@ -166,12 +167,12 @@ func TestPrefsEqual(t *testing.T) { { &Prefs{AdvertiseRoutes: nil}, - &Prefs{AdvertiseRoutes: []wgcfg.CIDR{}}, + &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}}, true, }, { - &Prefs{AdvertiseRoutes: []wgcfg.CIDR{}}, - &Prefs{AdvertiseRoutes: []wgcfg.CIDR{}}, + &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}}, + &Prefs{AdvertiseRoutes: []netaddr.IPPrefix{}}, true, }, { diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 5eddb9e27..1a198c667 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -14,7 +14,6 @@ "strings" "time" - "github.com/tailscale/wireguard-go/wgcfg" "go4.org/mem" "golang.org/x/oauth2" "inet.af/netaddr" @@ -143,10 +142,10 @@ type Node struct { KeyExpiry time.Time Machine MachineKey DiscoKey DiscoKey - Addresses []wgcfg.CIDR // IP addresses of this Node directly - AllowedIPs []wgcfg.CIDR // range of IP addresses to route to this node - Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs) - DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint + Addresses []netaddr.IPPrefix // IP addresses of this Node directly + AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node + Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs) + DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint Hostinfo Hostinfo Created time.Time LastSeen *time.Time `json:",omitempty"` @@ -279,20 +278,20 @@ type Service struct { type Hostinfo struct { // TODO(crawshaw): mark all these fields ",omitempty" when all the // iOS apps are updated with the latest swift version of this struct. - IPNVersion string `json:",omitempty"` // version of this code - FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance - BackendLogID string `json:",omitempty"` // logtail ID of backend instance - OS string // operating system the client runs on (a version.OS value) - OSVersion string `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041") - DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone 11 Pro") - Hostname string // name of the host the client runs on - ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections - ShareeNode bool `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user - GoArch string `json:",omitempty"` // the host's GOARCH value (of the running binary) - RoutableIPs []wgcfg.CIDR `json:",omitempty"` // set of IP ranges this client can route - RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim - Services []Service `json:",omitempty"` // services advertised by this machine - NetInfo *NetInfo `json:",omitempty"` + IPNVersion string `json:",omitempty"` // version of this code + FrontendLogID string `json:",omitempty"` // logtail ID of frontend instance + BackendLogID string `json:",omitempty"` // logtail ID of backend instance + OS string // operating system the client runs on (a version.OS value) + OSVersion string `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041") + DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone 11 Pro") + Hostname string // name of the host the client runs on + ShieldsUp bool `json:",omitempty"` // indicates whether the host is blocking incoming connections + ShareeNode bool `json:",omitempty"` // indicates this node exists in netmap because it's owned by a shared-to user + GoArch string `json:",omitempty"` // the host's GOARCH value (of the running binary) + RoutableIPs []netaddr.IPPrefix `json:",omitempty"` // set of IP ranges this client can route + RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim + Services []Service `json:",omitempty"` // services advertised by this machine + NetInfo *NetInfo `json:",omitempty"` // NOTE: any new fields containing pointers in this type // require changes to Hostinfo.Equal. @@ -627,7 +626,7 @@ type MapResponse struct { // DNS is the same as DNSConfig.Nameservers. // // TODO(dmytro): should be sent in DNSConfig.Nameservers once clients have updated. - DNS []wgcfg.IP `json:",omitempty"` + DNS []netaddr.IP `json:",omitempty"` // SearchPaths are the same as DNSConfig.Domains. // // TODO(dmytro): should be sent in DNSConfig.Domains once clients have updated. @@ -780,7 +779,7 @@ func eqStrings(a, b []string) bool { return true } -func eqCIDRs(a, b []wgcfg.CIDR) bool { +func eqCIDRs(a, b []netaddr.IPPrefix) bool { if len(a) != len(b) || ((a == nil) != (b == nil)) { return false } diff --git a/tailcfg/tailcfg_clone.go b/tailcfg/tailcfg_clone.go index d89607dd4..d22afb914 100644 --- a/tailcfg/tailcfg_clone.go +++ b/tailcfg/tailcfg_clone.go @@ -7,7 +7,6 @@ package tailcfg import ( - "github.com/tailscale/wireguard-go/wgcfg" "inet.af/netaddr" "tailscale.com/types/opt" "tailscale.com/types/structs" @@ -69,8 +68,8 @@ func (src *Node) Clone() *Node { KeyExpiry time.Time Machine MachineKey DiscoKey DiscoKey - Addresses []wgcfg.CIDR - AllowedIPs []wgcfg.CIDR + Addresses []netaddr.IPPrefix + AllowedIPs []netaddr.IPPrefix Endpoints []string DERP string Hostinfo Hostinfo @@ -108,7 +107,7 @@ func (src *Hostinfo) Clone() *Hostinfo { ShieldsUp bool ShareeNode bool GoArch string - RoutableIPs []wgcfg.CIDR + RoutableIPs []netaddr.IPPrefix RequestTags []string Services []Service NetInfo *NetInfo diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go index 3f8cbcf69..d0e2d6dce 100644 --- a/tailcfg/tailcfg_test.go +++ b/tailcfg/tailcfg_test.go @@ -12,6 +12,7 @@ "time" "github.com/tailscale/wireguard-go/wgcfg" + "inet.af/netaddr" ) func fieldsOf(t reflect.Type) (fields []string) { @@ -35,9 +36,9 @@ func TestHostinfoEqual(t *testing.T) { have, hiHandles) } - nets := func(strs ...string) (ns []wgcfg.CIDR) { + nets := func(strs ...string) (ns []netaddr.IPPrefix) { for _, s := range strs { - n, err := wgcfg.ParseCIDR(s) + n, err := netaddr.ParseIPPrefix(s) if err != nil { panic(err) } @@ -264,23 +265,23 @@ func TestNodeEqual(t *testing.T) { true, }, { - &Node{Addresses: []wgcfg.CIDR{}}, + &Node{Addresses: []netaddr.IPPrefix{}}, &Node{Addresses: nil}, false, }, { - &Node{Addresses: []wgcfg.CIDR{}}, - &Node{Addresses: []wgcfg.CIDR{}}, + &Node{Addresses: []netaddr.IPPrefix{}}, + &Node{Addresses: []netaddr.IPPrefix{}}, true, }, { - &Node{AllowedIPs: []wgcfg.CIDR{}}, + &Node{AllowedIPs: []netaddr.IPPrefix{}}, &Node{AllowedIPs: nil}, false, }, { - &Node{Addresses: []wgcfg.CIDR{}}, - &Node{Addresses: []wgcfg.CIDR{}}, + &Node{Addresses: []netaddr.IPPrefix{}}, + &Node{Addresses: []netaddr.IPPrefix{}}, true, }, { @@ -429,8 +430,8 @@ func TestCloneNode(t *testing.T) { }{ {"nil_fields", &Node{}}, {"zero_fields", &Node{ - Addresses: make([]wgcfg.CIDR, 0), - AllowedIPs: make([]wgcfg.CIDR, 0), + Addresses: make([]netaddr.IPPrefix, 0), + AllowedIPs: make([]netaddr.IPPrefix, 0), Endpoints: make([]string, 0), }}, } diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 210a9a59f..8073d01e0 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -702,18 +702,17 @@ func peerForIP(nm *controlclient.NetworkMap, ip netaddr.IP) (n *tailcfg.Node, ok if nm == nil { return nil, false } - wgIP := wgcfg.IP{Addr: ip.As16()} // Check for exact matches before looking for subnet matches. for _, p := range nm.Peers { for _, a := range p.Addresses { - if a.IP == wgIP { + if a.IP == ip { return p, true } } } for _, p := range nm.Peers { for _, cidr := range p.AllowedIPs { - if cidr.Contains(wgIP) { + if cidr.Contains(ip) { return p, true } } @@ -2720,16 +2719,15 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) { if c.netMap != nil { for _, addr := range c.netMap.Addresses { - ip := netaddr.IPFrom16(addr.IP.Addr) - if addr.Mask != ip.BitLen() { + if !addr.IsSingleIP() { continue } - sb.AddTailscaleIP(ip) + sb.AddTailscaleIP(addr.IP) // TailAddr only allows for a single Tailscale IP. For // readability of `tailscale status`, make it the IPv4 // address. if addr.IP.Is4() { - ss.TailAddr = ip.String() + ss.TailAddr = addr.IP.String() } } } diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go index 93e8ee83f..0ca3816c4 100644 --- a/wgengine/magicsock/magicsock_test.go +++ b/wgengine/magicsock/magicsock_test.go @@ -248,13 +248,13 @@ func meshStacks(logf logger.Logf, ms []*magicStack) (cleanup func()) { nm := &controlclient.NetworkMap{ PrivateKey: me.privateKey, NodeKey: tailcfg.NodeKey(me.privateKey.Public()), - Addresses: []wgcfg.CIDR{{IP: wgcfg.IPv4(1, 0, 0, byte(myIdx+1)), Mask: 32}}, + Addresses: []netaddr.IPPrefix{{IP: netaddr.IPv4(1, 0, 0, byte(myIdx+1)), Bits: 32}}, } for i, peer := range ms { if i == myIdx { continue } - addrs := []wgcfg.CIDR{{IP: wgcfg.IPv4(1, 0, 0, byte(i+1)), Mask: 32}} + addrs := []netaddr.IPPrefix{{IP: netaddr.IPv4(1, 0, 0, byte(i+1)), Bits: 32}} peer := &tailcfg.Node{ ID: tailcfg.NodeID(i + 1), Name: fmt.Sprintf("node%d", i+1), @@ -454,7 +454,7 @@ func makeConfigs(t *testing.T, addrs []netaddr.IPPort) []wgcfg.Config { t.Helper() var privKeys []wgcfg.PrivateKey - var addresses [][]wgcfg.CIDR + var addresses [][]netaddr.IPPrefix for i := range addrs { privKey, err := wgcfg.NewPrivateKey() @@ -463,7 +463,7 @@ func makeConfigs(t *testing.T, addrs []netaddr.IPPort) []wgcfg.Config { } privKeys = append(privKeys, privKey) - addresses = append(addresses, []wgcfg.CIDR{ + addresses = append(addresses, []netaddr.IPPrefix{ parseCIDR(t, fmt.Sprintf("1.0.0.%d/32", i+1)), }) } @@ -496,9 +496,9 @@ func makeConfigs(t *testing.T, addrs []netaddr.IPPort) []wgcfg.Config { return cfgs } -func parseCIDR(t *testing.T, addr string) wgcfg.CIDR { +func parseCIDR(t *testing.T, addr string) netaddr.IPPrefix { t.Helper() - cidr, err := wgcfg.ParseCIDR(addr) + cidr, err := netaddr.ParseIPPrefix(addr) if err != nil { t.Fatal(err) } diff --git a/wgengine/router/router_openbsd.go b/wgengine/router/router_openbsd.go index 05c06a70a..5bfd05eed 100644 --- a/wgengine/router/router_openbsd.go +++ b/wgengine/router/router_openbsd.go @@ -81,7 +81,7 @@ func (r *openbsdRouter) Set(cfg *Config) error { var errq error if localAddr != r.local { - if r.local != (netaddr.IPPrefix{}) { + if !r.local.IsZero() { addrdel := []string{"ifconfig", r.tunname, "inet", r.local.String(), "-alias"} out, err := cmd(addrdel...).CombinedOutput() diff --git a/wgengine/router/router_userspace_bsd.go b/wgengine/router/router_userspace_bsd.go index 30fc8e7cb..33848c8bb 100644 --- a/wgengine/router/router_userspace_bsd.go +++ b/wgengine/router/router_userspace_bsd.go @@ -81,7 +81,7 @@ func (r *userspaceBSDRouter) Set(cfg *Config) error { // Update the address. if localAddr != r.local { // If the interface is already set, remove it. - if r.local != (netaddr.IPPrefix{}) { + if !r.local.IsZero() { addrdel := []string{"ifconfig", r.tunname, "inet", r.local.String(), "-alias"} out, err := cmd(addrdel...).CombinedOutput() diff --git a/wgengine/userspace.go b/wgengine/userspace.go index a0f9e074a..13397c60f 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -278,12 +278,14 @@ func newUserspaceEngineAdvanced(conf EngineConfig) (_ Engine, reterr error) { // Ping every single-IP that peer routes. // These synthetic packets are used to traverse NATs. - var ips []wgcfg.IP + var ips []netaddr.IP allowedIPs := deviceAllowedIPs.EntriesForPeer(peer) for _, ipNet := range allowedIPs { if ones, bits := ipNet.Mask.Size(); ones == bits && ones != 0 { - var ip wgcfg.IP - copy(ip.Addr[:], ipNet.IP.To16()) + ip, ok := netaddr.FromStdIP(ipNet.IP) + if !ok { + continue + } ips = append(ips, ip) } } @@ -485,7 +487,7 @@ func (p *pinger) close() { <-p.done } -func (p *pinger) run(ctx context.Context, peerKey wgcfg.Key, ips []wgcfg.IP, srcIP netaddr.IP) { +func (p *pinger) run(ctx context.Context, peerKey wgcfg.Key, ips []netaddr.IP, srcIP netaddr.IP) { defer func() { p.e.mu.Lock() if p.e.pingers[peerKey] == p { @@ -520,7 +522,7 @@ func (p *pinger) run(ctx context.Context, peerKey wgcfg.Key, ips []wgcfg.IP, src // work. continue } - dstIPs = append(dstIPs, netaddr.IPFrom16(ip.Addr)) + dstIPs = append(dstIPs, ip) } payload := []byte("magicsock_spray") // no meaning @@ -554,13 +556,13 @@ func (p *pinger) run(ctx context.Context, peerKey wgcfg.Key, ips []wgcfg.IP, src // // This is only used with legacy peers (before 0.100.0) that don't // have advertised discovery keys. -func (e *userspaceEngine) pinger(peerKey wgcfg.Key, ips []wgcfg.IP) { +func (e *userspaceEngine) pinger(peerKey wgcfg.Key, ips []netaddr.IP) { e.logf("[v1] generating initial ping traffic to %s (%v)", peerKey.ShortString(), ips) var srcIP netaddr.IP e.wgLock.Lock() if len(e.lastCfgFull.Addresses) > 0 { - srcIP = netaddr.IPFrom16(e.lastCfgFull.Addresses[0].IP.Addr) + srcIP = e.lastCfgFull.Addresses[0].IP } e.wgLock.Unlock() @@ -642,9 +644,7 @@ func isTrimmablePeer(p *wgcfg.Peer, numPeers int) bool { // AllowedIPs must all be single IPs, not subnets. for _, aip := range p.AllowedIPs { - if aip.IP.Is4() && aip.Mask != 32 { - return false - } else if aip.IP.Is6() && aip.Mask != 128 { + if !aip.IsSingleIP() { return false } } @@ -684,12 +684,11 @@ func (e *userspaceEngine) noteReceiveActivity(dk tailcfg.DiscoKey) { // had a packet sent to or received from it since t. // // e.wgLock must be held. -func (e *userspaceEngine) isActiveSince(dk tailcfg.DiscoKey, ip wgcfg.IP, t time.Time) bool { +func (e *userspaceEngine) isActiveSince(dk tailcfg.DiscoKey, ip netaddr.IP, t time.Time) bool { if e.recvActivityAt[dk].After(t) { return true } - pip := netaddr.IPFrom16(ip.Addr) - timePtr, ok := e.sentActivityAt[pip] + timePtr, ok := e.sentActivityAt[ip] if !ok { return false } @@ -746,7 +745,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Publ // we'll need to install tracking hooks for to watch their // send/receive activity. trackDisco := make([]tailcfg.DiscoKey, 0, len(full.Peers)) - trackIPs := make([]wgcfg.IP, 0, len(full.Peers)) + trackIPs := make([]netaddr.IP, 0, len(full.Peers)) trimmedDisco := map[tailcfg.DiscoKey]bool{} // TODO: don't re-alloc this map each time @@ -816,7 +815,7 @@ func (e *userspaceEngine) maybeReconfigWireguardLocked(discoChanged map[key.Publ // as given to wireguard-go. // // e.wgLock must be held. -func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey, trackIPs []wgcfg.IP) { +func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey, trackIPs []netaddr.IP) { // Generate the new map of which discokeys we want to track // receive times for. mr := map[tailcfg.DiscoKey]time.Time{} // TODO: only recreate this if set of keys changed @@ -857,19 +856,18 @@ func (e *userspaceEngine) updateActivityMapsLocked(trackDisco []tailcfg.DiscoKey } } - for _, wip := range trackIPs { - pip := netaddr.IPFrom16(wip.Addr) - timePtr := oldTime[pip] + for _, ip := range trackIPs { + timePtr := oldTime[ip] if timePtr == nil { timePtr = new(int64) } - e.sentActivityAt[pip] = timePtr + e.sentActivityAt[ip] = timePtr - fn := oldFunc[pip] + fn := oldFunc[ip] if fn == nil { fn = updateFn(timePtr) } - e.destIPActivityFuncs[pip] = fn + e.destIPActivityFuncs[ip] = fn } e.tundev.SetDestIPActivityFuncs(e.destIPActivityFuncs) } diff --git a/wgengine/userspace_test.go b/wgengine/userspace_test.go index 6c7e05e99..440e750e3 100644 --- a/wgengine/userspace_test.go +++ b/wgengine/userspace_test.go @@ -13,6 +13,7 @@ "github.com/tailscale/wireguard-go/wgcfg" "go4.org/mem" + "inet.af/netaddr" "tailscale.com/tailcfg" "tailscale.com/types/key" "tailscale.com/wgengine/router" @@ -99,8 +100,8 @@ func TestUserspaceEngineReconfig(t *testing.T) { cfg := &wgcfg.Config{ Peers: []wgcfg.Peer{ { - AllowedIPs: []wgcfg.CIDR{ - {IP: wgcfg.IPv4(100, 100, 99, 1), Mask: 32}, + AllowedIPs: []netaddr.IPPrefix{ + {IP: netaddr.IPv4(100, 100, 99, 1), Bits: 32}, }, Endpoints: []wgcfg.Endpoint{ {