Explorar o código

Remove deprecated features

世界 %!s(int64=2) %!d(string=hai) anos
pai
achega
aa05a4d050

+ 0 - 50
common/proxyproto/dialer.go

@@ -1,50 +0,0 @@
-package proxyproto
-
-import (
-	"context"
-	"net"
-	"net/netip"
-
-	"github.com/sagernet/sing-box/adapter"
-	E "github.com/sagernet/sing/common/exceptions"
-	M "github.com/sagernet/sing/common/metadata"
-	N "github.com/sagernet/sing/common/network"
-
-	"github.com/pires/go-proxyproto"
-)
-
-var _ N.Dialer = (*Dialer)(nil)
-
-type Dialer struct {
-	N.Dialer
-}
-
-func (d *Dialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
-	switch N.NetworkName(network) {
-	case N.NetworkTCP:
-		conn, err := d.Dialer.DialContext(ctx, network, destination)
-		if err != nil {
-			return nil, err
-		}
-		var source M.Socksaddr
-		metadata := adapter.ContextFrom(ctx)
-		if metadata != nil {
-			source = metadata.Source
-		}
-		if !source.IsValid() {
-			source = M.SocksaddrFromNet(conn.LocalAddr())
-		}
-		if destination.Addr.Is6() {
-			source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port)
-		}
-		h := proxyproto.HeaderProxyFromAddrs(1, source.TCPAddr(), destination.TCPAddr())
-		_, err = h.WriteTo(conn)
-		if err != nil {
-			conn.Close()
-			return nil, E.Cause(err, "write proxy protocol header")
-		}
-		return conn, nil
-	default:
-		return d.Dialer.DialContext(ctx, network, destination)
-	}
-}

+ 0 - 62
common/proxyproto/listener.go

@@ -1,62 +0,0 @@
-package proxyproto
-
-import (
-	std_bufio "bufio"
-	"net"
-
-	"github.com/sagernet/sing/common/buf"
-	"github.com/sagernet/sing/common/bufio"
-	M "github.com/sagernet/sing/common/metadata"
-
-	"github.com/pires/go-proxyproto"
-)
-
-type Listener struct {
-	net.Listener
-	AcceptNoHeader bool
-}
-
-func (l *Listener) Accept() (net.Conn, error) {
-	conn, err := l.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	bufReader := std_bufio.NewReader(conn)
-	header, err := proxyproto.Read(bufReader)
-	if err != nil && !(l.AcceptNoHeader && err == proxyproto.ErrNoProxyProtocol) {
-		return nil, &Error{err}
-	}
-	if bufReader.Buffered() > 0 {
-		cache := buf.NewSize(bufReader.Buffered())
-		_, err = cache.ReadFullFrom(bufReader, cache.FreeLen())
-		if err != nil {
-			return nil, &Error{err}
-		}
-		conn = bufio.NewCachedConn(conn, cache)
-	}
-	if header != nil {
-		return &bufio.AddrConn{Conn: conn, Metadata: M.Metadata{
-			Source:      M.SocksaddrFromNet(header.SourceAddr).Unwrap(),
-			Destination: M.SocksaddrFromNet(header.DestinationAddr).Unwrap(),
-		}}, nil
-	}
-	return conn, nil
-}
-
-var _ net.Error = (*Error)(nil)
-
-type Error struct {
-	error
-}
-
-func (e *Error) Unwrap() error {
-	return e.error
-}
-
-func (e *Error) Timeout() bool {
-	return false
-}
-
-func (e *Error) Temporary() bool {
-	return true
-}

+ 0 - 3
go.mod

