Add ws compatibility test

This commit is contained in:
世界 2022-09-01 20:04:04 +08:00
parent ef801cbfbe
commit 4a0df713aa
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
17 changed files with 305 additions and 115 deletions

View file

@ -0,0 +1,52 @@
{
"log": {
"loglevel": "debug"
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": "1080",
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true,
"ip": "127.0.0.1"
}
}
],
"outbounds": [
{
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "127.0.0.1",
"port": 1234,
"users": [
{
"id": ""
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.org",
"certificates": [
{
"certificateFile": "/path/to/certificate.crt",
"keyFile": "/path/to/private.key"
}
]
},
"wsSettings": {
"maxEarlyData": 2048,
"earlyDataHeaderName": ""
}
}
}
]
}

View file

@ -0,0 +1,41 @@
{
"log": {
"loglevel": "debug"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": 1234,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "b831381d-6324-4d53-ad4f-8cda48b30811"
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.org",
"certificates": [
{
"certificateFile": "/path/to/certificate.crt",
"keyFile": "/path/to/private.key"
}
]
},
"wsSettings": {
"maxEarlyData": 2048,
"earlyDataHeaderName": ""
}
}
}
],
"outbounds": [
{
"protocol": "freedom"
}
]
}

View file

@ -10,9 +10,6 @@ import (
func TestProxyProtocol(t *testing.T) { func TestProxyProtocol(t *testing.T) {
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -62,22 +62,22 @@ require (
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 // indirect github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 // indirect
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 // indirect github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 // indirect
github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c // indirect github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c // indirect
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect github.com/sirupsen/logrus v1.8.1 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.6.0 // indirect go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.22.0 // indirect go.uber.org/zap v1.22.0 // indirect
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // indirect golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f // indirect golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 // indirect golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b // indirect
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect
google.golang.org/grpc v1.49.0 // indirect google.golang.org/grpc v1.49.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect

View file

@ -165,8 +165,8 @@ github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 h1:SoWiHYuOCVedq
github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83/go.mod h1:76r07HS1WRcEI4mE9pFsohfTBUt1j/G9Avz6DaOP3VU= github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83/go.mod h1:76r07HS1WRcEI4mE9pFsohfTBUt1j/G9Avz6DaOP3VU=
github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c h1:92Gn78/z/t6CkzZ4XWG/uPiCxhUmjPULFEHFMDY6K8k= github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c h1:92Gn78/z/t6CkzZ4XWG/uPiCxhUmjPULFEHFMDY6K8k=
github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps= github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
@ -205,8 +205,8 @@ golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaE
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
@ -275,8 +275,8 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -311,8 +311,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 h1:vDy//hdR+GnROE3OdYbQKt9rdtNdHkDtONvpRwmls/0= golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b h1:qgrKnOfe1zyURRNdmDlGbN32i38Zjmw0B1+TMdHcOvg=
golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U= golang.zx2c4.com/wireguard v0.0.0-20220829161405-d1d08426b27b/go.mod h1:6y4CqPAy54NwiN4nC8K+R1eMpQDB1P2d25qmunh2RSA=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

View file

@ -14,9 +14,6 @@ func TestHysteriaSelf(t *testing.T) {
} }
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -92,9 +89,6 @@ func TestHysteriaInbound(t *testing.T) {
} }
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeHysteria, Type: C.TypeHysteria,
@ -145,9 +139,6 @@ func TestHysteriaOutbound(t *testing.T) {
}, },
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -13,9 +13,6 @@ func TestChainedInbound(t *testing.T) {
method := shadowaead_2022.List[0] method := shadowaead_2022.List[0]
password := mkBase64(t, 16) password := mkBase64(t, 16)
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -37,9 +37,6 @@ func testShadowsocksMux(t *testing.T, protocol string) {
method := shadowaead_2022.List[0] method := shadowaead_2022.List[0]
password := mkBase64(t, 16) password := mkBase64(t, 16)
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -101,9 +98,6 @@ func testShadowsocksMux(t *testing.T, protocol string) {
func testVMessMux(t *testing.T, protocol string) { func testVMessMux(t *testing.T, protocol string) {
user, _ := uuid.NewV4() user, _ := uuid.NewV4()
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -13,9 +13,6 @@ import (
func TestNaiveInboundWithNginx(t *testing.T) { func TestNaiveInboundWithNginx(t *testing.T) {
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeNaive, Type: C.TypeNaive,
@ -62,9 +59,6 @@ func TestNaiveInboundWithNginx(t *testing.T) {
func TestNaiveInbound(t *testing.T) { func TestNaiveInbound(t *testing.T) {
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeNaive, Type: C.TypeNaive,
@ -110,9 +104,6 @@ func TestNaiveHTTP3Inbound(t *testing.T) {
} }
caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeNaive, Type: C.TypeNaive,

View file

@ -77,9 +77,6 @@ func testShadowsocksInboundWithShadowsocksRust(t *testing.T, method string, pass
Cmd: []string{"-s", F.ToString("127.0.0.1:", serverPort), "-b", F.ToString("0.0.0.0:", clientPort), "-m", method, "-k", password, "-U"}, Cmd: []string{"-s", F.ToString("127.0.0.1:", serverPort), "-b", F.ToString("0.0.0.0:", clientPort), "-m", method, "-k", password, "-U"},
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeShadowsocks, Type: C.TypeShadowsocks,
@ -105,9 +102,6 @@ func testShadowsocksOutboundWithShadowsocksRust(t *testing.T, method string, pas
Cmd: []string{"-s", F.ToString("0.0.0.0:", serverPort), "-m", method, "-k", password, "-U"}, Cmd: []string{"-s", F.ToString("0.0.0.0:", serverPort), "-m", method, "-k", password, "-U"},
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -138,9 +132,6 @@ func testShadowsocksOutboundWithShadowsocksRust(t *testing.T, method string, pas
func testShadowsocksSelf(t *testing.T, method string, password string) { func testShadowsocksSelf(t *testing.T, method string, password string) {
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -199,9 +190,6 @@ func TestShadowsocksUoT(t *testing.T) {
method := shadowaead_2022.List[0] method := shadowaead_2022.List[0]
password := mkBase64(t, 16) password := mkBase64(t, 16)
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -20,9 +20,6 @@ func TestTrojanOutbound(t *testing.T) {
}, },
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -58,9 +55,6 @@ func TestTrojanOutbound(t *testing.T) {
func TestTrojanSelf(t *testing.T) { func TestTrojanSelf(t *testing.T) {
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -27,9 +27,6 @@ func testV2RayGRPCInbound(t *testing.T, forceLite bool) {
require.NoError(t, err) require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeVMess, Type: C.TypeVMess,
@ -125,9 +122,6 @@ func testV2RayGRPCOutbound(t *testing.T, forceLite bool) {
}, },
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -11,31 +11,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestV2RayWebscoketSelf(t *testing.T) {
t.Run("basic", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
})
})
t.Run("v2ray early data", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: 2048,
},
})
})
t.Run("xray early data", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: 2048,
EarlyDataHeaderName: "Sec-WebSocket-Protocol",
},
})
})
}
func TestV2RayHTTPSelf(t *testing.T) { func TestV2RayHTTPSelf(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{ testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeHTTP, Type: C.V2RayTransportTypeHTTP,
@ -69,9 +44,6 @@ func testVMessTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
require.NoError(t, err) require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -148,9 +120,6 @@ func testTrojanTransportSelf(t *testing.T, server *option.V2RayTransportOptions,
require.NoError(t, err) require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -229,9 +198,6 @@ func TestVMessQUICSelf(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org") _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -307,9 +273,6 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO
user, err := uuid.DefaultGenerator.NewV4() user, err := uuid.DefaultGenerator.NewV4()
require.NoError(t, err) require.NoError(t, err)
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

197
test/v2ray_ws_test.go Normal file
View file

@ -0,0 +1,197 @@
package main
import (
"net/netip"
"os"
"testing"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/gofrs/uuid"
"github.com/spyzhov/ajson"
"github.com/stretchr/testify/require"
)
func TestV2RayWebsocket(t *testing.T) {
t.Run("self", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
})
})
t.Run("self-early-data", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: 2048,
},
})
})
t.Run("self-xray-early-data", func(t *testing.T) {
testV2RayTransportSelf(t, &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: 2048,
EarlyDataHeaderName: "Sec-WebSocket-Protocol",
},
})
})
t.Run("inbound", func(t *testing.T) {
testV2RayWebsocketInbound(t, 0, "")
})
t.Run("inbound-early-data", func(t *testing.T) {
testV2RayWebsocketInbound(t, 2048, "")
})
t.Run("inbound-xray-early-data", func(t *testing.T) {
testV2RayWebsocketInbound(t, 2048, "Sec-WebSocket-Protocol")
})
t.Run("outbound", func(t *testing.T) {
testV2RayWebsocketOutbound(t, 0, "")
})
t.Run("outbound-early-data", func(t *testing.T) {
testV2RayWebsocketOutbound(t, 2048, "")
})
t.Run("outbound-xray-early-data", func(t *testing.T) {
testV2RayWebsocketOutbound(t, 2048, "Sec-WebSocket-Protocol")
})
}
func testV2RayWebsocketInbound(t *testing.T, maxEarlyData uint32, earlyDataHeaderName string) {
userId, err := uuid.DefaultGenerator.NewV4()
require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeVMess,
VMessOptions: option.VMessInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.ListenAddress(netip.IPv4Unspecified()),
ListenPort: serverPort,
},
Users: []option.VMessUser{
{
Name: "sekai",
UUID: userId.String(),
},
},
TLS: &option.InboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
KeyPath: keyPem,
},
Transport: &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: maxEarlyData,
EarlyDataHeaderName: earlyDataHeaderName,
},
},
},
},
},
})
content, err := os.ReadFile("config/vmess-ws-client.json")
require.NoError(t, err)
config, err := ajson.Unmarshal(content)
require.NoError(t, err)
config.MustKey("inbounds").MustIndex(0).MustKey("port").SetNumeric(float64(clientPort))
outbound := config.MustKey("outbounds").MustIndex(0)
settings := outbound.MustKey("settings").MustKey("vnext").MustIndex(0)
settings.MustKey("port").SetNumeric(float64(serverPort))
user := settings.MustKey("users").MustIndex(0)
user.MustKey("id").SetString(userId.String())
wsSettings := outbound.MustKey("streamSettings").MustKey("wsSettings")
wsSettings.MustKey("maxEarlyData").SetNumeric(float64(maxEarlyData))
wsSettings.MustKey("earlyDataHeaderName").SetString(earlyDataHeaderName)
content, err = ajson.Marshal(config)
require.NoError(t, err)
startDockerContainer(t, DockerOptions{
Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray",
Stdin: content,
Bind: map[string]string{
certPem: "/path/to/certificate.crt",
keyPem: "/path/to/private.key",
},
})
testSuitSimple(t, clientPort, testPort)
}
func testV2RayWebsocketOutbound(t *testing.T, maxEarlyData uint32, earlyDataHeaderName string) {
userId, err := uuid.DefaultGenerator.NewV4()
require.NoError(t, err)
_, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
content, err := os.ReadFile("config/vmess-ws-server.json")
require.NoError(t, err)
config, err := ajson.Unmarshal(content)
require.NoError(t, err)
inbound := config.MustKey("inbounds").MustIndex(0)
inbound.MustKey("port").SetNumeric(float64(serverPort))
inbound.MustKey("settings").MustKey("clients").MustIndex(0).MustKey("id").SetString(userId.String())
wsSettings := inbound.MustKey("streamSettings").MustKey("wsSettings")
wsSettings.MustKey("maxEarlyData").SetNumeric(float64(maxEarlyData))
wsSettings.MustKey("earlyDataHeaderName").SetString(earlyDataHeaderName)
content, err = ajson.Marshal(config)
require.NoError(t, err)
startDockerContainer(t, DockerOptions{
Image: ImageV2RayCore,
Ports: []uint16{serverPort, testPort},
EntryPoint: "v2ray",
Stdin: content,
Env: []string{"V2RAY_VMESS_AEAD_FORCED=false"},
Bind: map[string]string{
certPem: "/path/to/certificate.crt",
keyPem: "/path/to/private.key",
},
})
startInstance(t, option.Options{
Inbounds: []option.Inbound{
{
Type: C.TypeMixed,
Tag: "mixed-in",
MixedOptions: option.HTTPMixedInboundOptions{
ListenOptions: option.ListenOptions{
Listen: option.ListenAddress(netip.IPv4Unspecified()),
ListenPort: clientPort,
},
},
},
},
Outbounds: []option.Outbound{
{
Type: C.TypeVMess,
Tag: "vmess-out",
VMessOptions: option.VMessOutboundOptions{
ServerOptions: option.ServerOptions{
Server: "127.0.0.1",
ServerPort: serverPort,
},
UUID: userId.String(),
Security: "zero",
TLS: &option.OutboundTLSOptions{
Enabled: true,
ServerName: "example.org",
CertificatePath: certPem,
},
Transport: &option.V2RayTransportOptions{
Type: C.V2RayTransportTypeWebsocket,
WebsocketOptions: option.V2RayWebsocketOptions{
MaxEarlyData: maxEarlyData,
EarlyDataHeaderName: earlyDataHeaderName,
},
},
},
},
},
})
testSuitSimple(t, clientPort, testPort)
}

View file

@ -182,9 +182,6 @@ func testVMessInboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, al
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeVMess, Type: C.TypeVMess,
@ -231,9 +228,6 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, g
}) })
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,
@ -267,9 +261,6 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, g
func testVMessSelf(t *testing.T, security string, uuid uuid.UUID, alterId int, globalPadding bool, authenticatedLength bool, packetAddr bool) { func testVMessSelf(t *testing.T, security string, uuid uuid.UUID, alterId int, globalPadding bool, authenticatedLength bool, packetAddr bool) {
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -21,9 +21,6 @@ func TestWireGuard(t *testing.T) {
}) })
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
startInstance(t, option.Options{ startInstance(t, option.Options{
Log: &option.LogOptions{
Level: "error",
},
Inbounds: []option.Inbound{ Inbounds: []option.Inbound{
{ {
Type: C.TypeMixed, Type: C.TypeMixed,

View file

@ -167,6 +167,9 @@ func (c *EarlyWebsocketConn) SetWriteDeadline(t time.Time) error {
func wrapError(err error) error { func wrapError(err error) error {
if websocket.IsCloseError(err, websocket.CloseNormalClosure) { if websocket.IsCloseError(err, websocket.CloseNormalClosure) {
return io.EOF
}
if websocket.IsCloseError(err, websocket.CloseAbnormalClosure) {
return net.ErrClosed return net.ErrClosed
} }
return err return err