Browse Source

wgengine/magicsock: use math/rands/v2

Updates #11058

Co-authored-by: James Tucker <[email protected]>
Signed-off-by: Maisem Ali <[email protected]>
Maisem Ali 1 year ago
parent
commit
36e8e8cd64
3 changed files with 11 additions and 8 deletions
  1. 0 1
      cmd/tailscaled/depaware.txt
  2. 8 0
      util/rands/cheap.go
  3. 3 7
      wgengine/magicsock/derp.go

+ 0 - 1
cmd/tailscaled/depaware.txt

@@ -514,7 +514,6 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         hash                                                         from compress/zlib+
         hash/adler32                                                 from compress/zlib+
         hash/crc32                                                   from compress/gzip+
-        hash/fnv                                                     from tailscale.com/wgengine/magicsock
         hash/maphash                                                 from go4.org/mem
         html                                                         from html/template+
         html/template                                                from github.com/gorilla/csrf

+ 8 - 0
util/rands/cheap.go

@@ -23,6 +23,14 @@ func Shuffle[T any](seed uint64, data []T) {
 	}
 }
 
+// IntN is like rand.IntN, but it is seeded on the stack and does not allocate
+// or lock any RNG state.
+func IntN(seed uint64, n int) int {
+	var pcg randv2.PCG
+	pcg.Seed(seed, seed)
+	return int(uint64n(&pcg, uint64(n)))
+}
+
 // Perm is like rand.Perm, but it is seeded on the stack and does not allocate
 // or lock any RNG state.
 func Perm(seed uint64, n int) []int {

+ 3 - 7
wgengine/magicsock/derp.go

@@ -7,8 +7,6 @@ import (
 	"bufio"
 	"context"
 	"fmt"
-	"hash/fnv"
-	"math/rand"
 	"net"
 	"net/netip"
 	"reflect"
@@ -16,6 +14,7 @@ import (
 	"sort"
 	"sync"
 	"time"
+	"unsafe"
 
 	"github.com/tailscale/wireguard-go/conn"
 	"tailscale.com/derp"
@@ -31,6 +30,7 @@ import (
 	"tailscale.com/types/key"
 	"tailscale.com/types/logger"
 	"tailscale.com/util/mak"
+	"tailscale.com/util/rands"
 	"tailscale.com/util/sysresources"
 	"tailscale.com/util/testenv"
 )
@@ -94,7 +94,6 @@ type activeDerp struct {
 }
 
 var (
-	processStartUnixNano     = time.Now().UnixNano()
 	pickDERPFallbackForTests func() int
 )
 
@@ -136,10 +135,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))]
+	return ids[rands.IntN(uint64(uintptr(unsafe.Pointer(c))), len(ids))]
 }
 
 // This allows existing tests to pass, but allows us to still test the