@@ -4,7 +4,6 @@ go 1.20
 
 require (
 	berty.tech/go-libtor v1.0.385
-	github.com/Dreamacro/clash v1.17.0
 	github.com/caddyserver/certmagic v0.19.2
 	github.com/cloudflare/circl v1.3.5
 	github.com/cretz/bine v0.2.0
@@ -21,7 +20,6 @@ require (
 	github.com/miekg/dns v1.1.56
 	github.com/ooni/go-libtor v1.1.8
 	github.com/oschwald/maxminddb-golang v1.12.0
-	github.com/pires/go-proxyproto v0.7.0
 	github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
 	github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a
 	github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950
@@ -59,7 +57,6 @@ require (
 //replace github.com/sagernet/sing => ../sing
 
 require (
-	github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 // indirect
 	github.com/ajg/form v1.5.1 // indirect
 	github.com/andybalholm/brotli v1.0.5 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect

+ 0 - 6
go.sum

@@ -1,9 +1,5 @@
 berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
 berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
-github.com/Dreamacro/clash v1.17.0 h1:LWtp6KcnrCiujY58ufI8pylI+hbCBgSCsLI90EWhpi4=
-github.com/Dreamacro/clash v1.17.0/go.mod h1:PtcAft7sdsK325BD6uwm8wvhOkMV3TCeED6dfZ/lnfE=
-github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 h1:JFnwKplz9hj8ubqYjm8HkgZS1Rvz9yW+u/XCNNTxr0k=
-github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158/go.mod h1:QvmEZ/h6KXszPOr2wUFl7Zn3hfFNYdfbXwPVDTyZs6k=
 github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
 github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
 github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
@@ -89,8 +85,6 @@ github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq5
 github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
 github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
 github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
-github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
-github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=

+ 2 - 4
inbound/default_tcp.go

@@ -5,7 +5,6 @@ import (
 	"net"
 
 	"github.com/sagernet/sing-box/adapter"
-	"github.com/sagernet/sing-box/common/proxyproto"
 	"github.com/sagernet/sing-box/log"
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
@@ -34,9 +33,8 @@ func (a *myInboundAdapter) ListenTCP() (net.Listener, error) {
 	if err == nil {
 		a.logger.Info("tcp server started at ", tcpListener.Addr())
 	}
-	if a.listenOptions.ProxyProtocol {
-		a.logger.Warn("Proxy Protocol is deprecated, see https://sing-box.sagernet.org/deprecated")
-		tcpListener = &proxyproto.Listener{Listener: tcpListener, AcceptNoHeader: a.listenOptions.ProxyProtocolAcceptNoHeader}
+	if a.listenOptions.ProxyProtocol || a.listenOptions.ProxyProtocolAcceptNoHeader {
+		return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
 	}
 	a.tcpListener = tcpListener
 	return tcpListener, err

+ 4 - 48
outbound/direct.go

@@ -17,8 +17,6 @@ import (
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
-
-	"github.com/pires/go-proxyproto"
 )
 
 var (
@@ -33,7 +31,6 @@ type Direct struct {
 	fallbackDelay       time.Duration
 	overrideOption      int
 	overrideDestination M.Socksaddr
-	proxyProto          uint8
 }
 
 func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, options option.DirectOutboundOptions) (*Direct, error) {
@@ -54,10 +51,9 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
 		domainStrategy: dns.DomainStrategy(options.DomainStrategy),
 		fallbackDelay:  time.Duration(options.FallbackDelay),
 		dialer:         outboundDialer,
-		proxyProto:     options.ProxyProtocol,
 	}
-	if options.ProxyProtocol > 2 {
-		return nil, E.New("invalid proxy protocol option: ", options.ProxyProtocol)
+	if options.ProxyProtocol != 0 {
+		return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
 	}
 	if options.OverrideAddress != "" && options.OverridePort != 0 {
 		outbound.overrideOption = 1
@@ -74,7 +70,6 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
 
 func (h *Direct) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
 	ctx, metadata := adapter.AppendContext(ctx)
-	originDestination := metadata.Destination
 	metadata.Outbound = h.tag
 	metadata.Destination = destination
 	switch h.overrideOption {
@@ -94,31 +89,11 @@ func (h *Direct) DialContext(ctx context.Context, network string, destination M.
 	case N.NetworkUDP:
 		h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
 	}
-	conn, err := h.dialer.DialContext(ctx, network, destination)
-	if err != nil {
-		return nil, err
-	}
-	if h.proxyProto > 0 {
-		source := metadata.Source
-		if !source.IsValid() {
-			source = M.SocksaddrFromNet(conn.LocalAddr())
-		}
-		if originDestination.Addr.Is6() {
-			source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port)
-		}
-		header := proxyproto.HeaderProxyFromAddrs(h.proxyProto, source.TCPAddr(), originDestination.TCPAddr())
-		_, err = header.WriteTo(conn)
-		if err != nil {
-			conn.Close()
-			return nil, E.Cause(err, "write proxy protocol header")
-		}
-	}
-	return conn, nil
+	return h.dialer.DialContext(ctx, network, destination)
 }
 
 func (h *Direct) DialParallel(ctx context.Context, network string, destination M.Socksaddr, destinationAddresses []netip.Addr) (net.Conn, error) {
 	ctx, metadata := adapter.AppendContext(ctx)
-	originDestination := metadata.Destination
 	metadata.Outbound = h.tag
 	metadata.Destination = destination
 	switch h.overrideOption {
@@ -141,26 +116,7 @@ func (h *Direct) DialParallel(ctx context.Context, network string, destination M
 	} else {
 		domainStrategy = dns.DomainStrategy(metadata.InboundOptions.DomainStrategy)
 	}
-	conn, err := N.DialParallel(ctx, h.dialer, network, destination, destinationAddresses, domainStrategy == dns.DomainStrategyPreferIPv6, h.fallbackDelay)
-	if err != nil {
-		return nil, err
-	}
-	if h.proxyProto > 0 {
-		source := metadata.Source
-		if !source.IsValid() {
-			source = M.SocksaddrFromNet(conn.LocalAddr())
-		}
-		if originDestination.Addr.Is6() {
-			source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port)
-		}
-		header := proxyproto.HeaderProxyFromAddrs(h.proxyProto, source.TCPAddr(), originDestination.TCPAddr())
-		_, err = header.WriteTo(conn)
-		if err != nil {
-			conn.Close()
-			return nil, E.Cause(err, "write proxy protocol header")
-		}
-	}
-	return conn, nil
+	return N.DialParallel(ctx, h.dialer, network, destination, destinationAddresses, domainStrategy == dns.DomainStrategyPreferIPv6, h.fallbackDelay)
 }
 
 func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {

+ 4 - 181
outbound/shadowsocksr.go

@@ -4,192 +4,15 @@ package outbound
 
 import (
 	"context"
-	"errors"
-	"fmt"
-	"net"
+	"os"
 
 	"github.com/sagernet/sing-box/adapter"
-	"github.com/sagernet/sing-box/common/dialer"
-	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
-	"github.com/sagernet/sing-box/transport/clashssr/obfs"
-	"github.com/sagernet/sing-box/transport/clashssr/protocol"
-	"github.com/sagernet/sing/common/bufio"
-	E "github.com/sagernet/sing/common/exceptions"
-	M "github.com/sagernet/sing/common/metadata"
-	N "github.com/sagernet/sing/common/network"
-
-	"github.com/Dreamacro/clash/transport/shadowsocks/core"
-	"github.com/Dreamacro/clash/transport/shadowsocks/shadowstream"
-	"github.com/Dreamacro/clash/transport/socks5"
 )
 
-var _ adapter.Outbound = (*ShadowsocksR)(nil)
-
-type ShadowsocksR struct {
-	myOutboundAdapter
-	dialer     N.Dialer
-	serverAddr M.Socksaddr
-	cipher     core.Cipher
-	obfs       obfs.Obfs
-	protocol   protocol.Protocol
-}
-
-func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (*ShadowsocksR, error) {
-	logger.Warn("ShadowsocksR is deprecated, see https://sing-box.sagernet.org/deprecated")
-	outboundDialer, err := dialer.New(router, options.DialerOptions)
-	if err != nil {
-		return nil, err
-	}
-	outbound := &ShadowsocksR{
-		myOutboundAdapter: myOutboundAdapter{
-			protocol:     C.TypeShadowsocksR,
-			network:      options.Network.Build(),
-			router:       router,
-			logger:       logger,
-			tag:          tag,
-			dependencies: withDialerDependency(options.DialerOptions),
-		},
-		dialer:     outboundDialer,
-		serverAddr: options.ServerOptions.Build(),
-	}
-	var cipher string
-	switch options.Method {
-	case "none":
-		cipher = "dummy"
-	default:
-		cipher = options.Method
-	}
-	outbound.cipher, err = core.PickCipher(cipher, nil, options.Password)
-	if err != nil {
-		return nil, err
-	}
-	var (
-		ivSize int
-		key    []byte
-	)
-	if cipher == "dummy" {
-		ivSize = 0
-		key = core.Kdf(options.Password, 16)
-	} else {
-		streamCipher, ok := outbound.cipher.(*core.StreamCipher)
-		if !ok {
-			return nil, fmt.Errorf("%s is not none or a supported stream cipher in ssr", cipher)
-		}
-		ivSize = streamCipher.IVSize()
-		key = streamCipher.Key
-	}
-	obfs, obfsOverhead, err := obfs.PickObfs(options.Obfs, &obfs.Base{
-		Host:   options.Server,
-		Port:   int(options.ServerPort),
-		Key:    key,
-		IVSize: ivSize,
-		Param:  options.ObfsParam,
-	})
-	if err != nil {
-		return nil, E.Cause(err, "initialize obfs")
-	}
-	protocol, err := protocol.PickProtocol(options.Protocol, &protocol.Base{
-		Key:      key,
-		Overhead: obfsOverhead,
-		Param:    options.ProtocolParam,
-	})
-	if err != nil {
-		return nil, E.Cause(err, "initialize protocol")
-	}
-	outbound.obfs = obfs
-	outbound.protocol = protocol
-	return outbound, nil
-}
-
-func (h *ShadowsocksR) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
-	ctx, metadata := adapter.AppendContext(ctx)
-	metadata.Outbound = h.tag
-	metadata.Destination = destination
-	switch network {
-	case N.NetworkTCP:
-		h.logger.InfoContext(ctx, "outbound connection to ", destination)
-		conn, err := h.dialer.DialContext(ctx, network, h.serverAddr)
-		if err != nil {
-			return nil, err
-		}
-		conn = h.cipher.StreamConn(h.obfs.StreamConn(conn))
-		writeIv, err := conn.(*shadowstream.Conn).ObtainWriteIV()
-		if err != nil {
-			conn.Close()
-			return nil, err
-		}
-		conn = h.protocol.StreamConn(conn, writeIv)
-		err = M.SocksaddrSerializer.WriteAddrPort(conn, destination)
-		if err != nil {
-			conn.Close()
-			return nil, E.Cause(err, "write request")
-		}
-		return conn, nil
-	case N.NetworkUDP:
-		conn, err := h.ListenPacket(ctx, destination)
-		if err != nil {
-			return nil, err
-		}
-		return bufio.NewBindPacketConn(conn, destination), nil
-	default:
-		return nil, E.Extend(N.ErrUnknownNetwork, network)
-	}
-}
-
-func (h *ShadowsocksR) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
-	ctx, metadata := adapter.AppendContext(ctx)
-	metadata.Outbound = h.tag
-	metadata.Destination = destination
-	h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
-	outConn, err := h.dialer.DialContext(ctx, N.NetworkUDP, h.serverAddr)
-	if err != nil {
-		return nil, err
-	}
-	packetConn := h.cipher.PacketConn(bufio.NewUnbindPacketConn(outConn))
-	packetConn = h.protocol.PacketConn(packetConn)
-	packetConn = &ssPacketConn{packetConn, outConn.RemoteAddr()}
-	return packetConn, nil
-}
-
-func (h *ShadowsocksR) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
-	return NewConnection(ctx, h, conn, metadata)
-}
-
-func (h *ShadowsocksR) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
-	return NewPacketConnection(ctx, h, conn, metadata)
-}
-
-type ssPacketConn struct {
-	net.PacketConn
-	rAddr net.Addr
-}
-
-func (spc *ssPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) {
-	packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b)
-	if err != nil {
-		return
-	}
-	return spc.PacketConn.WriteTo(packet[3:], spc.rAddr)
-}
-
-func (spc *ssPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
-	n, _, e := spc.PacketConn.ReadFrom(b)
-	if e != nil {
-		return 0, nil, e
-	}
-
-	addr := socks5.SplitAddr(b[:n])
-	if addr == nil {
-		return 0, nil, errors.New("parse addr error")
-	}
-
-	udpAddr := addr.UDPAddr()
-	if udpAddr == nil {
-		return 0, nil, errors.New("parse addr error")
-	}
+var _ int = "ShadowsocksR is deprecated and removed in sing-box 1.6.0"
 
-	copy(b, b[len(addr):])
-	return n - len(addr), udpAddr, e
+func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (adapter.Outbound, error) {
+	return nil, os.ErrInvalid
 }

+ 1 - 1
outbound/shadowsocksr_stub.go

@@ -12,5 +12,5 @@ import (
 )
 
 func NewShadowsocksR(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksROutboundOptions) (adapter.Outbound, error) {
-	return nil, E.New(`ShadowsocksR is not included in this build, rebuild with -tags with_shadowsocksr`)
+	return nil, E.New("ShadowsocksR is deprecated and removed in sing-box 1.6.0")
 }

+ 0 - 2
test/clash_test.go

@@ -36,7 +36,6 @@ const (
 	ImageHysteria2             = "tobyxdd/hysteria:v2"
 	ImageNginx                 = "nginx:stable"
 	ImageShadowTLS             = "ghcr.io/ihciah/shadow-tls:latest"
-	ImageShadowsocksR          = "teddysun/shadowsocks-r:latest"
 	ImageXRayCore              = "teddysun/xray:latest"
 	ImageShadowsocksLegacy     = "mritd/shadowsocks:latest"
 	ImageTUICServer            = "kilvn/tuic-server:latest"
@@ -54,7 +53,6 @@ var allImages = []string{
 	ImageHysteria2,
 	ImageNginx,
 	ImageShadowTLS,
-	ImageShadowsocksR,
 	ImageXRayCore,
 	ImageShadowsocksLegacy,
 	ImageTUICServer,

+ 0 - 3
test/go.mod

@@ -24,8 +24,6 @@ require (
 
 require (
 	berty.tech/go-libtor v1.0.385 // indirect
-	github.com/Dreamacro/clash v1.17.0 // indirect
-	github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 // indirect
 	github.com/Microsoft/go-winio v0.6.1 // indirect
 	github.com/ajg/form v1.5.1 // indirect
 	github.com/andybalholm/brotli v1.0.5 // indirect
@@ -65,7 +63,6 @@ require (
 	github.com/opencontainers/image-spec v1.0.2 // indirect
 	github.com/oschwald/maxminddb-golang v1.12.0 // indirect
 	github.com/pierrec/lz4/v4 v4.1.14 // indirect
-	github.com/pires/go-proxyproto v0.7.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/quic-go/qpack v0.4.0 // indirect

+ 0 - 6
test/go.sum

@@ -1,10 +1,6 @@
 berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
 berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
-github.com/Dreamacro/clash v1.17.0 h1:LWtp6KcnrCiujY58ufI8pylI+hbCBgSCsLI90EWhpi4=
-github.com/Dreamacro/clash v1.17.0/go.mod h1:PtcAft7sdsK325BD6uwm8wvhOkMV3TCeED6dfZ/lnfE=
-github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158 h1:JFnwKplz9hj8ubqYjm8HkgZS1Rvz9yW+u/XCNNTxr0k=
-github.com/Dreamacro/protobytes v0.0.0-20230617041236-6500a9f4f158/go.mod h1:QvmEZ/h6KXszPOr2wUFl7Zn3hfFNYdfbXwPVDTyZs6k=
 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
 github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
@@ -107,8 +103,6 @@ github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq5
 github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
 github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
 github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
-github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
-github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

+ 0 - 48
test/shadowsocksr_test.go

@@ -1,48 +0,0 @@
-package main
-
-import (
-	"net/netip"
-	"testing"
-
-	C "github.com/sagernet/sing-box/constant"
-	"github.com/sagernet/sing-box/option"
-)
-
-func TestShadowsocksR(t *testing.T) {
-	startDockerContainer(t, DockerOptions{
-		Image: ImageShadowsocksR,
-		Ports: []uint16{serverPort, testPort},
-		Bind: map[string]string{
-			"shadowsocksr.json": "/etc/shadowsocks-r/config.json",
-		},
-	})
-	startInstance(t, option.Options{
-		Inbounds: []option.Inbound{
-			{
-				Type: C.TypeMixed,
-				MixedOptions: option.HTTPMixedInboundOptions{
-					ListenOptions: option.ListenOptions{
-						Listen:     option.NewListenAddress(netip.IPv4Unspecified()),
-						ListenPort: clientPort,
-					},
-				},
-			},
-		},
-		Outbounds: []option.Outbound{
-			{
-				Type: C.TypeShadowsocksR,
-				ShadowsocksROptions: option.ShadowsocksROutboundOptions{
-					ServerOptions: option.ServerOptions{
-						Server:     "127.0.0.1",
-						ServerPort: serverPort,
-					},
-					Method:   "aes-256-cfb",
-					Password: "password0",
-					Obfs:     "plain",
-					Protocol: "origin",
-				},
-			},
-		},
-	})
-	testSuit(t, clientPort, testPort)
-}

+ 0 - 9
transport/clashssr/obfs/base.go

@@ -1,9 +0,0 @@
-package obfs
-
-type Base struct {
-	Host   string
-	Port   int
-	Key    []byte
-	IVSize int
-	Param  string
-}

+ 0 - 9
transport/clashssr/obfs/http_post.go

@@ -1,9 +0,0 @@
-package obfs
-
-func init() {
-	register("http_post", newHTTPPost, 0)
-}
-
-func newHTTPPost(b *Base) Obfs {
-	return &httpObfs{Base: b, post: true}
-}

+ 0 - 405
transport/clashssr/obfs/http_simple.go

@@ -1,405 +0,0 @@
-package obfs
-
-import (
-	"bytes"
-	"encoding/hex"
-	"io"
-	"math/rand"
-	"net"
-	"strconv"
-	"strings"
-
-	"github.com/Dreamacro/clash/common/pool"
-)
-
-func init() {
-	register("http_simple", newHTTPSimple, 0)
-}
-
-type httpObfs struct {
-	*Base
-	post bool
-}
-
-func newHTTPSimple(b *Base) Obfs {
-	return &httpObfs{Base: b}
-}
-
-type httpConn struct {
-	net.Conn
-	*httpObfs
-	hasSentHeader bool
-	hasRecvHeader bool
-	buf           []byte
-}
-
-func (h *httpObfs) StreamConn(c net.Conn) net.Conn {
-	return &httpConn{Conn: c, httpObfs: h}
-}
-
-func (c *httpConn) Read(b []byte) (int, error) {
-	if c.buf != nil {
-		n := copy(b, c.buf)
-		if n == len(c.buf) {
-			c.buf = nil
-		} else {
-			c.buf = c.buf[n:]
-		}
-		return n, nil
-	}
-
-	if c.hasRecvHeader {
-		return c.Conn.Read(b)
-	}
-
-	buf := pool.Get(pool.RelayBufferSize)
-	defer pool.Put(buf)
-	n, err := c.Conn.Read(buf)
-	if err != nil {
-		return 0, err
-	}
-	pos := bytes.Index(buf[:n], []byte("\r\n\r\n"))
-	if pos == -1 {
-		return 0, io.EOF
-	}
-	c.hasRecvHeader = true
-	dataLength := n - pos - 4
-	n = copy(b, buf[4+pos:n])
-	if dataLength > n {
-		c.buf = append(c.buf, buf[4+pos+n:4+pos+dataLength]...)
-	}
-	return n, nil
-}
-
-func (c *httpConn) Write(b []byte) (int, error) {
-	if c.hasSentHeader {
-		return c.Conn.Write(b)
-	}
-	// 30: head length
-	headLength := c.IVSize + 30
-
-	bLength := len(b)
-	headDataLength := bLength
-	if bLength-headLength > 64 {
-		headDataLength = headLength + rand.Intn(65)
-	}
-	headData := b[:headDataLength]
-	b = b[headDataLength:]
-
-	var body string
-	host := c.Host
-	if len(c.Param) > 0 {
-		pos := strings.Index(c.Param, "#")
-		if pos != -1 {
-			body = strings.ReplaceAll(c.Param[pos+1:], "\n", "\r\n")
-			body = strings.ReplaceAll(body, "\\n", "\r\n")
-			host = c.Param[:pos]
-		} else {
-			host = c.Param
-		}
-	}
-	hosts := strings.Split(host, ",")
-	host = hosts[rand.Intn(len(hosts))]
-
-	buf := pool.GetBuffer()
-	defer pool.PutBuffer(buf)
-	if c.post {
-		buf.WriteString("POST /")
-	} else {
-		buf.WriteString("GET /")
-	}
-	packURLEncodedHeadData(buf, headData)
-	buf.WriteString(" HTTP/1.1\r\nHost: " + host)
-	if c.Port != 80 {
-		buf.WriteString(":" + strconv.Itoa(c.Port))
-	}
-	buf.WriteString("\r\n")
-	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("\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)
-		}
-		buf.WriteString("DNT: 1\r\nConnection: keep-alive\r\n\r\n")
-	}
-	buf.Write(b)
-	_, err := c.Conn.Write(buf.Bytes())
-	if err != nil {
-		return 0, nil
-	}
-	c.hasSentHeader = true
-	return bLength, nil
-}
-
-func packURLEncodedHeadData(buf *bytes.Buffer, data []byte) {
-	dataLength := len(data)
-	for i := 0; i < dataLength; i++ {
-		buf.WriteRune('%')
-		buf.WriteString(hex.EncodeToString(data[i : i+1]))
-	}
-}
-
-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.WriteString("\r\n")
-}
-
-var userAgent = []string{
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; Moto C Build/NRD90M.059) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-G532M Build/MMB29T; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1.1; SM-J120M Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; Moto G (5) Build/NPPS25.137-93-14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-G570M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0; CAM-L03 Build/HUAWEICAM-L03) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3",
-	"Mozilla/5.0 (Linux; Android 8.0.0; FIG-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.1 Safari/533.2",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36",
-	"Mozilla/5.0 (X11; Datanyze; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1.1; SM-J111M Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36",
-	"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-J700M Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36",
-	"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Slackware/Chrome/12.0.742.100 Safari/534.30",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
-	"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.100 Safari/534.30",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 8.0.0; WAS-LX3 Build/HUAWEIWAS-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.1805 Safari/537.36 MVisionPlayer/1.0.0.0",
-	"Mozilla/5.0 (Linux; Android 7.0; TRT-LX3 Build/HUAWEITRT-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0; vivo 1610 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.124 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 4.4.2; de-de; SAMSUNG GT-I9195 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
-	"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 8.0.0; ANE-LX3 Build/HUAWEIANE-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (X11; U; Linux i586; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.1 Safari/533.2",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-G610M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-J500M Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0; vivo 1606 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.124 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-G610M Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.1; vivo 1716 Build/N2G47H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-G570M Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0; MYA-L22 Build/HUAWEIMYA-L22) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1; A1601 Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.98 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; TRT-LX2 Build/HUAWEITRT-LX2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/59.0.3071.125 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17",
-	"Mozilla/5.0 (Linux; Android 6.0; CAM-L21 Build/HUAWEICAM-L21; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
-	"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24",
-	"Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4X Build/N2G47H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 4.4.2; SM-G7102 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1; HUAWEI CUN-L22 Build/HUAWEICUN-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1.1; A37fw Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-J730GM Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-G610F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.1.2; Redmi Note 5A Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; Redmi Note 4 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36",
-	"Mozilla/5.0 (Unknown; Linux) AppleWebKit/538.1 (KHTML, like Gecko) Chrome/v1.0.0 Safari/538.1",
-	"Mozilla/5.0 (Linux; Android 7.0; BLL-L22 Build/HUAWEIBLL-L22) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.0; SM-J710F Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-G532M Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.1.1; CPH1723 Build/N6F26Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 8.0.0; FIG-LX3 Build/HUAWEIFIG-LX3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 7.1; Mi A1 Build/N2G47H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
-	"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36 MVisionPlayer/1.0.0.0",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 5.1; A37f Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.93 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; CPH1607 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
-	"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; vivo 1603 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-G532M Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; Redmi 4A Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.116 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0.1; SM-G532G Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.83 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36",
-	"Mozilla/5.0 (Linux; Android 6.0; vivo 1713 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.124 Mobile Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36",
-	"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
-}

+ 0 - 42
transport/clashssr/obfs/obfs.go

@@ -1,42 +0,0 @@
-package obfs
-
-import (
-	"errors"
-	"fmt"
-	"net"
-)
-
-var (
-	errTLS12TicketAuthIncorrectMagicNumber = errors.New("tls1.2_ticket_auth incorrect magic number")
-	errTLS12TicketAuthTooShortData         = errors.New("tls1.2_ticket_auth too short data")
-	errTLS12TicketAuthHMACError            = errors.New("tls1.2_ticket_auth hmac verifying failed")
-)
-
-type authData struct {
-	clientID [32]byte
-}
-
-type Obfs interface {
-	StreamConn(net.Conn) net.Conn
-}
-
-type obfsCreator func(b *Base) Obfs
-
-var obfsList = make(map[string]struct {
-	overhead int
-	new      obfsCreator
-})
-
-func register(name string, c obfsCreator, o int) {
-	obfsList[name] = struct {
-		overhead int
-		new      obfsCreator
-	}{overhead: o, new: c}
-}
-
-func PickObfs(name string, b *Base) (Obfs, int, error) {
-	if choice, ok := obfsList[name]; ok {
-		return choice.new(b), choice.overhead, nil
-	}
-	return nil, 0, fmt.Errorf("Obfs %s not supported", name)
-}

+ 0 - 15
transport/clashssr/obfs/plain.go

@@ -1,15 +0,0 @@
-package obfs
-
-import "net"
-
-type plain struct{}
-
-func init() {
-	register("plain", newPlain, 0)
-}
-
-func newPlain(b *Base) Obfs {
-	return &plain{}
-}
-
-func (p *plain) StreamConn(c net.Conn) net.Conn { return c }

+ 0 - 71
transport/clashssr/obfs/random_head.go

@@ -1,71 +0,0 @@
-package obfs
-
-import (
-	"encoding/binary"
-	"hash/crc32"
-	"math/rand"
-	"net"
-
-	"github.com/Dreamacro/clash/common/pool"
-)
-
-func init() {
-	register("random_head", newRandomHead, 0)
-}
-
-type randomHead struct {
-	*Base
-}
-
-func newRandomHead(b *Base) Obfs {
-	return &randomHead{Base: b}
-}
-
-type randomHeadConn struct {
-	net.Conn
-	*randomHead
-	hasSentHeader bool
-	rawTransSent  bool
-	rawTransRecv  bool
-	buf           []byte
-}
-
-func (r *randomHead) StreamConn(c net.Conn) net.Conn {
-	return &randomHeadConn{Conn: c, randomHead: r}
-}
-
-func (c *randomHeadConn) Read(b []byte) (int, error) {
-	if c.rawTransRecv {
-		return c.Conn.Read(b)
-	}
-	buf := pool.Get(pool.RelayBufferSize)
-	defer pool.Put(buf)
-	c.Conn.Read(buf)
-	c.rawTransRecv = true
-	c.Write(nil)
-	return 0, nil
-}
-
-func (c *randomHeadConn) Write(b []byte) (int, error) {
-	if c.rawTransSent {
-		return c.Conn.Write(b)
-	}
-	c.buf = append(c.buf, b...)
-	if !c.hasSentHeader {
-		c.hasSentHeader = true
-		dataLength := rand.Intn(96) + 4
-		buf := pool.Get(dataLength + 4)
-		defer pool.Put(buf)
-		rand.Read(buf[:dataLength])
-		binary.LittleEndian.PutUint32(buf[dataLength:], 0xffffffff-crc32.ChecksumIEEE(buf[:dataLength]))
-		_, err := c.Conn.Write(buf)
-		return len(b), err
-	}
-	if c.rawTransRecv {
-		_, err := c.Conn.Write(c.buf)
-		c.buf = nil
-		c.rawTransSent = true
-		return len(b), err
-	}
-	return len(b), nil
-}

+ 0 - 226
transport/clashssr/obfs/tls1.2_ticket_auth.go

@@ -1,226 +0,0 @@
-package obfs
-
-import (
-	"bytes"
-	"crypto/hmac"
-	"encoding/binary"
-	"math/rand"
-	"net"
-	"strings"
-	"time"
-
-	"github.com/Dreamacro/clash/common/pool"
-	"github.com/Dreamacro/clash/transport/ssr/tools"
-)
-
-func init() {
-	register("tls1.2_ticket_auth", newTLS12Ticket, 5)
-	register("tls1.2_ticket_fastauth", newTLS12Ticket, 5)
-}
-
-type tls12Ticket struct {
-	*Base
-	*authData
-}
-
-func newTLS12Ticket(b *Base) Obfs {
-	r := &tls12Ticket{Base: b, authData: &authData{}}
-	rand.Read(r.clientID[:])
-	return r
-}
-
-type tls12TicketConn struct {
-	net.Conn
-	*tls12Ticket
-	handshakeStatus int
-	decoded         bytes.Buffer
-	underDecoded    bytes.Buffer
-	sendBuf         bytes.Buffer
-}
-
-func (t *tls12Ticket) StreamConn(c net.Conn) net.Conn {
-	return &tls12TicketConn{Conn: c, tls12Ticket: t}
-}
-
-func (c *tls12TicketConn) Read(b []byte) (int, error) {
-	if c.decoded.Len() > 0 {
-		return c.decoded.Read(b)
-	}
-
-	buf := pool.Get(pool.RelayBufferSize)
-	defer pool.Put(buf)
-	n, err := c.Conn.Read(buf)
-	if err != nil {
-		return 0, err
-	}
-
-	if c.handshakeStatus == 8 {
-		c.underDecoded.Write(buf[:n])
-		for c.underDecoded.Len() > 5 {
-			if !bytes.Equal(c.underDecoded.Bytes()[:3], []byte{0x17, 3, 3}) {
-				c.underDecoded.Reset()
-				return 0, errTLS12TicketAuthIncorrectMagicNumber
-			}
-			size := int(binary.BigEndian.Uint16(c.underDecoded.Bytes()[3:5]))
-			if c.underDecoded.Len() < 5+size {
-				break
-			}
-			c.underDecoded.Next(5)
-			c.decoded.Write(c.underDecoded.Next(size))
-		}
-		n, _ = c.decoded.Read(b)
-		return n, nil
-	}
-
-	if n < 11+32+1+32 {
-		return 0, errTLS12TicketAuthTooShortData
-	}
-
-	if !hmac.Equal(buf[33:43], c.hmacSHA1(buf[11:33])[:10]) || !hmac.Equal(buf[n-10:n], c.hmacSHA1(buf[:n-10])[:10]) {
-		return 0, errTLS12TicketAuthHMACError
-	}
-
-	c.Write(nil)
-	return 0, nil
-}
-
-func (c *tls12TicketConn) Write(b []byte) (int, error) {
-	length := len(b)
-	if c.handshakeStatus == 8 {
-		buf := pool.GetBuffer()
-		defer pool.PutBuffer(buf)
-		for len(b) > 2048 {
-			size := rand.Intn(4096) + 100
-			if len(b) < size {
-				size = len(b)
-			}
-			packData(buf, b[:size])
-			b = b[size:]
-		}
-		if len(b) > 0 {
-			packData(buf, b)
-		}
-		_, err := c.Conn.Write(buf.Bytes())
-		if err != nil {
-			return 0, err
-		}
-		return length, nil
-	}
-
-	if len(b) > 0 {
-		packData(&c.sendBuf, b)
-	}
-
-	if c.handshakeStatus == 0 {
-		c.handshakeStatus = 1
-
-		data := pool.GetBuffer()
-		defer pool.PutBuffer(data)
-
-		data.Write([]byte{3, 3})
-		c.packAuthData(data)
-		data.WriteByte(0x20)
-		data.Write(c.clientID[:])
-		data.Write([]byte{0x00, 0x1c, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x9c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0x0a})
-		data.Write([]byte{0x1, 0x0})
-
-		ext := pool.GetBuffer()
-		defer pool.PutBuffer(ext)
-
-		host := c.getHost()
-		ext.Write([]byte{0xff, 0x01, 0x00, 0x01, 0x00})
-		packSNIData(ext, host)
-		ext.Write([]byte{0, 0x17, 0, 0})
-		c.packTicketBuf(ext, host)
-		ext.Write([]byte{0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03})
-		ext.Write([]byte{0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00})
-		ext.Write([]byte{0x00, 0x12, 0x00, 0x00})
-		ext.Write([]byte{0x75, 0x50, 0x00, 0x00})
-		ext.Write([]byte{0x00, 0x0b, 0x00, 0x02, 0x01, 0x00})
-		ext.Write([]byte{0x00, 0x0a, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18})
-
-		binary.Write(data, binary.BigEndian, uint16(ext.Len()))
-		data.ReadFrom(ext)
-
-		ret := pool.GetBuffer()
-		defer pool.PutBuffer(ret)
-
-		ret.Write([]byte{0x16, 3, 1})
-		binary.Write(ret, binary.BigEndian, uint16(data.Len()+4))
-		ret.Write([]byte{1, 0})
-		binary.Write(ret, binary.BigEndian, uint16(data.Len()))
-		ret.ReadFrom(data)
-
-		_, err := c.Conn.Write(ret.Bytes())
-		if err != nil {
-			return 0, err
-		}
-		return length, nil
-	} else if c.handshakeStatus == 1 && len(b) == 0 {
-		buf := pool.GetBuffer()
-		defer pool.PutBuffer(buf)
-
-		buf.Write([]byte{0x14, 3, 3, 0, 1, 1, 0x16, 3, 3, 0, 0x20})
-		tools.AppendRandBytes(buf, 22)
-		buf.Write(c.hmacSHA1(buf.Bytes())[:10])
-		buf.ReadFrom(&c.sendBuf)
-
-		c.handshakeStatus = 8
-
-		_, err := c.Conn.Write(buf.Bytes())
-		return 0, err
-	}
-	return length, nil
-}
-
-func packData(buf *bytes.Buffer, data []byte) {
-	buf.Write([]byte{0x17, 3, 3})
-	binary.Write(buf, binary.BigEndian, uint16(len(data)))
-	buf.Write(data)
-}
-
-func (t *tls12Ticket) packAuthData(buf *bytes.Buffer) {
-	binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
-	tools.AppendRandBytes(buf, 18)
-	buf.Write(t.hmacSHA1(buf.Bytes()[buf.Len()-22:])[:10])
-}
-
-func packSNIData(buf *bytes.Buffer, u string) {
-	len := uint16(len(u))
-	buf.Write([]byte{0, 0})
-	binary.Write(buf, binary.BigEndian, len+5)
-	binary.Write(buf, binary.BigEndian, len+3)
-	buf.WriteByte(0)
-	binary.Write(buf, binary.BigEndian, len)
-	buf.WriteString(u)
-}
-
-func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) {
-	length := 16 * (rand.Intn(17) + 8)
-	buf.Write([]byte{0, 0x23})
-	binary.Write(buf, binary.BigEndian, uint16(length))
-	tools.AppendRandBytes(buf, length)
-}
-
-func (t *tls12Ticket) hmacSHA1(data []byte) []byte {
-	key := pool.Get(len(t.Key) + 32)
-	defer pool.Put(key)
-	copy(key, t.Key)
-	copy(key[len(t.Key):], t.clientID[:])
-
-	sha1Data := tools.HmacSHA1(key, data)
-	return sha1Data[:10]
-}
-
-func (t *tls12Ticket) getHost() string {
-	host := t.Param
-	if len(host) == 0 {
-		host = t.Host
-	}
-	if len(host) > 0 && host[len(host)-1] >= '0' && host[len(host)-1] <= '9' {
-		host = ""
-	}
-	hosts := strings.Split(host, ",")
-	host = hosts[rand.Intn(len(hosts))]
-	return host
-}

+ 0 - 18
transport/clashssr/protocol/auth_aes128_md5.go

@@ -1,18 +0,0 @@
-package protocol
-
-import "github.com/Dreamacro/clash/transport/ssr/tools"
-
-func init() {
-	register("auth_aes128_md5", newAuthAES128MD5, 9)
-}
-
-func newAuthAES128MD5(b *Base) Protocol {
-	a := &authAES128{
-		Base:               b,
-		authData:           &authData{},
-		authAES128Function: &authAES128Function{salt: "auth_aes128_md5", hmac: tools.HmacMD5, hashDigest: tools.MD5Sum},
-		userData:           &userData{},
-	}
-	a.initUserData()
-	return a
-}

+ 0 - 277
transport/clashssr/protocol/auth_aes128_sha1.go

@@ -1,277 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"encoding/binary"
-	"math"
-	"math/rand"
-	"net"
-	"strconv"
-	"strings"
-
-	"github.com/Dreamacro/clash/common/pool"
-	"github.com/Dreamacro/clash/transport/ssr/tools"
-)
-
-type (
-	hmacMethod       func(key, data []byte) []byte
-	hashDigestMethod func([]byte) []byte
-)
-
-func init() {
-	register("auth_aes128_sha1", newAuthAES128SHA1, 9)
-}
-
-type authAES128Function struct {
-	salt       string
-	hmac       hmacMethod
-	hashDigest hashDigestMethod
-}
-
-type authAES128 struct {
-	*Base
-	*authData
-	*authAES128Function
-	*userData
-	iv            []byte
-	hasSentHeader bool
-	rawTrans      bool
-	packID        uint32
-	recvID        uint32
-}
-
-func newAuthAES128SHA1(b *Base) Protocol {
-	a := &authAES128{
-		Base:               b,
-		authData:           &authData{},
-		authAES128Function: &authAES128Function{salt: "auth_aes128_sha1", hmac: tools.HmacSHA1, hashDigest: tools.SHA1Sum},
-		userData:           &userData{},
-	}
-	a.initUserData()
-	return a
-}
-
-func (a *authAES128) initUserData() {
-	params := strings.Split(a.Param, ":")
-	if len(params) > 1 {
-		if userID, err := strconv.ParseUint(params[0], 10, 32); err == nil {
-			binary.LittleEndian.PutUint32(a.userID[:], uint32(userID))
-			a.userKey = a.hashDigest([]byte(params[1]))
-		}
-	}
-	if len(a.userKey) == 0 {
-		a.userKey = a.Key
-		rand.Read(a.userID[:])
-	}
-}
-
-func (a *authAES128) StreamConn(c net.Conn, iv []byte) net.Conn {
-	p := &authAES128{
-		Base:               a.Base,
-		authData:           a.next(),
-		authAES128Function: a.authAES128Function,
-		userData:           a.userData,
-		packID:             1,
-		recvID:             1,
-	}
-	p.iv = iv
-	return &Conn{Conn: c, Protocol: p}
-}
-
-func (a *authAES128) PacketConn(c net.PacketConn) net.PacketConn {
-	p := &authAES128{
-		Base:               a.Base,
-		authAES128Function: a.authAES128Function,
-		userData:           a.userData,
-	}
-	return &PacketConn{PacketConn: c, Protocol: p}
-}
-
-func (a *authAES128) Decode(dst, src *bytes.Buffer) error {
-	if a.rawTrans {
-		dst.ReadFrom(src)
-		return nil
-	}
-	for src.Len() > 4 {
-		macKey := pool.Get(len(a.userKey) + 4)
-		defer pool.Put(macKey)
-		copy(macKey, a.userKey)
-		binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.recvID)
-		if !bytes.Equal(a.hmac(macKey, src.Bytes()[:2])[:2], src.Bytes()[2:4]) {
-			src.Reset()
-			return errAuthAES128MACError
-		}
-
-		length := int(binary.LittleEndian.Uint16(src.Bytes()[:2]))
-		if length >= 8192 || length < 7 {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthAES128LengthError
-		}
-		if length > src.Len() {
-			break
-		}
-
-		if !bytes.Equal(a.hmac(macKey, src.Bytes()[:length-4])[:4], src.Bytes()[length-4:length]) {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthAES128ChksumError
-		}
-
-		a.recvID++
-
-		pos := int(src.Bytes()[4])
-		if pos < 255 {
-			pos += 4
-		} else {
-			pos = int(binary.LittleEndian.Uint16(src.Bytes()[5:7])) + 4
-		}
-		dst.Write(src.Bytes()[pos : length-4])
-		src.Next(length)
-	}
-	return nil
-}
-
-func (a *authAES128) Encode(buf *bytes.Buffer, b []byte) error {
-	fullDataLength := len(b)
-	if !a.hasSentHeader {
-		dataLength := getDataLength(b)
-		a.packAuthData(buf, b[:dataLength])
-		b = b[dataLength:]
-		a.hasSentHeader = true
-	}
-	for len(b) > 8100 {
-		a.packData(buf, b[:8100], fullDataLength)
-		b = b[8100:]
-	}
-	if len(b) > 0 {
-		a.packData(buf, b, fullDataLength)
-	}
-	return nil
-}
-
-func (a *authAES128) DecodePacket(b []byte) ([]byte, error) {
-	if len(b) < 4 {
-		return nil, errAuthAES128LengthError
-	}
-	if !bytes.Equal(a.hmac(a.Key, b[:len(b)-4])[:4], b[len(b)-4:]) {
-		return nil, errAuthAES128ChksumError
-	}
-	return b[:len(b)-4], nil
-}
-
-func (a *authAES128) EncodePacket(buf *bytes.Buffer, b []byte) error {
-	buf.Write(b)
-	buf.Write(a.userID[:])
-	buf.Write(a.hmac(a.userKey, buf.Bytes())[:4])
-	return nil
-}
-
-func (a *authAES128) packData(poolBuf *bytes.Buffer, data []byte, fullDataLength int) {
-	dataLength := len(data)
-	randDataLength := a.getRandDataLengthForPackData(dataLength, fullDataLength)
-	/*
-		2:	uint16 LittleEndian packedDataLength
-		2:	hmac of packedDataLength
-		3:	maxRandDataLengthPrefix (min:1)
-		4:	hmac of packedData except the last 4 bytes
-	*/
-	packedDataLength := 2 + 2 + 3 + randDataLength + dataLength + 4
-	if randDataLength < 128 {
-		packedDataLength -= 2
-	}
-
-	macKey := pool.Get(len(a.userKey) + 4)
-	defer pool.Put(macKey)
-	copy(macKey, a.userKey)
-	binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.packID)
-	a.packID++
-
-	binary.Write(poolBuf, binary.LittleEndian, uint16(packedDataLength))
-	poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[poolBuf.Len()-2:])[:2])
-	a.packRandData(poolBuf, randDataLength)
-	poolBuf.Write(data)
-	poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[poolBuf.Len()-packedDataLength+4:])[:4])
-}
-
-func trapezoidRandom(max int, d float64) int {
-	base := rand.Float64()
-	if d-0 > 1e-6 {
-		a := 1 - d
-		base = (math.Sqrt(a*a+4*d*base) - a) / (2 * d)
-	}
-	return int(base * float64(max))
-}
-
-func (a *authAES128) getRandDataLengthForPackData(dataLength, fullDataLength int) int {
-	if fullDataLength >= 32*1024-a.Overhead {
-		return 0
-	}
-	// 1460: tcp_mss
-	revLength := 1460 - dataLength - 9
-	if revLength == 0 {
-		return 0
-	}
-	if revLength < 0 {
-		if revLength > -1460 {
-			return trapezoidRandom(revLength+1460, -0.3)
-		}
-		return rand.Intn(32)
-	}
-	if dataLength > 900 {
-		return rand.Intn(revLength)
-	}
-	return trapezoidRandom(revLength, -0.3)
-}
-
-func (a *authAES128) packAuthData(poolBuf *bytes.Buffer, data []byte) {
-	if len(data) == 0 {
-		return
-	}
-	dataLength := len(data)
-	randDataLength := a.getRandDataLengthForPackAuthData(dataLength)
-	/*
-		7:	checkHead(1) and hmac of checkHead(6)
-		4:	userID
-		16:	encrypted data of authdata(12), uint16 BigEndian packedDataLength(2) and uint16 BigEndian randDataLength(2)
-		4:	hmac of userID and encrypted data
-		4:	hmac of packedAuthData except the last 4 bytes
-	*/
-	packedAuthDataLength := 7 + 4 + 16 + 4 + randDataLength + dataLength + 4
-
-	macKey := pool.Get(len(a.iv) + len(a.Key))
-	defer pool.Put(macKey)
-	copy(macKey, a.iv)
-	copy(macKey[len(a.iv):], a.Key)
-
-	poolBuf.WriteByte(byte(rand.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)
-	if err != nil {
-		poolBuf.Reset()
-		return
-	}
-	poolBuf.Write(a.hmac(macKey, poolBuf.Bytes()[7:])[:4])
-	tools.AppendRandBytes(poolBuf, randDataLength)
-	poolBuf.Write(data)
-	poolBuf.Write(a.hmac(a.userKey, poolBuf.Bytes())[:4])
-}
-
-func (a *authAES128) getRandDataLengthForPackAuthData(size int) int {
-	if size > 400 {
-		return rand.Intn(512)
-	}
-	return rand.Intn(1024)
-}
-
-func (a *authAES128) packRandData(poolBuf *bytes.Buffer, size int) {
-	if size < 128 {
-		poolBuf.WriteByte(byte(size + 1))
-		tools.AppendRandBytes(poolBuf, size)
-		return
-	}
-	poolBuf.WriteByte(255)
-	binary.Write(poolBuf, binary.LittleEndian, uint16(size+3))
-	tools.AppendRandBytes(poolBuf, size)
-}

+ 0 - 306
transport/clashssr/protocol/auth_chain_a.go

@@ -1,306 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"crypto/cipher"
-	"crypto/rand"
-	"crypto/rc4"
-	"encoding/base64"
-	"encoding/binary"
-	"net"
-	"strconv"
-	"strings"
-
-	"github.com/Dreamacro/clash/common/pool"
-	"github.com/Dreamacro/clash/transport/shadowsocks/core"
-	"github.com/Dreamacro/clash/transport/ssr/tools"
-)
-
-func init() {
-	register("auth_chain_a", newAuthChainA, 4)
-}
-
-type randDataLengthMethod func(int, []byte, *tools.XorShift128Plus) int
-
-type authChainA struct {
-	*Base
-	*authData
-	*userData
-	iv             []byte
-	salt           string
-	hasSentHeader  bool
-	rawTrans       bool
-	lastClientHash []byte
-	lastServerHash []byte
-	encrypter      cipher.Stream
-	decrypter      cipher.Stream
-	randomClient   tools.XorShift128Plus
-	randomServer   tools.XorShift128Plus
-	randDataLength randDataLengthMethod
-	packID         uint32
-	recvID         uint32
-}
-
-func newAuthChainA(b *Base) Protocol {
-	a := &authChainA{
-		Base:     b,
-		authData: &authData{},
-		userData: &userData{},
-		salt:     "auth_chain_a",
-	}
-	a.initUserData()
-	return a
-}
-
-func (a *authChainA) initUserData() {
-	params := strings.Split(a.Param, ":")
-	if len(params) > 1 {
-		if userID, err := strconv.ParseUint(params[0], 10, 32); err == nil {
-			binary.LittleEndian.PutUint32(a.userID[:], uint32(userID))
-			a.userKey = []byte(params[1])
-		}
-	}
-	if len(a.userKey) == 0 {
-		a.userKey = a.Key
-		rand.Read(a.userID[:])
-	}
-}
-
-func (a *authChainA) StreamConn(c net.Conn, iv []byte) net.Conn {
-	p := &authChainA{
-		Base:     a.Base,
-		authData: a.next(),
-		userData: a.userData,
-		salt:     a.salt,
-		packID:   1,
-		recvID:   1,
-	}
-	p.iv = iv
-	p.randDataLength = p.getRandLength
-	return &Conn{Conn: c, Protocol: p}
-}
-
-func (a *authChainA) PacketConn(c net.PacketConn) net.PacketConn {
-	p := &authChainA{
-		Base:     a.Base,
-		salt:     a.salt,
-		userData: a.userData,
-	}
-	return &PacketConn{PacketConn: c, Protocol: p}
-}
-
-func (a *authChainA) Decode(dst, src *bytes.Buffer) error {
-	if a.rawTrans {
-		dst.ReadFrom(src)
-		return nil
-	}
-	for src.Len() > 4 {
-		macKey := pool.Get(len(a.userKey) + 4)
-		defer pool.Put(macKey)
-		copy(macKey, a.userKey)
-		binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.recvID)
-
-		dataLength := int(binary.LittleEndian.Uint16(src.Bytes()[:2]) ^ binary.LittleEndian.Uint16(a.lastServerHash[14:16]))
-		randDataLength := a.randDataLength(dataLength, a.lastServerHash, &a.randomServer)
-		length := dataLength + randDataLength
-
-		if length >= 4096 {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthChainLengthError
-		}
-
-		if 4+length > src.Len() {
-			break
-		}
-
-		serverHash := tools.HmacMD5(macKey, src.Bytes()[:length+2])
-		if !bytes.Equal(serverHash[:2], src.Bytes()[length+2:length+4]) {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthChainChksumError
-		}
-		a.lastServerHash = serverHash
-
-		pos := 2
-		if dataLength > 0 && randDataLength > 0 {
-			pos += getRandStartPos(randDataLength, &a.randomServer)
-		}
-		wantedData := src.Bytes()[pos : pos+dataLength]
-		a.decrypter.XORKeyStream(wantedData, wantedData)
-		if a.recvID == 1 {
-			dst.Write(wantedData[2:])
-		} else {
-			dst.Write(wantedData)
-		}
-		a.recvID++
-		src.Next(length + 4)
-	}
-	return nil
-}
-
-func (a *authChainA) Encode(buf *bytes.Buffer, b []byte) error {
-	if !a.hasSentHeader {
-		dataLength := getDataLength(b)
-		a.packAuthData(buf, b[:dataLength])
-		b = b[dataLength:]
-		a.hasSentHeader = true
-	}
-	for len(b) > 2800 {
-		a.packData(buf, b[:2800])
-		b = b[2800:]
-	}
-	if len(b) > 0 {
-		a.packData(buf, b)
-	}
-	return nil
-}
-
-func (a *authChainA) DecodePacket(b []byte) ([]byte, error) {
-	if len(b) < 9 {
-		return nil, errAuthChainLengthError
-	}
-	if !bytes.Equal(tools.HmacMD5(a.userKey, b[:len(b)-1])[:1], b[len(b)-1:]) {
-		return nil, errAuthChainChksumError
-	}
-	md5Data := tools.HmacMD5(a.Key, b[len(b)-8:len(b)-1])
-
-	randDataLength := udpGetRandLength(md5Data, &a.randomServer)
-
-	key := core.Kdf(base64.StdEncoding.EncodeToString(a.userKey)+base64.StdEncoding.EncodeToString(md5Data), 16)
-	rc4Cipher, err := rc4.NewCipher(key)
-	if err != nil {
-		return nil, err
-	}
-	wantedData := b[:len(b)-8-randDataLength]
-	rc4Cipher.XORKeyStream(wantedData, wantedData)
-	return wantedData, nil
-}
-
-func (a *authChainA) EncodePacket(buf *bytes.Buffer, b []byte) error {
-	authData := pool.Get(3)
-	defer pool.Put(authData)
-	rand.Read(authData)
-
-	md5Data := tools.HmacMD5(a.Key, authData)
-
-	randDataLength := udpGetRandLength(md5Data, &a.randomClient)
-
-	key := core.Kdf(base64.StdEncoding.EncodeToString(a.userKey)+base64.StdEncoding.EncodeToString(md5Data), 16)
-	rc4Cipher, err := rc4.NewCipher(key)
-	if err != nil {
-		return err
-	}
-	rc4Cipher.XORKeyStream(b, b)
-
-	buf.Write(b)
-	tools.AppendRandBytes(buf, randDataLength)
-	buf.Write(authData)
-	binary.Write(buf, binary.LittleEndian, binary.LittleEndian.Uint32(a.userID[:])^binary.LittleEndian.Uint32(md5Data[:4]))
-	buf.Write(tools.HmacMD5(a.userKey, buf.Bytes())[:1])
-	return nil
-}
-
-func (a *authChainA) packAuthData(poolBuf *bytes.Buffer, data []byte) {
-	/*
-		dataLength := len(data)
-		12:	checkHead(4) and hmac of checkHead(8)
-		4:	uint32 LittleEndian uid (uid = userID ^ last client hash)
-		16:	encrypted data of authdata(12), uint16 LittleEndian overhead(2) and uint16 LittleEndian number zero(2)
-		4:	last server hash(4)
-		packedAuthDataLength := 12 + 4 + 16 + 4 + dataLength
-	*/
-
-	macKey := pool.Get(len(a.iv) + len(a.Key))
-	defer pool.Put(macKey)
-	copy(macKey, a.iv)
-	copy(macKey[len(a.iv):], a.Key)
-
-	// check head
-	tools.AppendRandBytes(poolBuf, 4)
-	a.lastClientHash = tools.HmacMD5(macKey, poolBuf.Bytes())
-	a.initRC4Cipher()
-	poolBuf.Write(a.lastClientHash[:8])
-	// uid
-	binary.Write(poolBuf, binary.LittleEndian, binary.LittleEndian.Uint32(a.userID[:])^binary.LittleEndian.Uint32(a.lastClientHash[8:12]))
-	// encrypted data
-	err := a.putEncryptedData(poolBuf, a.userKey, [2]int{a.Overhead, 0}, a.salt)
-	if err != nil {
-		poolBuf.Reset()
-		return
-	}
-	// last server hash
-	a.lastServerHash = tools.HmacMD5(a.userKey, poolBuf.Bytes()[12:])
-	poolBuf.Write(a.lastServerHash[:4])
-	// packed data
-	a.packData(poolBuf, data)
-}
-
-func (a *authChainA) packData(poolBuf *bytes.Buffer, data []byte) {
-	a.encrypter.XORKeyStream(data, data)
-
-	macKey := pool.Get(len(a.userKey) + 4)
-	defer pool.Put(macKey)
-	copy(macKey, a.userKey)
-	binary.LittleEndian.PutUint32(macKey[len(a.userKey):], a.packID)
-	a.packID++
-
-	length := uint16(len(data)) ^ binary.LittleEndian.Uint16(a.lastClientHash[14:16])
-
-	originalLength := poolBuf.Len()
-	binary.Write(poolBuf, binary.LittleEndian, length)
-	a.putMixedRandDataAndData(poolBuf, data)
-	a.lastClientHash = tools.HmacMD5(macKey, poolBuf.Bytes()[originalLength:])
-	poolBuf.Write(a.lastClientHash[:2])
-}
-
-func (a *authChainA) putMixedRandDataAndData(poolBuf *bytes.Buffer, data []byte) {
-	randDataLength := a.randDataLength(len(data), a.lastClientHash, &a.randomClient)
-	if len(data) == 0 {
-		tools.AppendRandBytes(poolBuf, randDataLength)
-		return
-	}
-	if randDataLength > 0 {
-		startPos := getRandStartPos(randDataLength, &a.randomClient)
-		tools.AppendRandBytes(poolBuf, startPos)
-		poolBuf.Write(data)
-		tools.AppendRandBytes(poolBuf, randDataLength-startPos)
-		return
-	}
-	poolBuf.Write(data)
-}
-
-func getRandStartPos(length int, random *tools.XorShift128Plus) int {
-	if length == 0 {
-		return 0
-	}
-	return int(int64(random.Next()%8589934609) % int64(length))
-}
-
-func (a *authChainA) getRandLength(length int, lastHash []byte, random *tools.XorShift128Plus) int {
-	if length > 1440 {
-		return 0
-	}
-	random.InitFromBinAndLength(lastHash, length)
-	if length > 1300 {
-		return int(random.Next() % 31)
-	}
-	if length > 900 {
-		return int(random.Next() % 127)
-	}
-	if length > 400 {
-		return int(random.Next() % 521)
-	}
-	return int(random.Next() % 1021)
-}
-
-func (a *authChainA) initRC4Cipher() {
-	key := core.Kdf(base64.StdEncoding.EncodeToString(a.userKey)+base64.StdEncoding.EncodeToString(a.lastClientHash), 16)
-	a.encrypter, _ = rc4.NewCipher(key)
-	a.decrypter, _ = rc4.NewCipher(key)
-}
-
-func udpGetRandLength(lastHash []byte, random *tools.XorShift128Plus) int {
-	random.InitFromBin(lastHash)
-	return int(random.Next() % 127)
-}

