chore: use fastrand to replace math/rand
This commit is contained in:
parent
ad6336231c
commit
6a97ab9ecb
26 changed files with 109 additions and 111 deletions
|
@ -2,7 +2,6 @@ package convert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -10,6 +9,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/common/utils"
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
|
|
||||||
"github.com/metacubex/sing-shadowsocks/shadowimpl"
|
"github.com/metacubex/sing-shadowsocks/shadowimpl"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var hostsSuffix = []string{
|
var hostsSuffix = []string{
|
||||||
|
@ -303,11 +303,11 @@ func RandHost() string {
|
||||||
prefix += string(buf[6:8]) + "-"
|
prefix += string(buf[6:8]) + "-"
|
||||||
prefix += string(buf[len(buf)-8:])
|
prefix += string(buf[len(buf)-8:])
|
||||||
|
|
||||||
return prefix + hostsSuffix[rand.Intn(hostsLen)]
|
return prefix + hostsSuffix[fastrand.Intn(hostsLen)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandUserAgent() string {
|
func RandUserAgent() string {
|
||||||
return userAgents[rand.Intn(uaLen)]
|
return userAgents[fastrand.Intn(uaLen)]
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetUserAgent(header http.Header) {
|
func SetUserAgent(header http.Header) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package pool
|
package pool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAllocGet(t *testing.T) {
|
func TestAllocGet(t *testing.T) {
|
||||||
|
@ -43,6 +43,6 @@ func TestAllocPutThenGet(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkMSB(b *testing.B) {
|
func BenchmarkMSB(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
msb(rand.Int())
|
msb(fastrand.Int())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -13,6 +12,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/component/trie"
|
"github.com/Dreamacro/clash/component/trie"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -96,7 +96,7 @@ func ResolveIPv4WithResolver(ctx context.Context, host string, r Resolver) (neti
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
|
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
|
// ResolveIPv4 with a host, return ipv4
|
||||||
|
@ -153,7 +153,7 @@ func ResolveIPv6WithResolver(ctx context.Context, host string, r Resolver) (neti
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
|
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) {
|
func ResolveIPv6(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
|
@ -202,7 +202,7 @@ func ResolveIPWithResolver(ctx context.Context, host string, r Resolver) (netip.
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
|
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
|
// ResolveIP with a host, return ip
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -16,6 +15,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/component/resolver"
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
|
|
||||||
D "github.com/miekg/dns"
|
D "github.com/miekg/dns"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type client struct {
|
type client struct {
|
||||||
|
@ -68,7 +68,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error)
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return nil, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, c.host)
|
return nil, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, c.host)
|
||||||
}
|
}
|
||||||
ip = ips[rand.Intn(len(ips))]
|
ip = ips[fastrand.Intn(len(ips))]
|
||||||
}
|
}
|
||||||
|
|
||||||
network := "udp"
|
network := "udp"
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -20,6 +19,7 @@ import (
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
|
|
||||||
D "github.com/miekg/dns"
|
D "github.com/miekg/dns"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ func (r *Resolver) ResolveIP(ctx context.Context, host string) (ip netip.Addr, e
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host)
|
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
|
// LookupIPv4 request with TypeA
|
||||||
|
@ -129,7 +129,7 @@ func (r *Resolver) ResolveIPv4(ctx context.Context, host string) (ip netip.Addr,
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host)
|
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
|
// LookupIPv6 request with TypeAAAA
|
||||||
|
@ -145,7 +145,7 @@ func (r *Resolver) ResolveIPv6(ctx context.Context, host string) (ip netip.Addr,
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return netip.Addr{}, fmt.Errorf("%w: %s", resolver.ErrIPNotFound, host)
|
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 {
|
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package udp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,6 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/utils"
|
"github.com/Dreamacro/clash/transport/hysteria/utils"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -85,7 +86,7 @@ func NewObfsUDPHopClientPacketConn(server string, serverPorts string, hopInterva
|
||||||
serverAddrs: serverAddrs,
|
serverAddrs: serverAddrs,
|
||||||
hopInterval: hopInterval,
|
hopInterval: hopInterval,
|
||||||
obfs: obfs,
|
obfs: obfs,
|
||||||
addrIndex: rand.Intn(len(serverAddrs)),
|
addrIndex: fastrand.Intn(len(serverAddrs)),
|
||||||
recvQueue: make(chan *udpPacket, packetQueueSize),
|
recvQueue: make(chan *udpPacket, packetQueueSize),
|
||||||
closeChan: make(chan struct{}),
|
closeChan: make(chan struct{}),
|
||||||
bufPool: sync.Pool{
|
bufPool: sync.Pool{
|
||||||
|
@ -176,7 +177,7 @@ func (c *ObfsUDPHopClientPacketConn) hop(dialer utils.PacketDialer, rAddr net.Ad
|
||||||
_ = trySetPacketConnWriteBuffer(c.currentConn, c.writeBufferSize)
|
_ = trySetPacketConnWriteBuffer(c.currentConn, c.writeBufferSize)
|
||||||
}
|
}
|
||||||
go c.recvRoutine(c.currentConn)
|
go c.recvRoutine(c.currentConn)
|
||||||
c.addrIndex = rand.Intn(len(c.serverAddrs))
|
c.addrIndex = fastrand.Intn(len(c.serverAddrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ObfsUDPHopClientPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
func (c *ObfsUDPHopClientPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
|
|
|
@ -2,12 +2,14 @@ package wechat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"github.com/Dreamacro/clash/log"
|
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/log"
|
||||||
|
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
const udpBufferSize = 65535
|
const udpBufferSize = 65535
|
||||||
|
@ -29,7 +31,7 @@ func NewObfsWeChatUDPConn(orig net.PacketConn, obfs obfs.Obfuscator) *ObfsWeChat
|
||||||
obfs: obfs,
|
obfs: obfs,
|
||||||
readBuf: make([]byte, udpBufferSize),
|
readBuf: make([]byte, udpBufferSize),
|
||||||
writeBuf: make([]byte, udpBufferSize),
|
writeBuf: make([]byte, udpBufferSize),
|
||||||
sn: rand.Uint32() & 0xFFFF,
|
sn: fastrand.Uint32() & 0xFFFF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,20 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/lunixbochs/struc"
|
|
||||||
"github.com/metacubex/quic-go"
|
|
||||||
"github.com/metacubex/quic-go/congestion"
|
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
"github.com/Dreamacro/clash/transport/hysteria/obfs"
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/pmtud_fix"
|
"github.com/Dreamacro/clash/transport/hysteria/pmtud_fix"
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/transport"
|
"github.com/Dreamacro/clash/transport/hysteria/transport"
|
||||||
"github.com/Dreamacro/clash/transport/hysteria/utils"
|
"github.com/Dreamacro/clash/transport/hysteria/utils"
|
||||||
|
|
||||||
|
"github.com/lunixbochs/struc"
|
||||||
|
"github.com/metacubex/quic-go"
|
||||||
|
"github.com/metacubex/quic-go/congestion"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -408,7 +408,7 @@ func (c *quicPktConn) WriteTo(p []byte, addr string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errSize, ok := err.(quic.ErrMessageTooLarge); ok {
|
if errSize, ok := err.(quic.ErrMessageTooLarge); ok {
|
||||||
// need to frag
|
// need to frag
|
||||||
msg.MsgID = uint16(rand.Intn(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1
|
msg.MsgID = uint16(fastrand.Intn(0xFFFF)) + 1 // msgID must be > 0 when fragCount > 1
|
||||||
fragMsgs := fragUDPMessage(msg, int(errSize))
|
fragMsgs := fragUDPMessage(msg, int(errSize))
|
||||||
for _, fragMsg := range fragMsgs {
|
for _, fragMsg := range fragMsgs {
|
||||||
msgBuf.Reset()
|
msgBuf.Reset()
|
||||||
|
|
|
@ -2,9 +2,8 @@ package obfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"math/rand"
|
|
||||||
"sync"
|
"github.com/zhangyunhao116/fastrand"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// [salt][obfuscated payload]
|
// [salt][obfuscated payload]
|
||||||
|
@ -12,16 +11,12 @@ import (
|
||||||
const saltLen = 16
|
const saltLen = 16
|
||||||
|
|
||||||
type XPlusObfuscator struct {
|
type XPlusObfuscator struct {
|
||||||
Key []byte
|
Key []byte
|
||||||
RandSrc *rand.Rand
|
|
||||||
|
|
||||||
lk sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewXPlusObfuscator(key []byte) *XPlusObfuscator {
|
func NewXPlusObfuscator(key []byte) *XPlusObfuscator {
|
||||||
return &XPlusObfuscator{
|
return &XPlusObfuscator{
|
||||||
Key: key,
|
Key: key,
|
||||||
RandSrc: rand.New(rand.NewSource(time.Now().UnixNano())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +35,7 @@ func (x *XPlusObfuscator) Deobfuscate(in []byte, out []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int {
|
func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int {
|
||||||
x.lk.Lock()
|
_, _ = fastrand.Read(out[:saltLen]) // salt
|
||||||
_, _ = x.RandSrc.Read(out[:saltLen]) // salt
|
|
||||||
x.lk.Unlock()
|
|
||||||
// Obfuscate the payload
|
// Obfuscate the payload
|
||||||
key := sha256.Sum256(append(x.Key, out[:saltLen]...))
|
key := sha256.Sum256(append(x.Key, out[:saltLen]...))
|
||||||
for i, c := range in {
|
for i, c := range in {
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPObfs is shadowsocks http simple-obfs implementation
|
// HTTPObfs is shadowsocks http simple-obfs implementation
|
||||||
|
@ -63,9 +64,9 @@ func (ho *HTTPObfs) Read(b []byte) (int, error) {
|
||||||
func (ho *HTTPObfs) Write(b []byte) (int, error) {
|
func (ho *HTTPObfs) Write(b []byte) (int, error) {
|
||||||
if ho.firstRequest {
|
if ho.firstRequest {
|
||||||
randBytes := make([]byte, 16)
|
randBytes := make([]byte, 16)
|
||||||
rand.Read(randBytes)
|
fastrand.Read(randBytes)
|
||||||
req, _ := http.NewRequest("GET", fmt.Sprintf("http://%s/", ho.host), bytes.NewBuffer(b[:]))
|
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("Upgrade", "websocket")
|
||||||
req.Header.Set("Connection", "Upgrade")
|
req.Header.Set("Connection", "Upgrade")
|
||||||
req.Host = ho.host
|
req.Host = ho.host
|
||||||
|
|
|
@ -4,16 +4,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
"github.com/zhangyunhao116/fastrand"
|
||||||
rand.Seed(time.Now().Unix())
|
)
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
chunkSize = 1 << 14 // 2 ** 14 == 16 * 1024
|
chunkSize = 1 << 14 // 2 ** 14 == 16 * 1024
|
||||||
|
@ -130,8 +127,8 @@ func NewTLSObfs(conn net.Conn, server string) net.Conn {
|
||||||
func makeClientHelloMsg(data []byte, server string) []byte {
|
func makeClientHelloMsg(data []byte, server string) []byte {
|
||||||
random := make([]byte, 28)
|
random := make([]byte, 28)
|
||||||
sessionID := make([]byte, 32)
|
sessionID := make([]byte, 32)
|
||||||
rand.Read(random)
|
fastrand.Read(random)
|
||||||
rand.Read(sessionID)
|
fastrand.Read(sessionID)
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -81,7 +82,7 @@ func (c *httpConn) Write(b []byte) (int, error) {
|
||||||
bLength := len(b)
|
bLength := len(b)
|
||||||
headDataLength := bLength
|
headDataLength := bLength
|
||||||
if bLength-headLength > 64 {
|
if bLength-headLength > 64 {
|
||||||
headDataLength = headLength + rand.Intn(65)
|
headDataLength = headLength + fastrand.Intn(65)
|
||||||
}
|
}
|
||||||
headData := b[:headDataLength]
|
headData := b[:headDataLength]
|
||||||
b = b[headDataLength:]
|
b = b[headDataLength:]
|
||||||
|
@ -99,7 +100,7 @@ func (c *httpConn) Write(b []byte) (int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hosts := strings.Split(host, ",")
|
hosts := strings.Split(host, ",")
|
||||||
host = hosts[rand.Intn(len(hosts))]
|
host = hosts[fastrand.Intn(len(hosts))]
|
||||||
|
|
||||||
buf := pool.GetBuffer()
|
buf := pool.GetBuffer()
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
|
@ -118,7 +119,7 @@ func (c *httpConn) Write(b []byte) (int, error) {
|
||||||
buf.WriteString(body + "\r\n\r\n")
|
buf.WriteString(body + "\r\n\r\n")
|
||||||
} else {
|
} else {
|
||||||
buf.WriteString("User-Agent: ")
|
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")
|
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 {
|
if c.post {
|
||||||
packBoundary(buf)
|
packBoundary(buf)
|
||||||
|
@ -146,7 +147,7 @@ func packBoundary(buf *bytes.Buffer) {
|
||||||
buf.WriteString("Content-Type: multipart/form-data; boundary=")
|
buf.WriteString("Content-Type: multipart/form-data; boundary=")
|
||||||
set := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
set := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
for i := 0; i < 32; i++ {
|
for i := 0; i < 32; i++ {
|
||||||
buf.WriteByte(set[rand.Intn(62)])
|
buf.WriteByte(set[fastrand.Intn(62)])
|
||||||
}
|
}
|
||||||
buf.WriteString("\r\n")
|
buf.WriteString("\r\n")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@ package obfs
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -53,10 +54,10 @@ func (c *randomHeadConn) Write(b []byte) (int, error) {
|
||||||
c.buf = append(c.buf, b...)
|
c.buf = append(c.buf, b...)
|
||||||
if !c.hasSentHeader {
|
if !c.hasSentHeader {
|
||||||
c.hasSentHeader = true
|
c.hasSentHeader = true
|
||||||
dataLength := rand.Intn(96) + 4
|
dataLength := fastrand.Intn(96) + 4
|
||||||
buf := pool.Get(dataLength + 4)
|
buf := pool.Get(dataLength + 4)
|
||||||
defer pool.Put(buf)
|
defer pool.Put(buf)
|
||||||
rand.Read(buf[:dataLength])
|
fastrand.Read(buf[:dataLength])
|
||||||
binary.LittleEndian.PutUint32(buf[dataLength:], 0xffffffff-crc32.ChecksumIEEE(buf[:dataLength]))
|
binary.LittleEndian.PutUint32(buf[dataLength:], 0xffffffff-crc32.ChecksumIEEE(buf[:dataLength]))
|
||||||
_, err := c.Conn.Write(buf)
|
_, err := c.Conn.Write(buf)
|
||||||
return len(b), err
|
return len(b), err
|
||||||
|
|
|
@ -4,13 +4,14 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
"github.com/Dreamacro/clash/transport/ssr/tools"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -25,7 +26,7 @@ type tls12Ticket struct {
|
||||||
|
|
||||||
func newTLS12Ticket(b *Base) Obfs {
|
func newTLS12Ticket(b *Base) Obfs {
|
||||||
r := &tls12Ticket{Base: b, authData: &authData{}}
|
r := &tls12Ticket{Base: b, authData: &authData{}}
|
||||||
rand.Read(r.clientID[:])
|
fastrand.Read(r.clientID[:])
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ func (c *tls12TicketConn) Write(b []byte) (int, error) {
|
||||||
buf := pool.GetBuffer()
|
buf := pool.GetBuffer()
|
||||||
defer pool.PutBuffer(buf)
|
defer pool.PutBuffer(buf)
|
||||||
for len(b) > 2048 {
|
for len(b) > 2048 {
|
||||||
size := rand.Intn(4096) + 100
|
size := fastrand.Intn(4096) + 100
|
||||||
if len(b) < size {
|
if len(b) < size {
|
||||||
size = len(b)
|
size = len(b)
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ func packSNIData(buf *bytes.Buffer, u string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) {
|
func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) {
|
||||||
length := 16 * (rand.Intn(17) + 8)
|
length := 16 * (fastrand.Intn(17) + 8)
|
||||||
buf.Write([]byte{0, 0x23})
|
buf.Write([]byte{0, 0x23})
|
||||||
binary.Write(buf, binary.BigEndian, uint16(length))
|
binary.Write(buf, binary.BigEndian, uint16(length))
|
||||||
tools.AppendRandBytes(buf, length)
|
tools.AppendRandBytes(buf, length)
|
||||||
|
@ -221,6 +222,6 @@ func (t *tls12Ticket) getHost() string {
|
||||||
host = ""
|
host = ""
|
||||||
}
|
}
|
||||||
hosts := strings.Split(host, ",")
|
hosts := strings.Split(host, ",")
|
||||||
host = hosts[rand.Intn(len(hosts))]
|
host = hosts[fastrand.Intn(len(hosts))]
|
||||||
return host
|
return host
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,6 +11,8 @@ import (
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
"github.com/Dreamacro/clash/transport/ssr/tools"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -64,7 +65,7 @@ func (a *authAES128) initUserData() {
|
||||||
}
|
}
|
||||||
if len(a.userKey) == 0 {
|
if len(a.userKey) == 0 {
|
||||||
a.userKey = a.Key
|
a.userKey = a.Key
|
||||||
rand.Read(a.userID[:])
|
fastrand.Read(a.userID[:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +199,7 @@ func (a *authAES128) packData(poolBuf *bytes.Buffer, data []byte, fullDataLength
|
||||||
}
|
}
|
||||||
|
|
||||||
func trapezoidRandom(max int, d float64) int {
|
func trapezoidRandom(max int, d float64) int {
|
||||||
base := rand.Float64()
|
base := fastrand.Float64()
|
||||||
if d-0 > 1e-6 {
|
if d-0 > 1e-6 {
|
||||||
a := 1 - d
|
a := 1 - d
|
||||||
base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d)
|
base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d)
|
||||||
|
@ -219,10 +220,10 @@ func (a *authAES128) getRandDataLengthForPackData(dataLength, fullDataLength int
|
||||||
if revLength > -1460 {
|
if revLength > -1460 {
|
||||||
return trapezoidRandom(revLength+1460, -0.3)
|
return trapezoidRandom(revLength+1460, -0.3)
|
||||||
}
|
}
|
||||||
return rand.Intn(32)
|
return fastrand.Intn(32)
|
||||||
}
|
}
|
||||||
if dataLength > 900 {
|
if dataLength > 900 {
|
||||||
return rand.Intn(revLength)
|
return fastrand.Intn(revLength)
|
||||||
}
|
}
|
||||||
return trapezoidRandom(revLength, -0.3)
|
return trapezoidRandom(revLength, -0.3)
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) {
|
||||||
copy(macKey, a.iv)
|
copy(macKey, a.iv)
|
||||||
copy(macKey[len(a.iv):], a.Key)
|
copy(macKey[len(a.iv):], a.Key)
|
||||||
|
|
||||||
poolBuf.WriteByte(byte(rand.Intn(256)))
|
poolBuf.WriteByte(byte(fastrand.Intn(256)))
|
||||||
poolBuf.Write(a.hmac(macKey, poolBuf.Bytes())[:6])
|
poolBuf.Write(a.hmac(macKey, poolBuf.Bytes())[:6])
|
||||||
poolBuf.Write(a.userID[:])
|
poolBuf.Write(a.userID[:])
|
||||||
err := a.authData.putEncryptedData(poolBuf, a.userKey, [2]int{packedAuthDataLength, randDataLength}, a.salt)
|
err := a.authData.putEncryptedData(poolBuf, a.userKey, [2]int{packedAuthDataLength, randDataLength}, a.salt)
|
||||||
|
@ -263,9 +264,9 @@ func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) {
|
||||||
|
|
||||||
func (a *authAES128) getRandDataLengthForPackAuthData(size int) int {
|
func (a *authAES128) getRandDataLengthForPackAuthData(size int) int {
|
||||||
if size > 400 {
|
if size > 400 {
|
||||||
return rand.Intn(512)
|
return fastrand.Intn(512)
|
||||||
}
|
}
|
||||||
return rand.Intn(1024)
|
return fastrand.Intn(1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *authAES128) packRandData(poolBuf *bytes.Buffer, size int) {
|
func (a *authAES128) packRandData(poolBuf *bytes.Buffer, size int) {
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"hash/adler32"
|
"hash/adler32"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/transport/ssr/tools"
|
"github.com/Dreamacro/clash/transport/ssr/tools"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -176,7 +177,7 @@ func (a *authSHA1V4) getRandDataLength(size int) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if size > 400 {
|
if size > 400 {
|
||||||
return rand.Intn(256)
|
return fastrand.Intn(256)
|
||||||
}
|
}
|
||||||
return rand.Intn(512)
|
return fastrand.Intn(512)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,14 @@ import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math/rand"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
"github.com/Dreamacro/clash/transport/shadowsocks/core"
|
"github.com/Dreamacro/clash/transport/shadowsocks/core"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Base struct {
|
type Base struct {
|
||||||
|
@ -37,8 +38,8 @@ func (a *authData) next() *authData {
|
||||||
a.mutex.Lock()
|
a.mutex.Lock()
|
||||||
defer a.mutex.Unlock()
|
defer a.mutex.Unlock()
|
||||||
if a.connectionID > 0xff000000 || a.connectionID == 0 {
|
if a.connectionID > 0xff000000 || a.connectionID == 0 {
|
||||||
rand.Read(a.clientID[:])
|
fastrand.Read(a.clientID[:])
|
||||||
a.connectionID = rand.Uint32() & 0xffffff
|
a.connectionID = fastrand.Uint32() & 0xffffff
|
||||||
}
|
}
|
||||||
a.connectionID++
|
a.connectionID++
|
||||||
copy(r.clientID[:], a.clientID[:])
|
copy(r.clientID[:], a.clientID[:])
|
||||||
|
|
|
@ -4,8 +4,9 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -68,7 +69,7 @@ func getHeadSize(b []byte, defaultValue int) int {
|
||||||
|
|
||||||
func getDataLength(b []byte) int {
|
func getDataLength(b []byte) int {
|
||||||
bLength := len(b)
|
bLength := len(b)
|
||||||
dataLength := getHeadSize(b, 30) + rand.Intn(32)
|
dataLength := getHeadSize(b, 30) + fastrand.Intn(32)
|
||||||
if bLength < dataLength {
|
if bLength < dataLength {
|
||||||
return bLength
|
return bLength
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,19 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/quic-go"
|
|
||||||
|
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
"github.com/Dreamacro/clash/common/pool"
|
"github.com/Dreamacro/clash/common/pool"
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
|
|
||||||
|
"github.com/metacubex/quic-go"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -352,7 +352,7 @@ func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Met
|
||||||
pipe1, pipe2 := net.Pipe()
|
pipe1, pipe2 := net.Pipe()
|
||||||
var connId uint32
|
var connId uint32
|
||||||
for {
|
for {
|
||||||
connId = rand.Uint32()
|
connId = fastrand.Uint32()
|
||||||
_, loaded := t.udpInputMap.LoadOrStore(connId, pipe1)
|
_, loaded := t.udpInputMap.LoadOrStore(connId, pipe1)
|
||||||
if !loaded {
|
if !loaded {
|
||||||
break
|
break
|
||||||
|
|
|
@ -5,11 +5,11 @@ package congestion
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/quic-go/congestion"
|
"github.com/metacubex/quic-go/congestion"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -780,7 +780,7 @@ func (b *bbrSender) EnterProbeBandwidthMode(now time.Time) {
|
||||||
// Pick a random offset for the gain cycle out of {0, 2..7} range. 1 is
|
// 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
|
// excluded because in that case increased gain and decreased gain would not
|
||||||
// follow each other.
|
// follow each other.
|
||||||
b.cycleCurrentOffset = rand.Int() % (GainCycleLength - 1)
|
b.cycleCurrentOffset = fastrand.Int() % (GainCycleLength - 1)
|
||||||
if b.cycleCurrentOffset >= 1 {
|
if b.cycleCurrentOffset >= 1 {
|
||||||
b.cycleCurrentOffset += 1
|
b.cycleCurrentOffset += 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,11 @@ package vless
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/common/buf"
|
"github.com/Dreamacro/clash/common/buf"
|
||||||
"github.com/Dreamacro/clash/log"
|
"github.com/Dreamacro/clash/log"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -24,9 +23,9 @@ func WriteWithPadding(buffer *buf.Buffer, p []byte, command byte, userUUID *uuid
|
||||||
var paddingLen int32
|
var paddingLen int32
|
||||||
if contentLen < 900 && paddingTLS {
|
if contentLen < 900 && paddingTLS {
|
||||||
log.Debugln("long padding")
|
log.Debugln("long padding")
|
||||||
paddingLen = rand.Int31n(500) + 900 - contentLen
|
paddingLen = fastrand.Int31n(500) + 900 - contentLen
|
||||||
} else {
|
} else {
|
||||||
paddingLen = rand.Int31n(256)
|
paddingLen = fastrand.Int31n(256)
|
||||||
}
|
}
|
||||||
if paddingLen > buf.BufferSize-21-contentLen {
|
if paddingLen > buf.BufferSize-21-contentLen {
|
||||||
paddingLen = buf.BufferSize - 21 - contentLen
|
paddingLen = buf.BufferSize - 21 - contentLen
|
||||||
|
@ -48,9 +47,9 @@ func ApplyPadding(buffer *buf.Buffer, command byte, userUUID *uuid.UUID, padding
|
||||||
var paddingLen int32
|
var paddingLen int32
|
||||||
if contentLen < 900 && paddingTLS {
|
if contentLen < 900 && paddingTLS {
|
||||||
log.Debugln("long padding")
|
log.Debugln("long padding")
|
||||||
paddingLen = rand.Int31n(500) + 900 - contentLen
|
paddingLen = fastrand.Int31n(500) + 900 - contentLen
|
||||||
} else {
|
} else {
|
||||||
paddingLen = rand.Int31n(256)
|
paddingLen = fastrand.Int31n(256)
|
||||||
}
|
}
|
||||||
if paddingLen > buf.BufferSize-21-contentLen {
|
if paddingLen > buf.BufferSize-21-contentLen {
|
||||||
paddingLen = buf.BufferSize - 21 - contentLen
|
paddingLen = buf.BufferSize - 21 - contentLen
|
||||||
|
|
|
@ -11,17 +11,13 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conn wrapper a net.Conn with vmess protocol
|
// Conn wrapper a net.Conn with vmess protocol
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
|
@ -76,7 +72,7 @@ func (vc *Conn) sendRequest() error {
|
||||||
buf.WriteByte(vc.respV)
|
buf.WriteByte(vc.respV)
|
||||||
buf.WriteByte(OptionChunkStream)
|
buf.WriteByte(OptionChunkStream)
|
||||||
|
|
||||||
p := rand.Intn(16)
|
p := fastrand.Intn(16)
|
||||||
// P Sec Reserve Cmd
|
// P Sec Reserve Cmd
|
||||||
buf.WriteByte(byte(p<<4) | byte(vc.security))
|
buf.WriteByte(byte(p<<4) | byte(vc.security))
|
||||||
buf.WriteByte(0)
|
buf.WriteByte(0)
|
||||||
|
@ -94,7 +90,7 @@ func (vc *Conn) sendRequest() error {
|
||||||
// padding
|
// padding
|
||||||
if p > 0 {
|
if p > 0 {
|
||||||
padding := make([]byte, p)
|
padding := make([]byte, p)
|
||||||
rand.Read(padding)
|
fastrand.Read(padding)
|
||||||
buf.Write(padding)
|
buf.Write(padding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +196,7 @@ func hashTimestamp(t time.Time) []byte {
|
||||||
// newConn return a Conn instance
|
// newConn return a Conn instance
|
||||||
func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool) (*Conn, error) {
|
func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool) (*Conn, error) {
|
||||||
randBytes := make([]byte, 33)
|
randBytes := make([]byte, 33)
|
||||||
rand.Read(randBytes)
|
fastrand.Read(randBytes)
|
||||||
reqBodyIV := make([]byte, 16)
|
reqBodyIV := make([]byte, 16)
|
||||||
reqBodyKey := make([]byte, 16)
|
reqBodyKey := make([]byte, 16)
|
||||||
copy(reqBodyIV[:], randBytes[:16])
|
copy(reqBodyIV[:], randBytes[:16])
|
||||||
|
|
|
@ -2,11 +2,11 @@ package vmess
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ type H2Config struct {
|
||||||
func (hc *h2Conn) establishConn() error {
|
func (hc *h2Conn) establishConn() error {
|
||||||
preader, pwriter := io.Pipe()
|
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
|
path := hc.cfg.Path
|
||||||
// TODO: connect use VMess Host instead of H2 Host
|
// TODO: connect use VMess Host instead of H2 Host
|
||||||
req := http.Request{
|
req := http.Request{
|
||||||
|
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
|
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type httpConn struct {
|
type httpConn struct {
|
||||||
|
@ -51,16 +52,16 @@ func (hc *httpConn) Write(b []byte) (int, error) {
|
||||||
return hc.Conn.Write(b)
|
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
|
host := hc.cfg.Host
|
||||||
if header := hc.cfg.Headers["Host"]; len(header) != 0 {
|
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)
|
u := fmt.Sprintf("http://%s%s", host, path)
|
||||||
req, _ := http.NewRequest("GET", u, bytes.NewBuffer(b))
|
req, _ := http.NewRequest("GET", u, bytes.NewBuffer(b))
|
||||||
for key, list := range hc.cfg.Headers {
|
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))
|
req.ContentLength = int64(len(b))
|
||||||
if err := req.Write(hc.Conn); err != nil {
|
if err := req.Write(hc.Conn); err != nil {
|
||||||
|
|
|
@ -2,12 +2,13 @@ package vmess
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Dreamacro/clash/common/utils"
|
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/Dreamacro/clash/common/utils"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version of vmess
|
// Version of vmess
|
||||||
|
@ -77,7 +78,7 @@ type Config struct {
|
||||||
|
|
||||||
// StreamConn return a Conn with net.Conn and DstAddr
|
// StreamConn return a Conn with net.Conn and DstAddr
|
||||||
func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) {
|
func (c *Client) StreamConn(conn net.Conn, dst *DstAddr) (net.Conn, error) {
|
||||||
r := rand.Intn(len(c.user))
|
r := fastrand.Intn(len(c.user))
|
||||||
return newConn(conn, c.user[r], dst, c.security, c.isAead)
|
return newConn(conn, c.user[r], dst, c.security, c.isAead)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -22,7 +20,9 @@ import (
|
||||||
"github.com/Dreamacro/clash/common/buf"
|
"github.com/Dreamacro/clash/common/buf"
|
||||||
N "github.com/Dreamacro/clash/common/net"
|
N "github.com/Dreamacro/clash/common/net"
|
||||||
tlsC "github.com/Dreamacro/clash/component/tls"
|
tlsC "github.com/Dreamacro/clash/component/tls"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/zhangyunhao116/fastrand"
|
||||||
)
|
)
|
||||||
|
|
||||||
type websocketConn struct {
|
type websocketConn struct {
|
||||||
|
@ -120,7 +120,7 @@ func (wsc *websocketConn) WriteBuffer(buffer *buf.Buffer) error {
|
||||||
binary.BigEndian.PutUint64(header[2:], uint64(dataLen))
|
binary.BigEndian.PutUint64(header[2:], uint64(dataLen))
|
||||||
}
|
}
|
||||||
|
|
||||||
maskKey := rand.Uint32()
|
maskKey := fastrand.Uint32()
|
||||||
binary.LittleEndian.PutUint32(header[1+payloadBitLength:], maskKey)
|
binary.LittleEndian.PutUint32(header[1+payloadBitLength:], maskKey)
|
||||||
N.MaskWebSocket(maskKey, data)
|
N.MaskWebSocket(maskKey, data)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue