diff --git a/common/baderror/baderror.go b/common/baderror/baderror.go new file mode 100644 index 00000000..1e9a207d --- /dev/null +++ b/common/baderror/baderror.go @@ -0,0 +1,12 @@ +package baderror + +import "strings" + +func Contains(err error, msgList ...string) bool { + for _, msg := range msgList { + if strings.Contains(err.Error(), msg) { + return true + } + } + return false +} diff --git a/common/baderror/grpc.go b/common/baderror/grpc.go new file mode 100644 index 00000000..4e42cea4 --- /dev/null +++ b/common/baderror/grpc.go @@ -0,0 +1,26 @@ +package baderror + +import ( + "context" + "io" + "net" +) + +func WrapGRPC(err error) error { + // grpc uses stupid internal error types + if err == nil { + return nil + } + if Contains(err, "EOF") { + return io.EOF + } + if Contains(err, "Canceled") { + return context.Canceled + } + if Contains(err, + "the client connection is closing", + "server closed the stream without sending trailers") { + return net.ErrClosed + } + return err +} diff --git a/common/baderror/h2.go b/common/baderror/h2.go new file mode 100644 index 00000000..f447b630 --- /dev/null +++ b/common/baderror/h2.go @@ -0,0 +1,22 @@ +package baderror + +import ( + "io" + "net" + + E "github.com/sagernet/sing/common/exceptions" +) + +func WrapH2(err error) error { + if err == nil { + return nil + } + err = E.Unwrap(err) + if err == io.ErrUnexpectedEOF { + return io.EOF + } + if Contains(err, "client disconnected", "body closed by handler") { + return net.ErrClosed + } + return err +} diff --git a/go.mod b/go.mod index d8a53002..d945e18a 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 - github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 + github.com/sagernet/sing-vmess v0.0.0-20220829020559-33915075430c github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 github.com/spf13/cobra v1.5.0 github.com/stretchr/testify v1.8.0 diff --git a/go.sum b/go.sum index cb304a8d..e0363702 100644 --- a/go.sum +++ b/go.sum @@ -143,8 +143,8 @@ github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDe github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 h1:SoWiHYuOCVedqA7T/CJSZUUrcPGKQb2wFKEq8DphiAI= github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83/go.mod h1:76r07HS1WRcEI4mE9pFsohfTBUt1j/G9Avz6DaOP3VU= -github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 h1:FAsJsVwpPcoITcj6/9JxRKxy8n3bIKLqKmDGVzmfeOo= -github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps= +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/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4= github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= diff --git a/inbound/trojan.go b/inbound/trojan.go index ef6af65f..7255a84f 100644 --- a/inbound/trojan.go +++ b/inbound/trojan.go @@ -145,15 +145,15 @@ func (h *Trojan) Close() error { ) } -func (h *Trojan) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { - if h.tlsConfig != nil { - conn = tls.Server(conn, h.tlsConfig.Config()) - } - return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) +func (h *Trojan) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { + h.injectTCP(conn) + return nil } -func (h *Trojan) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { - metadata = h.createMetadata(conn, metadata) +func (h *Trojan) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { + if h.tlsConfig != nil && h.transport == nil { + conn = tls.Server(conn, h.tlsConfig.Config()) + } return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) } diff --git a/inbound/vmess.go b/inbound/vmess.go index 5a6d91b9..6ba8a4c7 100644 --- a/inbound/vmess.go +++ b/inbound/vmess.go @@ -125,15 +125,15 @@ func (h *VMess) Close() error { ) } -func (h *VMess) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { - if h.tlsConfig != nil { - conn = tls.Server(conn, h.tlsConfig.Config()) - } - return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) +func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { + h.injectTCP(conn) + return nil } -func (h *VMess) newTransportConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { - metadata = h.createMetadata(conn, metadata) +func (h *VMess) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { + if h.tlsConfig != nil && h.transport == nil { + conn = tls.Server(conn, h.tlsConfig.Config()) + } return h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, adapter.UpstreamMetadata(metadata)) } diff --git a/test/box_test.go b/test/box_test.go index aef5ea43..1d824ee4 100644 --- a/test/box_test.go +++ b/test/box_test.go @@ -60,7 +60,7 @@ func testTCP(t *testing.T, clientPort uint16, testPort uint16) { require.NoError(t, testLargeDataWithConn(t, testPort, dialTCP)) } -func testSuitQUIC(t *testing.T, clientPort uint16, testPort uint16) { +func testSuitSimple(t *testing.T, clientPort uint16, testPort uint16) { dialer := socks.NewClient(N.SystemDialer, M.ParseSocksaddrHostPort("127.0.0.1", clientPort), socks.Version5, "", "") dialTCP := func() (net.Conn, error) { return dialer.DialContext(context.Background(), "tcp", M.ParseSocksaddrHostPort("127.0.0.1", testPort)) diff --git a/test/config/vmess-client.json b/test/config/vmess-client.json index 868b8b08..72381a99 100644 --- a/test/config/vmess-client.json +++ b/test/config/vmess-client.json @@ -26,7 +26,7 @@ { "id": "", "alterId": 0, - "security": "", + "security": "none", "experiments": "" } ] diff --git a/test/config/vmess-grpc-client.json b/test/config/vmess-grpc-client.json new file mode 100644 index 00000000..a5cd49a5 --- /dev/null +++ b/test/config/vmess-grpc-client.json @@ -0,0 +1,51 @@ +{ + "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": "gun", + "security": "tls", + "tlsSettings": { + "serverName": "example.org", + "certificates": [ + { + "certificateFile": "/path/to/certificate.crt", + "keyFile": "/path/to/private.key" + } + ] + }, + "grpcSettings": { + "serviceName": "TunService" + } + } + } + ] +} \ No newline at end of file diff --git a/test/config/vmess-grpc-server.json b/test/config/vmess-grpc-server.json new file mode 100644 index 00000000..3867d447 --- /dev/null +++ b/test/config/vmess-grpc-server.json @@ -0,0 +1,40 @@ +{ + "log": { + "loglevel": "debug" + }, + "inbounds": [ + { + "listen": "0.0.0.0", + "port": 1234, + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "b831381d-6324-4d53-ad4f-8cda48b30811" + } + ] + }, + "streamSettings": { + "network": "gun", + "security": "tls", + "tlsSettings": { + "serverName": "example.org", + "certificates": [ + { + "certificateFile": "/path/to/certificate.crt", + "keyFile": "/path/to/private.key" + } + ] + }, + "grpcSettings": { + "serviceName": "TunService" + } + } + } + ], + "outbounds": [ + { + "protocol": "freedom" + } + ] +} \ No newline at end of file diff --git a/test/go.mod b/test/go.mod index 32bdbc93..28e9a689 100644 --- a/test/go.mod +++ b/test/go.mod @@ -14,7 +14,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/spyzhov/ajson v0.7.1 github.com/stretchr/testify v1.8.0 - golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c + golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b ) require ( @@ -60,8 +60,8 @@ require ( github.com/sagernet/netlink v0.0.0-20220826133217-3fb4ff92ea17 // indirect github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb // indirect github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 // indirect - github.com/sagernet/sing-tun v0.0.0-20220827013030-e01ce3a8a70e // indirect - github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 // 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/smux v0.0.0-20220812084127-e2d085ee3939 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect @@ -69,22 +69,22 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.22.0 // indirect go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect - golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect + golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d // 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/sys v0.0.0-20220818161305-2296e01440c6 // indirect + golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // 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/wireguard v0.0.0-20220703234212-c31a7b1ab478 // indirect google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect - google.golang.org/grpc v1.48.0 // indirect + google.golang.org/grpc v1.49.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.3.0 // indirect - gvisor.dev/gvisor v0.0.0-20220812001733-b5c0f23893fb // indirect + gvisor.dev/gvisor v0.0.0-20220819163037-ba6e795b139a // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/test/go.sum b/test/go.sum index 30db1b02..6a1b7ba6 100644 --- a/test/go.sum +++ b/test/go.sum @@ -13,15 +13,10 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo= @@ -44,7 +39,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -89,7 +83,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -168,10 +161,10 @@ github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFx github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM= -github.com/sagernet/sing-tun v0.0.0-20220827013030-e01ce3a8a70e h1:7GGZfIhbTAiUmVsWVLEccrKbwsgocUaJDJ859RVFNTA= -github.com/sagernet/sing-tun v0.0.0-20220827013030-e01ce3a8a70e/go.mod h1:B9BsLZmK01+9Dzhl634lM6YU80aTqOZ2yyrOzhA/Bto= -github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31 h1:FAsJsVwpPcoITcj6/9JxRKxy8n3bIKLqKmDGVzmfeOo= -github.com/sagernet/sing-vmess v0.0.0-20220827032426-01665c9c4e31/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps= +github.com/sagernet/sing-tun v0.0.0-20220828031750-185b6c880a83 h1:SoWiHYuOCVedqA7T/CJSZUUrcPGKQb2wFKEq8DphiAI= +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/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps= github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4= github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -212,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-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-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= @@ -245,8 +238,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes= -golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -282,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-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-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= -golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/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-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -335,8 +328,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -371,8 +364,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= -gvisor.dev/gvisor v0.0.0-20220812001733-b5c0f23893fb h1:Z7S1dQX1RX+Tq55/Jq5kJQnPBdxA19ZmhgCmFjyK+yA= -gvisor.dev/gvisor v0.0.0-20220812001733-b5c0f23893fb/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= +gvisor.dev/gvisor v0.0.0-20220819163037-ba6e795b139a h1:W1h3JsEzYWg7eD4908iHv49p7AOx7JPKsoh/fsxgylM= +gvisor.dev/gvisor v0.0.0-20220819163037-ba6e795b139a/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= diff --git a/test/hysteria_test.go b/test/hysteria_test.go index 4b846e66..9afe8c81 100644 --- a/test/hysteria_test.go +++ b/test/hysteria_test.go @@ -83,7 +83,7 @@ func TestHysteriaSelf(t *testing.T) { }, }, }) - testSuitQUIC(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } func TestHysteriaInbound(t *testing.T) { @@ -180,5 +180,5 @@ func TestHysteriaOutbound(t *testing.T) { }, }, }) - testSuitQUIC(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } diff --git a/test/v2ray_grpc_test.go b/test/v2ray_grpc_test.go new file mode 100644 index 00000000..641ddc39 --- /dev/null +++ b/test/v2ray_grpc_test.go @@ -0,0 +1,217 @@ +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 TestV2RayGRPCInbound(t *testing.T) { + t.Run("origin", func(t *testing.T) { + testV2RayGRPCInbound(t, false) + }) + t.Run("lite", func(t *testing.T) { + testV2RayGRPCInbound(t, true) + }) +} + +func testV2RayGRPCInbound(t *testing.T, forceLite bool) { + userId, err := uuid.DefaultGenerator.NewV4() + require.NoError(t, err) + _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + startInstance(t, option.Options{ + Log: &option.LogOptions{ + Level: "error", + }, + 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.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: forceLite, + }, + }, + }, + }, + }, + }) + content, err := os.ReadFile("config/vmess-grpc-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).MustKey("settings").MustKey("vnext").MustIndex(0) + outbound.MustKey("port").SetNumeric(float64(serverPort)) + user := outbound.MustKey("users").MustIndex(0) + user.MustKey("id").SetString(userId.String()) + 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 TestV2RayGRPCOutbound(t *testing.T) { + t.Run("origin", func(t *testing.T) { + testV2RayGRPCOutbound(t, false) + }) + t.Run("lite", func(t *testing.T) { + testV2RayGRPCOutbound(t, true) + }) +} + +func testV2RayGRPCOutbound(t *testing.T, forceLite bool) { + userId, err := uuid.DefaultGenerator.NewV4() + require.NoError(t, err) + _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + + content, err := os.ReadFile("config/vmess-grpc-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()) + 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{ + Log: &option.LogOptions{ + Level: "error", + }, + 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.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: forceLite, + }, + }, + }, + }, + }, + }) + testSuitSimple(t, clientPort, testPort) +} + +func TestV2RayGRPCLite(t *testing.T) { + t.Run("server", func(t *testing.T) { + testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: true, + }, + }, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + }, + }) + }) + t.Run("client", func(t *testing.T) { + testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + }, + }, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: true, + }, + }) + }) + t.Run("self", func(t *testing.T) { + testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: true, + }, + }, &option.V2RayTransportOptions{ + Type: C.V2RayTransportTypeGRPC, + GRPCOptions: option.V2RayGRPCOptions{ + ServiceName: "TunService", + ForceLite: true, + }, + }) + }) +} diff --git a/test/v2ray_transport_test.go b/test/v2ray_transport_test.go index ec8237dc..3f1caae0 100644 --- a/test/v2ray_transport_test.go +++ b/test/v2ray_transport_test.go @@ -11,61 +11,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestV2RayGRPCSelf(t *testing.T) { - testV2RayTransportSelf(t, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - }, - }) -} - -func TestV2RayGRPCLite(t *testing.T) { - t.Run("server", func(t *testing.T) { - testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - ForceLite: true, - }, - }, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - }, - }) - }) - t.Run("client", func(t *testing.T) { - testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - }, - }, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - ForceLite: true, - }, - }) - }) - t.Run("self", func(t *testing.T) { - testV2RayTransportSelfWith(t, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - ForceLite: true, - }, - }, &option.V2RayTransportOptions{ - Type: C.V2RayTransportTypeGRPC, - GRPCOptions: option.V2RayGRPCOptions{ - ServiceName: "TunService", - ForceLite: true, - }, - }) - }) -} - func TestV2RayWebscoketSelf(t *testing.T) { t.Run("basic", func(t *testing.T) { testV2RayTransportSelf(t, &option.V2RayTransportOptions{ @@ -355,7 +300,7 @@ func TestVMessQUICSelf(t *testing.T) { }, }, }) - testSuitQUIC(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportOptions) { @@ -422,5 +367,5 @@ func testV2RayTransportNOTLSSelf(t *testing.T, transport *option.V2RayTransportO }, }, }) - testSuitQUIC(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } diff --git a/test/vmess_test.go b/test/vmess_test.go index 70c9534d..386e8420 100644 --- a/test/vmess_test.go +++ b/test/vmess_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestVMessAuto(t *testing.T) { +func _TestVMessAuto(t *testing.T) { security := "auto" user, err := uuid.DefaultGenerator.NewV4() require.NoError(t, err) @@ -31,7 +31,7 @@ func TestVMessAuto(t *testing.T) { }) } -func _TestVMess(t *testing.T) { +func TestVMess(t *testing.T) { for _, security := range []string{ "zero", } { @@ -40,12 +40,19 @@ func _TestVMess(t *testing.T) { }) } for _, security := range []string{ - "aes-128-gcm", "chacha20-poly1305", "aes-128-cfb", + "none", } { t.Run(security, func(t *testing.T) { testVMess1(t, security) }) } + for _, security := range []string{ + "aes-128-gcm", "chacha20-poly1305", "aes-128-cfb", + } { + t.Run(security, func(t *testing.T) { + testVMess2(t, security) + }) + } } func testVMess0(t *testing.T, security string) { @@ -69,6 +76,29 @@ func testVMess0(t *testing.T, security string) { } func testVMess1(t *testing.T, security string) { + user, err := uuid.DefaultGenerator.NewV4() + require.NoError(t, err) + t.Run("self", func(t *testing.T) { + testVMessSelf(t, security, user, 0, false, false, false) + }) + t.Run("self-legacy", func(t *testing.T) { + testVMessSelf(t, security, user, 1, false, false, false) + }) + t.Run("packetaddr", func(t *testing.T) { + testVMessSelf(t, security, user, 0, false, false, true) + }) + t.Run("inbound", func(t *testing.T) { + testVMessInboundWithV2Ray(t, security, user, 0, false) + }) + t.Run("outbound", func(t *testing.T) { + testVMessOutboundWithV2Ray(t, security, user, false, false, 0) + }) + t.Run("outbound-legacy", func(t *testing.T) { + testVMessOutboundWithV2Ray(t, security, user, false, false, 1) + }) +} + +func testVMess2(t *testing.T, security string) { user, err := uuid.DefaultGenerator.NewV4() require.NoError(t, err) t.Run("self", func(t *testing.T) { @@ -175,7 +205,7 @@ func testVMessInboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, al }, }) - testSuit(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } func testVMessOutboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, globalPadding bool, authenticatedLength bool, alterId int) { @@ -232,13 +262,13 @@ func testVMessOutboundWithV2Ray(t *testing.T, security string, uuid uuid.UUID, g }, }, }) - testSuit(t, clientPort, testPort) + testSuitSimple(t, clientPort, testPort) } func testVMessSelf(t *testing.T, security string, uuid uuid.UUID, alterId int, globalPadding bool, authenticatedLength bool, packetAddr bool) { startInstance(t, option.Options{ Log: &option.LogOptions{ - Level: "trace", + Level: "error", }, Inbounds: []option.Inbound{ { diff --git a/transport/v2raygrpc/conn.go b/transport/v2raygrpc/conn.go index a8b06c65..1ef3f391 100644 --- a/transport/v2raygrpc/conn.go +++ b/transport/v2raygrpc/conn.go @@ -2,12 +2,11 @@ package v2raygrpc import ( "context" - "io" "net" "os" - "strings" "time" + "github.com/sagernet/sing-box/common/baderror" "github.com/sagernet/sing/common/rw" ) @@ -36,7 +35,7 @@ func (c *GRPCConn) Read(b []byte) (n int, err error) { return } hunk, err := c.Recv() - err = wrapError(err) + err = baderror.WrapGRPC(err) if err != nil { return } @@ -48,7 +47,7 @@ func (c *GRPCConn) Read(b []byte) (n int, err error) { } func (c *GRPCConn) Write(b []byte) (n int, err error) { - err = wrapError(c.Send(&Hunk{Data: b})) + err = baderror.WrapGRPC(c.Send(&Hunk{Data: b})) if err != nil { return } @@ -93,20 +92,3 @@ type clientConnWrapper struct { func (c *clientConnWrapper) CloseWrite() error { return c.CloseSend() } - -func wrapError(err error) error { - // grpc uses stupid internal error types - if err == nil { - return nil - } - if strings.Contains(err.Error(), "EOF") { - return io.EOF - } - if strings.Contains(err.Error(), "the client connection is closing") { - return net.ErrClosed - } - if strings.Contains(err.Error(), "server closed the stream without sending trailers") { - return net.ErrClosed - } - return err -} diff --git a/transport/v2raygrpclite/conn.go b/transport/v2raygrpclite/conn.go index 22803a98..66fbadff 100644 --- a/transport/v2raygrpclite/conn.go +++ b/transport/v2raygrpclite/conn.go @@ -10,10 +10,10 @@ import ( "os" "time" + "github.com/sagernet/sing-box/common/baderror" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/bufio" - E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/rw" ) @@ -53,7 +53,7 @@ func (c *GunConn) setup(reader io.Reader, err error) { func (c *GunConn) Read(b []byte) (n int, err error) { n, err = c.read(b) - return n, wrapError(err) + return n, baderror.WrapH2(err) } func (c *GunConn) read(b []byte) (n int, err error) { @@ -105,7 +105,7 @@ func (c *GunConn) Write(b []byte) (n int, err error) { if c.flusher != nil { c.flusher.Flush() } - return len(b), wrapError(err) + return len(b), baderror.WrapH2(err) } func uLen(x uint64) int { @@ -129,7 +129,7 @@ func (c *GunConn) WriteBuffer(buffer *buf.Buffer) error { if c.flusher != nil { c.flusher.Flush() } - return wrapError(err) + return baderror.WrapH2(err) } func (c *GunConn) FrontHeadroom() int { @@ -159,10 +159,3 @@ func (c *GunConn) SetReadDeadline(t time.Time) error { func (c *GunConn) SetWriteDeadline(t time.Time) error { return os.ErrInvalid } - -func wrapError(err error) error { - if E.IsMulti(err, io.ErrUnexpectedEOF) { - return io.EOF - } - return err -} diff --git a/transport/v2rayhttp/conn.go b/transport/v2rayhttp/conn.go index 22f3ca4a..e99e48b8 100644 --- a/transport/v2rayhttp/conn.go +++ b/transport/v2rayhttp/conn.go @@ -7,8 +7,8 @@ import ( "os" "time" + "github.com/sagernet/sing-box/common/baderror" "github.com/sagernet/sing/common" - E "github.com/sagernet/sing/common/exceptions" ) type HTTPConn struct { @@ -18,12 +18,12 @@ type HTTPConn struct { func (c *HTTPConn) Read(b []byte) (n int, err error) { n, err = c.reader.Read(b) - return n, wrapError(err) + return n, baderror.WrapH2(err) } func (c *HTTPConn) Write(b []byte) (n int, err error) { n, err = c.writer.Write(b) - return n, wrapError(err) + return n, baderror.WrapH2(err) } func (c *HTTPConn) Close() error { @@ -62,10 +62,3 @@ func (c *ServerHTTPConn) Write(b []byte) (n int, err error) { } return } - -func wrapError(err error) error { - if E.IsMulti(err, io.ErrUnexpectedEOF) { - return io.EOF - } - return err -}