From 4a8cb1d9f372ee43326973cd2846380c2bbb4643 Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Wed, 5 Jun 2024 14:37:31 -0700 Subject: [PATCH] all: use math/rand/v2 more Updates #11058 Signed-off-by: Maisem Ali --- cmd/sniproxy/handlers.go | 4 +-- cmd/stund/depaware.txt | 2 +- cmd/stunstamp/stunstamp.go | 4 +-- cmd/tailscale/depaware.txt | 1 + cmd/tailscaled/depaware.txt | 2 +- cmd/tsconnect/wasm/wasm_js.go | 8 +++--- derp/derp_server.go | 4 +-- ipn/ipnlocal/cert.go | 4 +-- ipn/ipnlocal/local.go | 6 ++-- ipn/ipnlocal/profiles.go | 2 +- logtail/backoff/backoff.go | 2 +- logtail/logtail.go | 4 +-- net/netcheck/netcheck.go | 4 +-- net/portmapper/upnp.go | 4 +-- tstest/integration/testcontrol/testcontrol.go | 4 +-- tstest/jsdeps/jsdeps.go | 2 +- tstest/natlab/natlab.go | 4 +-- tstime/jitter.go | 28 ++----------------- util/cloudenv/cloudenv.go | 5 ++-- util/reload/reload.go | 4 +-- util/slicesx/slicesx.go | 6 ++-- wgengine/magicsock/derp.go | 1 + wgengine/magicsock/endpoint.go | 4 +-- 23 files changed, 43 insertions(+), 66 deletions(-) diff --git a/cmd/sniproxy/handlers.go b/cmd/sniproxy/handlers.go index daa07aaa5..102110fe3 100644 --- a/cmd/sniproxy/handlers.go +++ b/cmd/sniproxy/handlers.go @@ -7,7 +7,7 @@ import ( "context" "fmt" "log" - "math/rand" + "math/rand/v2" "net" "net/netip" "slices" @@ -47,7 +47,7 @@ func (h *tcpRoundRobinHandler) Handle(c net.Conn) { return netutil.NewOneConnListener(c, nil), nil } - dest := h.To[rand.Intn(len(h.To))] + dest := h.To[rand.IntN(len(h.To))] dial := &tcpproxy.DialProxy{ Addr: fmt.Sprintf("%s:%s", dest, port), DialContext: h.DialContext, diff --git a/cmd/stund/depaware.txt b/cmd/stund/depaware.txt index b78465002..7395e0f38 100644 --- a/cmd/stund/depaware.txt +++ b/cmd/stund/depaware.txt @@ -153,7 +153,7 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar math/big from crypto/dsa+ math/bits from compress/flate+ math/rand from math/big+ - math/rand/v2 from tailscale.com/util/fastuuid + math/rand/v2 from tailscale.com/util/fastuuid+ mime from github.com/prometheus/common/expfmt+ mime/multipart from net/http mime/quotedprintable from mime/multipart diff --git a/cmd/stunstamp/stunstamp.go b/cmd/stunstamp/stunstamp.go index 6a018585b..0336ace32 100644 --- a/cmd/stunstamp/stunstamp.go +++ b/cmd/stunstamp/stunstamp.go @@ -15,7 +15,7 @@ import ( "io" "log" "math" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -151,7 +151,7 @@ func probe(meta nodeMeta, conn io.ReadWriteCloser, fn measureFn) (*time.Duration Port: 3478, } - time.Sleep(time.Millisecond * time.Duration(rand.Intn(200))) // jitter across tx + time.Sleep(rand.N(200 * time.Millisecond)) // jitter across tx rtt, err := fn(conn, ua) if err != nil { if isTemporaryOrTimeoutErr(err) { diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt index 4d8aa3b19..eff138ac6 100644 --- a/cmd/tailscale/depaware.txt +++ b/cmd/tailscale/depaware.txt @@ -277,6 +277,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep math/big from crypto/dsa+ math/bits from compress/flate+ math/rand from github.com/mdlayher/netlink+ + math/rand/v2 from tailscale.com/derp+ mime from golang.org/x/oauth2/internal+ mime/multipart from net/http mime/quotedprintable from mime/multipart diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index 39a2fb0ec..c5da78609 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -529,7 +529,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de math/big from crypto/dsa+ math/bits from compress/flate+ math/rand from github.com/mdlayher/netlink+ - math/rand/v2 from tailscale.com/util/rands + math/rand/v2 from tailscale.com/util/rands+ mime from github.com/tailscale/xnet/webdav+ mime/multipart from net/http+ mime/quotedprintable from mime/multipart diff --git a/cmd/tsconnect/wasm/wasm_js.go b/cmd/tsconnect/wasm/wasm_js.go index 517c66b3c..8291ac9b4 100644 --- a/cmd/tsconnect/wasm/wasm_js.go +++ b/cmd/tsconnect/wasm/wasm_js.go @@ -16,7 +16,7 @@ import ( "encoding/json" "fmt" "log" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -604,7 +604,7 @@ func filterSlice[T any](a []T, f func(T) bool) []T { func generateHostname() string { tails := words.Tails() scales := words.Scales() - if rand.Int()%2 == 0 { + if rand.IntN(2) == 0 { // JavaScript tails = filterSlice(tails, func(s string) bool { return strings.HasPrefix(s, "j") }) scales = filterSlice(scales, func(s string) bool { return strings.HasPrefix(s, "s") }) @@ -614,8 +614,8 @@ func generateHostname() string { scales = filterSlice(scales, func(s string) bool { return strings.HasPrefix(s, "a") }) } - tail := tails[rand.Intn(len(tails))] - scale := scales[rand.Intn(len(scales))] + tail := tails[rand.IntN(len(tails))] + scale := scales[rand.IntN(len(scales))] return fmt.Sprintf("%s-%s", tail, scale) } diff --git a/derp/derp_server.go b/derp/derp_server.go index 11ba82661..0acfb2909 100644 --- a/derp/derp_server.go +++ b/derp/derp_server.go @@ -22,7 +22,7 @@ import ( "log" "math" "math/big" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -1514,7 +1514,7 @@ func (c *sclient) sendLoop(ctx context.Context) error { } }() - jitter := time.Duration(rand.Intn(5000)) * time.Millisecond + jitter := rand.N(5 * time.Second) keepAliveTick, keepAliveTickChannel := c.s.clock.NewTicker(keepAlive + jitter) defer keepAliveTick.Stop() diff --git a/ipn/ipnlocal/cert.go b/ipn/ipnlocal/cert.go index 3940d2bbf..11ea05df3 100644 --- a/ipn/ipnlocal/cert.go +++ b/ipn/ipnlocal/cert.go @@ -22,7 +22,7 @@ import ( "fmt" "io" "log" - insecurerand "math/rand" + randv2 "math/rand/v2" "net" "os" "path/filepath" @@ -212,7 +212,7 @@ func (b *LocalBackend) domainRenewalTimeByARI(cs certStore, pair *TLSCertKeyPair // passed. Time is randomized per recommendation in // https://datatracker.ietf.org/doc/draft-ietf-acme-ari/ start, end := ri.SuggestedWindow.Start, ri.SuggestedWindow.End - renewTime := start.Add(time.Duration(insecurerand.Int63n(int64(end.Sub(start))))) + renewTime := start.Add(randv2.N(end.Sub(start))) return renewTime, nil } diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 3d79618c0..8f13f79d0 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -15,7 +15,7 @@ import ( "log" "maps" "math" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -6650,12 +6650,12 @@ func pickWeighted(candidates []tailcfg.NodeView) []tailcfg.NodeView { // randomRegion is a selectRegionFunc that selects a uniformly random region. func randomRegion(regions views.Slice[int]) int { - return regions.At(rand.Intn(regions.Len())) + return regions.At(rand.IntN(regions.Len())) } // randomNode is a selectNodeFunc that returns a uniformly random node. func randomNode(nodes views.Slice[tailcfg.NodeView]) tailcfg.NodeView { - return nodes.At(rand.Intn(nodes.Len())) + return nodes.At(rand.IntN(nodes.Len())) } // minLatencyDERPRegion returns the region with the lowest latency value given the last netcheck report. diff --git a/ipn/ipnlocal/profiles.go b/ipn/ipnlocal/profiles.go index b01ff836d..b3c688160 100644 --- a/ipn/ipnlocal/profiles.go +++ b/ipn/ipnlocal/profiles.go @@ -5,10 +5,10 @@ package ipnlocal import ( "cmp" + "crypto/rand" "encoding/json" "errors" "fmt" - "math/rand" "runtime" "slices" "strings" diff --git a/logtail/backoff/backoff.go b/logtail/backoff/backoff.go index f135da52a..c6aeae998 100644 --- a/logtail/backoff/backoff.go +++ b/logtail/backoff/backoff.go @@ -6,7 +6,7 @@ package backoff import ( "context" - "math/rand" + "math/rand/v2" "time" "tailscale.com/tstime" diff --git a/logtail/logtail.go b/logtail/logtail.go index 14cded52a..9eaa32a94 100644 --- a/logtail/logtail.go +++ b/logtail/logtail.go @@ -12,7 +12,7 @@ import ( "fmt" "io" "log" - mrand "math/rand" + mrand "math/rand/v2" "net/http" "net/netip" "os" @@ -435,7 +435,7 @@ func (l *Logger) uploading(ctx context.Context) { // Sleep for the specified retryAfter period, // otherwise default to some random value. if retryAfter <= 0 { - retryAfter = time.Duration(30+mrand.Intn(30)) * time.Second + retryAfter = mrand.N(30*time.Second) + 30*time.Second } tstime.Sleep(ctx, retryAfter) } else { diff --git a/net/netcheck/netcheck.go b/net/netcheck/netcheck.go index 40f6adcbe..32b73512b 100644 --- a/net/netcheck/netcheck.go +++ b/net/netcheck/netcheck.go @@ -14,7 +14,7 @@ import ( "io" "log" "maps" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -1010,7 +1010,7 @@ func (c *Client) checkCaptivePortal(ctx context.Context, dm *tailcfg.DERPMap, pr if len(rids) == 0 { return false, nil } - preferredDERP = rids[rand.Intn(len(rids))] + preferredDERP = rids[rand.IntN(len(rids))] } node := dm.Regions[preferredDERP].Nodes[0] diff --git a/net/portmapper/upnp.go b/net/portmapper/upnp.go index acdb64f3b..54b0f81b2 100644 --- a/net/portmapper/upnp.go +++ b/net/portmapper/upnp.go @@ -15,7 +15,7 @@ import ( "encoding/xml" "fmt" "io" - "math/rand" + "math/rand/v2" "net" "net/http" "net/netip" @@ -165,7 +165,7 @@ func addAnyPortMapping( // number in [0, 65535 - 1024] and then adding 1024 to it, shifting the // range to [1024, 65535]. if externalPort < 1024 { - externalPort = uint16(rand.Intn(65535-1024) + 1024) + externalPort = uint16(rand.N(65535-1024) + 1024) } // First off, try using AddAnyPortMapping; if there's a conflict, the diff --git a/tstest/integration/testcontrol/testcontrol.go b/tstest/integration/testcontrol/testcontrol.go index 6903465cf..44ed2da06 100644 --- a/tstest/integration/testcontrol/testcontrol.go +++ b/tstest/integration/testcontrol/testcontrol.go @@ -14,7 +14,7 @@ import ( "io" "log" "maps" - "math/rand" + "math/rand/v2" "net/http" "net/http/httptest" "net/netip" @@ -774,7 +774,7 @@ func (s *Server) serveMap(w http.ResponseWriter, r *http.Request, mkey key.Machi go panic(fmt.Sprintf("bad map request: %v", err)) } - jitter := time.Duration(rand.Intn(8000)) * time.Millisecond + jitter := rand.N(8 * time.Second) keepAlive := 50*time.Second + jitter node := s.Node(req.NodeKey) diff --git a/tstest/jsdeps/jsdeps.go b/tstest/jsdeps/jsdeps.go index 659a7459c..1d188152f 100644 --- a/tstest/jsdeps/jsdeps.go +++ b/tstest/jsdeps/jsdeps.go @@ -14,7 +14,7 @@ import ( _ "encoding/json" _ "fmt" _ "log" - _ "math/rand" + _ "math/rand/v2" _ "net" _ "strings" _ "time" diff --git a/tstest/natlab/natlab.go b/tstest/natlab/natlab.go index 172fe1b3b..92a4ccb68 100644 --- a/tstest/natlab/natlab.go +++ b/tstest/natlab/natlab.go @@ -14,7 +14,7 @@ import ( "encoding/base64" "errors" "fmt" - "math/rand" + "math/rand/v2" "net" "net/netip" "os" @@ -566,7 +566,7 @@ func (m *Machine) pickEphemPort() (port uint16, err error) { m.mu.Lock() defer m.mu.Unlock() for tries := 0; tries < 500; tries++ { - port := uint16(rand.Intn(32<<10) + 32<<10) + port := uint16(rand.IntN(32<<10) + 32<<10) if !m.portInUseLocked(port) { return port, nil } diff --git a/tstime/jitter.go b/tstime/jitter.go index 1d5e5c272..c5095c15d 100644 --- a/tstime/jitter.go +++ b/tstime/jitter.go @@ -4,33 +4,10 @@ package tstime import ( - crand "crypto/rand" - "encoding/binary" - "math/rand" - "sync" + "math/rand/v2" "time" ) -// crandSource is a rand.Source64 that gets its numbers from -// crypto/rand.Reader. -type crandSource struct{ sync.Mutex } - -var _ rand.Source64 = (*crandSource)(nil) - -func (s *crandSource) Int63() int64 { return int64(s.Uint64() >> 1) } - -func (s *crandSource) Uint64() uint64 { - s.Lock() - defer s.Unlock() - var buf [8]byte - crand.Read(buf[:]) - return binary.BigEndian.Uint64(buf[:]) -} - -func (*crandSource) Seed(seed int64) {} // nope - -var durRand = rand.New(new(crandSource)) - // RandomDurationBetween returns a random duration in range [min,max). // If panics if max < min. func RandomDurationBetween(min, max time.Duration) time.Duration { @@ -38,6 +15,5 @@ func RandomDurationBetween(min, max time.Duration) time.Duration { if diff == 0 { return min } - ns := durRand.Int63n(int64(diff)) - return min + time.Duration(ns) + return min + rand.N(max-min) } diff --git a/util/cloudenv/cloudenv.go b/util/cloudenv/cloudenv.go index 4a07bdeeb..be60ca007 100644 --- a/util/cloudenv/cloudenv.go +++ b/util/cloudenv/cloudenv.go @@ -8,7 +8,7 @@ import ( "context" "encoding/json" "log" - "math/rand" + "math/rand/v2" "net" "net/http" "os" @@ -74,8 +74,7 @@ func getDigitalOceanResolver() string { // Randomly select one of the available resolvers so we don't overload // one of them by sending all traffic there. return digitalOceanResolver.Get(func() string { - rn := rand.New(rand.NewSource(time.Now().UnixNano())) - return digitalOceanResolvers[rn.Intn(len(digitalOceanResolvers))] + return digitalOceanResolvers[rand.IntN(len(digitalOceanResolvers))] }) } diff --git a/util/reload/reload.go b/util/reload/reload.go index 84e7ba2bf..f18f9ebd1 100644 --- a/util/reload/reload.go +++ b/util/reload/reload.go @@ -9,7 +9,7 @@ import ( "context" "encoding/json" "fmt" - "math/rand" + "math/rand/v2" "os" "reflect" "time" @@ -73,7 +73,7 @@ func (r *ReloadOpts[T]) intervalWithJitter() time.Duration { return tt } - jitter := time.Duration(rand.Intn(int(r.IntervalJitter))) + jitter := rand.N(r.IntervalJitter) return tt + jitter } diff --git a/util/slicesx/slicesx.go b/util/slicesx/slicesx.go index 6896c1f3c..5f6eb8d91 100644 --- a/util/slicesx/slicesx.go +++ b/util/slicesx/slicesx.go @@ -4,7 +4,7 @@ // Package slicesx contains some helpful generic slice functions. package slicesx -import "math/rand" +import "math/rand/v2" // Interleave combines two slices of the form [a, b, c] and [x, y, z] into a // slice with elements interleaved; i.e. [a, x, b, y, c, z]. @@ -34,11 +34,11 @@ func Shuffle[S ~[]T, T any](s S) { n := len(s) i := n - 1 for ; i > 1<<31-1-1; i-- { - j := int(rand.Int63n(int64(i + 1))) + j := int(rand.N(int64(i + 1))) s[i], s[j] = s[j], s[i] } for ; i > 0; i-- { - j := int(rand.Int31n(int32(i + 1))) + j := int(rand.N(int32(i + 1))) s[i], s[j] = s[j], s[i] } } diff --git a/wgengine/magicsock/derp.go b/wgengine/magicsock/derp.go index 063843545..a5f43cda0 100644 --- a/wgengine/magicsock/derp.go +++ b/wgengine/magicsock/derp.go @@ -136,6 +136,7 @@ func (c *Conn) pickDERPFallback() int { return pickDERPFallbackForTests() } + // TODO: use math/rand/v2 here. h := fnv.New64() fmt.Fprintf(h, "%p/%d", c, processStartUnixNano) // arbitrary return ids[rand.New(rand.NewSource(int64(h.Sum64()))).Intn(len(ids))] diff --git a/wgengine/magicsock/endpoint.go b/wgengine/magicsock/endpoint.go index 2f8f1630e..b4ea54a02 100644 --- a/wgengine/magicsock/endpoint.go +++ b/wgengine/magicsock/endpoint.go @@ -10,7 +10,7 @@ import ( "errors" "fmt" "math" - "math/rand" + "math/rand/v2" "net" "net/netip" "reflect" @@ -592,7 +592,7 @@ func (de *endpoint) addrForWireGuardSendLocked(now mono.Time) (udpAddr netip.Add // Randomly select an address to use until we retrieve latency information // and give it a short trustBestAddrUntil time so we avoid flapping between // addresses while waiting on latency information to be populated. - udpAddr = candidates[rand.Intn(len(candidates))] + udpAddr = candidates[rand.IntN(len(candidates))] } de.bestAddr.AddrPort = udpAddr