+ 0 - 97
transport/clashssr/protocol/auth_chain_b.go

@@ -1,97 +0,0 @@
-package protocol
-
-import (
-	"net"
-	"sort"
-
-	"github.com/Dreamacro/clash/transport/ssr/tools"
-)
-
-func init() {
-	register("auth_chain_b", newAuthChainB, 4)
-}
-
-type authChainB struct {
-	*authChainA
-	dataSizeList  []int
-	dataSizeList2 []int
-}
-
-func newAuthChainB(b *Base) Protocol {
-	a := &authChainB{
-		authChainA: &authChainA{
-			Base:     b,
-			authData: &authData{},
-			userData: &userData{},
-			salt:     "auth_chain_b",
-		},
-	}
-	a.initUserData()
-	return a
-}
-
-func (a *authChainB) StreamConn(c net.Conn, iv []byte) net.Conn {
-	p := &authChainB{
-		authChainA: &authChainA{
-			Base:     a.Base,
-			authData: a.next(),
-			userData: a.userData,
-			salt:     a.salt,
-			packID:   1,
-			recvID:   1,
-		},
-	}
-	p.iv = iv
-	p.randDataLength = p.getRandLength
-	p.initDataSize()
-	return &Conn{Conn: c, Protocol: p}
-}
-
-func (a *authChainB) initDataSize() {
-	a.dataSizeList = a.dataSizeList[:0]
-	a.dataSizeList2 = a.dataSizeList2[:0]
-
-	a.randomServer.InitFromBin(a.Key)
-	length := a.randomServer.Next()%8 + 4
-	for ; length > 0; length-- {
-		a.dataSizeList = append(a.dataSizeList, int(a.randomServer.Next()%2340%2040%1440))
-	}
-	sort.Ints(a.dataSizeList)
-
-	length = a.randomServer.Next()%16 + 8
-	for ; length > 0; length-- {
-		a.dataSizeList2 = append(a.dataSizeList2, int(a.randomServer.Next()%2340%2040%1440))
-	}
-	sort.Ints(a.dataSizeList2)
-}
-
-func (a *authChainB) getRandLength(length int, lashHash []byte, random *tools.XorShift128Plus) int {
-	if length >= 1440 {
-		return 0
-	}
-	random.InitFromBinAndLength(lashHash, length)
-	pos := sort.Search(len(a.dataSizeList), func(i int) bool { return a.dataSizeList[i] >= length+a.Overhead })
-	finalPos := pos + int(random.Next()%uint64(len(a.dataSizeList)))
-	if finalPos < len(a.dataSizeList) {
-		return a.dataSizeList[finalPos] - length - a.Overhead
-	}
-
-	pos = sort.Search(len(a.dataSizeList2), func(i int) bool { return a.dataSizeList2[i] >= length+a.Overhead })
-	finalPos = pos + int(random.Next()%uint64(len(a.dataSizeList2)))
-	if finalPos < len(a.dataSizeList2) {
-		return a.dataSizeList2[finalPos] - length - a.Overhead
-	}
-	if finalPos < pos+len(a.dataSizeList2)-1 {
-		return 0
-	}
-	if length > 1300 {
-		return int(random.Next() % 31)
-	}
-	if length > 900 {
-		return int(random.Next() % 127)
-	}
-	if length > 400 {
-		return int(random.Next() % 521)
-	}
-	return int(random.Next() % 1021)
-}

