diff --git a/adapter/outbound/hysteria2.go b/adapter/outbound/hysteria2.go index 0ad7c2147a..b8abf39cc2 100644 --- a/adapter/outbound/hysteria2.go +++ b/adapter/outbound/hysteria2.go @@ -21,8 +21,8 @@ import ( "github.com/metacubex/sing-quic/hysteria2" + "github.com/metacubex/randv2" M "github.com/sagernet/sing/common/metadata" - "github.com/zhangyunhao116/fastrand" ) func init() { @@ -165,7 +165,7 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) { }) if len(serverAddress) > 0 { clientOptions.ServerAddress = func(ctx context.Context) (*net.UDPAddr, error) { - return resolveUDPAddrWithPrefer(ctx, "udp", serverAddress[fastrand.Intn(len(serverAddress))], C.NewDNSPrefer(option.IPVersion)) + return resolveUDPAddrWithPrefer(ctx, "udp", serverAddress[randv2.IntN(len(serverAddress))], C.NewDNSPrefer(option.IPVersion)) } if option.HopInterval == 0 { diff --git a/adapter/outbound/ssh.go b/adapter/outbound/ssh.go index a0efabca4e..8b2776a663 100644 --- a/adapter/outbound/ssh.go +++ b/adapter/outbound/ssh.go @@ -17,7 +17,7 @@ import ( "github.com/metacubex/mihomo/component/proxydialer" C "github.com/metacubex/mihomo/constant" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" "golang.org/x/crypto/ssh" ) @@ -180,10 +180,10 @@ func NewSsh(option SshOption) (*Ssh, error) { } version := "SSH-2.0-OpenSSH_" - if fastrand.Intn(2) == 0 { - version += "7." + strconv.Itoa(fastrand.Intn(10)) + if randv2.IntN(2) == 0 { + version += "7." + strconv.Itoa(randv2.IntN(10)) } else { - version += "8." + strconv.Itoa(fastrand.Intn(9)) + version += "8." + strconv.Itoa(randv2.IntN(9)) } config.ClientVersion = version diff --git a/common/convert/util.go b/common/convert/util.go index a715b556f5..ab00637493 100644 --- a/common/convert/util.go +++ b/common/convert/util.go @@ -8,8 +8,8 @@ import ( "github.com/metacubex/mihomo/common/utils" + "github.com/metacubex/randv2" "github.com/metacubex/sing-shadowsocks/shadowimpl" - "github.com/zhangyunhao116/fastrand" ) var hostsSuffix = []string{ @@ -302,11 +302,11 @@ func RandHost() string { prefix += string(buf[6:8]) + "-" prefix += string(buf[len(buf)-8:]) - return prefix + hostsSuffix[fastrand.Intn(hostsLen)] + return prefix + hostsSuffix[randv2.IntN(hostsLen)] } func RandUserAgent() string { - return userAgents[fastrand.Intn(uaLen)] + return userAgents[randv2.IntN(uaLen)] } func SetUserAgent(header http.Header) { diff --git a/common/pool/alloc_test.go b/common/pool/alloc_test.go index 0ac72ee05d..c76ff26a0c 100644 --- a/common/pool/alloc_test.go +++ b/common/pool/alloc_test.go @@ -3,8 +3,8 @@ package pool import ( "testing" + "github.com/metacubex/randv2" "github.com/stretchr/testify/assert" - "github.com/zhangyunhao116/fastrand" ) func TestAllocGet(t *testing.T) { @@ -43,6 +43,6 @@ func TestAllocPutThenGet(t *testing.T) { func BenchmarkMSB(b *testing.B) { for i := 0; i < b.N; i++ { - msb(fastrand.Int()) + msb(randv2.Int()) } } diff --git a/common/utils/uuid.go b/common/utils/uuid.go index f559b471fd..ec4082cc34 100644 --- a/common/utils/uuid.go +++ b/common/utils/uuid.go @@ -2,19 +2,13 @@ package utils import ( "github.com/gofrs/uuid/v5" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) -type fastRandReader struct{} - -func (r fastRandReader) Read(p []byte) (int, error) { - return fastrand.Read(p) -} - -var UnsafeUUIDGenerator = uuid.NewGenWithOptions(uuid.WithRandomReader(fastRandReader{})) +var UnsafeUUIDGenerator = uuid.NewGenWithOptions(uuid.WithRandomReader(randv2.Reader)) func NewUUIDV1() uuid.UUID { - u, _ := UnsafeUUIDGenerator.NewV1() // fastrand.Read wouldn't cause error, so ignore err is safe + u, _ := UnsafeUUIDGenerator.NewV1() // randv2.Read wouldn't cause error, so ignore err is safe return u } @@ -23,7 +17,7 @@ func NewUUIDV3(ns uuid.UUID, name string) uuid.UUID { } func NewUUIDV4() uuid.UUID { - u, _ := UnsafeUUIDGenerator.NewV4() // fastrand.Read wouldn't cause error, so ignore err is safe + u, _ := UnsafeUUIDGenerator.NewV4() // randv2.Read wouldn't cause error, so ignore err is safe return u } @@ -32,12 +26,12 @@ func NewUUIDV5(ns uuid.UUID, name string) uuid.UUID { } func NewUUIDV6() uuid.UUID { - u, _ := UnsafeUUIDGenerator.NewV6() // fastrand.Read wouldn't cause error, so ignore err is safe + u, _ := UnsafeUUIDGenerator.NewV6() // randv2.Read wouldn't cause error, so ignore err is safe return u } func NewUUIDV7() uuid.UUID { - u, _ := UnsafeUUIDGenerator.NewV7() // fastrand.Read wouldn't cause error, so ignore err is safe + u, _ := UnsafeUUIDGenerator.NewV7() // randv2.Read wouldn't cause error, so ignore err is safe return u } diff --git a/component/resolver/host.go b/component/resolver/host.go index 53fa5924b8..34da8e9f58 100644 --- a/component/resolver/host.go +++ b/component/resolver/host.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/resolver/hosts" "github.com/metacubex/mihomo/component/trie" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) var ( @@ -125,5 +125,5 @@ func (hv HostValue) RandIP() (netip.Addr, error) { if hv.IsDomain { return netip.Addr{}, errors.New("value type is error") } - return hv.IPs[fastrand.Intn(len(hv.IPs))], nil + return hv.IPs[randv2.IntN(len(hv.IPs))], nil } diff --git a/component/resolver/resolver.go b/component/resolver/resolver.go index f9b56e476b..07c68824c3 100644 --- a/component/resolver/resolver.go +++ b/component/resolver/resolver.go @@ -12,8 +12,8 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/trie" + "github.com/metacubex/randv2" "github.com/miekg/dns" - "github.com/zhangyunhao116/fastrand" ) var ( @@ -93,7 +93,7 @@ func ResolveIPv4WithResolver(ctx context.Context, host string, r Resolver) (neti } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host) } - return ips[fastrand.Intn(len(ips))], nil + return ips[randv2.IntN(len(ips))], nil } // ResolveIPv4 with a host, return ipv4 @@ -149,7 +149,7 @@ func ResolveIPv6WithResolver(ctx context.Context, host string, r Resolver) (neti } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host) } - return ips[fastrand.Intn(len(ips))], nil + return ips[randv2.IntN(len(ips))], nil } func ResolveIPv6(ctx context.Context, host string) (netip.Addr, error) { @@ -200,9 +200,9 @@ func ResolveIPWithResolver(ctx context.Context, host string, r Resolver) (netip. } ipv4s, ipv6s := SortationAddr(ips) if len(ipv4s) > 0 { - return ipv4s[fastrand.Intn(len(ipv4s))], nil + return ipv4s[randv2.IntN(len(ipv4s))], nil } - return ipv6s[fastrand.Intn(len(ipv6s))], nil + return ipv6s[randv2.IntN(len(ipv6s))], nil } // ResolveIP with a host, return ip and priority return TypeA diff --git a/component/tls/reality.go b/component/tls/reality.go index 48da3e92ac..ff028257f7 100644 --- a/component/tls/reality.go +++ b/component/tls/reality.go @@ -22,8 +22,8 @@ import ( "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/ntp" + "github.com/metacubex/randv2" utls "github.com/metacubex/utls" - "github.com/zhangyunhao116/fastrand" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/hkdf" "golang.org/x/net/http2" @@ -138,13 +138,13 @@ func realityClientFallback(uConn net.Conn, serverName string, fingerprint utls.C return } request.Header.Set("User-Agent", fingerprint.Client) - request.AddCookie(&http.Cookie{Name: "padding", Value: strings.Repeat("0", fastrand.Intn(32)+30)}) + request.AddCookie(&http.Cookie{Name: "padding", Value: strings.Repeat("0", randv2.IntN(32)+30)}) response, err := client.Do(request) if err != nil { return } //_, _ = io.Copy(io.Discard, response.Body) - time.Sleep(time.Duration(5+fastrand.Int63n(10)) * time.Second) + time.Sleep(time.Duration(5+randv2.IntN(10)) * time.Second) response.Body.Close() client.CloseIdleConnections() } diff --git a/dns/client.go b/dns/client.go index 3b4efed105..a6f0a7d492 100644 --- a/dns/client.go +++ b/dns/client.go @@ -14,8 +14,8 @@ import ( C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/log" + "github.com/metacubex/randv2" D "github.com/miekg/dns" - "github.com/zhangyunhao116/fastrand" ) type client struct { @@ -65,7 +65,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) } else if len(ips) == 0 { return nil, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, c.host) } - ip = ips[fastrand.Intn(len(ips))] + ip = ips[randv2.IntN(len(ips))] } network := "udp" diff --git a/go.mod b/go.mod index 08e5b5aa06..68f586363a 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/mdlayher/netlink v1.7.2 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 + github.com/metacubex/randv2 v0.1.2 github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 github.com/metacubex/sing-shadowsocks v0.2.6 github.com/metacubex/sing-shadowsocks2 v0.2.0 @@ -44,7 +45,6 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/wk8/go-ordered-map/v2 v2.1.8 - github.com/zhangyunhao116/fastrand v0.4.0 go.uber.org/automaxprocs v1.5.3 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba golang.org/x/crypto v0.23.0 diff --git a/go.sum b/go.sum index b9f1af1449..7252d8eec3 100644 --- a/go.sum +++ b/go.sum @@ -106,6 +106,8 @@ github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec h1:HxreOiFTUrJXJa github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec/go.mod h1:8BVmQ+3cxjqzWElafm24rb2Ae4jRI6vAXNXWqWjfrXw= github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22 h1:hsQ0b2A509b6ubnLtLOcUgZ8vOb+d/667zVEJ1T2fao= github.com/metacubex/quic-go v0.44.1-0.20240521004242-fcd70d587e22/go.mod h1:88wAATpevav4xdy5N8oejQ2cbbI6EcLYEklFeo+qywA= +github.com/metacubex/randv2 v0.1.2 h1:k3T2yI/hNymhBsYXWahMjKKaEfG+yI7mH3ymgjgeBr8= +github.com/metacubex/randv2 v0.1.2/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco= github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew= @@ -210,8 +212,6 @@ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zhangyunhao116/fastrand v0.4.0 h1:86QB6Y+GGgLZRFRDCjMmAS28QULwspK9sgL5d1Bx3H4= -github.com/zhangyunhao116/fastrand v0.4.0/go.mod h1:vIyo6EyBhjGKpZv6qVlkPl4JVAklpMM4DSKzbAkMguA= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= diff --git a/transport/hysteria/conns/udp/hop.go b/transport/hysteria/conns/udp/hop.go index eb0732f02b..0a88874921 100644 --- a/transport/hysteria/conns/udp/hop.go +++ b/transport/hysteria/conns/udp/hop.go @@ -12,7 +12,7 @@ import ( "github.com/metacubex/mihomo/transport/hysteria/obfs" "github.com/metacubex/mihomo/transport/hysteria/utils" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) const ( @@ -86,7 +86,7 @@ func NewObfsUDPHopClientPacketConn(server string, serverPorts string, hopInterva serverAddrs: serverAddrs, hopInterval: hopInterval, obfs: obfs, - addrIndex: fastrand.Intn(len(serverAddrs)), + addrIndex: randv2.IntN(len(serverAddrs)), recvQueue: make(chan *udpPacket, packetQueueSize), closeChan: make(chan struct{}), bufPool: sync.Pool{ @@ -177,7 +177,7 @@ func (c *ObfsUDPHopClientPacketConn) hop(dialer utils.PacketDialer, rAddr net.Ad _ = trySetPacketConnWriteBuffer(c.currentConn, c.writeBufferSize) } go c.recvRoutine(c.currentConn) - c.addrIndex = fastrand.Intn(len(c.serverAddrs)) + c.addrIndex = randv2.IntN(len(c.serverAddrs)) } func (c *ObfsUDPHopClientPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { diff --git a/transport/hysteria/conns/wechat/obfs.go b/transport/hysteria/conns/wechat/obfs.go index 4266d268ca..c5ec47ee91 100644 --- a/transport/hysteria/conns/wechat/obfs.go +++ b/transport/hysteria/conns/wechat/obfs.go @@ -9,7 +9,7 @@ import ( "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/transport/hysteria/obfs" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) const udpBufferSize = 65535 @@ -31,7 +31,7 @@ func NewObfsWeChatUDPConn(orig net.PacketConn, obfs obfs.Obfuscator) *ObfsWeChat obfs: obfs, readBuf: make([]byte, udpBufferSize), writeBuf: make([]byte, udpBufferSize), - sn: fastrand.Uint32() & 0xFFFF, + sn: randv2.Uint32() & 0xFFFF, } } diff --git a/transport/hysteria/core/client.go b/transport/hysteria/core/client.go index 97c9225e37..60db8fdf45 100644 --- a/transport/hysteria/core/client.go +++ b/transport/hysteria/core/client.go @@ -19,7 +19,7 @@ import ( "github.com/lunixbochs/struc" "github.com/metacubex/quic-go" "github.com/metacubex/quic-go/congestion" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) var ( @@ -405,7 +405,7 @@ func (c *quicPktConn) WriteTo(p []byte, addr string) error { var errSize *quic.DatagramTooLargeError if errors.As(err, &errSize) { // need to frag - msg.MsgID = uint16(fastrand.Intn(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1 + msg.MsgID = uint16(randv2.IntN(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1 fragMsgs := fragUDPMessage(msg, int(errSize.MaxDatagramPayloadSize)) for _, fragMsg := range fragMsgs { msgBuf.Reset() diff --git a/transport/hysteria/obfs/xplus.go b/transport/hysteria/obfs/xplus.go index 171bf28186..5ead76ff87 100644 --- a/transport/hysteria/obfs/xplus.go +++ b/transport/hysteria/obfs/xplus.go @@ -3,7 +3,7 @@ package obfs import ( "crypto/sha256" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) // [salt][obfuscated payload] @@ -35,7 +35,7 @@ func (x *XPlusObfuscator) Deobfuscate(in []byte, out []byte) int { } func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int { - _, _ = fastrand.Read(out[:saltLen]) // salt + _, _ = randv2.Read(out[:saltLen]) // salt // Obfuscate the payload key := sha256.Sum256(append(x.Key, out[:saltLen]...)) for i, c := range in { diff --git a/transport/simple-obfs/http.go b/transport/simple-obfs/http.go index a38b1d6971..df84ac09a3 100644 --- a/transport/simple-obfs/http.go +++ b/transport/simple-obfs/http.go @@ -10,7 +10,7 @@ import ( "github.com/metacubex/mihomo/common/pool" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) // HTTPObfs is shadowsocks http simple-obfs implementation @@ -64,12 +64,12 @@ func (ho *HTTPObfs) Read(b []byte) (int, error) { func (ho *HTTPObfs) Write(b []byte) (int, error) { if ho.firstRequest { randBytes := make([]byte, 16) - fastrand.Read(randBytes) + randv2.Read(randBytes) req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/", ho.host), bytes.NewBuffer(b[:])) if err != nil { return 0, err } - req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", fastrand.Int()%54, fastrand.Int()%2)) + req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", randv2.Int()%54, randv2.Int()%2)) req.Header.Set("Upgrade", "websocket") req.Header.Set("Connection", "Upgrade") req.Host = ho.host diff --git a/transport/simple-obfs/tls.go b/transport/simple-obfs/tls.go index 78317f0a37..af3d11b1e7 100644 --- a/transport/simple-obfs/tls.go +++ b/transport/simple-obfs/tls.go @@ -9,7 +9,7 @@ import ( "github.com/metacubex/mihomo/common/pool" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) const ( @@ -127,8 +127,8 @@ func NewTLSObfs(conn net.Conn, server string) net.Conn { func makeClientHelloMsg(data []byte, server string) []byte { random := make([]byte, 28) sessionID := make([]byte, 32) - fastrand.Read(random) - fastrand.Read(sessionID) + randv2.Read(random) + randv2.Read(sessionID) buf := &bytes.Buffer{} diff --git a/transport/ssr/obfs/http_simple.go b/transport/ssr/obfs/http_simple.go index 359ca34272..d59b490d46 100644 --- a/transport/ssr/obfs/http_simple.go +++ b/transport/ssr/obfs/http_simple.go @@ -10,7 +10,7 @@ import ( "github.com/metacubex/mihomo/common/pool" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) func init() { @@ -82,7 +82,7 @@ func (c *httpConn) Write(b []byte) (int, error) { bLength := len(b) headDataLength := bLength if bLength-headLength > 64 { - headDataLength = headLength + fastrand.Intn(65) + headDataLength = headLength + randv2.IntN(65) } headData := b[:headDataLength] b = b[headDataLength:] @@ -100,7 +100,7 @@ func (c *httpConn) Write(b []byte) (int, error) { } } hosts := strings.Split(host, ",") - host = hosts[fastrand.Intn(len(hosts))] + host = hosts[randv2.IntN(len(hosts))] buf := pool.GetBuffer() defer pool.PutBuffer(buf) @@ -119,7 +119,7 @@ func (c *httpConn) Write(b []byte) (int, error) { buf.WriteString(body + "\r\n\r\n") } else { buf.WriteString("User-Agent: ") - buf.WriteString(userAgent[fastrand.Intn(len(userAgent))]) + buf.WriteString(userAgent[randv2.IntN(len(userAgent))]) buf.WriteString("\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Encoding: gzip, deflate\r\n") if c.post { packBoundary(buf) @@ -147,7 +147,7 @@ func packBoundary(buf *bytes.Buffer) { buf.WriteString("Content-Type: multipart/form-data; boundary=") set := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" for i := 0; i < 32; i++ { - buf.WriteByte(set[fastrand.Intn(62)]) + buf.WriteByte(set[randv2.IntN(62)]) } buf.WriteString("\r\n") } diff --git a/transport/ssr/obfs/random_head.go b/transport/ssr/obfs/random_head.go index 9a2072fe44..94a3cf92fb 100644 --- a/transport/ssr/obfs/random_head.go +++ b/transport/ssr/obfs/random_head.go @@ -7,7 +7,7 @@ import ( "github.com/metacubex/mihomo/common/pool" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) func init() { @@ -54,10 +54,10 @@ func (c *randomHeadConn) Write(b []byte) (int, error) { c.buf = append(c.buf, b...) if !c.hasSentHeader { c.hasSentHeader = true - dataLength := fastrand.Intn(96) + 4 + dataLength := randv2.IntN(96) + 4 buf := pool.Get(dataLength + 4) defer pool.Put(buf) - fastrand.Read(buf[:dataLength]) + randv2.Read(buf[:dataLength]) binary.LittleEndian.PutUint32(buf[dataLength:], 0xffffffff-crc32.ChecksumIEEE(buf[:dataLength])) _, err := c.Conn.Write(buf) return len(b), err diff --git a/transport/ssr/obfs/tls1.2_ticket_auth.go b/transport/ssr/obfs/tls1.2_ticket_auth.go index d5e3ca8875..94c97c629f 100644 --- a/transport/ssr/obfs/tls1.2_ticket_auth.go +++ b/transport/ssr/obfs/tls1.2_ticket_auth.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/pool" "github.com/metacubex/mihomo/transport/ssr/tools" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) func init() { @@ -26,7 +26,7 @@ type tls12Ticket struct { func newTLS12Ticket(b *Base) Obfs { r := &tls12Ticket{Base: b, authData: &authData{}} - fastrand.Read(r.clientID[:]) + randv2.Read(r.clientID[:]) return r } @@ -91,7 +91,7 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) { buf := pool.GetBuffer() defer pool.PutBuffer(buf) for len(b) > 2048 { - size := fastrand.Intn(4096) + 100 + size := randv2.IntN(4096) + 100 if len(b) < size { size = len(b) } @@ -197,7 +197,7 @@ func packSNIData(buf *bytes.Buffer, u string) { } func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) { - length := 16 * (fastrand.Intn(17) + 8) + length := 16 * (randv2.IntN(17) + 8) buf.Write([]byte{0, 0x23}) binary.Write(buf, binary.BigEndian, uint16(length)) tools.AppendRandBytes(buf, length) @@ -222,6 +222,6 @@ func (t *tls12Ticket) getHost() string { host = "" } hosts := strings.Split(host, ",") - host = hosts[fastrand.Intn(len(hosts))] + host = hosts[randv2.IntN(len(hosts))] return host } diff --git a/transport/ssr/protocol/auth_aes128_sha1.go b/transport/ssr/protocol/auth_aes128_sha1.go index 6ee4160e33..7219f1ffe3 100644 --- a/transport/ssr/protocol/auth_aes128_sha1.go +++ b/transport/ssr/protocol/auth_aes128_sha1.go @@ -13,7 +13,7 @@ import ( "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/transport/ssr/tools" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) type ( @@ -66,7 +66,7 @@ func (a *authAES128) initUserData() { } if len(a.userKey) == 0 { a.userKey = a.Key - fastrand.Read(a.userID[:]) + randv2.Read(a.userID[:]) } } @@ -200,7 +200,7 @@ func (a *authAES128) packData(poolBuf *bytes.Buffer, data []byte, fullDataLength } func trapezoidRandom(max int, d float64) int { - base := fastrand.Float64() + base := randv2.Float64() if d-0 > 1e-6 { a := 1 - d base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d) @@ -221,10 +221,10 @@ func (a *authAES128) getRandDataLengthForPackData(dataLength, fullDataLength int if revLength > -1460 { return trapezoidRandom(revLength+1460, -0.3) } - return fastrand.Intn(32) + return randv2.IntN(32) } if dataLength > 900 { - return fastrand.Intn(revLength) + return randv2.IntN(revLength) } return trapezoidRandom(revLength, -0.3) } @@ -249,7 +249,7 @@ func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) { copy(macKey, a.iv) copy(macKey[len(a.iv):], a.Key) - poolBuf.WriteByte(byte(fastrand.Intn(256))) + poolBuf.WriteByte(byte(randv2.IntN(256))) poolBuf.Write(a.hmac(macKey, poolBuf.Bytes())[:6]) poolBuf.Write(a.userID[:]) err := a.authData.putEncryptedData(poolBuf, a.userKey, [2]int{packedAuthDataLength, randDataLength}, a.salt) @@ -265,9 +265,9 @@ func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) { func (a *authAES128) getRandDataLengthForPackAuthData(size int) int { if size > 400 { - return fastrand.Intn(512) + return randv2.IntN(512) } - return fastrand.Intn(1024) + return randv2.IntN(1024) } func (a *authAES128) packRandData(poolBuf *bytes.Buffer, size int) { diff --git a/transport/ssr/protocol/auth_sha1_v4.go b/transport/ssr/protocol/auth_sha1_v4.go index ed1a39f189..1c616c3fc2 100644 --- a/transport/ssr/protocol/auth_sha1_v4.go +++ b/transport/ssr/protocol/auth_sha1_v4.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/pool" "github.com/metacubex/mihomo/transport/ssr/tools" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) func init() { @@ -178,7 +178,7 @@ func (a *authSHA1V4) getRandDataLength(size int) int { return 0 } if size > 400 { - return fastrand.Intn(256) + return randv2.IntN(256) } - return fastrand.Intn(512) + return randv2.IntN(512) } diff --git a/transport/ssr/protocol/base.go b/transport/ssr/protocol/base.go index e26a65875a..5ccc4034c0 100644 --- a/transport/ssr/protocol/base.go +++ b/transport/ssr/protocol/base.go @@ -13,7 +13,7 @@ import ( "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/transport/shadowsocks/core" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) type Base struct { @@ -38,8 +38,8 @@ func (a *authData) next() *authData { a.mutex.Lock() defer a.mutex.Unlock() if a.connectionID > 0xff000000 || a.connectionID == 0 { - fastrand.Read(a.clientID[:]) - a.connectionID = fastrand.Uint32() & 0xffffff + randv2.Read(a.clientID[:]) + a.connectionID = randv2.Uint32() & 0xffffff } a.connectionID++ copy(r.clientID[:], a.clientID[:]) diff --git a/transport/ssr/protocol/protocol.go b/transport/ssr/protocol/protocol.go index a04e6bd4d3..ad6bf6ba77 100644 --- a/transport/ssr/protocol/protocol.go +++ b/transport/ssr/protocol/protocol.go @@ -8,7 +8,7 @@ import ( N "github.com/metacubex/mihomo/common/net" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) var ( @@ -71,7 +71,7 @@ func getHeadSize(b []byte, defaultValue int) int { func getDataLength(b []byte) int { bLength := len(b) - dataLength := getHeadSize(b, 30) + fastrand.Intn(32) + dataLength := getHeadSize(b, 30) + randv2.IntN(32) if bLength < dataLength { return bLength } diff --git a/transport/tuic/congestion/bbr_sender.go b/transport/tuic/congestion/bbr_sender.go index 6cea9355fb..5a8633621f 100644 --- a/transport/tuic/congestion/bbr_sender.go +++ b/transport/tuic/congestion/bbr_sender.go @@ -9,7 +9,7 @@ import ( "github.com/metacubex/quic-go" "github.com/metacubex/quic-go/congestion" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) const ( @@ -716,7 +716,7 @@ func (b *bbrSender) EnterProbeBandwidthMode(now time.Time) { // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is // excluded because in that case increased gain and decreased gain would not // follow each other. - b.cycleCurrentOffset = fastrand.Int() % (GainCycleLength - 1) + b.cycleCurrentOffset = randv2.Int() % (GainCycleLength - 1) if b.cycleCurrentOffset >= 1 { b.cycleCurrentOffset += 1 } diff --git a/transport/tuic/congestion_v2/bbr_sender.go b/transport/tuic/congestion_v2/bbr_sender.go index 54705978cc..ed29bd7e95 100644 --- a/transport/tuic/congestion_v2/bbr_sender.go +++ b/transport/tuic/congestion_v2/bbr_sender.go @@ -9,7 +9,7 @@ import ( "github.com/metacubex/quic-go" "github.com/metacubex/quic-go/congestion" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) // BbrSender implements BBR congestion control algorithm. BBR aims to estimate @@ -620,7 +620,7 @@ func (b *bbrSender) enterProbeBandwidthMode(now time.Time) { // Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is // excluded because in that case increased gain and decreased gain would not // follow each other. - b.cycleCurrentOffset = int(fastrand.Int31n(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) + b.cycleCurrentOffset = int(randv2.Int32N(congestion.PacketsPerConnectionID)) % (gainCycleLength - 1) if b.cycleCurrentOffset >= 1 { b.cycleCurrentOffset += 1 } diff --git a/transport/tuic/v4/client.go b/transport/tuic/v4/client.go index 5c9c889cff..62b419b7a5 100644 --- a/transport/tuic/v4/client.go +++ b/transport/tuic/v4/client.go @@ -20,8 +20,8 @@ import ( "github.com/metacubex/mihomo/transport/tuic/common" "github.com/metacubex/quic-go" + "github.com/metacubex/randv2" "github.com/puzpuzpuz/xsync/v3" - "github.com/zhangyunhao116/fastrand" ) type ClientOption struct { @@ -367,7 +367,7 @@ func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Met pipe1, pipe2 := N.Pipe() var connId uint32 for { - connId = fastrand.Uint32() + connId = randv2.Uint32() _, loaded := t.udpInputMap.LoadOrStore(connId, pipe1) if !loaded { break diff --git a/transport/tuic/v5/client.go b/transport/tuic/v5/client.go index 89454add19..a3c13d2b29 100644 --- a/transport/tuic/v5/client.go +++ b/transport/tuic/v5/client.go @@ -20,8 +20,8 @@ import ( "github.com/metacubex/mihomo/transport/tuic/common" "github.com/metacubex/quic-go" + "github.com/metacubex/randv2" "github.com/puzpuzpuz/xsync/v3" - "github.com/zhangyunhao116/fastrand" ) type ClientOption struct { @@ -351,7 +351,7 @@ func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Met pipe1, pipe2 := N.Pipe() var connId uint16 for { - connId = uint16(fastrand.Intn(0xFFFF)) + connId = uint16(randv2.IntN(0xFFFF)) _, loaded := t.udpInputMap.LoadOrStore(connId, pipe1) if !loaded { break diff --git a/transport/tuic/v5/packet.go b/transport/tuic/v5/packet.go index 5608db81f7..8281a11eff 100644 --- a/transport/tuic/v5/packet.go +++ b/transport/tuic/v5/packet.go @@ -12,7 +12,7 @@ import ( "github.com/metacubex/mihomo/transport/tuic/common" "github.com/metacubex/quic-go" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) type quicStreamPacketConn struct { @@ -157,7 +157,7 @@ func (q *quicStreamPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro if err != nil { return } - pktId := uint16(fastrand.Uint32()) + pktId := uint16(randv2.Uint32()) packet := NewPacket(q.connId, pktId, 1, 0, uint16(len(p)), address, p) switch q.udpRelayMode { case common.QUIC: diff --git a/transport/vless/vision/padding.go b/transport/vless/vision/padding.go index e5f9dc85e2..dd9cb261a3 100644 --- a/transport/vless/vision/padding.go +++ b/transport/vless/vision/padding.go @@ -8,7 +8,7 @@ import ( "github.com/metacubex/mihomo/log" "github.com/gofrs/uuid/v5" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) const ( @@ -25,9 +25,9 @@ func WriteWithPadding(buffer *buf.Buffer, p []byte, command byte, userUUID *uuid if contentLen < 900 { if paddingTLS { //log.Debugln("long padding") - paddingLen = fastrand.Int31n(500) + 900 - contentLen + paddingLen = randv2.Int32N(500) + 900 - contentLen } else { - paddingLen = fastrand.Int31n(256) + paddingLen = randv2.Int32N(256) } } if userUUID != nil { @@ -49,9 +49,9 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, padding if contentLen < 900 { if paddingTLS { //log.Debugln("long padding") - paddingLen = fastrand.Int31n(500) + 900 - contentLen + paddingLen = randv2.Int32N(500) + 900 - contentLen } else { - paddingLen = fastrand.Int31n(256) + paddingLen = randv2.Int32N(256) } } diff --git a/transport/vmess/conn.go b/transport/vmess/conn.go index 292137abc3..5dcc098562 100644 --- a/transport/vmess/conn.go +++ b/transport/vmess/conn.go @@ -14,7 +14,7 @@ import ( "net" "time" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" "golang.org/x/crypto/chacha20poly1305" ) @@ -72,7 +72,7 @@ func (vc *Conn) sendRequest() error { buf.WriteByte(vc.respV) buf.WriteByte(OptionChunkStream) - p := fastrand.Intn(16) + p := randv2.IntN(16) // P Sec Reserve Cmd buf.WriteByte(byte(p<<4) | byte(vc.security)) buf.WriteByte(0) @@ -90,7 +90,7 @@ func (vc *Conn) sendRequest() error { // padding if p > 0 { padding := make([]byte, p) - fastrand.Read(padding) + randv2.Read(padding) buf.Write(padding) } @@ -196,7 +196,7 @@ func hashTimestamp(t time.Time) []byte { // newConn return a Conn instance func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool) (*Conn, error) { randBytes := make([]byte, 33) - fastrand.Read(randBytes) + randv2.Read(randBytes) reqBodyIV := make([]byte, 16) reqBodyKey := make([]byte, 16) copy(reqBodyIV[:], randBytes[:16]) diff --git a/transport/vmess/h2.go b/transport/vmess/h2.go index f91c276626..a39ec5d992 100644 --- a/transport/vmess/h2.go +++ b/transport/vmess/h2.go @@ -7,7 +7,7 @@ import ( "net/http" "net/url" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" "golang.org/x/net/http2" ) @@ -27,7 +27,7 @@ type H2Config struct { func (hc *h2Conn) establishConn() error { preader, pwriter := io.Pipe() - host := hc.cfg.Hosts[fastrand.Intn(len(hc.cfg.Hosts))] + host := hc.cfg.Hosts[randv2.IntN(len(hc.cfg.Hosts))] path := hc.cfg.Path // TODO: connect use VMess Host instead of H2 Host req := http.Request{ diff --git a/transport/vmess/http.go b/transport/vmess/http.go index 4a1b93ecd8..3c66fe6b24 100644 --- a/transport/vmess/http.go +++ b/transport/vmess/http.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/utils" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) type httpConn struct { @@ -59,10 +59,10 @@ func (hc *httpConn) Write(b []byte) (int, error) { return -1, errors.New("path is empty") } - path := hc.cfg.Path[fastrand.Intn(len(hc.cfg.Path))] + path := hc.cfg.Path[randv2.IntN(len(hc.cfg.Path))] host := hc.cfg.Host if header := hc.cfg.Headers["Host"]; len(header) != 0 { - host = header[fastrand.Intn(len(header))] + host = header[randv2.IntN(len(header))] } u := fmt.Sprintf("http://%s%s", net.JoinHostPort(host, "80"), path) @@ -71,7 +71,7 @@ func (hc *httpConn) Write(b []byte) (int, error) { return 0, err } for key, list := range hc.cfg.Headers { - req.Header.Set(key, list[fastrand.Intn(len(list))]) + req.Header.Set(key, list[randv2.IntN(len(list))]) } req.ContentLength = int64(len(b)) if err := req.Write(hc.Conn); err != nil { diff --git a/transport/vmess/vmess.go b/transport/vmess/vmess.go index 7c587c6a0e..22c77ab7d5 100644 --- a/transport/vmess/vmess.go +++ b/transport/vmess/vmess.go @@ -8,7 +8,7 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/gofrs/uuid/v5" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) // Version of vmess @@ -78,7 +78,7 @@ type Config struct { // StreamConn return a Conn with net.Conn and DstAddr func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { - r := fastrand.Intn(len(c.user)) + r := randv2.IntN(len(c.user)) return newConn(conn, c.user[r], dst, c.security, c.isAead) } diff --git a/transport/vmess/websocket.go b/transport/vmess/websocket.go index f69141998a..913bfe51a0 100644 --- a/transport/vmess/websocket.go +++ b/transport/vmess/websocket.go @@ -25,7 +25,7 @@ import ( "github.com/gobwas/ws" "github.com/gobwas/ws/wsutil" - "github.com/zhangyunhao116/fastrand" + "github.com/metacubex/randv2" ) type websocketConn struct { @@ -150,7 +150,7 @@ func (wsc *websocketConn) WriteBuffer(buffer *buf.Buffer) error { } if wsc.state.ClientSide() { - maskKey := fastrand.Uint32() + maskKey := randv2.Uint32() binary.LittleEndian.PutUint32(header[1+payloadBitLength:], maskKey) N.MaskWebSocket(maskKey, data) } @@ -398,7 +398,7 @@ func streamWebsocketConn(ctx context.Context, conn net.Conn, c *WebsocketConfig, const nonceKeySize = 16 // NOTE: bts does not escape. bts := make([]byte, nonceKeySize) - if _, err = fastrand.Read(bts); err != nil { + if _, err = randv2.Read(bts); err != nil { return nil, fmt.Errorf("rand read error: %w", err) } secKey = base64.StdEncoding.EncodeToString(bts)