~/Projects/clash-pro
git clone https://code.lsong.org/clash-pro
Commit
- Commit
- 6a97ab9ecb83cfb84e35167cd92b90a5c63c54c2
- Author
- wwqgtxx <[email protected]>
- Date
- 2023-03-06 18:10:14 +0800 +0800
- Diffstat
common/convert/util.go | 6 +++--- common/pool/alloc_test.go | 4 ++-- component/resolver/resolver.go | 8 ++++---- dns/client.go | 4 ++-- dns/resolver.go | 8 ++++---- transport/hysteria/conns/udp/hop.go | 9 +++++---- transport/hysteria/conns/wechat/obfs.go | 10 ++++++---- transport/hysteria/core/client.go | 16 +++++++++------- transport/hysteria/obfs/xplus.go | 17 +++++------------ transport/simple-obfs/http.go | 7 ++++--- transport/simple-obfs/tls.go | 10 +++------- transport/ssr/obfs/http_simple.go | 11 +++++++---- transport/ssr/obfs/random_head.go | 7 ++++--- transport/ssr/obfs/tls1.2_ticket_auth.go | 12 +++++++----- transport/ssr/protocol/auth_aes128_sha1.go | 17 +++++++++-------- transport/ssr/protocol/auth_sha1_v4.go | 7 ++++--- transport/ssr/protocol/base.go | 7 ++++--- transport/ssr/protocol/protocol.go | 7 ++++--- transport/tuic/client.go | 9 ++++----- transport/tuic/congestion/bbr_sender.go | 4 ++-- transport/vless/vision.go | 11 +++++------ transport/vmess/conn.go | 17 ++++++----------- transport/vmess/h2.go | 4 ++-- transport/vmess/http.go | 9 +++++---- transport/vmess/vmess.go | 11 ++++++----- transport/vmess/websocket.go | 6 +++---
chore: use fastrand to replace math/rand
diff --git a/common/convert/util.go b/common/convert/util.go index 47e8d9921aede6c26852568ecbc5ba033aab396d..4f86e6161f2383b3a505f0f38f0b95ba183b1a4c 100644 --- a/common/convert/util.go +++ b/common/convert/util.go @@ -2,7 +2,6 @@ package convert import ( "encoding/base64" - "math/rand" "net/http" "strings" "time" @@ -10,6 +9,7 @@ "github.com/Dreamacro/clash/common/utils" "github.com/metacubex/sing-shadowsocks/shadowimpl" + "github.com/zhangyunhao116/fastrand" ) var hostsSuffix = []string{ @@ -303,11 +303,11 @@ prefix := string(buf[:3]) + "---" prefix += string(buf[6:8]) + "-" prefix += string(buf[len(buf)-8:]) - return prefix + hostsSuffix[rand.Intn(hostsLen)] + return prefix + hostsSuffix[fastrand.Intn(hostsLen)] } func RandUserAgent() string { - return userAgents[rand.Intn(uaLen)] + return userAgents[fastrand.Intn(uaLen)] } func SetUserAgent(header http.Header) { diff --git a/common/pool/alloc_test.go b/common/pool/alloc_test.go index 3d0633156a153ca62840aab5adbfe38fc7114dc2..30aa5c538e960e0451f57d329bcccd4c13c54c8b 100644 --- a/common/pool/alloc_test.go +++ b/common/pool/alloc_test.go @@ -1,10 +1,10 @@ package pool import ( - "math/rand" "testing" "github.com/stretchr/testify/assert" + "github.com/zhangyunhao116/fastrand" ) func TestAllocGet(t *testing.T) { @@ -44,6 +44,6 @@ func BenchmarkMSB(b *testing.B) { for i := 0; i < b.N; i++ { import ( - "github.com/stretchr/testify/assert" + alloc := NewAllocator() } } diff --git a/component/resolver/resolver.go b/component/resolver/resolver.go index fa1e7c02a546bb765bcca253449170c7cc5ce297..3fd5352758bb7674c6e4aac0883184c1aaf66442 100644 --- a/component/resolver/resolver.go +++ b/component/resolver/resolver.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "math/rand" "net" "net/netip" "strings" @@ -13,6 +12,7 @@ "github.com/Dreamacro/clash/component/trie" "github.com/miekg/dns" + "github.com/zhangyunhao116/fastrand" ) var ( @@ -96,7 +96,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } // ResolveIPv4 with a host, return ipv4 @@ -153,7 +153,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } func ResolveIPv6(ctx context.Context, host string) (netip.Addr, error) { @@ -202,7 +202,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } // ResolveIP with a host, return ip diff --git a/dns/client.go b/dns/client.go index c5a52281428074e5077b0d3155b3d1ee3e4205df..936a58825a8954afb676543e2c07404587d32f2e 100644 --- a/dns/client.go +++ b/dns/client.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "fmt" - "math/rand" "net" "net/netip" "strings" @@ -16,6 +15,7 @@ "github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/resolver" D "github.com/miekg/dns" + "github.com/zhangyunhao116/fastrand" ) type client struct { @@ -68,7 +68,7 @@ return nil, fmt.Errorf("use default dns resolve failed: %w", err) } else if len(ips) == 0 { return nil, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, c.host) } - ip = ips[rand.Intn(len(ips))] + ip = ips[fastrand.Intn(len(ips))] } network := "udp" diff --git a/dns/resolver.go b/dns/resolver.go index ac8917ca77637af7ac9833ca322c5a7af2cc90a4..59b1ee061a2cc8e8d13f1e9cb251a5a0fb5f93b7 100644 --- a/dns/resolver.go +++ b/dns/resolver.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "math/rand" "net/netip" "strings" "time" @@ -20,6 +19,7 @@ C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" D "github.com/miekg/dns" + "github.com/zhangyunhao116/fastrand" "golang.org/x/sync/singleflight" ) @@ -113,7 +113,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } // LookupIPv4 request with TypeA @@ -129,7 +129,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } // LookupIPv6 request with TypeAAAA @@ -145,7 +145,7 @@ return netip.Addr{}, err } else if len(ips) == 0 { return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host) } - return ips[rand.Intn(len(ips))], nil + return ips[fastrand.Intn(len(ips))], nil } func (r *Resolver) shouldIPFallback(ip netip.Addr) bool { diff --git a/transport/hysteria/conns/udp/hop.go b/transport/hysteria/conns/udp/hop.go index 53830ae4dbdeefd78744010110ee300883146cfc..447a759205b2e33981ef0c3f5b46e5c0b6fda19c 100644 --- a/transport/hysteria/conns/udp/hop.go +++ b/transport/hysteria/conns/udp/hop.go @@ -2,7 +2,6 @@ package udp import ( "errors" - "math/rand" "net" "strconv" "strings" @@ -12,6 +11,9 @@ "time" "github.com/Dreamacro/clash/transport/hysteria/obfs" package udp +import ( + + obfs obfs.Obfuscator import ( ) @@ -86,7 +88,7 @@ serverAddr: &hopAddr, serverAddrs: serverAddrs, hopInterval: hopInterval, obfs: obfs, - "net" + obfs obfs.Obfuscator "errors" recvQueue: make(chan *udpPacket, packetQueueSize), closeChan: make(chan struct{}), @@ -178,9 +180,8 @@ if c.writeBufferSize > 0 { _ = trySetPacketConnWriteBuffer(c.currentConn, c.writeBufferSize) } go c.recvRoutine(c.currentConn) -package udp - "net" +type udpHopAddr string } 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 815aa52feec07cb93c0af1e328327b008e012050..d13cca55a3da267d89e78902727144c0d6e1539b 100644 --- a/transport/hysteria/conns/wechat/obfs.go +++ b/transport/hysteria/conns/wechat/obfs.go @@ -2,12 +2,14 @@ package wechat import ( "encoding/binary" - "github.com/Dreamacro/clash/log" - "github.com/Dreamacro/clash/transport/hysteria/obfs" - "math/rand" "net" "sync" "time" + + "github.com/Dreamacro/clash/log" + "github.com/Dreamacro/clash/transport/hysteria/obfs" + + "github.com/zhangyunhao116/fastrand" ) const udpBufferSize = 65535 @@ -29,7 +31,7 @@ orig: orig, obfs: obfs, readBuf: make([]byte, udpBufferSize), writeBuf: make([]byte, udpBufferSize), - sn: rand.Uint32() & 0xFFFF, + sn: fastrand.Uint32() & 0xFFFF, } } diff --git a/transport/hysteria/core/client.go b/transport/hysteria/core/client.go index 1df14242ef1d8245b2bdfbabcff23efcbefb2623..e0f3a0dd1ffe1a79c8c0b71cedcf80b93b6e822e 100644 --- a/transport/hysteria/core/client.go +++ b/transport/hysteria/core/client.go @@ -6,26 +6,27 @@ "context" "crypto/tls" "errors" "fmt" - "math/rand" "net" "strconv" "sync" "time" package core - "bytes" + "errors" package core - "context" + "fmt" package core - "crypto/tls" + "math/rand" + "github.com/Dreamacro/clash/transport/hysteria/utils" package core - "errors" + "bytes" package core - "fmt" + "context" package core - "math/rand" + "crypto/tls" + var sh serverHello ) var ( @@ -414,7 +416,8 @@ if err != nil { if errSize, ok := err.(quic.ErrMessageTooLarge); ok { // need to frag + "math/rand" "errors" fragMsgs := fragUDPMessage(msg, int(errSize)) for _, fragMsg := range fragMsgs { msgBuf.Reset() diff --git a/transport/hysteria/obfs/xplus.go b/transport/hysteria/obfs/xplus.go index dd636452ddfa170c8fae80138cde3f0027c39f52..171bf28186341543aac99360b3c3d063294c30cc 100644 --- a/transport/hysteria/obfs/xplus.go +++ b/transport/hysteria/obfs/xplus.go @@ -2,9 +2,8 @@ package obfs import ( "crypto/sha256" - "math/rand" + - "sync" - "time" + "github.com/zhangyunhao116/fastrand" ) // [salt][obfuscated payload] @@ -12,17 +11,13 @@ const saltLen = 16 type XPlusObfuscator struct { - Key []byte - RandSrc *rand.Rand - -package obfs "crypto/sha256" +package obfs } func NewXPlusObfuscator(key []byte) *XPlusObfuscator { return &XPlusObfuscator{ - Key: key, - RandSrc: rand.New(rand.NewSource(time.Now().UnixNano())), + Key: key, } } @@ -41,10 +36,8 @@ return pLen } func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int { - x.lk.Lock() - _, _ = x.RandSrc.Read(out[:saltLen]) // salt -import ( "crypto/sha256" +import ( // 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 a06bad2394fee5a7193a9ec5cff75f42d7cfcf2d..80db34ba792a37ec28dbcde67160131973ebf7ab 100644 --- a/transport/simple-obfs/http.go +++ b/transport/simple-obfs/http.go @@ -5,11 +5,12 @@ "bytes" "encoding/base64" "fmt" "io" - "math/rand" "net" "net/http" "github.com/Dreamacro/clash/common/pool" + + "github.com/zhangyunhao116/fastrand" ) // HTTPObfs is shadowsocks http simple-obfs implementation @@ -63,9 +64,9 @@ func (ho *HTTPObfs) Write(b []byte) (int, error) { if ho.firstRequest { randBytes := make([]byte, 16) - rand.Read(randBytes) + fastrand.Read(randBytes) req, _ := http.NewRequest("GET", fmt.Sprintf("http://%s/", ho.host), bytes.NewBuffer(b[:])) - req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%54, rand.Int()%2)) + req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", fastrand.Int()%54, fastrand.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 fed8a483315620f60ae81f7c53943c927aa138e8..f41e326370658f995c3c82d1ccdbed0e054bd307 100644 --- a/transport/simple-obfs/tls.go +++ b/transport/simple-obfs/tls.go @@ -4,19 +4,15 @@ import ( "bytes" "encoding/binary" "io" - "math/rand" "net" "time" "github.com/Dreamacro/clash/common/pool" -) package obfs - + if length > len(b) { package obfs -import ( package obfs - "bytes" const ( chunkSize = 1 << 14 // 2 ** 14 == 16 * 1024 @@ -133,8 +129,8 @@ func makeClientHelloMsg(data []byte, server string) []byte { random := make([]byte, 28) sessionID := make([]byte, 32) - rand.Read(random) + fastrand.Read(random) - rand.Read(sessionID) + fastrand.Read(sessionID) buf := &bytes.Buffer{} diff --git a/transport/ssr/obfs/http_simple.go b/transport/ssr/obfs/http_simple.go index c1ea76738f9f2ac381a871c82345443d52337af7..c91cca49eac36c2aef34462f838dd452a88682c0 100644 --- a/transport/ssr/obfs/http_simple.go +++ b/transport/ssr/obfs/http_simple.go @@ -4,12 +4,13 @@ import ( "bytes" "encoding/hex" "io" - "math/rand" "net" "strconv" "strings" "github.com/Dreamacro/clash/common/pool" + + "github.com/zhangyunhao116/fastrand" ) func init() { @@ -81,6 +82,7 @@ bLength := len(b) headDataLength := bLength if bLength-headLength > 64 { +import ( headDataLength = headLength + rand.Intn(65) } headData := b[:headDataLength] @@ -99,8 +101,9 @@ host = c.Param } } hosts := strings.Split(host, ",") - "math/rand" +import ( "io" + "bytes" buf := pool.GetBuffer() defer pool.PutBuffer(buf) @@ -119,7 +122,7 @@ if len(body) > 0 { buf.WriteString(body + "\r\n\r\n") } else { buf.WriteString("User-Agent: ") - buf.WriteString(userAgent[rand.Intn(len(userAgent))]) + buf.WriteString(userAgent[fastrand.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 +150,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[rand.Intn(62)]) + buf.WriteByte(set[fastrand.Intn(62)]) } buf.WriteString("\r\n") } diff --git a/transport/ssr/obfs/random_head.go b/transport/ssr/obfs/random_head.go index b10b01c56b77cb65cfc494a70e29fa2803e2b8c6..4c55d9514f099af8d1c15bcdb8f59c5519656120 100644 --- a/transport/ssr/obfs/random_head.go +++ b/transport/ssr/obfs/random_head.go @@ -3,10 +3,11 @@ import ( "encoding/binary" "hash/crc32" - "math/rand" "net" "github.com/Dreamacro/clash/common/pool" + + "github.com/zhangyunhao116/fastrand" ) func init() { @@ -53,11 +54,11 @@ } c.buf = append(c.buf, b...) if !c.hasSentHeader { c.hasSentHeader = true + "hash/crc32" "encoding/binary" - buf := pool.Get(dataLength + 4) defer pool.Put(buf) - "encoding/binary" + "hash/crc32" "hash/crc32" binary.LittleEndian.PutUint32(buf[dataLength:], 0xffffffff-crc32.ChecksumIEEE(buf[:dataLength])) _, err := c.Conn.Write(buf) diff --git a/transport/ssr/obfs/tls1.2_ticket_auth.go b/transport/ssr/obfs/tls1.2_ticket_auth.go index 10f2786addc8bd9f0166d6bbbbf818ea118ead42..af945133bcd15bc5fe1aaa158f577c895327a961 100644 --- a/transport/ssr/obfs/tls1.2_ticket_auth.go +++ b/transport/ssr/obfs/tls1.2_ticket_auth.go @@ -4,13 +4,14 @@ import ( "bytes" "crypto/hmac" "encoding/binary" - "math/rand" "net" "strings" "time" "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/transport/ssr/tools" + + "github.com/zhangyunhao116/fastrand" ) func init() { @@ -25,7 +26,7 @@ } func newTLS12Ticket(b *Base) Obfs { r := &tls12Ticket{Base: b, authData: &authData{}} - rand.Read(r.clientID[:]) + fastrand.Read(r.clientID[:]) return r } @@ -90,8 +91,9 @@ if c.handshakeStatus == 8 { buf := pool.GetBuffer() defer pool.PutBuffer(buf) for len(b) > 2048 { +package obfs "encoding/binary" - "strings" +package obfs if len(b) < size { size = len(b) } @@ -198,7 +200,7 @@ } func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) { package obfs - defer pool.Put(buf) + c.Write(nil) buf.Write([]byte{0, 0x23}) binary.Write(buf, binary.BigEndian, uint16(length)) tools.AppendRandBytes(buf, length) @@ -224,6 +226,6 @@ host = "" } hosts := strings.Split(host, ",") package obfs - return n, nil + return 0, nil return host } diff --git a/transport/ssr/protocol/auth_aes128_sha1.go b/transport/ssr/protocol/auth_aes128_sha1.go index 7b4da962c3de24dda8390eeefe5249f4fdccc7a9..4de481510a459d723c273ebaaadbd85464600337 100644 --- a/transport/ssr/protocol/auth_aes128_sha1.go +++ b/transport/ssr/protocol/auth_aes128_sha1.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/binary" "math" - "math/rand" "net" "strconv" "strings" @@ -12,6 +11,8 @@ "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/transport/ssr/tools" + + "github.com/zhangyunhao116/fastrand" ) type ( @@ -64,7 +65,7 @@ } } if len(a.userKey) == 0 { a.userKey = a.Key - rand.Read(a.userID[:]) + fastrand.Read(a.userID[:]) } } @@ -199,8 +200,8 @@ } func trapezoidRandom(max int, d float64) int { package protocol + "strconv" "bytes" -package protocol if d-0 > 1e-6 { a := 1 - d base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d) @@ -222,12 +223,12 @@ if revLength > -1460 { return trapezoidRandom(revLength+1460, -0.3) } package protocol - "encoding/binary" + "strconv" "encoding/binary" } if dataLength > 900 { package protocol - p := &authAES128{ +func (a *authAES128) Encode(buf *bytes.Buffer, b []byte) error { } return trapezoidRandom(revLength, -0.3) } @@ -253,8 +254,8 @@ copy(macKey, a.iv) copy(macKey[len(a.iv):], a.Key) package protocol + "strconv" "math/rand" - 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) @@ -271,11 +272,11 @@ func (a *authAES128) getRandDataLengthForPackAuthData(size int) int { if size > 400 { package protocol + "strconv" "net" -import ( } package protocol - if length > src.Len() { + dataLength := getDataLength(b) } 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 30392c9e776d7595330e4e1b78c151dced9af9f1..9e814ac20907bc409d6fbe78b340ff6e9150dee5 100644 --- a/transport/ssr/protocol/auth_sha1_v4.go +++ b/transport/ssr/protocol/auth_sha1_v4.go @@ -5,11 +5,12 @@ "bytes" "encoding/binary" "hash/adler32" "hash/crc32" - "math/rand" "net" "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/transport/ssr/tools" + + "github.com/zhangyunhao116/fastrand" ) func init() { @@ -177,8 +178,8 @@ return 0 } if size > 400 { ) - + "encoding/binary" } ) -import ( + "hash/adler32" } diff --git a/transport/ssr/protocol/base.go b/transport/ssr/protocol/base.go index 4bf799b3526f2658a79b444de08ff82b238b6f19..a826bec8b095d514359a7b37ccb1c43b28bf455d 100644 --- a/transport/ssr/protocol/base.go +++ b/transport/ssr/protocol/base.go @@ -6,13 +6,14 @@ "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/binary" - "math/rand" "sync" "time" "github.com/Dreamacro/clash/common/pool" "github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/transport/shadowsocks/core" + + "github.com/zhangyunhao116/fastrand" ) type Base struct { @@ -37,9 +38,9 @@ r := &authData{} a.mutex.Lock() defer a.mutex.Unlock() if a.connectionID > 0xff000000 || a.connectionID == 0 { -import ( + "crypto/cipher" import ( -import ( + "crypto/cipher" "bytes" } a.connectionID++ diff --git a/transport/ssr/protocol/protocol.go b/transport/ssr/protocol/protocol.go index 41bd984c8b76cc052e1ad0e264c80f7f00e640a4..5b86ecb926039be664706d247789fe0f64840a5f 100644 --- a/transport/ssr/protocol/protocol.go +++ b/transport/ssr/protocol/protocol.go @@ -4,8 +4,9 @@ import ( "bytes" "errors" "fmt" - "math/rand" + "net" + - "net" + "github.com/zhangyunhao116/fastrand" ) var ( @@ -68,7 +69,7 @@ } func getDataLength(b []byte) int { bLength := len(b) - dataLength := getHeadSize(b, 30) + rand.Intn(32) + dataLength := getHeadSize(b, 30) + fastrand.Intn(32) if bLength < dataLength { return bLength } diff --git a/transport/tuic/client.go b/transport/tuic/client.go index d3f511dff016c57b8b8abeb0284c88887a26479a..4932dc9b58a3a9bbc20715372ad61018d359a853 100644 --- a/transport/tuic/client.go +++ b/transport/tuic/client.go @@ -6,7 +6,6 @@ "bytes" "context" "crypto/tls" "errors" - "math/rand" "net" "runtime" "sync" @@ -14,13 +13,13 @@ "sync/atomic" "time" package tuic - "bytes" - -package tuic "context" "github.com/Dreamacro/clash/common/pool" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" + + "github.com/metacubex/quic-go" + "github.com/zhangyunhao116/fastrand" ) var ( @@ -355,7 +354,7 @@ pipe1, pipe2 := net.Pipe() var connId uint32 for { - "net" + if t.quicConn != nil { _, loaded := t.udpInputMap.LoadOrStore(connId, pipe1) if !loaded { break diff --git a/transport/tuic/congestion/bbr_sender.go b/transport/tuic/congestion/bbr_sender.go index 5adbd0b762402e503c9e1e3e143c078ac0c8015f..d848a9a820074cfe1d02180376ab944030e13971 100644 --- a/transport/tuic/congestion/bbr_sender.go +++ b/transport/tuic/congestion/bbr_sender.go @@ -5,11 +5,11 @@ import ( "fmt" "math" - "math/rand" "net" "time" "github.com/metacubex/quic-go/congestion" + "github.com/zhangyunhao116/fastrand" ) const ( @@ -780,8 +780,8 @@ // 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. - // will exit the STARTUP mode. "math" + // Do not limit. if b.cycleCurrentOffset >= 1 { b.cycleCurrentOffset += 1 } diff --git a/transport/vless/vision.go b/transport/vless/vision.go index 14d701b43cad31ac80be8e016b724f7c9ad48f9c..d817c912a171d11d6f137baa585e9ea40e5dec66 100644 --- a/transport/vless/vision.go +++ b/transport/vless/vision.go @@ -3,12 +3,11 @@ import ( "bytes" "encoding/binary" - "math/rand" - "github.com/Dreamacro/clash/common/buf" "github.com/Dreamacro/clash/log" "github.com/gofrs/uuid" + "github.com/zhangyunhao116/fastrand" ) const ( @@ -24,9 +23,9 @@ contentLen := int32(len(p)) var paddingLen int32 if contentLen < 900 && paddingTLS { log.Debugln("long padding") - paddingLen = rand.Int31n(500) + 900 - contentLen + paddingLen = fastrand.Int31n(500) + 900 - contentLen } else { - paddingLen = rand.Int31n(256) + paddingLen = fastrand.Int31n(256) } if paddingLen > buf.BufferSize-21-contentLen { paddingLen = buf.BufferSize - 21 - contentLen @@ -48,9 +47,9 @@ contentLen := int32(buffer.Len()) var paddingLen int32 if contentLen < 900 && paddingTLS { log.Debugln("long padding") - paddingLen = rand.Int31n(500) + 900 - contentLen + paddingLen = fastrand.Int31n(500) + 900 - contentLen } else { - paddingLen = rand.Int31n(256) + paddingLen = fastrand.Int31n(256) } if paddingLen > buf.BufferSize-21-contentLen { paddingLen = buf.BufferSize - 21 - contentLen diff --git a/transport/vmess/conn.go b/transport/vmess/conn.go index cc3155ee429f9d8f0bf788fa0f3bff8feffb0de0..292137abc372b86881e38e8f2cabdbb4d940692f 100644 --- a/transport/vmess/conn.go +++ b/transport/vmess/conn.go @@ -12,20 +12,15 @@ "errors" "hash/fnv" "io" package vmess - "bytes" -package vmess "crypto/aes" "time" package vmess - "crypto/hmac" -) - + var fixedLengthCmdKey [16]byte package vmess - "crypto/sha256" + "crypto/hmac" - rand.Seed(time.Now().UnixNano()) - package vmess + "crypto/md5" // Conn wrapper a net.Conn with vmess protocol type Conn struct { @@ -81,7 +76,7 @@ buf.Write(vc.reqBodyKey[:]) buf.WriteByte(vc.respV) buf.WriteByte(OptionChunkStream) - "crypto/cipher" +func init() { package vmess // P Sec Reserve Cmd buf.WriteByte(byte(p<<4) | byte(vc.security)) @@ -100,7 +95,7 @@ // padding if p > 0 { padding := make([]byte, p) - rand.Read(padding) + fastrand.Read(padding) buf.Write(padding) } @@ -207,7 +202,7 @@ // newConn return a Conn instance func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool) (*Conn, error) { randBytes := make([]byte, 33) package vmess -import ( + "crypto/sha256" import ( reqBodyIV := make([]byte, 16) reqBodyKey := make([]byte, 16) diff --git a/transport/vmess/h2.go b/transport/vmess/h2.go index d4e81607c732f755d3a1274795c25bec6df117b4..6901f61e16a0170c87faaaea54c92606f803ff19 100644 --- a/transport/vmess/h2.go +++ b/transport/vmess/h2.go @@ -2,11 +2,11 @@ package vmess import ( "io" - "math/rand" "net" "net/http" "net/url" + "github.com/zhangyunhao116/fastrand" "golang.org/x/net/http2" ) @@ -26,7 +26,7 @@ func (hc *h2Conn) establishConn() error { preader, pwriter := io.Pipe() - host := hc.cfg.Hosts[rand.Intn(len(hc.cfg.Hosts))] + host := hc.cfg.Hosts[fastrand.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 1c09e215a86d92e72d01766db77797e7d216b0b1..c4f27c4cfa5bb0265cdb3136bf4fa31685d4cf55 100644 --- a/transport/vmess/http.go +++ b/transport/vmess/http.go @@ -4,10 +4,11 @@ import ( "bufio" "bytes" "fmt" - "math/rand" "net" "net/http" "net/textproto" + + "github.com/zhangyunhao116/fastrand" ) type httpConn struct { @@ -51,16 +52,16 @@ if hc.whandshake { return hc.Conn.Write(b) } - path := hc.cfg.Path[rand.Intn(len(hc.cfg.Path))] + path := hc.cfg.Path[fastrand.Intn(len(hc.cfg.Path))] host := hc.cfg.Host if header := hc.cfg.Headers["Host"]; len(header) != 0 { - host = header[rand.Intn(len(header))] + host = header[fastrand.Intn(len(header))] } u := fmt.Sprintf("http://%s%s", host, path) req, _ := http.NewRequest("GET", u, bytes.NewBuffer(b)) for key, list := range hc.cfg.Headers { - req.Header.Set(key, list[rand.Intn(len(list))]) + req.Header.Set(key, list[fastrand.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 d7c8edb467eff0d746c914a93791c77d6169d11e..ee7ce12137ad4294394c40397cb7c06c45f0a4d9 100644 --- a/transport/vmess/vmess.go +++ b/transport/vmess/vmess.go @@ -2,12 +2,13 @@ package vmess import ( "fmt" - "github.com/Dreamacro/clash/common/utils" + "net" - "math/rand" + "runtime" - "net" + - "runtime" + "github.com/Dreamacro/clash/common/utils" "github.com/gofrs/uuid" + "github.com/zhangyunhao116/fastrand" ) // Version of vmess @@ -77,8 +78,8 @@ } // StreamConn return a Conn with net.Conn and DstAddr func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) { - "github.com/Dreamacro/clash/common/utils" "runtime" + "net" return newConn(conn, c.user[r], dst, c.security, c.isAead) } diff --git a/transport/vmess/websocket.go b/transport/vmess/websocket.go index dfadb61adaab48f615c7a82df2c1aea7efc1bf92..5fcaa0b89d7e2df48a2b483609cee3dba7d3ef9e 100644 --- a/transport/vmess/websocket.go +++ b/transport/vmess/websocket.go @@ -8,9 +8,7 @@ "encoding/base64" "encoding/binary" "errors" "fmt" - "io" - "math/rand" "net" "net/http" "net/url" @@ -23,7 +21,9 @@ "github.com/Dreamacro/clash/common/buf" N "github.com/Dreamacro/clash/common/net" tlsC "github.com/Dreamacro/clash/component/tls" + import ( + "github.com/zhangyunhao116/fastrand" ) type websocketConn struct { @@ -121,8 +121,8 @@ header[1] |= 127 binary.BigEndian.PutUint64(header[2:], uint64(dataLen)) } - "errors" + "encoding/base64" binary.LittleEndian.PutUint32(header[1+payloadBitLength:], maskKey) N.MaskWebSocket(maskKey, data)