+ 0 - 182
transport/clashssr/protocol/auth_sha1_v4.go

@@ -1,182 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"encoding/binary"
-	"hash/adler32"
-	"hash/crc32"
-	"math/rand"
-	"net"
-
-	"github.com/Dreamacro/clash/common/pool"
-	"github.com/Dreamacro/clash/transport/ssr/tools"
-)
-
-func init() {
-	register("auth_sha1_v4", newAuthSHA1V4, 7)
-}
-
-type authSHA1V4 struct {
-	*Base
-	*authData
-	iv            []byte
-	hasSentHeader bool
-	rawTrans      bool
-}
-
-func newAuthSHA1V4(b *Base) Protocol {
-	return &authSHA1V4{Base: b, authData: &authData{}}
-}
-
-func (a *authSHA1V4) StreamConn(c net.Conn, iv []byte) net.Conn {
-	p := &authSHA1V4{Base: a.Base, authData: a.next()}
-	p.iv = iv
-	return &Conn{Conn: c, Protocol: p}
-}
-
-func (a *authSHA1V4) PacketConn(c net.PacketConn) net.PacketConn {
-	return c
-}
-
-func (a *authSHA1V4) Decode(dst, src *bytes.Buffer) error {
-	if a.rawTrans {
-		dst.ReadFrom(src)
-		return nil
-	}
-	for src.Len() > 4 {
-		if uint16(crc32.ChecksumIEEE(src.Bytes()[:2])&0xffff) != binary.LittleEndian.Uint16(src.Bytes()[2:4]) {
-			src.Reset()
-			return errAuthSHA1V4CRC32Error
-		}
-
-		length := int(binary.BigEndian.Uint16(src.Bytes()[:2]))
-		if length >= 8192 || length < 7 {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthSHA1V4LengthError
-		}
-		if length > src.Len() {
-			break
-		}
-
-		if adler32.Checksum(src.Bytes()[:length-4]) != binary.LittleEndian.Uint32(src.Bytes()[length-4:length]) {
-			a.rawTrans = true
-			src.Reset()
-			return errAuthSHA1V4Adler32Error
-		}
-
-		pos := int(src.Bytes()[4])
-		if pos < 255 {
-			pos += 4
-		} else {
-			pos = int(binary.BigEndian.Uint16(src.Bytes()[5:7])) + 4
-		}
-		dst.Write(src.Bytes()[pos : length-4])
-		src.Next(length)
-	}
-	return nil
-}
-
-func (a *authSHA1V4) Encode(buf *bytes.Buffer, b []byte) error {
-	if !a.hasSentHeader {
-		dataLength := getDataLength(b)
-
-		a.packAuthData(buf, b[:dataLength])
-		b = b[dataLength:]
-
-		a.hasSentHeader = true
-	}
-	for len(b) > 8100 {
-		a.packData(buf, b[:8100])
-		b = b[8100:]
-	}
-	if len(b) > 0 {
-		a.packData(buf, b)
-	}
-
-	return nil
-}
-
-func (a *authSHA1V4) DecodePacket(b []byte) ([]byte, error) { return b, nil }
-
-func (a *authSHA1V4) EncodePacket(buf *bytes.Buffer, b []byte) error {
-	buf.Write(b)
-	return nil
-}
-
-func (a *authSHA1V4) packData(poolBuf *bytes.Buffer, data []byte) {
-	dataLength := len(data)
-	randDataLength := a.getRandDataLength(dataLength)
-	/*
-		2:	uint16 BigEndian packedDataLength
-		2:	uint16 LittleEndian crc32Data & 0xffff
-		3:	maxRandDataLengthPrefix (min:1)
-		4:	adler32Data
-	*/
-	packedDataLength := 2 + 2 + 3 + randDataLength + dataLength + 4
-	if randDataLength < 128 {
-		packedDataLength -= 2
-	}
-
-	binary.Write(poolBuf, binary.BigEndian, uint16(packedDataLength))
-	binary.Write(poolBuf, binary.LittleEndian, uint16(crc32.ChecksumIEEE(poolBuf.Bytes()[poolBuf.Len()-2:])&0xffff))
-	a.packRandData(poolBuf, randDataLength)
-	poolBuf.Write(data)
-	binary.Write(poolBuf, binary.LittleEndian, adler32.Checksum(poolBuf.Bytes()[poolBuf.Len()-packedDataLength+4:]))
-}
-
-func (a *authSHA1V4) packAuthData(poolBuf *bytes.Buffer, data []byte) {
-	dataLength := len(data)
-	randDataLength := a.getRandDataLength(12 + dataLength)
-	/*
-		2:	uint16 BigEndian packedAuthDataLength
-		4:	uint32 LittleEndian crc32Data
-		3:	maxRandDataLengthPrefix (min: 1)
-		12:	authDataLength
-		10:	hmacSHA1DataLength
-	*/
-	packedAuthDataLength := 2 + 4 + 3 + randDataLength + 12 + dataLength + 10
-	if randDataLength < 128 {
-		packedAuthDataLength -= 2
-	}
-
-	salt := []byte("auth_sha1_v4")
-	crcData := pool.Get(len(salt) + len(a.Key) + 2)
-	defer pool.Put(crcData)
-	binary.BigEndian.PutUint16(crcData, uint16(packedAuthDataLength))
-	copy(crcData[2:], salt)
-	copy(crcData[2+len(salt):], a.Key)
-
-	key := pool.Get(len(a.iv) + len(a.Key))
-	defer pool.Put(key)
-	copy(key, a.iv)
-	copy(key[len(a.iv):], a.Key)
-
-	poolBuf.Write(crcData[:2])
-	binary.Write(poolBuf, binary.LittleEndian, crc32.ChecksumIEEE(crcData))
-	a.packRandData(poolBuf, randDataLength)
-	a.putAuthData(poolBuf)
-	poolBuf.Write(data)
-	poolBuf.Write(tools.HmacSHA1(key, poolBuf.Bytes()[poolBuf.Len()-packedAuthDataLength+10:])[:10])
-}
-
-func (a *authSHA1V4) packRandData(poolBuf *bytes.Buffer, size int) {
-	if size < 128 {
-		poolBuf.WriteByte(byte(size + 1))
-		tools.AppendRandBytes(poolBuf, size)
-		return
-	}
-	poolBuf.WriteByte(255)
-	binary.Write(poolBuf, binary.BigEndian, uint16(size+3))
-	tools.AppendRandBytes(poolBuf, size)
-}
-
-func (a *authSHA1V4) getRandDataLength(size int) int {
-	if size > 1200 {
-		return 0
-	}
-	if size > 400 {
-		return rand.Intn(256)
-	}
-	return rand.Intn(512)
-}

