diff --git a/hscontrol/derp/derp.go b/hscontrol/derp/derp.go index 3d0b7d5b..c5701276 100644 --- a/hscontrol/derp/derp.go +++ b/hscontrol/derp/derp.go @@ -85,16 +85,12 @@ func mergeDERPMaps(derpMaps []*tailcfg.DERPMap) *tailcfg.DERPMap { for _, derpMap := range derpMaps { // Clone each region: copying the pointer would let a later in-place - // shuffle (shuffleRegionNoClone) alias regions shared with the source - // map or a previously served map, racing concurrent readers. + // shuffle alias regions shared with the source map or a previously + // served map, racing concurrent readers. for id, region := range derpMap.Regions { - result.Regions[id] = region.Clone() - } - } - - for id, region := range result.Regions { - if region == nil { - delete(result.Regions, id) + if cloned := region.Clone(); cloned != nil { + result.Regions[id] = cloned + } } } @@ -152,14 +148,13 @@ func shuffleDERPMap(dm *tailcfg.DERPMap) { continue } - dm.Regions[id] = shuffleRegionNoClone(region) + derpRandom().Shuffle(len(region.Nodes), reflect.Swapper(region.Nodes)) } } var crc64Table = crc64.MakeTable(crc64.ISO) var ( - derpRandomOnce sync.Once derpRandomInst *rand.Rand derpRandomMu sync.Mutex ) @@ -168,12 +163,10 @@ func derpRandom() *rand.Rand { derpRandomMu.Lock() defer derpRandomMu.Unlock() - derpRandomOnce.Do(func() { + if derpRandomInst == nil { seed := cmp.Or(viper.GetString("dns.base_domain"), time.Now().String()) - rnd := rand.New(rand.NewSource(0)) //nolint:gosec // weak random is fine for DERP scrambling - rnd.Seed(int64(crc64.Checksum([]byte(seed), crc64Table))) //nolint:gosec // safe conversion - derpRandomInst = rnd - }) + derpRandomInst = rand.New(rand.NewSource(int64(crc64.Checksum([]byte(seed), crc64Table)))) //nolint:gosec // weak random is fine for DERP scrambling + } return derpRandomInst } @@ -182,11 +175,5 @@ func resetDerpRandomForTesting() { derpRandomMu.Lock() defer derpRandomMu.Unlock() - derpRandomOnce = sync.Once{} derpRandomInst = nil } - -func shuffleRegionNoClone(r *tailcfg.DERPRegion) *tailcfg.DERPRegion { - derpRandom().Shuffle(len(r.Nodes), reflect.Swapper(r.Nodes)) - return r -} diff --git a/hscontrol/derp/server/derp_server.go b/hscontrol/derp/server/derp_server.go index fdca651a..0cb8339b 100644 --- a/hscontrol/derp/server/derp_server.go +++ b/hscontrol/derp/server/derp_server.go @@ -76,20 +76,15 @@ func (d *DERPServer) GenerateRegion() (tailcfg.DERPRegion, error) { return tailcfg.DERPRegion{}, err } - var ( - host string - port int - portStr string - ) - // Extract hostname and port from URL - host, portStr, err = net.SplitHostPort(serverURL.Host) + host, portStr, err := net.SplitHostPort(serverURL.Host) + + var port int if err != nil { + host = serverURL.Host if serverURL.Scheme == "https" { - host = serverURL.Host port = 443 } else { - host = serverURL.Host port = 80 } } else { @@ -371,15 +366,10 @@ func (d *DERPServer) ServeSTUN() { } func serverSTUNListener(ctx context.Context, packetConn *net.UDPConn) { - var ( - buf [64 << 10]byte - bytesRead int - udpAddr *net.UDPAddr - err error - ) + var buf [64 << 10]byte for { - bytesRead, udpAddr, err = packetConn.ReadFromUDP(buf[:]) + bytesRead, udpAddr, err := packetConn.ReadFromUDP(buf[:]) if err != nil { if ctx.Err() != nil { return