From c8c24a2e60d109d3985af73230607916e2c73a00 Mon Sep 17 00:00:00 2001 From: Fangliding Date: Thu, 5 Nov 2026 18:19:47 +0800 Subject: [PATCH] Remove dice package --- app/observatory/burst/healthping.go | 4 +- app/proxyman/outbound/handler.go | 4 +- app/reverse/config.go | 5 +- app/router/strategy_leastload.go | 4 +- app/router/strategy_random.go | 4 +- common/dice/dice.go | 55 ------------------- common/dice/dice_test.go | 50 ----------------- common/drain/drainer.go | 10 ++-- common/protocol/time.go | 5 +- proxy/blackhole/blackhole.go | 4 +- proxy/freedom/freedom.go | 6 +- proxy/shadowsocks/validator.go | 4 +- proxy/vmess/encoding/client.go | 4 +- proxy/vmess/validator.go | 4 +- proxy/wireguard/client.go | 4 +- transport/internet/dialer.go | 4 +- .../finalmask/mkcp/header/header_dns.go | 5 +- transport/internet/headers/http/config.go | 5 +- transport/internet/kcp/dialer.go | 4 +- transport/internet/xdrive/drive.go | 4 +- 20 files changed, 40 insertions(+), 149 deletions(-) delete mode 100644 common/dice/dice.go delete mode 100644 common/dice/dice_test.go diff --git a/app/observatory/burst/healthping.go b/app/observatory/burst/healthping.go index b5cc021fb..7f75b1c8d 100644 --- a/app/observatory/burst/healthping.go +++ b/app/observatory/burst/healthping.go @@ -3,12 +3,12 @@ package burst import ( "context" "fmt" + "math/rand/v2" "strings" "sync" "sync/atomic" "time" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/features/routing" ) @@ -181,7 +181,7 @@ func (h *HealthPing) doCheck(ctx context.Context, tags []string, duration time.D for i := 0; i < rounds; i++ { delay := time.Duration(0) if duration > 0 { - delay = time.Duration(dice.RollInt63n(int64(duration))) + delay = rand.N(duration) } timers = append(timers, time.AfterFunc(delay, func() { errors.LogDebug(h.ctx, "checking ", handler) diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index fe43c429f..f823ca105 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -7,7 +7,7 @@ import ( "io" "math/big" - "github.com/xtls/xray-core/common/dice" + mrand "math/rand/v2" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" @@ -196,7 +196,7 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) { } } else { unchangedDomain := ob.Target.Address.Domain() - ob.Target.Address = net.IPAddress(ips[dice.Roll(len(ips))]) + ob.Target.Address = net.IPAddress(ips[mrand.N(len(ips))]) errors.LogInfo(ctx, "target: ", unchangedDomain, " resolved to: ", ob.Target.Address.String()) } } diff --git a/app/reverse/config.go b/app/reverse/config.go index 8ce38c9c0..948b79b32 100644 --- a/app/reverse/config.go +++ b/app/reverse/config.go @@ -3,12 +3,11 @@ package reverse import ( "crypto/rand" "io" - - "github.com/xtls/xray-core/common/dice" + mrand "math/rand/v2" ) func (c *Control) FillInRandom() { - randomLength := dice.Roll(64) + randomLength := mrand.N(64) randomLength++ c.Random = make([]byte, randomLength) io.ReadFull(rand.Reader, c.Random) diff --git a/app/router/strategy_leastload.go b/app/router/strategy_leastload.go index 289982a84..db797b56b 100644 --- a/app/router/strategy_leastload.go +++ b/app/router/strategy_leastload.go @@ -3,13 +3,13 @@ package router import ( "context" "math" + "math/rand/v2" "slices" "sort" "time" "github.com/xtls/xray-core/app/observatory" "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/extension" @@ -74,7 +74,7 @@ func (s *LeastLoadStrategy) PickOutbound(candidates []string) string { // goes to fallbackTag return "" } - return selects[dice.Roll(count)].Tag + return selects[rand.N(count)].Tag } func (s *LeastLoadStrategy) pickOutbounds(candidates []string) []*node { diff --git a/app/router/strategy_random.go b/app/router/strategy_random.go index ea9b7add0..15b9f2b75 100644 --- a/app/router/strategy_random.go +++ b/app/router/strategy_random.go @@ -2,10 +2,10 @@ package router import ( "context" + "math/rand/v2" "github.com/xtls/xray-core/app/observatory" "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/extension" ) @@ -63,5 +63,5 @@ func (s *RandomStrategy) PickOutbound(candidates []string) string { // goes to fallbackTag return "" } - return candidates[dice.Roll(count)] + return candidates[rand.N(count)] } diff --git a/common/dice/dice.go b/common/dice/dice.go deleted file mode 100644 index 0a0a40e49..000000000 --- a/common/dice/dice.go +++ /dev/null @@ -1,55 +0,0 @@ -// Package dice contains common functions to generate random number. -// It also initialize math/rand with the time in seconds at launch time. -package dice // import "github.com/xtls/xray-core/common/dice" - -import ( - "math/rand" -) - -// Roll returns a non-negative number between 0 (inclusive) and n (exclusive). -func Roll(n int) int { - if n == 1 { - return 0 - } - return rand.Intn(n) -} - -// RollInt63n returns a non-negative number between 0 (inclusive) and n (exclusive). -func RollInt63n(n int64) int64 { - if n == 1 { - return 0 - } - return rand.Int63n(n) -} - -// Roll returns a non-negative number between 0 (inclusive) and n (exclusive). -func RollDeterministic(n int, seed int64) int { - if n == 1 { - return 0 - } - return rand.New(rand.NewSource(seed)).Intn(n) -} - -// RollUint16 returns a random uint16 value. -func RollUint16() uint16 { - return uint16(rand.Int63() >> 47) -} - -func RollUint64() uint64 { - return rand.Uint64() -} - -func NewDeterministicDice(seed int64) *DeterministicDice { - return &DeterministicDice{rand.New(rand.NewSource(seed))} -} - -type DeterministicDice struct { - *rand.Rand -} - -func (dd *DeterministicDice) Roll(n int) int { - if n == 1 { - return 0 - } - return dd.Intn(n) -} diff --git a/common/dice/dice_test.go b/common/dice/dice_test.go deleted file mode 100644 index 02eba57b6..000000000 --- a/common/dice/dice_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package dice_test - -import ( - "math/rand" - "testing" - - . "github.com/xtls/xray-core/common/dice" -) - -func BenchmarkRoll1(b *testing.B) { - for i := 0; i < b.N; i++ { - Roll(1) - } -} - -func BenchmarkRoll20(b *testing.B) { - for i := 0; i < b.N; i++ { - Roll(20) - } -} - -func BenchmarkIntn1(b *testing.B) { - for i := 0; i < b.N; i++ { - rand.Intn(1) - } -} - -func BenchmarkIntn20(b *testing.B) { - for i := 0; i < b.N; i++ { - rand.Intn(20) - } -} - -func BenchmarkInt63(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = uint16(rand.Int63() >> 47) - } -} - -func BenchmarkInt31(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = uint16(rand.Int31() >> 15) - } -} - -func BenchmarkIntn(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = uint16(rand.Intn(65536)) - } -} diff --git a/common/drain/drainer.go b/common/drain/drainer.go index 16ed1f23c..3ca873d6a 100644 --- a/common/drain/drainer.go +++ b/common/drain/drainer.go @@ -2,8 +2,8 @@ package drain import ( "io" + "math/rand/v2" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" ) @@ -12,10 +12,10 @@ type BehaviorSeedLimitedDrainer struct { } func NewBehaviorSeedLimitedDrainer(behaviorSeed int64, drainFoundation, maxBaseDrainSize, maxRandDrain int) (Drainer, error) { - behaviorRand := dice.NewDeterministicDice(behaviorSeed) - BaseDrainSize := behaviorRand.Roll(maxBaseDrainSize) - RandDrainMax := behaviorRand.Roll(maxRandDrain) + 1 - RandDrainRolled := dice.Roll(RandDrainMax) + behaviorRand := rand.New(rand.NewPCG(uint64(behaviorSeed), 0)) + BaseDrainSize := behaviorRand.N(maxBaseDrainSize) + RandDrainMax := behaviorRand.N(maxRandDrain) + 1 + RandDrainRolled := rand.N(RandDrainMax) DrainSize := drainFoundation + BaseDrainSize + RandDrainRolled return &BehaviorSeedLimitedDrainer{DrainSize: DrainSize}, nil } diff --git a/common/protocol/time.go b/common/protocol/time.go index 195496ed4..e6e5c9559 100644 --- a/common/protocol/time.go +++ b/common/protocol/time.go @@ -1,9 +1,8 @@ package protocol import ( + "math/rand/v2" "time" - - "github.com/xtls/xray-core/common/dice" ) type Timestamp int64 @@ -16,7 +15,7 @@ func NowTime() Timestamp { func NewTimestampGenerator(base Timestamp, delta int) TimestampGenerator { return func() Timestamp { - rangeInDelta := dice.Roll(delta*2) - delta + rangeInDelta := rand.N(delta*2) - delta return base + Timestamp(rangeInDelta) } } diff --git a/proxy/blackhole/blackhole.go b/proxy/blackhole/blackhole.go index ee0ee7b08..9335f52c7 100644 --- a/proxy/blackhole/blackhole.go +++ b/proxy/blackhole/blackhole.go @@ -4,12 +4,12 @@ package blackhole import ( "bytes" "context" + "math/rand/v2" "net/http" "time" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" @@ -74,7 +74,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte ctx, cancel := context.WithCancel(ctx) timer := signal.CancelAfterInactivity(ctx, func() { cancel() - }, time.Duration(30+dice.Roll(61))*time.Second) + }, time.Duration(30+rand.N(61))*time.Second) go buf.Copy(link.Reader, buf.Discard, buf.UpdateActivity(timer)) <-ctx.Done() } diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index 6215647a2..b1756d6ae 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -12,7 +12,6 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/crypto" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/geodata" "github.com/xtls/xray-core/common/log" @@ -30,6 +29,7 @@ import ( "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/stat" + mrand "math/rand/v2" ) var ( @@ -228,7 +228,7 @@ func (r *FinalRule) blockDuration() time.Duration { if max < min { span = min - max } - return time.Duration(min+uint64(dice.Roll(int(span+1)))) * time.Second + return time.Duration(min+mrand.N(span+1)) * time.Second } func (r *FinalRule) log(ctx context.Context, msg ...interface{}) { @@ -634,7 +634,7 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { continue } } else { - ip = net.IPAddress(ips[dice.Roll(len(ips))]) + ip = net.IPAddress(ips[mrand.N(len(ips))]) shouldUseSystemResolver = false } } diff --git a/proxy/shadowsocks/validator.go b/proxy/shadowsocks/validator.go index e8b33738f..05b504a35 100644 --- a/proxy/shadowsocks/validator.go +++ b/proxy/shadowsocks/validator.go @@ -5,10 +5,10 @@ import ( "crypto/hmac" "crypto/sha256" "hash/crc64" + "math/rand/v2" "strings" "sync" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/protocol" ) @@ -158,7 +158,7 @@ func (v *Validator) GetBehaviorSeed() uint64 { v.behaviorFused = true if v.behaviorSeed == 0 { - v.behaviorSeed = dice.RollUint64() + v.behaviorSeed = rand.Uint64() } return v.behaviorSeed } diff --git a/proxy/vmess/encoding/client.go b/proxy/vmess/encoding/client.go index 2890fc7b1..d2ef0975a 100644 --- a/proxy/vmess/encoding/client.go +++ b/proxy/vmess/encoding/client.go @@ -13,13 +13,13 @@ import ( "github.com/xtls/xray-core/common/bitmask" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/crypto" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/drain" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy/vmess" vmessaead "github.com/xtls/xray-core/proxy/vmess/aead" "golang.org/x/crypto/chacha20poly1305" + mrand "math/rand/v2" ) // ClientSession stores connection session info for VMess client. @@ -72,7 +72,7 @@ func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writ common.Must(buffer.WriteByte(c.responseHeader)) common.Must(buffer.WriteByte(byte(header.Option))) - paddingLen := dice.Roll(16) + paddingLen := mrand.N(16) security := byte(paddingLen<<4) | byte(header.Security) common.Must2(buffer.Write([]byte{security, byte(0), byte(header.Command)})) diff --git a/proxy/vmess/validator.go b/proxy/vmess/validator.go index bfffadcf7..afd53f6d4 100644 --- a/proxy/vmess/validator.go +++ b/proxy/vmess/validator.go @@ -4,10 +4,10 @@ import ( "crypto/hmac" "crypto/sha256" "hash/crc64" + "math/rand/v2" "strings" "sync" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy/vmess/aead" @@ -117,7 +117,7 @@ func (v *TimedUserValidator) GetBehaviorSeed() uint64 { v.behaviorFused = true if v.behaviorSeed == 0 { - v.behaviorSeed = dice.RollUint64() + v.behaviorSeed = rand.Uint64() } return v.behaviorSeed } diff --git a/proxy/wireguard/client.go b/proxy/wireguard/client.go index a207c71bc..d5b62451b 100644 --- a/proxy/wireguard/client.go +++ b/proxy/wireguard/client.go @@ -3,6 +3,7 @@ package wireguard import ( "context" "fmt" + "math/rand/v2" "net/netip" "reflect" "strings" @@ -14,7 +15,6 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/net" @@ -364,7 +364,7 @@ func MakeResolveLocal(d dns.Client, streamSettings *internet.MemoryStreamConfig) return nil, dns.ErrEmptyResponse } } - return got[dice.Roll(len(got))], nil + return got[rand.N(len(got))], nil } } diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 6d7b905db..13f71e8a9 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -3,10 +3,10 @@ package internet import ( "context" "fmt" + "math/rand/v2" "strings" "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net/cnc" @@ -260,7 +260,7 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig return nil, err } } else if sockopt.HappyEyeballs == nil || sockopt.HappyEyeballs.TryDelayMs == 0 || sockopt.HappyEyeballs.MaxConcurrentTry == 0 || len(ips) < 2 || len(sockopt.DialerProxy) > 0 || dest.Network != net.Network_TCP { - dest.Address = net.IPAddress(ips[dice.Roll(len(ips))]) + dest.Address = net.IPAddress(ips[rand.N(len(ips))]) errors.LogInfo(ctx, "replace destination with "+dest.String()) } else { return TcpRaceDial(ctx, src, ips, dest.Port, sockopt, dest.Address.String()) diff --git a/transport/internet/finalmask/mkcp/header/header_dns.go b/transport/internet/finalmask/mkcp/header/header_dns.go index bcbb0e004..a46718865 100644 --- a/transport/internet/finalmask/mkcp/header/header_dns.go +++ b/transport/internet/finalmask/mkcp/header/header_dns.go @@ -3,8 +3,7 @@ package header import ( "encoding/binary" "errors" - - "github.com/xtls/xray-core/common/dice" + "math/rand/v2" ) type dns struct { @@ -17,7 +16,7 @@ func (h *dns) Size() int { func (h *dns) Serialize(b []byte) { copy(b, h.header) - binary.BigEndian.PutUint16(b[0:], dice.RollUint16()) + binary.BigEndian.PutUint16(b[0:], uint16(rand.Uint32())) } func NewHeaderDNS(domain string) (*dns, error) { diff --git a/transport/internet/headers/http/config.go b/transport/internet/headers/http/config.go index baa69663b..c2045ba2a 100644 --- a/transport/internet/headers/http/config.go +++ b/transport/internet/headers/http/config.go @@ -1,9 +1,8 @@ package http import ( + "math/rand/v2" "strings" - - "github.com/xtls/xray-core/common/dice" ) func pickString(arr []string) string { @@ -14,7 +13,7 @@ func pickString(arr []string) string { case 1: return arr[0] default: - return arr[dice.Roll(n)] + return arr[rand.N(n)] } } diff --git a/transport/internet/kcp/dialer.go b/transport/internet/kcp/dialer.go index 443befc73..c68270606 100644 --- a/transport/internet/kcp/dialer.go +++ b/transport/internet/kcp/dialer.go @@ -3,11 +3,11 @@ package kcp import ( "context" "io" + "math/rand/v2" "sync/atomic" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/transport/internet" @@ -15,7 +15,7 @@ import ( "github.com/xtls/xray-core/transport/internet/tls" ) -var globalConv = uint32(dice.RollUint16()) +var globalConv = uint32(uint16(rand.Uint32())) func fetchInput(_ context.Context, input io.Reader, reader PacketReader, conn *Connection) { cache := make(chan *buf.Buffer, 1024) diff --git a/transport/internet/xdrive/drive.go b/transport/internet/xdrive/drive.go index 658b14a5a..707252328 100644 --- a/transport/internet/xdrive/drive.go +++ b/transport/internet/xdrive/drive.go @@ -7,13 +7,13 @@ import ( "encoding/json" "fmt" "io" + "math/rand/v2" "net/http" "net/url" "strings" "sync" "time" - "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/transport/internet" ) @@ -182,7 +182,7 @@ func jitter(backoff time.Duration) time.Duration { if half <= 0 { return backoff } - return half + time.Duration(dice.RollInt63n(int64(half))) + return half + rand.N(half) } func rateLimited(payload []byte) bool {