+ 0 - 75
transport/clashssr/protocol/base.go

@@ -1,75 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"crypto/aes"
-	"crypto/cipher"
-	"encoding/base64"
-	"encoding/binary"
-	"math/rand"
-	"sync"
-	"time"
-
-	"github.com/Dreamacro/clash/common/pool"
-	"github.com/Dreamacro/clash/transport/shadowsocks/core"
-)
-
-type Base struct {
-	Key      []byte
-	Overhead int
-	Param    string
-}
-
-type userData struct {
-	userKey []byte
-	userID  [4]byte
-}
-
-type authData struct {
-	clientID     [4]byte
-	connectionID uint32
-	mutex        sync.Mutex
-}
-
-func (a *authData) next() *authData {
-	r := &authData{}
-	a.mutex.Lock()
-	defer a.mutex.Unlock()
-	if a.connectionID > 0xff000000 || a.connectionID == 0 {
-		rand.Read(a.clientID[:])
-		a.connectionID = rand.Uint32() & 0xffffff
-	}
-	a.connectionID++
-	copy(r.clientID[:], a.clientID[:])
-	r.connectionID = a.connectionID
-	return r
-}
-
-func (a *authData) putAuthData(buf *bytes.Buffer) {
-	binary.Write(buf, binary.LittleEndian, uint32(time.Now().Unix()))
-	buf.Write(a.clientID[:])
-	binary.Write(buf, binary.LittleEndian, a.connectionID)
-}
-
-func (a *authData) putEncryptedData(b *bytes.Buffer, userKey []byte, paddings [2]int, salt string) error {
-	encrypt := pool.Get(16)
-	defer pool.Put(encrypt)
-	binary.LittleEndian.PutUint32(encrypt, uint32(time.Now().Unix()))
-	copy(encrypt[4:], a.clientID[:])
-	binary.LittleEndian.PutUint32(encrypt[8:], a.connectionID)
-	binary.LittleEndian.PutUint16(encrypt[12:], uint16(paddings[0]))
-	binary.LittleEndian.PutUint16(encrypt[14:], uint16(paddings[1]))
-
-	cipherKey := core.Kdf(base64.StdEncoding.EncodeToString(userKey)+salt, 16)
-	block, err := aes.NewCipher(cipherKey)
-	if err != nil {
-		return err
-	}
-	iv := bytes.Repeat([]byte{0}, 16)
-	cbcCipher := cipher.NewCBCEncrypter(block, iv)
-
-	cbcCipher.CryptBlocks(encrypt, encrypt)
-
-	b.Write(encrypt)
-	return nil
-}

