mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2025-05-12 21:18:03 +08:00
chore: add inbound test for shadowsocks/trojan
This commit is contained in:
parent
b5fcd1d1d1
commit
3d806b5e4c
@ -24,6 +24,9 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var httpPath = "/inbound_test"
|
||||||
|
var httpData = make([]byte, 10240)
|
||||||
|
var remoteAddr = netip.MustParseAddr("1.2.3.4")
|
||||||
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = N.NewRandomTLSKeyPair()
|
var tlsCertificate, tlsPrivateKey, tlsFingerprint, _ = N.NewRandomTLSKeyPair()
|
||||||
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
var tlsConfigCert, _ = tls.X509KeyPair([]byte(tlsCertificate), []byte(tlsPrivateKey))
|
||||||
var tlsConfig = &tls.Config{Certificates: []tls.Certificate{tlsConfigCert}, NextProtos: []string{"h2", "http/1.1"}}
|
var tlsConfig = &tls.Config{Certificates: []tls.Certificate{tlsConfigCert}, NextProtos: []string{"h2", "http/1.1"}}
|
||||||
@ -33,6 +36,7 @@ var realityDest = "itunes.apple.com"
|
|||||||
var realityShortid = "10f897e26c4b9478"
|
var realityShortid = "10f897e26c4b9478"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
rand.Read(httpData)
|
||||||
privateKey, err := generater.GeneratePrivateKey()
|
privateKey, err := generater.GeneratePrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -115,30 +119,17 @@ func (c *WaitCloseConn) Close() error {
|
|||||||
var _ C.Tunnel = (*TestTunnel)(nil)
|
var _ C.Tunnel = (*TestTunnel)(nil)
|
||||||
var _ net.Listener = (*TestTunnelListener)(nil)
|
var _ net.Listener = (*TestTunnelListener)(nil)
|
||||||
|
|
||||||
type HttpTestConfig struct {
|
|
||||||
RemoteAddr netip.Addr
|
|
||||||
HttpPath string
|
|
||||||
HttpData []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHttpTestTunnel() *TestTunnel {
|
func NewHttpTestTunnel() *TestTunnel {
|
||||||
httpData := make([]byte, 10240)
|
|
||||||
rand.Read(httpData)
|
|
||||||
config := &HttpTestConfig{
|
|
||||||
HttpPath: "/inbound_test",
|
|
||||||
HttpData: httpData,
|
|
||||||
RemoteAddr: netip.MustParseAddr("1.2.3.4"),
|
|
||||||
}
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
ln := &TestTunnelListener{ch: make(chan net.Conn), ctx: ctx, cancel: cancel, addr: net.TCPAddrFromAddrPort(netip.AddrPortFrom(config.RemoteAddr, 0))}
|
ln := &TestTunnelListener{ch: make(chan net.Conn), ctx: ctx, cancel: cancel, addr: net.TCPAddrFromAddrPort(netip.AddrPortFrom(remoteAddr, 0))}
|
||||||
|
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Get(config.HttpPath, func(w http.ResponseWriter, r *http.Request) {
|
r.Get(httpPath, func(w http.ResponseWriter, r *http.Request) {
|
||||||
render.Data(w, r, config.HttpData)
|
render.Data(w, r, httpData)
|
||||||
})
|
})
|
||||||
go http.Serve(ln, r)
|
go http.Serve(ln, r)
|
||||||
testFn := func(t *testing.T, proxy C.ProxyAdapter, proto string) {
|
testFn := func(t *testing.T, proxy C.ProxyAdapter, proto string) {
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s://%s%s", proto, config.RemoteAddr, config.HttpPath), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s://%s%s", proto, remoteAddr, httpPath), nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
@ -148,7 +139,7 @@ func NewHttpTestTunnel() *TestTunnel {
|
|||||||
}
|
}
|
||||||
metadata := &C.Metadata{
|
metadata := &C.Metadata{
|
||||||
NetWork: C.TCP,
|
NetWork: C.TCP,
|
||||||
DstIP: config.RemoteAddr,
|
DstIP: remoteAddr,
|
||||||
DstPort: dstPort,
|
DstPort: dstPort,
|
||||||
}
|
}
|
||||||
instance, err := proxy.DialContext(ctx, metadata)
|
instance, err := proxy.DialContext(ctx, metadata)
|
||||||
@ -165,7 +156,7 @@ func NewHttpTestTunnel() *TestTunnel {
|
|||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
// for our self-signed cert
|
// for our self-signed cert
|
||||||
TLSClientConfig: tlsClientConfig,
|
TLSClientConfig: tlsClientConfig.Clone(),
|
||||||
// open http2
|
// open http2
|
||||||
ForceAttemptHTTP2: true,
|
ForceAttemptHTTP2: true,
|
||||||
}
|
}
|
||||||
@ -189,12 +180,12 @@ func NewHttpTestTunnel() *TestTunnel {
|
|||||||
|
|
||||||
data, err := io.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, config.HttpData, data)
|
assert.Equal(t, httpData, data)
|
||||||
}
|
}
|
||||||
tunnel := &TestTunnel{
|
tunnel := &TestTunnel{
|
||||||
HandleTCPConnFn: func(conn net.Conn, metadata *C.Metadata) {
|
HandleTCPConnFn: func(conn net.Conn, metadata *C.Metadata) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
if metadata.DstIP != config.RemoteAddr && metadata.Host != realityDest {
|
if metadata.DstIP != remoteAddr && metadata.Host != realityDest {
|
||||||
return // not match, just return
|
return // not match, just return
|
||||||
}
|
}
|
||||||
c := &WaitCloseConn{
|
c := &WaitCloseConn{
|
||||||
@ -202,7 +193,7 @@ func NewHttpTestTunnel() *TestTunnel {
|
|||||||
ch: make(chan struct{}),
|
ch: make(chan struct{}),
|
||||||
}
|
}
|
||||||
if metadata.DstPort == 443 {
|
if metadata.DstPort == 443 {
|
||||||
tlsConn := tls.Server(c, tlsConfig)
|
tlsConn := tls.Server(c, tlsConfig.Clone())
|
||||||
if metadata.Host == realityDest { // ignore the tls handshake error for realityDest
|
if metadata.Host == realityDest { // ignore the tls handshake error for realityDest
|
||||||
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
85
listener/inbound/shadowsocks_test.go
Normal file
85
listener/inbound/shadowsocks_test.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package inbound_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"net/netip"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/adapter/outbound"
|
||||||
|
"github.com/metacubex/mihomo/listener/inbound"
|
||||||
|
|
||||||
|
shadowsocks "github.com/metacubex/sing-shadowsocks"
|
||||||
|
"github.com/metacubex/sing-shadowsocks/shadowaead"
|
||||||
|
"github.com/metacubex/sing-shadowsocks/shadowaead_2022"
|
||||||
|
"github.com/metacubex/sing-shadowsocks/shadowstream"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var shadowsocksCipherList = []string{shadowsocks.MethodNone}
|
||||||
|
var shadowsocksPassword32 string
|
||||||
|
var shadowsocksPassword16 string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
shadowsocksCipherList = append(shadowsocksCipherList, shadowaead.List...)
|
||||||
|
shadowsocksCipherList = append(shadowsocksCipherList, shadowaead_2022.List...)
|
||||||
|
shadowsocksCipherList = append(shadowsocksCipherList, shadowstream.List...)
|
||||||
|
passwordBytes := make([]byte, 32)
|
||||||
|
rand.Read(passwordBytes)
|
||||||
|
shadowsocksPassword32 = base64.StdEncoding.EncodeToString(passwordBytes)
|
||||||
|
shadowsocksPassword16 = base64.StdEncoding.EncodeToString(passwordBytes[:16])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInboundShadowSocks(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption) {
|
||||||
|
for _, cipher := range shadowsocksCipherList {
|
||||||
|
t.Run(cipher, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
inboundOptions.Cipher = cipher
|
||||||
|
outboundOptions.Cipher = cipher
|
||||||
|
testInboundShadowSocks0(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOption, outboundOptions outbound.ShadowSocksOption) {
|
||||||
|
password := shadowsocksPassword32
|
||||||
|
if strings.Contains(inboundOptions.Cipher, "-128-") {
|
||||||
|
password = shadowsocksPassword16
|
||||||
|
}
|
||||||
|
inboundOptions.BaseOption = inbound.BaseOption{
|
||||||
|
NameStr: "shadowsocks_inbound",
|
||||||
|
Listen: "127.0.0.1",
|
||||||
|
Port: "0",
|
||||||
|
}
|
||||||
|
inboundOptions.Password = password
|
||||||
|
in, err := inbound.NewShadowSocks(&inboundOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
tunnel := NewHttpTestTunnel()
|
||||||
|
defer tunnel.Close()
|
||||||
|
|
||||||
|
err = in.Listen(tunnel)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
addrPort, err := netip.ParseAddrPort(in.Address())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
outboundOptions.Name = "shadowsocks_outbound"
|
||||||
|
outboundOptions.Server = addrPort.Addr().String()
|
||||||
|
outboundOptions.Port = int(addrPort.Port())
|
||||||
|
outboundOptions.Password = password
|
||||||
|
|
||||||
|
out, err := outbound.NewShadowSocks(outboundOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
tunnel.DoTest(t, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundShadowSocks_Basic(t *testing.T) {
|
||||||
|
inboundOptions := inbound.ShadowSocksOption{}
|
||||||
|
outboundOptions := outbound.ShadowSocksOption{}
|
||||||
|
testInboundShadowSocks(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
210
listener/inbound/trojan_test.go
Normal file
210
listener/inbound/trojan_test.go
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
package inbound_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/adapter/outbound"
|
||||||
|
"github.com/metacubex/mihomo/common/utils"
|
||||||
|
"github.com/metacubex/mihomo/listener/inbound"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testInboundTrojan(t *testing.T, inboundOptions inbound.TrojanOption, outboundOptions outbound.TrojanOption) {
|
||||||
|
userUUID := utils.NewUUIDV4().String()
|
||||||
|
inboundOptions.BaseOption = inbound.BaseOption{
|
||||||
|
NameStr: "trojan_inbound",
|
||||||
|
Listen: "127.0.0.1",
|
||||||
|
Port: "0",
|
||||||
|
}
|
||||||
|
inboundOptions.Users = []inbound.TrojanUser{
|
||||||
|
{Username: "test", Password: userUUID},
|
||||||
|
}
|
||||||
|
in, err := inbound.NewTrojan(&inboundOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
tunnel := NewHttpTestTunnel()
|
||||||
|
defer tunnel.Close()
|
||||||
|
|
||||||
|
err = in.Listen(tunnel)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
addrPort, err := netip.ParseAddrPort(in.Address())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
outboundOptions.Name = "trojan_outbound"
|
||||||
|
outboundOptions.Server = addrPort.Addr().String()
|
||||||
|
outboundOptions.Port = int(addrPort.Port())
|
||||||
|
outboundOptions.Password = userUUID
|
||||||
|
|
||||||
|
out, err := outbound.NewTrojan(outboundOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
tunnel.DoTest(t, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Tls(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Wss1(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
WsPath: "/ws",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
Network: "ws",
|
||||||
|
WSOpts: outbound.WSOptions{
|
||||||
|
Path: "/ws",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Wss2(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
WsPath: "/ws",
|
||||||
|
GrpcServiceName: "GunService",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
Network: "ws",
|
||||||
|
WSOpts: outbound.WSOptions{
|
||||||
|
Path: "/ws",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Grpc1(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
GrpcServiceName: "GunService",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
Network: "grpc",
|
||||||
|
GrpcOpts: outbound.GrpcOptions{GrpcServiceName: "GunService"},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Grpc2(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
WsPath: "/ws",
|
||||||
|
GrpcServiceName: "GunService",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
Network: "grpc",
|
||||||
|
GrpcOpts: outbound.GrpcOptions{GrpcServiceName: "GunService"},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Reality(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
RealityConfig: inbound.RealityConfig{
|
||||||
|
Dest: net.JoinHostPort(realityDest, "443"),
|
||||||
|
PrivateKey: realityPrivateKey,
|
||||||
|
ShortID: []string{realityShortid},
|
||||||
|
ServerNames: []string{realityDest},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
SNI: realityDest,
|
||||||
|
RealityOpts: outbound.RealityOptions{
|
||||||
|
PublicKey: realityPublickey,
|
||||||
|
ShortID: realityShortid,
|
||||||
|
},
|
||||||
|
ClientFingerprint: "chrome",
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Reality_Grpc(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
RealityConfig: inbound.RealityConfig{
|
||||||
|
Dest: net.JoinHostPort(realityDest, "443"),
|
||||||
|
PrivateKey: realityPrivateKey,
|
||||||
|
ShortID: []string{realityShortid},
|
||||||
|
ServerNames: []string{realityDest},
|
||||||
|
},
|
||||||
|
GrpcServiceName: "GunService",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
SNI: realityDest,
|
||||||
|
RealityOpts: outbound.RealityOptions{
|
||||||
|
PublicKey: realityPublickey,
|
||||||
|
ShortID: realityShortid,
|
||||||
|
},
|
||||||
|
ClientFingerprint: "chrome",
|
||||||
|
Network: "grpc",
|
||||||
|
GrpcOpts: outbound.GrpcOptions{GrpcServiceName: "GunService"},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Tls_TrojanSS(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
SSOption: inbound.TrojanSSOption{
|
||||||
|
Enabled: true,
|
||||||
|
Method: "",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
SSOpts: outbound.TrojanSSOption{
|
||||||
|
Enabled: true,
|
||||||
|
Method: "",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInboundTrojan_Wss_TrojanSS(t *testing.T) {
|
||||||
|
inboundOptions := inbound.TrojanOption{
|
||||||
|
Certificate: tlsCertificate,
|
||||||
|
PrivateKey: tlsPrivateKey,
|
||||||
|
SSOption: inbound.TrojanSSOption{
|
||||||
|
Enabled: true,
|
||||||
|
Method: "",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
WsPath: "/ws",
|
||||||
|
}
|
||||||
|
outboundOptions := outbound.TrojanOption{
|
||||||
|
Fingerprint: tlsFingerprint,
|
||||||
|
SSOpts: outbound.TrojanSSOption{
|
||||||
|
Enabled: true,
|
||||||
|
Method: "",
|
||||||
|
Password: "password",
|
||||||
|
},
|
||||||
|
Network: "ws",
|
||||||
|
WSOpts: outbound.WSOptions{
|
||||||
|
Path: "/ws",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
testInboundTrojan(t, inboundOptions, outboundOptions)
|
||||||
|
}
|
@ -56,8 +56,10 @@ func TestInboundVless_Tls(t *testing.T) {
|
|||||||
Fingerprint: tlsFingerprint,
|
Fingerprint: tlsFingerprint,
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
outboundOptions.Flow = "xtls-rprx-vision"
|
t.Run("xtls-rprx-vision", func(t *testing.T) {
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
outboundOptions.Flow = "xtls-rprx-vision"
|
||||||
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundVless_Wss1(t *testing.T) {
|
func TestInboundVless_Wss1(t *testing.T) {
|
||||||
@ -73,11 +75,12 @@ func TestInboundVless_Wss1(t *testing.T) {
|
|||||||
WSOpts: outbound.WSOptions{
|
WSOpts: outbound.WSOptions{
|
||||||
Path: "/ws",
|
Path: "/ws",
|
||||||
},
|
},
|
||||||
ClientFingerprint: "chrome",
|
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
outboundOptions.Flow = "xtls-rprx-vision"
|
t.Run("xtls-rprx-vision", func(t *testing.T) {
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
outboundOptions.Flow = "xtls-rprx-vision"
|
||||||
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundVless_Wss2(t *testing.T) {
|
func TestInboundVless_Wss2(t *testing.T) {
|
||||||
@ -96,8 +99,10 @@ func TestInboundVless_Wss2(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
outboundOptions.Flow = "xtls-rprx-vision"
|
t.Run("xtls-rprx-vision", func(t *testing.T) {
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
outboundOptions.Flow = "xtls-rprx-vision"
|
||||||
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundVless_Grpc1(t *testing.T) {
|
func TestInboundVless_Grpc1(t *testing.T) {
|
||||||
@ -150,8 +155,10 @@ func TestInboundVless_Reality(t *testing.T) {
|
|||||||
ClientFingerprint: "chrome",
|
ClientFingerprint: "chrome",
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
outboundOptions.Flow = "xtls-rprx-vision"
|
t.Run("xtls-rprx-vision", func(t *testing.T) {
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
outboundOptions.Flow = "xtls-rprx-vision"
|
||||||
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInboundVless_Reality_Grpc(t *testing.T) {
|
func TestInboundVless_Reality_Grpc(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user