+ 0 - 33
transport/clashssr/protocol/origin.go

@@ -1,33 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"net"
-)
-
-type origin struct{}
-
-func init() { register("origin", newOrigin, 0) }
-
-func newOrigin(b *Base) Protocol { return &origin{} }
-
-func (o *origin) StreamConn(c net.Conn, iv []byte) net.Conn { return c }
-
-func (o *origin) PacketConn(c net.PacketConn) net.PacketConn { return c }
-
-func (o *origin) Decode(dst, src *bytes.Buffer) error {
-	dst.ReadFrom(src)
-	return nil
-}
-
-func (o *origin) Encode(buf *bytes.Buffer, b []byte) error {
-	buf.Write(b)
-	return nil
-}
-
-func (o *origin) DecodePacket(b []byte) ([]byte, error) { return b, nil }
-
-func (o *origin) EncodePacket(buf *bytes.Buffer, b []byte) error {
-	buf.Write(b)
-	return nil
-}

+ 0 - 36
transport/clashssr/protocol/packet.go

@@ -1,36 +0,0 @@
-package protocol
-
-import (
-	"net"
-
-	"github.com/Dreamacro/clash/common/pool"
-)
-
-type PacketConn struct {
-	net.PacketConn
-	Protocol
-}
-
-func (c *PacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
-	buf := pool.GetBuffer()
-	defer pool.PutBuffer(buf)
-	err := c.EncodePacket(buf, b)
-	if err != nil {
-		return 0, err
-	}
-	_, err = c.PacketConn.WriteTo(buf.Bytes(), addr)
-	return len(b), err
-}
-
-func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
-	n, addr, err := c.PacketConn.ReadFrom(b)
-	if err != nil {
-		return n, addr, err
-	}
-	decoded, err := c.DecodePacket(b[:n])
-	if err != nil {
-		return n, addr, err
-	}
-	copy(b, decoded)
-	return len(decoded), addr, nil
-}

+ 0 - 76
transport/clashssr/protocol/protocol.go

@@ -1,76 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"math/rand"
-	"net"
-)
-
-var (
-	errAuthSHA1V4CRC32Error   = errors.New("auth_sha1_v4 decode data wrong crc32")
-	errAuthSHA1V4LengthError  = errors.New("auth_sha1_v4 decode data wrong length")
-	errAuthSHA1V4Adler32Error = errors.New("auth_sha1_v4 decode data wrong adler32")
-	errAuthAES128MACError     = errors.New("auth_aes128 decode data wrong mac")
-	errAuthAES128LengthError  = errors.New("auth_aes128 decode data wrong length")
-	errAuthAES128ChksumError  = errors.New("auth_aes128 decode data wrong checksum")
-	errAuthChainLengthError   = errors.New("auth_chain decode data wrong length")
-	errAuthChainChksumError   = errors.New("auth_chain decode data wrong checksum")
-)
-
-type Protocol interface {
-	StreamConn(net.Conn, []byte) net.Conn
-	PacketConn(net.PacketConn) net.PacketConn
-	Decode(dst, src *bytes.Buffer) error
-	Encode(buf *bytes.Buffer, b []byte) error
-	DecodePacket([]byte) ([]byte, error)
-	EncodePacket(buf *bytes.Buffer, b []byte) error
-}
-
-type protocolCreator func(b *Base) Protocol
-
-var protocolList = make(map[string]struct {
-	overhead int
-	new      protocolCreator
-})
-
-func register(name string, c protocolCreator, o int) {
-	protocolList[name] = struct {
-		overhead int
-		new      protocolCreator
-	}{overhead: o, new: c}
-}
-
-func PickProtocol(name string, b *Base) (Protocol, error) {
-	if choice, ok := protocolList[name]; ok {
-		b.Overhead += choice.overhead
-		return choice.new(b), nil
-	}
-	return nil, fmt.Errorf("protocol %s not supported", name)
-}
-
-func getHeadSize(b []byte, defaultValue int) int {
-	if len(b) < 2 {
-		return defaultValue
-	}
-	headType := b[0] & 7
-	switch headType {
-	case 1:
-		return 7
-	case 4:
-		return 19
-	case 3:
-		return 4 + int(b[1])
-	}
-	return defaultValue
-}
-
-func getDataLength(b []byte) int {
-	bLength := len(b)
-	dataLength := getHeadSize(b, 30) + rand.Intn(32)
-	if bLength < dataLength {
-		return bLength
-	}
-	return dataLength
-}

+ 0 - 50
transport/clashssr/protocol/stream.go

@@ -1,50 +0,0 @@
-package protocol
-
-import (
-	"bytes"
-	"net"
-
-	"github.com/Dreamacro/clash/common/pool"
-)
-
-type Conn struct {
-	net.Conn
-	Protocol
-	decoded      bytes.Buffer
-	underDecoded bytes.Buffer
-}
-
-func (c *Conn) Read(b []byte) (int, error) {
-	if c.decoded.Len() > 0 {
-		return c.decoded.Read(b)
-	}
-
-	buf := pool.Get(pool.RelayBufferSize)
-	defer pool.Put(buf)
-	n, err := c.Conn.Read(buf)
-	if err != nil {
-		return 0, err
-	}
-	c.underDecoded.Write(buf[:n])
-	err = c.Decode(&c.decoded, &c.underDecoded)
-	if err != nil {
-		return 0, err
-	}
-	n, _ = c.decoded.Read(b)
-	return n, nil
-}
-
-func (c *Conn) Write(b []byte) (int, error) {
-	bLength := len(b)
-	buf := pool.GetBuffer()
-	defer pool.PutBuffer(buf)
-	err := c.Encode(buf, b)
-	if err != nil {
-		return 0, err
-	}
-	_, err = c.Conn.Write(buf.Bytes())
-	if err != nil {
-		return 0, err
-	}
-	return bLength, nil
-}