From 46d8bb58fc193edf3d72e5d51395ea1a336605a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jul 2023 01:21:02 +0000 Subject: [PATCH 01/71] Bump github.com/quic-go/quic-go from 0.36.0 to 0.36.1 (#2286) Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.36.0 to 0.36.1. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.36.0...v0.36.1) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0249c0ea..a878bb2f 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.36.0 + github.com/quic-go/quic-go v0.36.1 github.com/refraction-networking/utls v1.3.2 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 diff --git a/go.sum b/go.sum index 833a9e37..d824c4c9 100644 --- a/go.sum +++ b/go.sum @@ -116,8 +116,8 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8 github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.0 h1:JIrO7p7Ug6hssFcARjWDiqS2RAKJHCiwPxBAA989rbI= -github.com/quic-go/quic-go v0.36.0/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/quic-go v0.36.1 h1:WsG73nVtnDy1TiACxFxhQ3TqaW+DipmqzLEtNlAwZyY= +github.com/quic-go/quic-go v0.36.1/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From b870cc097b7d0aee11c90f218105d870f2215365 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 00:56:44 +0000 Subject: [PATCH 02/71] Bump golang.org/x/sys from 0.9.0 to 0.10.0 Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.9.0 to 0.10.0. - [Commits](https://github.com/golang/sys/compare/v0.9.0...v0.10.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a878bb2f..154c6ee5 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( golang.org/x/crypto v0.10.0 golang.org/x/net v0.11.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.9.0 + golang.org/x/sys v0.10.0 google.golang.org/grpc v1.56.1 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c diff --git a/go.sum b/go.sum index d824c4c9..3ffe2061 100644 --- a/go.sum +++ b/go.sum @@ -225,8 +225,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From a1ff507ef2de79082a593b2d2642b8f872863354 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 00:20:57 +0000 Subject: [PATCH 03/71] Bump golang.org/x/crypto from 0.10.0 to 0.11.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.10.0 to 0.11.0. - [Commits](https://github.com/golang/crypto/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 154c6ee5..e96b651d 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 - golang.org/x/crypto v0.10.0 + golang.org/x/crypto v0.11.0 golang.org/x/net v0.11.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 @@ -50,7 +50,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.11.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.10.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/go.sum b/go.sum index 3ffe2061..e4c28878 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= @@ -231,8 +231,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= From 846d3ebd6c2d63a3bad23bc50141d9cb7c87d142 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:34:06 +0000 Subject: [PATCH 04/71] Bump golang.org/x/net from 0.11.0 to 0.12.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.11.0 to 0.12.0. - [Commits](https://github.com/golang/net/compare/v0.11.0...v0.12.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e96b651d..162037c7 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 golang.org/x/crypto v0.11.0 - golang.org/x/net v0.11.0 + golang.org/x/net v0.12.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 google.golang.org/grpc v1.56.1 diff --git a/go.sum b/go.sum index e4c28878..8a2c5db1 100644 --- a/go.sum +++ b/go.sum @@ -200,8 +200,8 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= From 6d4194415d903523eb243a172f0beb1621c9267a Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Thu, 6 Jul 2023 15:18:05 +0000 Subject: [PATCH 05/71] Clean unnecessary code in Trojan --- infra/conf/trojan.go | 59 ++++++++++++++------------------- proxy/trojan/client.go | 18 +++------- proxy/trojan/config.go | 2 -- proxy/trojan/config.pb.go | 69 +++++++++++++++++---------------------- proxy/trojan/config.proto | 3 +- proxy/trojan/protocol.go | 1 - proxy/trojan/server.go | 4 +-- proxy/trojan/trojan.go | 4 +-- 8 files changed, 63 insertions(+), 97 deletions(-) diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index e7d8738b..e9d78f8a 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -30,13 +30,14 @@ type TrojanClientConfig struct { // Build implements Buildable func (c *TrojanClientConfig) Build() (proto.Message, error) { - config := new(trojan.ClientConfig) - if len(c.Servers) == 0 { return nil, newError("0 Trojan server configured.") } - serverSpecs := make([]*protocol.ServerEndpoint, len(c.Servers)) + config := &trojan.ClientConfig{ + Server: make([]*protocol.ServerEndpoint, len(c.Servers)), + } + for idx, rec := range c.Servers { if rec.Address == nil { return nil, newError("Trojan server address is not set.") @@ -47,34 +48,25 @@ func (c *TrojanClientConfig) Build() (proto.Message, error) { if rec.Password == "" { return nil, newError("Trojan password is not specified.") } - account := &trojan.Account{ - Password: rec.Password, - Flow: rec.Flow, + if rec.Flow != "" { + return nil, newError(`Trojan doesn't support "flow" anymore.`) } - switch account.Flow { - case "": - default: - return nil, newError(`Trojan servers: "flow" doesn't support "` + account.Flow + `" in this version`) - } - - trojan := &protocol.ServerEndpoint{ + config.Server[idx] = &protocol.ServerEndpoint{ Address: rec.Address.Build(), Port: uint32(rec.Port), User: []*protocol.User{ { - Level: uint32(rec.Level), - Email: rec.Email, - Account: serial.ToTypedMessage(account), + Level: uint32(rec.Level), + Email: rec.Email, + Account: serial.ToTypedMessage(&trojan.Account{ + Password: rec.Password, + }), }, }, } - - serverSpecs[idx] = trojan } - config.Server = serverSpecs - return config, nil } @@ -105,25 +97,22 @@ type TrojanServerConfig struct { // Build implements Buildable func (c *TrojanServerConfig) Build() (proto.Message, error) { - config := new(trojan.ServerConfig) - config.Users = make([]*protocol.User, len(c.Clients)) + config := &trojan.ServerConfig{ + Users: make([]*protocol.User, len(c.Clients)), + } + for idx, rawUser := range c.Clients { - user := new(protocol.User) - account := &trojan.Account{ - Password: rawUser.Password, - Flow: rawUser.Flow, + if rawUser.Flow != "" { + return nil, newError(`Trojan doesn't support "flow" anymore.`) } - switch account.Flow { - case "": - default: - return nil, newError(`Trojan clients: "flow" doesn't support "` + account.Flow + `" in this version`) + config.Users[idx] = &protocol.User{ + Level: uint32(rawUser.Level), + Email: rawUser.Email, + Account: serial.ToTypedMessage(&trojan.Account{ + Password: rawUser.Password, + }), } - - user.Email = rawUser.Email - user.Level = uint32(rawUser.Level) - user.Account = serial.ToTypedMessage(account) - config.Users[idx] = user } if c.Fallback != nil { diff --git a/proxy/trojan/client.go b/proxy/trojan/client.go index 2605239d..0c6f16d3 100644 --- a/proxy/trojan/client.go +++ b/proxy/trojan/client.go @@ -77,22 +77,12 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter defer conn.Close() - iConn := conn - statConn, ok := iConn.(*stat.CounterConnection) - if ok { - iConn = statConn.Connection - } - user := server.PickUser() account, ok := user.Account.(*MemoryAccount) if !ok { return newError("user account is not valid") } - connWriter := &ConnWriter{ - Flow: account.Flow, - } - var newCtx context.Context var newCancel context.CancelFunc if session.TimeoutOnlyFromContext(ctx) { @@ -113,9 +103,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn)) - connWriter.Writer = bufferWriter - connWriter.Target = destination - connWriter.Account = account + connWriter := &ConnWriter{ + Writer: bufferWriter, + Target: destination, + Account: account, + } var bodyWriter buf.Writer if destination.Network == net.Network_UDP { diff --git a/proxy/trojan/config.go b/proxy/trojan/config.go index ffac7854..a02dfe98 100644 --- a/proxy/trojan/config.go +++ b/proxy/trojan/config.go @@ -13,7 +13,6 @@ import ( type MemoryAccount struct { Password string Key []byte - Flow string } // AsAccount implements protocol.AsAccount. @@ -23,7 +22,6 @@ func (a *Account) AsAccount() (protocol.Account, error) { return &MemoryAccount{ Password: password, Key: key, - Flow: a.Flow, }, nil } diff --git a/proxy/trojan/config.pb.go b/proxy/trojan/config.pb.go index 6d81350f..49374001 100644 --- a/proxy/trojan/config.pb.go +++ b/proxy/trojan/config.pb.go @@ -27,7 +27,6 @@ type Account struct { unknownFields protoimpl.UnknownFields Password string `protobuf:"bytes,1,opt,name=password,proto3" json:"password,omitempty"` - Flow string `protobuf:"bytes,2,opt,name=flow,proto3" json:"flow,omitempty"` } func (x *Account) Reset() { @@ -69,13 +68,6 @@ func (x *Account) GetPassword() string { return "" } -func (x *Account) GetFlow() string { - if x != nil { - return x.Flow - } - return "" -} - type Fallback struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -216,7 +208,7 @@ type ServerConfig struct { unknownFields protoimpl.UnknownFields Users []*protocol.User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` - Fallbacks []*Fallback `protobuf:"bytes,3,rep,name=fallbacks,proto3" json:"fallbacks,omitempty"` + Fallbacks []*Fallback `protobuf:"bytes,2,rep,name=fallbacks,proto3" json:"fallbacks,omitempty"` } func (x *ServerConfig) Reset() { @@ -274,38 +266,37 @@ var file_proxy_trojan_config_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x39, 0x0a, + 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x25, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x82, 0x01, 0x0a, 0x08, 0x46, 0x61, 0x6c, - 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6c, 0x70, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x6c, 0x70, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, - 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0x4c, 0x0a, - 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, - 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x7b, 0x0a, 0x0c, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, - 0x09, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, - 0x6f, 0x6a, 0x61, 0x6e, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x09, 0x66, - 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, - 0x6e, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, - 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x77, 0x6f, 0x72, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6c, 0x70, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x6c, 0x70, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, 0x72, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0x4c, 0x0a, 0x0c, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, + 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x7b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x09, 0x66, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, + 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x09, 0x66, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x73, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x50, 0x01, 0x5a, + 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, + 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x2f, 0x74, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x54, 0x72, 0x6f, 0x6a, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/trojan/config.proto b/proxy/trojan/config.proto index 6ebed36b..4229e2ed 100644 --- a/proxy/trojan/config.proto +++ b/proxy/trojan/config.proto @@ -11,7 +11,6 @@ import "common/protocol/server_spec.proto"; message Account { string password = 1; - string flow = 2; } message Fallback { @@ -29,5 +28,5 @@ message ClientConfig { message ServerConfig { repeated xray.common.protocol.User users = 1; - repeated Fallback fallbacks = 3; + repeated Fallback fallbacks = 2; } diff --git a/proxy/trojan/protocol.go b/proxy/trojan/protocol.go index 363cf9e0..6fcfb4d4 100644 --- a/proxy/trojan/protocol.go +++ b/proxy/trojan/protocol.go @@ -31,7 +31,6 @@ type ConnWriter struct { io.Writer Target net.Destination Account *MemoryAccount - Flow string headerSent bool } diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index 368374ff..41245ba4 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -234,7 +234,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con }) newError("received request for ", destination).WriteToLog(sid) - return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher, iConn, statConn) + return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher) } func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { @@ -300,7 +300,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, destination net.Destination, clientReader buf.Reader, - clientWriter buf.Writer, dispatcher routing.Dispatcher, iConn stat.Connection, statConn *stat.CounterConnection, + clientWriter buf.Writer, dispatcher routing.Dispatcher, ) error { ctx, cancel := context.WithCancel(ctx) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) diff --git a/proxy/trojan/trojan.go b/proxy/trojan/trojan.go index 4639b7d9..d0cf5de4 100644 --- a/proxy/trojan/trojan.go +++ b/proxy/trojan/trojan.go @@ -1,5 +1,3 @@ package trojan -const ( - muxCoolAddress = "v1.mux.cool" -) +//go:generate go run github.com/xtls/xray-core/common/errors/errorgen From f0f3b417f779d1d76d9d515bd0070877d9975019 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Thu, 6 Jul 2023 16:30:39 +0000 Subject: [PATCH 06/71] Refactor: Fragmentation https://github.com/XTLS/Xray-core/commit/5f5ae375714abd67eb2f0a0f2e86410b6f29f7c2 https://github.com/XTLS/Xray-core/commit/9122d0f056ed5b0e6fc9b290fdc7b39f47b49a39 --- infra/conf/freedom.go | 134 ++++++++++++++--------------- proxy/freedom/config.pb.go | 62 +++++++------- proxy/freedom/config.proto | 12 +-- proxy/freedom/freedom.go | 171 +++++++++++++------------------------ 4 files changed, 161 insertions(+), 218 deletions(-) diff --git a/infra/conf/freedom.go b/infra/conf/freedom.go index c3510477..60c5b7f1 100644 --- a/infra/conf/freedom.go +++ b/infra/conf/freedom.go @@ -39,91 +39,89 @@ func (c *FreedomConfig) Build() (proto.Message, error) { } if c.Fragment != nil { - if len(c.Fragment.Interval) == 0 || len(c.Fragment.Length) == 0 { - return nil, newError("Invalid interval or length") - } - intervalMinMax := strings.Split(c.Fragment.Interval, "-") - var minInterval, maxInterval int64 + config.Fragment = new(freedom.Fragment) var err, err2 error - if len(intervalMinMax) == 2 { - minInterval, err = strconv.ParseInt(intervalMinMax[0], 10, 64) - maxInterval, err2 = strconv.ParseInt(intervalMinMax[1], 10, 64) - } else { - minInterval, err = strconv.ParseInt(intervalMinMax[0], 10, 64) - maxInterval = minInterval - } - if err != nil { - return nil, newError("Invalid minimum interval: ", err).Base(err) - } - if err2 != nil { - return nil, newError("Invalid maximum interval: ", err2).Base(err2) - } - - lengthMinMax := strings.Split(c.Fragment.Length, "-") - var minLength, maxLength int64 - if len(lengthMinMax) == 2 { - minLength, err = strconv.ParseInt(lengthMinMax[0], 10, 64) - maxLength, err2 = strconv.ParseInt(lengthMinMax[1], 10, 64) - - } else { - minLength, err = strconv.ParseInt(lengthMinMax[0], 10, 64) - maxLength = minLength - } - if err != nil { - return nil, newError("Invalid minimum length: ", err).Base(err) - } - if err2 != nil { - return nil, newError("Invalid maximum length: ", err2).Base(err2) - } - - if minInterval > maxInterval { - minInterval, maxInterval = maxInterval, minInterval - } - if minLength > maxLength { - minLength, maxLength = maxLength, minLength - } - - config.Fragment = &freedom.Fragment{ - MinInterval: int32(minInterval), - MaxInterval: int32(maxInterval), - MinLength: int32(minLength), - MaxLength: int32(maxLength), - } switch strings.ToLower(c.Fragment.Packets) { case "tlshello": // TLS Hello Fragmentation (into multiple handshake messages) - config.Fragment.StartPacket = 0 - config.Fragment.EndPacket = 1 + config.Fragment.PacketsFrom = 0 + config.Fragment.PacketsTo = 1 case "": // TCP Segmentation (all packets) - config.Fragment.StartPacket = 0 - config.Fragment.EndPacket = 0 + config.Fragment.PacketsFrom = 0 + config.Fragment.PacketsTo = 0 default: // TCP Segmentation (range) - packetRange := strings.Split(c.Fragment.Packets, "-") - var startPacket, endPacket int64 - if len(packetRange) == 2 { - startPacket, err = strconv.ParseInt(packetRange[0], 10, 64) - endPacket, err2 = strconv.ParseInt(packetRange[1], 10, 64) + packetsFromTo := strings.Split(c.Fragment.Packets, "-") + if len(packetsFromTo) == 2 { + config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64) + config.Fragment.PacketsTo, err2 = strconv.ParseUint(packetsFromTo[1], 10, 64) } else { - startPacket, err = strconv.ParseInt(packetRange[0], 10, 64) - endPacket = startPacket + config.Fragment.PacketsFrom, err = strconv.ParseUint(packetsFromTo[0], 10, 64) + config.Fragment.PacketsTo = config.Fragment.PacketsFrom } if err != nil { - return nil, newError("Invalid start packet: ", err).Base(err) + return nil, newError("Invalid PacketsFrom").Base(err) } if err2 != nil { - return nil, newError("Invalid end packet: ", err2).Base(err2) + return nil, newError("Invalid PacketsTo").Base(err2) } - if startPacket > endPacket { - return nil, newError("Invalid packet range: ", c.Fragment.Packets) + if config.Fragment.PacketsFrom > config.Fragment.PacketsTo { + config.Fragment.PacketsFrom, config.Fragment.PacketsTo = config.Fragment.PacketsTo, config.Fragment.PacketsFrom } - if startPacket < 1 { - return nil, newError("Cannot start from packet 0") + if config.Fragment.PacketsFrom == 0 { + return nil, newError("PacketsFrom can't be 0") + } + } + + { + if c.Fragment.Length == "" { + return nil, newError("Length can't be empty") + } + lengthMinMax := strings.Split(c.Fragment.Length, "-") + if len(lengthMinMax) == 2 { + config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64) + config.Fragment.LengthMax, err2 = strconv.ParseUint(lengthMinMax[1], 10, 64) + } else { + config.Fragment.LengthMin, err = strconv.ParseUint(lengthMinMax[0], 10, 64) + config.Fragment.LengthMax = config.Fragment.LengthMin + } + if err != nil { + return nil, newError("Invalid LengthMin").Base(err) + } + if err2 != nil { + return nil, newError("Invalid LengthMax").Base(err2) + } + if config.Fragment.LengthMin > config.Fragment.LengthMax { + config.Fragment.LengthMin, config.Fragment.LengthMax = config.Fragment.LengthMax, config.Fragment.LengthMin + } + if config.Fragment.LengthMin == 0 { + return nil, newError("LengthMin can't be 0") + } + } + + { + if c.Fragment.Interval == "" { + return nil, newError("Interval can't be empty") + } + intervalMinMax := strings.Split(c.Fragment.Interval, "-") + if len(intervalMinMax) == 2 { + config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64) + config.Fragment.IntervalMax, err2 = strconv.ParseUint(intervalMinMax[1], 10, 64) + } else { + config.Fragment.IntervalMin, err = strconv.ParseUint(intervalMinMax[0], 10, 64) + config.Fragment.IntervalMax = config.Fragment.IntervalMin + } + if err != nil { + return nil, newError("Invalid IntervalMin").Base(err) + } + if err2 != nil { + return nil, newError("Invalid IntervalMax").Base(err2) + } + if config.Fragment.IntervalMin > config.Fragment.IntervalMax { + config.Fragment.IntervalMin, config.Fragment.IntervalMax = config.Fragment.IntervalMax, config.Fragment.IntervalMin } - config.Fragment.StartPacket = int32(startPacket) - config.Fragment.EndPacket = int32(endPacket) } } diff --git a/proxy/freedom/config.pb.go b/proxy/freedom/config.pb.go index 2e2fb403..7561f7fd 100644 --- a/proxy/freedom/config.pb.go +++ b/proxy/freedom/config.pb.go @@ -125,12 +125,12 @@ type Fragment struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MinInterval int32 `protobuf:"varint,1,opt,name=min_interval,json=minInterval,proto3" json:"min_interval,omitempty"` - MaxInterval int32 `protobuf:"varint,2,opt,name=max_interval,json=maxInterval,proto3" json:"max_interval,omitempty"` - MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` - MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` - StartPacket int32 `protobuf:"varint,5,opt,name=start_packet,json=startPacket,proto3" json:"start_packet,omitempty"` - EndPacket int32 `protobuf:"varint,6,opt,name=end_packet,json=endPacket,proto3" json:"end_packet,omitempty"` + PacketsFrom uint64 `protobuf:"varint,1,opt,name=packets_from,json=packetsFrom,proto3" json:"packets_from,omitempty"` + PacketsTo uint64 `protobuf:"varint,2,opt,name=packets_to,json=packetsTo,proto3" json:"packets_to,omitempty"` + LengthMin uint64 `protobuf:"varint,3,opt,name=length_min,json=lengthMin,proto3" json:"length_min,omitempty"` + LengthMax uint64 `protobuf:"varint,4,opt,name=length_max,json=lengthMax,proto3" json:"length_max,omitempty"` + IntervalMin uint64 `protobuf:"varint,5,opt,name=interval_min,json=intervalMin,proto3" json:"interval_min,omitempty"` + IntervalMax uint64 `protobuf:"varint,6,opt,name=interval_max,json=intervalMax,proto3" json:"interval_max,omitempty"` } func (x *Fragment) Reset() { @@ -165,44 +165,44 @@ func (*Fragment) Descriptor() ([]byte, []int) { return file_proxy_freedom_config_proto_rawDescGZIP(), []int{1} } -func (x *Fragment) GetMinInterval() int32 { +func (x *Fragment) GetPacketsFrom() uint64 { if x != nil { - return x.MinInterval + return x.PacketsFrom } return 0 } -func (x *Fragment) GetMaxInterval() int32 { +func (x *Fragment) GetPacketsTo() uint64 { if x != nil { - return x.MaxInterval + return x.PacketsTo } return 0 } -func (x *Fragment) GetMinLength() int32 { +func (x *Fragment) GetLengthMin() uint64 { if x != nil { - return x.MinLength + return x.LengthMin } return 0 } -func (x *Fragment) GetMaxLength() int32 { +func (x *Fragment) GetLengthMax() uint64 { if x != nil { - return x.MaxLength + return x.LengthMax } return 0 } -func (x *Fragment) GetStartPacket() int32 { +func (x *Fragment) GetIntervalMin() uint64 { if x != nil { - return x.StartPacket + return x.IntervalMin } return 0 } -func (x *Fragment) GetEndPacket() int32 { +func (x *Fragment) GetIntervalMax() uint64 { if x != nil { - return x.EndPacket + return x.IntervalMax } return 0 } @@ -302,19 +302,19 @@ var file_proxy_freedom_config_proto_rawDesc = []byte{ 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xd0, 0x01, 0x0a, 0x08, 0x46, 0x72, 0x61, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x69, 0x6e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, - 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, - 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, - 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, - 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x65, 0x6e, 0x64, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x09, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x22, 0xf2, 0x02, 0x0a, 0x06, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, + 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x70, 0x61, 0x63, + 0x6b, 0x65, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x63, 0x6b, + 0x65, 0x74, 0x73, 0x5f, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x70, 0x61, + 0x63, 0x6b, 0x65, 0x74, 0x73, 0x54, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x4d, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x4d, 0x61, 0x78, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4d, 0x61, 0x78, 0x22, 0xf2, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x52, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x66, 0x72, 0x65, diff --git a/proxy/freedom/config.proto b/proxy/freedom/config.proto index 4422edd3..53524e19 100644 --- a/proxy/freedom/config.proto +++ b/proxy/freedom/config.proto @@ -13,12 +13,12 @@ message DestinationOverride { } message Fragment { - int32 min_interval = 1; - int32 max_interval = 2; - int32 min_length = 3; - int32 max_length = 4; - int32 start_packet = 5; - int32 end_packet = 6; + uint64 packets_from = 1; + uint64 packets_to = 2; + uint64 length_min = 3; + uint64 length_max = 4; + uint64 interval_min = 5; + uint64 interval_max = 6; } message Config { diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index b881ffde..c6907b4c 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -5,7 +5,6 @@ package freedom import ( "context" "crypto/rand" - "encoding/binary" "io" "math/big" "time" @@ -13,7 +12,6 @@ import ( "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/dice" - "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/retry" "github.com/xtls/xray-core/common/session" @@ -175,28 +173,12 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte var writer buf.Writer if destination.Network == net.Network_TCP { if h.config.Fragment != nil { - if h.config.Fragment.StartPacket == 0 && h.config.Fragment.EndPacket == 1 { - newError("FRAGMENT", int(h.config.Fragment.MaxLength)).WriteToLog(session.ExportIDToError(ctx)) - writer = buf.NewWriter( - &FragmentedClientHelloConn{ - Conn: conn, - maxLength: int(h.config.Fragment.MaxLength), - minInterval: time.Duration(h.config.Fragment.MinInterval) * time.Millisecond, - maxInterval: time.Duration(h.config.Fragment.MaxInterval) * time.Millisecond, - }) - } else { - writer = buf.NewWriter( - &FragmentWriter{ - Writer: conn, - minLength: int(h.config.Fragment.MinLength), - maxLength: int(h.config.Fragment.MaxLength), - minInterval: time.Duration(h.config.Fragment.MinInterval) * time.Millisecond, - maxInterval: time.Duration(h.config.Fragment.MaxInterval) * time.Millisecond, - startPacket: int(h.config.Fragment.StartPacket), - endPacket: int(h.config.Fragment.EndPacket), - PacketCount: 0, - }) - } + newError("FRAGMENT", h.config.Fragment.PacketsFrom, h.config.Fragment.PacketsTo, h.config.Fragment.LengthMin, h.config.Fragment.LengthMax, + h.config.Fragment.IntervalMin, h.config.Fragment.IntervalMax).AtDebug().WriteToLog(session.ExportIDToError(ctx)) + writer = buf.NewWriter(&FragmentWriter{ + fragment: h.config.Fragment, + writer: conn, + }) } else { writer = buf.NewWriter(conn) } @@ -356,40 +338,66 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { } type FragmentWriter struct { - io.Writer - minLength int - maxLength int - minInterval time.Duration - maxInterval time.Duration - startPacket int - endPacket int - PacketCount int + fragment *Fragment + writer io.Writer + count uint64 } -func (w *FragmentWriter) Write(buf []byte) (int, error) { - w.PacketCount += 1 - if (w.startPacket != 0 && (w.PacketCount < w.startPacket || w.PacketCount > w.endPacket)) || len(buf) <= w.minLength { - return w.Writer.Write(buf) +func (f *FragmentWriter) Write(b []byte) (int, error) { + f.count++ + + if f.fragment.PacketsFrom == 0 && f.fragment.PacketsTo == 1 { + if f.count != 1 || len(b) <= 5 || b[0] != 22 { + return f.writer.Write(b) + } + recordLen := 5 + ((int(b[3]) << 8) | int(b[4])) + data := b[5:recordLen] + buf := make([]byte, 1024) + for from := 0; ; { + to := from + int(randBetween(int64(f.fragment.LengthMin), int64(f.fragment.LengthMax))) + if to > len(data) { + to = len(data) + } + copy(buf[:3], b) + copy(buf[5:], data[from:to]) + l := to - from + from = to + buf[3] = byte(l >> 8) + buf[4] = byte(l) + _, err := f.writer.Write(buf[:5+l]) + time.Sleep(time.Duration(randBetween(int64(f.fragment.IntervalMin), int64(f.fragment.IntervalMax))) * time.Millisecond) + if err != nil { + return 0, err + } + if from == len(data) { + if len(b) > recordLen { + n, err := f.writer.Write(b[recordLen:]) + if err != nil { + return recordLen + n, err + } + } + return len(b), nil + } + } } - nTotal := 0 - for { - randomBytesTo := int(randBetween(int64(w.minLength), int64(w.maxLength))) + nTotal - if randomBytesTo > len(buf) { - randomBytesTo = len(buf) + if f.fragment.PacketsFrom != 0 && (f.count < f.fragment.PacketsFrom || f.count > f.fragment.PacketsTo) { + return f.writer.Write(b) + } + for from := 0; ; { + to := from + int(randBetween(int64(f.fragment.LengthMin), int64(f.fragment.LengthMax))) + if to > len(b) { + to = len(b) } - n, err := w.Writer.Write(buf[nTotal:randomBytesTo]) + n, err := f.writer.Write(b[from:to]) + from += n + time.Sleep(time.Duration(randBetween(int64(f.fragment.IntervalMin), int64(f.fragment.IntervalMax))) * time.Millisecond) if err != nil { - return nTotal + n, err + return from, err } - nTotal += n - - if nTotal >= len(buf) { - return nTotal, nil + if from >= len(b) { + return from, nil } - - randomInterval := randBetween(int64(w.minInterval), int64(w.maxInterval)) - time.Sleep(time.Duration(randomInterval)) } } @@ -401,66 +409,3 @@ func randBetween(left int64, right int64) int64 { bigInt, _ := rand.Int(rand.Reader, big.NewInt(right-left)) return left + bigInt.Int64() } - -type FragmentedClientHelloConn struct { - net.Conn - PacketCount int - minLength int - maxLength int - minInterval time.Duration - maxInterval time.Duration -} - -func (c *FragmentedClientHelloConn) Write(b []byte) (n int, err error) { - if len(b) >= 5 && b[0] == 22 && c.PacketCount == 0 { - n, err = sendFragmentedClientHello(c, b, c.minLength, c.maxLength) - - if err == nil { - c.PacketCount++ - return n, err - } - } - - return c.Conn.Write(b) -} - -func sendFragmentedClientHello(conn *FragmentedClientHelloConn, clientHello []byte, minFragmentSize, maxFragmentSize int) (n int, err error) { - if len(clientHello) < 5 || clientHello[0] != 22 { - return 0, errors.New("not a valid TLS ClientHello message") - } - - clientHelloLen := (int(clientHello[3]) << 8) | int(clientHello[4]) - - clientHelloData := clientHello[5:] - for i := 0; i < clientHelloLen; { - fragmentEnd := i + int(randBetween(int64(minFragmentSize), int64(maxFragmentSize))) - if fragmentEnd > clientHelloLen { - fragmentEnd = clientHelloLen - } - - fragment := clientHelloData[i:fragmentEnd] - i = fragmentEnd - - err = writeFragmentedRecord(conn, 22, fragment, clientHello) - if err != nil { - return 0, err - } - } - - return len(clientHello), nil -} - -func writeFragmentedRecord(c *FragmentedClientHelloConn, contentType uint8, data []byte, clientHello []byte) error { - header := make([]byte, 5) - header[0] = byte(clientHello[0]) - - tlsVersion := (int(clientHello[1]) << 8) | int(clientHello[2]) - binary.BigEndian.PutUint16(header[1:], uint16(tlsVersion)) - - binary.BigEndian.PutUint16(header[3:], uint16(len(data))) - _, err := c.Conn.Write(append(header, data...)) - randomInterval := randBetween(int64(c.minInterval), int64(c.maxInterval)) - time.Sleep(time.Duration(randomInterval)) - - return err -} From dca57aab2669ffdff5fc87020e41899f548d8308 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 00:27:17 +0000 Subject: [PATCH 07/71] Bump google.golang.org/grpc from 1.56.1 to 1.56.2 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.1 to 1.56.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.56.1...v1.56.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 162037c7..6c47723d 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( golang.org/x/net v0.12.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 - google.golang.org/grpc v1.56.1 + google.golang.org/grpc v1.56.2 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h12.io/socks v1.0.3 diff --git a/go.sum b/go.sum index 8a2c5db1..9e00d906 100644 --- a/go.sum +++ b/go.sum @@ -268,8 +268,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 929f286c2cbeb76913e9679205d68017402d71fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:31:59 +0000 Subject: [PATCH 08/71] Bump github.com/quic-go/quic-go from 0.36.1 to 0.36.2 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.36.1 to 0.36.2. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.36.1...v0.36.2) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6c47723d..8fc28fd2 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.36.1 + github.com/quic-go/quic-go v0.36.2 github.com/refraction-networking/utls v1.3.2 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 diff --git a/go.sum b/go.sum index 9e00d906..284fb64b 100644 --- a/go.sum +++ b/go.sum @@ -116,8 +116,8 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc8 github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.1 h1:WsG73nVtnDy1TiACxFxhQ3TqaW+DipmqzLEtNlAwZyY= -github.com/quic-go/quic-go v0.36.1/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= +github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From 8eb3cfe1444afc8217a9e11373957eba828669ea Mon Sep 17 00:00:00 2001 From: cty123 Date: Sat, 15 Jul 2023 23:58:08 +0200 Subject: [PATCH 09/71] fix: Patch potential nil pointer deference in proxy::http::client::fillRequestHeader(). --- proxy/http/client.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proxy/http/client.go b/proxy/http/client.go index b1661011..f597a502 100644 --- a/proxy/http/client.go +++ b/proxy/http/client.go @@ -172,6 +172,10 @@ func fillRequestHeader(ctx context.Context, header []*Header) ([]*Header, error) inbound := session.InboundFromContext(ctx) outbound := session.OutboundFromContext(ctx) + if inbound == nil || outbound == nil { + return nil, newError("missing inbound or outbound metadata from context") + } + data := struct { Source net.Destination Target net.Destination From 2df418abf1df4ad4a2d962bf21d26ed027ebd828 Mon Sep 17 00:00:00 2001 From: cty123 Date: Sun, 16 Jul 2023 23:02:15 +0200 Subject: [PATCH 10/71] fix: Check if address is nil for IsValid() function. --- common/net/destination.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/net/destination.go b/common/net/destination.go index 055395e9..2d0d09ed 100644 --- a/common/net/destination.go +++ b/common/net/destination.go @@ -113,7 +113,7 @@ func (d Destination) String() string { // IsValid returns true if this Destination is valid. func (d Destination) IsValid() bool { - return d.Network != Network_Unknown + return d.Address != nil && d.Network != Network_Unknown } // AsDestination converts current Endpoint into Destination. From 7aeca337298e3344c2ef983d1b6e0f1547ae83eb Mon Sep 17 00:00:00 2001 From: cty123 Date: Tue, 18 Jul 2023 22:11:09 +0200 Subject: [PATCH 11/71] fix: revert previous change on IsValid() function; add validation in getUoTConnection(); --- app/proxyman/outbound/uot.go | 3 +++ common/net/destination.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/proxyman/outbound/uot.go b/app/proxyman/outbound/uot.go index 4610bd79..f3c7426e 100644 --- a/app/proxyman/outbound/uot.go +++ b/app/proxyman/outbound/uot.go @@ -11,6 +11,9 @@ import ( ) func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) { + if dest.Address == nil { + return nil, newError("nil destination address") + } if !dest.Address.Family().IsDomain() { return nil, os.ErrInvalid } diff --git a/common/net/destination.go b/common/net/destination.go index 2d0d09ed..055395e9 100644 --- a/common/net/destination.go +++ b/common/net/destination.go @@ -113,7 +113,7 @@ func (d Destination) String() string { // IsValid returns true if this Destination is valid. func (d Destination) IsValid() bool { - return d.Address != nil && d.Network != Network_Unknown + return d.Network != Network_Unknown } // AsDestination converts current Endpoint into Destination. From b68a43f4fc2ae40aab344b1c720984326904f10f Mon Sep 17 00:00:00 2001 From: cty123 Date: Wed, 19 Jul 2023 00:28:51 +0200 Subject: [PATCH 12/71] fix: correct the logic of converting SocksAddr into net.Destination. --- common/singbridge/destination.go | 8 +++++++- proxy/shadowsocks_2022/inbound_multi.go | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common/singbridge/destination.go b/common/singbridge/destination.go index 7a89c9ef..98aed258 100644 --- a/common/singbridge/destination.go +++ b/common/singbridge/destination.go @@ -18,19 +18,25 @@ func ToNetwork(network string) net.Network { } func ToDestination(socksaddr M.Socksaddr, network net.Network) net.Destination { + // IsFqdn() implicitly checks if the domain name is valid if socksaddr.IsFqdn() { return net.Destination{ Network: network, Address: net.DomainAddress(socksaddr.Fqdn), Port: net.Port(socksaddr.Port), } - } else { + } + + // IsIP() implicitly checks if the IP address is valid + if socksaddr.IsIP() { return net.Destination{ Network: network, Address: net.IPAddress(socksaddr.Addr.AsSlice()), Port: net.Port(socksaddr.Port), } } + + return net.Destination{} } func ToSocksaddr(destination net.Destination) M.Socksaddr { diff --git a/proxy/shadowsocks_2022/inbound_multi.go b/proxy/shadowsocks_2022/inbound_multi.go index 04cac573..c9927476 100644 --- a/proxy/shadowsocks_2022/inbound_multi.go +++ b/proxy/shadowsocks_2022/inbound_multi.go @@ -204,7 +204,12 @@ func (i *MultiUserInbound) NewConnection(ctx context.Context, conn net.Conn, met }) newError("tunnelling request to tcp:", metadata.Destination).WriteToLog(session.ExportIDToError(ctx)) dispatcher := session.DispatcherFromContext(ctx) - link, err := dispatcher.Dispatch(ctx, singbridge.ToDestination(metadata.Destination, net.Network_TCP)) + destination := singbridge.ToDestination(metadata.Destination, net.Network_TCP) + if !destination.IsValid() { + return newError("invalid destination") + } + + link, err := dispatcher.Dispatch(ctx, destination) if err != nil { return err } From 4a496f94e80b6c9e2c8e687227f4abb48c9ecdd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 00:56:06 +0000 Subject: [PATCH 13/71] Bump github.com/refraction-networking/utls from 1.3.2 to 1.3.3 Bumps [github.com/refraction-networking/utls](https://github.com/refraction-networking/utls) from 1.3.2 to 1.3.3. - [Release notes](https://github.com/refraction-networking/utls/releases) - [Commits](https://github.com/refraction-networking/utls/compare/v1.3.2...v1.3.3) --- updated-dependencies: - dependency-name: github.com/refraction-networking/utls dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8fc28fd2..aac94b41 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 github.com/quic-go/quic-go v0.36.2 - github.com/refraction-networking/utls v1.3.2 + github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c diff --git a/go.sum b/go.sum index 284fb64b..4324d979 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8G github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= -github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8= -github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= +github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= +github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= From 316034226cbe964065c46e1b3cc31dc492778f08 Mon Sep 17 00:00:00 2001 From: KatyushaScarlet Date: Mon, 17 Jul 2023 15:09:02 +0800 Subject: [PATCH 14/71] CI: Add Linux loong64 build task --- .github/build/friendly-filenames.json | 3 ++- .github/workflows/release.yml | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/build/friendly-filenames.json b/.github/build/friendly-filenames.json index 65c20300..f7a3e526 100644 --- a/.github/build/friendly-filenames.json +++ b/.github/build/friendly-filenames.json @@ -22,6 +22,7 @@ "linux-ppc64le": { "friendlyName": "linux-ppc64le" }, "linux-ppc64": { "friendlyName": "linux-ppc64" }, "linux-riscv64": { "friendlyName": "linux-riscv64" }, + "linux-loong64": { "friendlyName": "linux-loong64" }, "linux-s390x": { "friendlyName": "linux-s390x" }, "openbsd-386": { "friendlyName": "openbsd-32" }, "openbsd-amd64": { "friendlyName": "openbsd-64" }, @@ -31,4 +32,4 @@ "windows-amd64": { "friendlyName": "windows-64" }, "windows-arm64": { "friendlyName": "windows-arm64-v8a" }, "windows-arm7": { "friendlyName": "windows-arm32-v7a" } -} \ No newline at end of file +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98ee485a..03c18811 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -105,12 +105,14 @@ jobs: goarch: arm goarm: 7 # BEGIN Other architectures - # BEGIN riscv64 & ARM64 + # BEGIN riscv64 & ARM64 & LOONG64 - goos: linux goarch: arm64 - goos: linux goarch: riscv64 - # END riscv64 & ARM64 + - goos: linux + goarch: loong64 + # END riscv64 & ARM64 & LOONG64 # BEGIN MIPS - goos: linux goarch: mips64 From e603b97ab4f2faeae723381860e7720569723bc4 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Fri, 21 Jul 2023 14:42:09 +0000 Subject: [PATCH 15/71] Add NekoRay and V2rayU to README/GUI Clients Closes https://github.com/XTLS/Xray-core/issues/2354 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 00a2a811..3e67915b 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ - [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray)) - Windows - [v2rayN](https://github.com/2dust/v2rayN) + - [NekoRay](https://github.com/Matsuridayo/nekoray) - [HiddifyN](https://github.com/hiddify/HiddifyN) - [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient) - Android @@ -73,10 +74,12 @@ - [Mango](https://github.com/arror/Mango) - [FoXray](https://apps.apple.com/app/foxray/id6448898396) - macOS arm64 & x64 + - [V2rayU](https://github.com/yanue/V2rayU) - [V2RayXS](https://github.com/tzmax/V2RayXS) - [FoXray](https://apps.apple.com/app/foxray/id6448898396) - Linux - [v2rayA](https://github.com/v2rayA/v2rayA) + - [NekoRay](https://github.com/Matsuridayo/nekoray) ## Others that support VLESS, XTLS, REALITY, XUDP, PLUX... From 51769fdde1ca663dcb08d942618e480bee13109f Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Sat, 22 Jul 2023 06:06:25 +0800 Subject: [PATCH 16/71] H2 transport: Abandon `client` if `client.Do(request)` failed See https://github.com/golang/go/issues/30702 Fixes https://github.com/XTLS/Xray-core/issues/2355 --- transport/internet/http/dialer.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/transport/internet/http/dialer.go b/transport/internet/http/dialer.go index 010a95a5..f2e55de8 100644 --- a/transport/internet/http/dialer.go +++ b/transport/internet/http/dialer.go @@ -173,6 +173,15 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if err != nil { newError("failed to dial to ", dest).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) wrc.Close() + { + // Abandon `client` if `client.Do(request)` failed + // See https://github.com/golang/go/issues/30702 + globalDialerAccess.Lock() + if globalDialerMap[dialerConf{dest, streamSettings}] == client { + delete(globalDialerMap, dialerConf{dest, streamSettings}) + } + globalDialerAccess.Unlock() + } return } if response.StatusCode != 200 { From 1e9d288b99376799732c0c1842f0b5b659b395f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 00:32:59 +0000 Subject: [PATCH 17/71] Bump google.golang.org/grpc from 1.56.2 to 1.57.0 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.56.2 to 1.57.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.56.2...v1.57.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index aac94b41..ca55dfd7 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( golang.org/x/net v0.12.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 - google.golang.org/grpc v1.56.2 + google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h12.io/socks v1.0.3 diff --git a/go.sum b/go.sum index 4324d979..f4dd0229 100644 --- a/go.sum +++ b/go.sum @@ -268,8 +268,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 81b27aa4cc15f481c11e347ca6e56befbf9514a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 00:27:44 +0000 Subject: [PATCH 18/71] Bump github.com/quic-go/quic-go from 0.36.2 to 0.37.1 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.36.2 to 0.37.1. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.36.2...v0.37.1) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 5 ++--- go.sum | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index ca55dfd7..dd9fde53 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.36.2 + github.com/quic-go/quic-go v0.37.1 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 @@ -44,8 +44,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-19 v0.3.2 // indirect - github.com/quic-go/qtls-go1-20 v0.2.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.0 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index f4dd0229..e88175a6 100644 --- a/go.sum +++ b/go.sum @@ -112,12 +112,10 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= -github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= -github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA= -github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ= +github.com/quic-go/qtls-go1-20 v0.3.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk= +github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.37.1 h1:M+mcsFq9KoxVjCetIwH65TvusW1UdRBc6zmxI6pkeD0= +github.com/quic-go/quic-go v0.37.1/go.mod h1:XtCUOCALTTWbPyd0IxFfHf6h0sEMubRFvEYHl3QxKw8= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From a45c343b89e27cc960ea1f7f011a05df047e15d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 00:19:26 +0000 Subject: [PATCH 19/71] Bump golang.org/x/net from 0.12.0 to 0.13.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.12.0 to 0.13.0. - [Commits](https://github.com/golang/net/compare/v0.12.0...v0.13.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dd9fde53..0595f906 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 golang.org/x/crypto v0.11.0 - golang.org/x/net v0.12.0 + golang.org/x/net v0.13.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 google.golang.org/grpc v1.57.0 diff --git a/go.sum b/go.sum index e88175a6..e5b2eea9 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,8 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= From ce89b5d7de17f228d303c293e0790c8bdf8a3ab6 Mon Sep 17 00:00:00 2001 From: Loren Eteval <139033850+LorenEteval@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:30:37 +0800 Subject: [PATCH 20/71] Add Furious to README/GUI Clients (#2405) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3e67915b..761b2ee7 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ - Windows - [v2rayN](https://github.com/2dust/v2rayN) - [NekoRay](https://github.com/Matsuridayo/nekoray) + - [Furious](https://github.com/LorenEteval/Furious) - [HiddifyN](https://github.com/hiddify/HiddifyN) - [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient) - Android @@ -76,10 +77,12 @@ - macOS arm64 & x64 - [V2rayU](https://github.com/yanue/V2rayU) - [V2RayXS](https://github.com/tzmax/V2RayXS) + - [Furious](https://github.com/LorenEteval/Furious) - [FoXray](https://apps.apple.com/app/foxray/id6448898396) - Linux - [v2rayA](https://github.com/v2rayA/v2rayA) - [NekoRay](https://github.com/Matsuridayo/nekoray) + - [Furious](https://github.com/LorenEteval/Furious) ## Others that support VLESS, XTLS, REALITY, XUDP, PLUX... @@ -90,6 +93,7 @@ - [xtlsapi](https://github.com/hiddify/xtlsapi) - [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite) - [XrayKit](https://github.com/arror/XrayKit) + - [Xray-core-python](https://github.com/LorenEteval/Xray-core-python) - [XrayR](https://github.com/XrayR-project/XrayR) - [XrayR-release](https://github.com/XrayR-project/XrayR-release) - [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board) From 017b56adf53d4813d01252157140dd9df5688477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AC=E8=8A=B1ice?= <67498111+flowerinsnowdh@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:47:31 +0800 Subject: [PATCH 21/71] Recognize .jsonc files automatically (#2398) Closes https://github.com/XTLS/Xray-core/issues/2399 --- core/config.go | 2 +- main/run.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/config.go b/core/config.go index 5892226b..c845e847 100644 --- a/core/config.go +++ b/core/config.go @@ -57,7 +57,7 @@ func GetFormatByExtension(ext string) string { return "yaml" case "toml": return "toml" - case "json": + case "json", "jsonc": return "json" default: return "" diff --git a/main/run.go b/main/run.go index 97967700..1f8a4b88 100644 --- a/main/run.go +++ b/main/run.go @@ -113,13 +113,13 @@ func dirExists(file string) bool { func getRegepxByFormat() string { switch strings.ToLower(*format) { case "json": - return `^.+\.json$` + return `^.+\.(json|jsonc)$` case "toml": return `^.+\.toml$` case "yaml", "yml": return `^.+\.(yaml|yml)$` default: - return `^.+\.(json|toml|yaml|yml)$` + return `^.+\.(json|jsonc|toml|yaml|yml)$` } } From cd547a3f43c5fd03462e4d359e761e9fb345a0ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 00:58:41 +0000 Subject: [PATCH 22/71] Bump golang.org/x/crypto from 0.11.0 to 0.12.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.11.0 to 0.12.0. - [Commits](https://github.com/golang/crypto/compare/v0.11.0...v0.12.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 0595f906..da3d05ba 100644 --- a/go.mod +++ b/go.mod @@ -20,10 +20,10 @@ require ( github.com/stretchr/testify v1.8.4 github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 - golang.org/x/crypto v0.11.0 + golang.org/x/crypto v0.12.0 golang.org/x/net v0.13.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.10.0 + golang.org/x/sys v0.11.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c @@ -49,7 +49,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.11.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.10.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/go.sum b/go.sum index e5b2eea9..9503325e 100644 --- a/go.sum +++ b/go.sum @@ -176,8 +176,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= @@ -223,14 +223,14 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= From d4806c8e54a4c1cb1f13aa1aaff5a6c8d60e64b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 00:59:06 +0000 Subject: [PATCH 23/71] Bump github.com/quic-go/quic-go from 0.37.1 to 0.37.3 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.1 to 0.37.3. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.37.1...v0.37.3) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index da3d05ba..97583fed 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.37.1 + github.com/quic-go/quic-go v0.37.3 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 @@ -44,7 +44,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.0 // indirect + github.com/quic-go/qtls-go1-20 v0.3.1 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index 9503325e..18686edb 100644 --- a/go.sum +++ b/go.sum @@ -112,10 +112,10 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/quic-go/qtls-go1-20 v0.3.0 h1:NrCXmDl8BddZwO67vlvEpBTwT89bJfKYygxv4HQvuDk= -github.com/quic-go/qtls-go1-20 v0.3.0/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.1 h1:M+mcsFq9KoxVjCetIwH65TvusW1UdRBc6zmxI6pkeD0= -github.com/quic-go/quic-go v0.37.1/go.mod h1:XtCUOCALTTWbPyd0IxFfHf6h0sEMubRFvEYHl3QxKw8= +github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= +github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.37.3 h1:pkHH3xaMNUNAh6OtgEV/0K6Fz+YIJXhPzgd/ShiRDm4= +github.com/quic-go/quic-go v0.37.3/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From d11826ee542bc06728c3436831a9e423666a4475 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 00:44:07 +0000 Subject: [PATCH 24/71] Bump golang.org/x/net from 0.13.0 to 0.14.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.13.0 to 0.14.0. - [Commits](https://github.com/golang/net/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 97583fed..65bb74a5 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 golang.org/x/crypto v0.12.0 - golang.org/x/net v0.13.0 + golang.org/x/net v0.14.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.11.0 google.golang.org/grpc v1.57.0 diff --git a/go.sum b/go.sum index 18686edb..93324e7a 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,8 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= From e584b71b6082585d322de84304e2e0ab50deed20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Aug 2023 00:29:10 +0000 Subject: [PATCH 25/71] Bump github.com/quic-go/quic-go from 0.37.3 to 0.37.4 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.3 to 0.37.4. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.37.3...v0.37.4) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 65bb74a5..1fdb91b7 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.37.3 + github.com/quic-go/quic-go v0.37.4 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 diff --git a/go.sum b/go.sum index 93324e7a..7900b808 100644 --- a/go.sum +++ b/go.sum @@ -114,8 +114,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.3 h1:pkHH3xaMNUNAh6OtgEV/0K6Fz+YIJXhPzgd/ShiRDm4= -github.com/quic-go/quic-go v0.37.3/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= +github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4= +github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From f67167bb3bbfcb0f45393f37005a51024e58864b Mon Sep 17 00:00:00 2001 From: hax0r31337 Date: Thu, 10 Aug 2023 04:43:34 +0000 Subject: [PATCH 26/71] refactor(deps): replace github.com/golang/protobuf with google.golang.org/protobuf --- app/observatory/observer.go | 2 +- app/reverse/bridge.go | 2 +- app/reverse/portal.go | 2 +- app/router/condition_geoip_test.go | 2 +- app/router/condition_test.go | 2 +- common/serial/typed_message.go | 18 +++++++++--------- core/config.go | 2 +- core/functions_test.go | 2 +- core/xray_test.go | 2 +- features/extension/observatory.go | 2 +- go.mod | 2 +- infra/conf/blackhole.go | 2 +- infra/conf/buildable.go | 2 +- infra/conf/dns_proxy.go | 2 +- infra/conf/dns_test.go | 2 +- infra/conf/dokodemo.go | 2 +- infra/conf/freedom.go | 2 +- infra/conf/general_test.go | 2 +- infra/conf/grpc.go | 2 +- infra/conf/http.go | 2 +- infra/conf/loopback.go | 2 +- infra/conf/observatory.go | 2 +- infra/conf/reverse.go | 2 +- infra/conf/router.go | 21 +++++++++++++++++++-- infra/conf/router_test.go | 2 +- infra/conf/shadowsocks.go | 2 +- infra/conf/socks.go | 2 +- infra/conf/transport_authenticators.go | 2 +- infra/conf/transport_internet.go | 2 +- infra/conf/transport_test.go | 2 +- infra/conf/trojan.go | 2 +- infra/conf/vless.go | 2 +- infra/conf/vmess.go | 2 +- infra/conf/wireguard.go | 2 +- infra/conf/xray_test.go | 2 +- proxy/vless/encoding/addons.go | 2 +- testing/scenarios/common.go | 2 +- 37 files changed, 63 insertions(+), 46 deletions(-) diff --git a/app/observatory/observer.go b/app/observatory/observer.go index 576818c4..9d961f66 100644 --- a/app/observatory/observer.go +++ b/app/observatory/observer.go @@ -9,7 +9,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common" v2net "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" @@ -19,6 +18,7 @@ import ( "github.com/xtls/xray-core/features/extension" "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/transport/internet/tagged" + "google.golang.org/protobuf/proto" ) type Observer struct { diff --git a/app/reverse/bridge.go b/app/reverse/bridge.go index 4b86c3a2..be0fdcd9 100644 --- a/app/reverse/bridge.go +++ b/app/reverse/bridge.go @@ -4,7 +4,6 @@ import ( "context" "time" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/mux" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" @@ -12,6 +11,7 @@ import ( "github.com/xtls/xray-core/features/routing" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/pipe" + "google.golang.org/protobuf/proto" ) // Bridge is a component in reverse proxy, that relays connections from Portal to local address. diff --git a/app/reverse/portal.go b/app/reverse/portal.go index b0860a6e..fb0b6930 100644 --- a/app/reverse/portal.go +++ b/app/reverse/portal.go @@ -5,7 +5,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/mux" @@ -15,6 +14,7 @@ import ( "github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/pipe" + "google.golang.org/protobuf/proto" ) type Portal struct { diff --git a/app/router/condition_geoip_test.go b/app/router/condition_geoip_test.go index b5a5ef90..1a730021 100644 --- a/app/router/condition_geoip_test.go +++ b/app/router/condition_geoip_test.go @@ -5,12 +5,12 @@ import ( "path/filepath" "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" + "google.golang.org/protobuf/proto" ) func init() { diff --git a/app/router/condition_test.go b/app/router/condition_test.go index fd898417..b5d59297 100644 --- a/app/router/condition_test.go +++ b/app/router/condition_test.go @@ -6,7 +6,6 @@ import ( "strconv" "testing" - "github.com/golang/protobuf/proto" . "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" @@ -18,6 +17,7 @@ import ( "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/features/routing" routing_session "github.com/xtls/xray-core/features/routing/session" + "google.golang.org/protobuf/proto" ) func init() { diff --git a/common/serial/typed_message.go b/common/serial/typed_message.go index e59d1d0d..baecc92e 100644 --- a/common/serial/typed_message.go +++ b/common/serial/typed_message.go @@ -1,10 +1,9 @@ package serial import ( - "errors" - "reflect" - - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" ) // ToTypedMessage converts a proto Message into TypedMessage. @@ -21,16 +20,17 @@ func ToTypedMessage(message proto.Message) *TypedMessage { // GetMessageType returns the name of this proto Message. func GetMessageType(message proto.Message) string { - return proto.MessageName(message) + return string(message.ProtoReflect().Descriptor().FullName()) } // GetInstance creates a new instance of the message with messageType. func GetInstance(messageType string) (interface{}, error) { - mType := proto.MessageType(messageType) - if mType == nil || mType.Elem() == nil { - return nil, errors.New("Serial: Unknown type: " + messageType) + messageTypeDescriptor := protoreflect.FullName(messageType) + mType, err := protoregistry.GlobalTypes.FindMessageByName(messageTypeDescriptor) + if err != nil { + return nil, err } - return reflect.New(mType.Elem()).Interface(), nil + return mType.New().Interface(), nil } // GetInstance converts current TypedMessage into a proto Message. diff --git a/core/config.go b/core/config.go index c845e847..f4077449 100644 --- a/core/config.go +++ b/core/config.go @@ -4,11 +4,11 @@ import ( "io" "strings" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/cmdarg" "github.com/xtls/xray-core/main/confloader" + "google.golang.org/protobuf/proto" ) // ConfigFormat is a configurable format of Xray config file. diff --git a/core/functions_test.go b/core/functions_test.go index 2355cc03..5658de1c 100644 --- a/core/functions_test.go +++ b/core/functions_test.go @@ -7,7 +7,6 @@ import ( "testing" "time" - "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" "github.com/xtls/xray-core/app/dispatcher" "github.com/xtls/xray-core/app/proxyman" @@ -18,6 +17,7 @@ import ( "github.com/xtls/xray-core/proxy/freedom" "github.com/xtls/xray-core/testing/servers/tcp" "github.com/xtls/xray-core/testing/servers/udp" + "google.golang.org/protobuf/proto" ) func xor(b []byte) []byte { diff --git a/core/xray_test.go b/core/xray_test.go index 59de0f46..a4a8ec9f 100644 --- a/core/xray_test.go +++ b/core/xray_test.go @@ -3,7 +3,6 @@ package core_test import ( "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/dispatcher" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" @@ -19,6 +18,7 @@ import ( "github.com/xtls/xray-core/proxy/vmess" "github.com/xtls/xray-core/proxy/vmess/outbound" "github.com/xtls/xray-core/testing/servers/tcp" + "google.golang.org/protobuf/proto" ) func TestXrayDependency(t *testing.T) { diff --git a/features/extension/observatory.go b/features/extension/observatory.go index eb51a61b..8e871030 100644 --- a/features/extension/observatory.go +++ b/features/extension/observatory.go @@ -3,8 +3,8 @@ package extension import ( "context" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/features" + "google.golang.org/protobuf/proto" ) type Observatory interface { diff --git a/go.mod b/go.mod index 1fdb91b7..e76ded6a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.20 require ( github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.5.9 github.com/gorilla/websocket v1.5.0 github.com/miekg/dns v1.1.55 @@ -38,6 +37,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/gaukas/godicttls v0.0.3 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/klauspost/compress v1.16.6 // indirect diff --git a/infra/conf/blackhole.go b/infra/conf/blackhole.go index c1551de1..5044a8c0 100644 --- a/infra/conf/blackhole.go +++ b/infra/conf/blackhole.go @@ -3,9 +3,9 @@ package conf import ( "encoding/json" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/blackhole" + "google.golang.org/protobuf/proto" ) type NoneResponse struct{} diff --git a/infra/conf/buildable.go b/infra/conf/buildable.go index 1d01cd66..967e9740 100644 --- a/infra/conf/buildable.go +++ b/infra/conf/buildable.go @@ -1,6 +1,6 @@ package conf -import "github.com/golang/protobuf/proto" +import "google.golang.org/protobuf/proto" type Buildable interface { Build() (proto.Message, error) diff --git a/infra/conf/dns_proxy.go b/infra/conf/dns_proxy.go index 564084e0..13a44597 100644 --- a/infra/conf/dns_proxy.go +++ b/infra/conf/dns_proxy.go @@ -1,9 +1,9 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/proxy/dns" + "google.golang.org/protobuf/proto" ) type DNSOutboundConfig struct { diff --git a/infra/conf/dns_test.go b/infra/conf/dns_test.go index c97c5bea..1c370cd9 100644 --- a/infra/conf/dns_test.go +++ b/infra/conf/dns_test.go @@ -6,7 +6,6 @@ import ( "path/filepath" "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/dns" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" @@ -14,6 +13,7 @@ import ( "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" . "github.com/xtls/xray-core/infra/conf" + "google.golang.org/protobuf/proto" ) func init() { diff --git a/infra/conf/dokodemo.go b/infra/conf/dokodemo.go index 03a21d71..2a4b74ea 100644 --- a/infra/conf/dokodemo.go +++ b/infra/conf/dokodemo.go @@ -1,8 +1,8 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/proxy/dokodemo" + "google.golang.org/protobuf/proto" ) type DokodemoConfig struct { diff --git a/infra/conf/freedom.go b/infra/conf/freedom.go index 60c5b7f1..21f0616a 100644 --- a/infra/conf/freedom.go +++ b/infra/conf/freedom.go @@ -5,10 +5,10 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/proto" v2net "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy/freedom" + "google.golang.org/protobuf/proto" ) type FreedomConfig struct { diff --git a/infra/conf/general_test.go b/infra/conf/general_test.go index 1de1109c..4d23b3b5 100644 --- a/infra/conf/general_test.go +++ b/infra/conf/general_test.go @@ -4,9 +4,9 @@ import ( "encoding/json" "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common" . "github.com/xtls/xray-core/infra/conf" + "google.golang.org/protobuf/proto" ) func loadJSON(creator func() Buildable) func(string) (proto.Message, error) { diff --git a/infra/conf/grpc.go b/infra/conf/grpc.go index 9085ab4d..18447512 100644 --- a/infra/conf/grpc.go +++ b/infra/conf/grpc.go @@ -1,8 +1,8 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/transport/internet/grpc" + "google.golang.org/protobuf/proto" ) type GRPCConfig struct { diff --git a/infra/conf/http.go b/infra/conf/http.go index ddeaa69e..b391dbf2 100644 --- a/infra/conf/http.go +++ b/infra/conf/http.go @@ -3,10 +3,10 @@ package conf import ( "encoding/json" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/http" + "google.golang.org/protobuf/proto" ) type HTTPAccount struct { diff --git a/infra/conf/loopback.go b/infra/conf/loopback.go index b6d83178..87d349ce 100644 --- a/infra/conf/loopback.go +++ b/infra/conf/loopback.go @@ -1,8 +1,8 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/proxy/loopback" + "google.golang.org/protobuf/proto" ) type LoopbackConfig struct { diff --git a/infra/conf/observatory.go b/infra/conf/observatory.go index 25a4d52c..f51787a4 100644 --- a/infra/conf/observatory.go +++ b/infra/conf/observatory.go @@ -1,9 +1,9 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/observatory" "github.com/xtls/xray-core/infra/conf/cfgcommon/duration" + "google.golang.org/protobuf/proto" ) type ObservatoryConfig struct { diff --git a/infra/conf/reverse.go b/infra/conf/reverse.go index 1b42a63a..f44c9992 100644 --- a/infra/conf/reverse.go +++ b/infra/conf/reverse.go @@ -1,8 +1,8 @@ package conf import ( - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/reverse" + "google.golang.org/protobuf/proto" ) type BridgeConfig struct { diff --git a/infra/conf/router.go b/infra/conf/router.go index 135454bc..a9f57cd6 100644 --- a/infra/conf/router.go +++ b/infra/conf/router.go @@ -6,10 +6,10 @@ import ( "strconv" "strings" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform/filesystem" + "google.golang.org/protobuf/proto" ) type RouterRulesConfig struct { @@ -245,6 +245,23 @@ func loadSite(file, code string) ([]*router.Domain, error) { return SiteCache[index].Domain, nil } +func DecodeVarint(buf []byte) (x uint64, n int) { + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + func find(data, code []byte) []byte { codeL := len(code) if codeL == 0 { @@ -255,7 +272,7 @@ func find(data, code []byte) []byte { if dataL < 2 { return nil } - x, y := proto.DecodeVarint(data[1:]) + x, y := DecodeVarint(data[1:]) if x == 0 && y == 0 { return nil } diff --git a/infra/conf/router_test.go b/infra/conf/router_test.go index 98e31b3a..63dc8e8d 100644 --- a/infra/conf/router_test.go +++ b/infra/conf/router_test.go @@ -7,13 +7,13 @@ import ( "testing" _ "unsafe" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/platform/filesystem" . "github.com/xtls/xray-core/infra/conf" + "google.golang.org/protobuf/proto" ) func init() { diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index 240d4aaa..3dcbb2f3 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -3,13 +3,13 @@ package conf import ( "strings" - "github.com/golang/protobuf/proto" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" C "github.com/sagernet/sing/common" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/shadowsocks" "github.com/xtls/xray-core/proxy/shadowsocks_2022" + "google.golang.org/protobuf/proto" ) func cipherFromString(c string) shadowsocks.CipherType { diff --git a/infra/conf/socks.go b/infra/conf/socks.go index 490c24bd..61f6fae2 100644 --- a/infra/conf/socks.go +++ b/infra/conf/socks.go @@ -4,10 +4,10 @@ import ( "encoding/json" "strings" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/socks" + "google.golang.org/protobuf/proto" ) type SocksAccount struct { diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index 46be8588..db9f4a72 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -3,7 +3,6 @@ package conf import ( "sort" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/transport/internet/headers/dns" "github.com/xtls/xray-core/transport/internet/headers/http" "github.com/xtls/xray-core/transport/internet/headers/noop" @@ -12,6 +11,7 @@ import ( "github.com/xtls/xray-core/transport/internet/headers/utp" "github.com/xtls/xray-core/transport/internet/headers/wechat" "github.com/xtls/xray-core/transport/internet/headers/wireguard" + "google.golang.org/protobuf/proto" ) type NoOpAuthenticator struct{} diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 958edfad..55cc8c2e 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -11,7 +11,6 @@ import ( "strings" "syscall" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/platform/filesystem" "github.com/xtls/xray-core/common/protocol" @@ -26,6 +25,7 @@ import ( "github.com/xtls/xray-core/transport/internet/tcp" "github.com/xtls/xray-core/transport/internet/tls" "github.com/xtls/xray-core/transport/internet/websocket" + "google.golang.org/protobuf/proto" ) var ( diff --git a/infra/conf/transport_test.go b/infra/conf/transport_test.go index 3afe9729..989c259c 100644 --- a/infra/conf/transport_test.go +++ b/infra/conf/transport_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "testing" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" . "github.com/xtls/xray-core/infra/conf" @@ -18,6 +17,7 @@ import ( "github.com/xtls/xray-core/transport/internet/quic" "github.com/xtls/xray-core/transport/internet/tcp" "github.com/xtls/xray-core/transport/internet/websocket" + "google.golang.org/protobuf/proto" ) func TestSocketConfig(t *testing.T) { diff --git a/infra/conf/trojan.go b/infra/conf/trojan.go index e9d78f8a..2cd1e520 100644 --- a/infra/conf/trojan.go +++ b/infra/conf/trojan.go @@ -6,11 +6,11 @@ import ( "strconv" "syscall" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/proxy/trojan" + "google.golang.org/protobuf/proto" ) // TrojanServerTarget is configuration of a single trojan server diff --git a/infra/conf/vless.go b/infra/conf/vless.go index d829cdee..2e5c5d64 100644 --- a/infra/conf/vless.go +++ b/infra/conf/vless.go @@ -6,7 +6,6 @@ import ( "strconv" "syscall" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" @@ -14,6 +13,7 @@ import ( "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/inbound" "github.com/xtls/xray-core/proxy/vless/outbound" + "google.golang.org/protobuf/proto" ) type VLessInboundFallback struct { diff --git a/infra/conf/vmess.go b/infra/conf/vmess.go index 93d0e75b..ba319356 100644 --- a/infra/conf/vmess.go +++ b/infra/conf/vmess.go @@ -4,13 +4,13 @@ import ( "encoding/json" "strings" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/uuid" "github.com/xtls/xray-core/proxy/vmess" "github.com/xtls/xray-core/proxy/vmess/inbound" "github.com/xtls/xray-core/proxy/vmess/outbound" + "google.golang.org/protobuf/proto" ) type VMessAccount struct { diff --git a/infra/conf/wireguard.go b/infra/conf/wireguard.go index 6b102b14..0c79297b 100644 --- a/infra/conf/wireguard.go +++ b/infra/conf/wireguard.go @@ -4,8 +4,8 @@ import ( "encoding/base64" "encoding/hex" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/proxy/wireguard" + "google.golang.org/protobuf/proto" ) type WireGuardPeerConfig struct { diff --git a/infra/conf/xray_test.go b/infra/conf/xray_test.go index a4898457..c7e20ed4 100644 --- a/infra/conf/xray_test.go +++ b/infra/conf/xray_test.go @@ -5,7 +5,6 @@ import ( "reflect" "testing" - "github.com/golang/protobuf/proto" "github.com/google/go-cmp/cmp" "github.com/xtls/xray-core/app/dispatcher" "github.com/xtls/xray-core/app/log" @@ -27,6 +26,7 @@ import ( "github.com/xtls/xray-core/transport/internet/http" "github.com/xtls/xray-core/transport/internet/tls" "github.com/xtls/xray-core/transport/internet/websocket" + "google.golang.org/protobuf/proto" ) func TestXrayConfig(t *testing.T) { diff --git a/proxy/vless/encoding/addons.go b/proxy/vless/encoding/addons.go index d62e400f..fc8ddc2a 100644 --- a/proxy/vless/encoding/addons.go +++ b/proxy/vless/encoding/addons.go @@ -3,10 +3,10 @@ package encoding import ( "io" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/proxy/vless" + "google.golang.org/protobuf/proto" ) func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error { diff --git a/testing/scenarios/common.go b/testing/scenarios/common.go index f011a64f..8d629c59 100644 --- a/testing/scenarios/common.go +++ b/testing/scenarios/common.go @@ -14,7 +14,6 @@ import ( "testing" "time" - "github.com/golang/protobuf/proto" "github.com/xtls/xray-core/app/dispatcher" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" @@ -25,6 +24,7 @@ import ( "github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/units" core "github.com/xtls/xray-core/core" + "google.golang.org/protobuf/proto" ) func xor(b []byte) []byte { From a343d689444e3ace08252b17ae1cf7f939a283ef Mon Sep 17 00:00:00 2001 From: cty123 Date: Sat, 19 Aug 2023 22:10:59 +0200 Subject: [PATCH 27/71] fix(proxy): removed the udp payload length check when encryption is disabled --- proxy/shadowsocks/protocol.go | 64 +++++++++++---------- proxy/shadowsocks/protocol_test.go | 91 ++++++++++++++++++++++-------- proxy/shadowsocks/validator.go | 5 ++ 3 files changed, 107 insertions(+), 53 deletions(-) diff --git a/proxy/shadowsocks/protocol.go b/proxy/shadowsocks/protocol.go index 3176d118..3a0c7e22 100644 --- a/proxy/shadowsocks/protocol.go +++ b/proxy/shadowsocks/protocol.go @@ -4,6 +4,7 @@ import ( "crypto/hmac" "crypto/rand" "crypto/sha256" + "errors" "hash/crc32" "io" @@ -236,37 +237,37 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buff } func DecodeUDPPacket(validator *Validator, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) { - bs := payload.Bytes() - if len(bs) <= 32 { - return nil, nil, newError("len(bs) <= 32") - } + rawPayload := payload.Bytes() + user, _, d, _, err := validator.Get(rawPayload, protocol.RequestCommandUDP) - user, _, d, _, err := validator.Get(bs, protocol.RequestCommandUDP) - switch err { - case ErrIVNotUnique: + if errors.Is(err, ErrIVNotUnique) { return nil, nil, newError("failed iv check").Base(err) - case ErrNotFound: - return nil, nil, newError("failed to match an user").Base(err) - default: - account := user.Account.(*MemoryAccount) - if account.Cipher.IsAEAD() { - payload.Clear() - payload.Write(d) - } else { - if account.Cipher.IVSize() > 0 { - iv := make([]byte, account.Cipher.IVSize()) - copy(iv, payload.BytesTo(account.Cipher.IVSize())) - } - if err = account.Cipher.DecodePacket(account.Key, payload); err != nil { - return nil, nil, newError("failed to decrypt UDP payload").Base(err) - } - } } - request := &protocol.RequestHeader{ - Version: Version, - User: user, - Command: protocol.RequestCommandUDP, + if errors.Is(err, ErrNotFound) { + return nil, nil, newError("failed to match an user").Base(err) + } + + if err != nil { + return nil, nil, newError("unexpected error").Base(err) + } + + account, ok := user.Account.(*MemoryAccount) + if !ok { + return nil, nil, newError("expected MemoryAccount returned from validator") + } + + if account.Cipher.IsAEAD() { + payload.Clear() + payload.Write(d) + } else { + if account.Cipher.IVSize() > 0 { + iv := make([]byte, account.Cipher.IVSize()) + copy(iv, payload.BytesTo(account.Cipher.IVSize())) + } + if err = account.Cipher.DecodePacket(account.Key, payload); err != nil { + return nil, nil, newError("failed to decrypt UDP payload").Base(err) + } } payload.SetByte(0, payload.Byte(0)&0x0F) @@ -276,8 +277,13 @@ func DecodeUDPPacket(validator *Validator, payload *buf.Buffer) (*protocol.Reque return nil, nil, newError("failed to parse address").Base(err) } - request.Address = addr - request.Port = port + request := &protocol.RequestHeader{ + Version: Version, + User: user, + Command: protocol.RequestCommandUDP, + Address: addr, + Port: port, + } return request, payload, nil } diff --git a/proxy/shadowsocks/protocol_test.go b/proxy/shadowsocks/protocol_test.go index e1b6495e..4083905d 100644 --- a/proxy/shadowsocks/protocol_test.go +++ b/proxy/shadowsocks/protocol_test.go @@ -23,37 +23,80 @@ func equalRequestHeader(x, y *protocol.RequestHeader) bool { })) } -func TestUDPEncoding(t *testing.T) { - request := &protocol.RequestHeader{ - Version: Version, - Command: protocol.RequestCommandUDP, - Address: net.LocalHostIP, - Port: 1234, - User: &protocol.MemoryUser{ - Email: "love@example.com", - Account: toAccount(&Account{ - Password: "password", - CipherType: CipherType_AES_128_GCM, - }), +func TestUDPEncodingDecoding(t *testing.T) { + testRequests := []protocol.RequestHeader{ + { + Version: Version, + Command: protocol.RequestCommandUDP, + Address: net.LocalHostIP, + Port: 1234, + User: &protocol.MemoryUser{ + Email: "love@example.com", + Account: toAccount(&Account{ + Password: "password", + CipherType: CipherType_AES_128_GCM, + }), + }, + }, + { + Version: Version, + Command: protocol.RequestCommandUDP, + Address: net.LocalHostIP, + Port: 1234, + User: &protocol.MemoryUser{ + Email: "love@example.com", + Account: toAccount(&Account{ + Password: "123", + CipherType: CipherType_NONE, + }), + }, }, } - data := buf.New() - common.Must2(data.WriteString("test string")) - encodedData, err := EncodeUDPPacket(request, data.Bytes()) - common.Must(err) + for _, request := range testRequests { + data := buf.New() + common.Must2(data.WriteString("test string")) + encodedData, err := EncodeUDPPacket(&request, data.Bytes()) + common.Must(err) - validator := new(Validator) - validator.Add(request.User) - decodedRequest, decodedData, err := DecodeUDPPacket(validator, encodedData) - common.Must(err) + validator := new(Validator) + validator.Add(request.User) + decodedRequest, decodedData, err := DecodeUDPPacket(validator, encodedData) + common.Must(err) - if r := cmp.Diff(decodedData.Bytes(), data.Bytes()); r != "" { - t.Error("data: ", r) + if r := cmp.Diff(decodedData.Bytes(), data.Bytes()); r != "" { + t.Error("data: ", r) + } + + if equalRequestHeader(decodedRequest, &request) == false { + t.Error("different request") + } + } +} + +func TestUDPDecodingWithPayloadTooShort(t *testing.T) { + testAccounts := []protocol.Account{ + toAccount(&Account{ + Password: "password", + CipherType: CipherType_AES_128_GCM, + }), + toAccount(&Account{ + Password: "password", + CipherType: CipherType_NONE, + }), } - if equalRequestHeader(decodedRequest, request) == false { - t.Error("different request") + for _, account := range testAccounts { + data := buf.New() + data.WriteString("short payload") + validator := new(Validator) + validator.Add(&protocol.MemoryUser{ + Account: account, + }) + _, _, err := DecodeUDPPacket(validator, data) + if err == nil { + t.Fatal("expected error") + } } } diff --git a/proxy/shadowsocks/validator.go b/proxy/shadowsocks/validator.go index 2aa62e06..8888a1c0 100644 --- a/proxy/shadowsocks/validator.go +++ b/proxy/shadowsocks/validator.go @@ -80,6 +80,11 @@ func (v *Validator) Get(bs []byte, command protocol.RequestCommand) (u *protocol for _, user := range v.users { if account := user.Account.(*MemoryAccount); account.Cipher.IsAEAD() { + // AEAD payload decoding requires the payload to be over 32 bytes + if len(bs) < 32 { + continue + } + aeadCipher := account.Cipher.(*AEADCipher) ivLen = aeadCipher.IVSize() iv := bs[:ivLen] From 75c99e283a397e43ccca9c7ead7d8596b1b6f633 Mon Sep 17 00:00:00 2001 From: iamybj <94730407+benjaminyin01@users.noreply.github.com> Date: Sat, 19 Aug 2023 22:19:46 +0800 Subject: [PATCH 28/71] Update README.md A better docker image of xray --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 761b2ee7..f4723d88 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ - Linux Script - [XTLS/Xray-install](https://github.com/XTLS/Xray-install) - Docker + - [iamybj/docker-xray](https://hub.docker.com/r/iamybj/docker-xray) - [teddysun/xray](https://hub.docker.com/r/teddysun/xray) - Web Panel - [X-UI](https://github.com/FranzKafkaYu/x-ui), [X-UI-English](https://github.com/NidukaAkalanka/x-ui-english), [3X-UI](https://github.com/MHSanaei/3x-ui), [X-UI](https://github.com/alireza0/x-ui), [X-UI](https://github.com/diditra/x-ui) From 599cfd09b08acb1f000a2e83b4563317872a5158 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 01:01:53 +0000 Subject: [PATCH 29/71] Bump github.com/quic-go/quic-go from 0.37.4 to 0.37.5 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.4 to 0.37.5. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.37.4...v0.37.5) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e76ded6a..973250b7 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.37.4 + github.com/quic-go/quic-go v0.37.5 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 diff --git a/go.sum b/go.sum index 7900b808..4198fcf5 100644 --- a/go.sum +++ b/go.sum @@ -114,8 +114,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.4 h1:ke8B73yMCWGq9MfrCCAw0Uzdm7GaViC3i39dsIdDlH4= -github.com/quic-go/quic-go v0.37.4/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= +github.com/quic-go/quic-go v0.37.5 h1:pzkYe8AgaxHi+7KJrYBMF+u2rLO5a9kwyCp2dAsljzk= +github.com/quic-go/quic-go v0.37.5/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From efe8f3f4d6cce5ed529c2b1aa0a39b7a08e031a3 Mon Sep 17 00:00:00 2001 From: cty123 Date: Sun, 20 Aug 2023 13:18:39 +0200 Subject: [PATCH 30/71] fix(config): fix grpc cofnig parsing when service name only has one '/' char --- transport/internet/grpc/config.go | 7 ++++++- transport/internet/grpc/config_test.go | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/transport/internet/grpc/config.go b/transport/internet/grpc/config.go index 39eadf31..aab1178e 100644 --- a/transport/internet/grpc/config.go +++ b/transport/internet/grpc/config.go @@ -21,8 +21,13 @@ func (c *Config) getServiceName() string { if !strings.HasPrefix(c.ServiceName, "/") { return url.PathEscape(c.ServiceName) } + // Otherwise new custom paths - rawServiceName := c.ServiceName[1:strings.LastIndex(c.ServiceName, "/")] // trim from first to last '/' + lastIndex := strings.LastIndex(c.ServiceName, "/") + if lastIndex < 1 { + lastIndex = 1 + } + rawServiceName := c.ServiceName[1:lastIndex] // trim from first to last '/' serviceNameParts := strings.Split(rawServiceName, "/") for i := range serviceNameParts { serviceNameParts[i] = url.PathEscape(serviceNameParts[i]) diff --git a/transport/internet/grpc/config_test.go b/transport/internet/grpc/config_test.go index fbc549b4..b159ffdf 100644 --- a/transport/internet/grpc/config_test.go +++ b/transport/internet/grpc/config_test.go @@ -1,8 +1,9 @@ package grpc import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestConfig_GetServiceName(t *testing.T) { @@ -31,6 +32,11 @@ func TestConfig_GetServiceName(t *testing.T) { ServiceName: "/hello /world!/a|b", Expected: "hello%20/world%21", }, + { + TestName: "path with only one '/'", + ServiceName: "/foo", + Expected: "", + }, } for _, test := range tests { t.Run(test.TestName, func(t *testing.T) { From 783ac10842aa424733ee5b9b057e6820c0f593d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 00:40:57 +0000 Subject: [PATCH 31/71] Bump github.com/quic-go/quic-go from 0.37.5 to 0.37.6 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.5 to 0.37.6. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.37.5...v0.37.6) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 973250b7..4b4e8c11 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.37.5 + github.com/quic-go/quic-go v0.37.6 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 diff --git a/go.sum b/go.sum index 4198fcf5..49facab3 100644 --- a/go.sum +++ b/go.sum @@ -114,8 +114,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.5 h1:pzkYe8AgaxHi+7KJrYBMF+u2rLO5a9kwyCp2dAsljzk= -github.com/quic-go/quic-go v0.37.5/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= +github.com/quic-go/quic-go v0.37.6 h1:2IIUmQzT5YNxAiaPGjs++Z4hGOtIR0q79uS5qE9ccfY= +github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From acadf5c0e99ecc94770c991ab1848f7e250e305c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 00:03:57 +0000 Subject: [PATCH 32/71] Bump github.com/quic-go/quic-go from 0.37.6 to 0.38.0 Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.6 to 0.38.0. - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.37.6...v0.38.0) --- updated-dependencies: - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 4b4e8c11..2625a6ab 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.37.6 + github.com/quic-go/quic-go v0.38.0 github.com/refraction-networking/utls v1.3.3 github.com/sagernet/sing v0.2.7 github.com/sagernet/sing-shadowsocks v0.2.2 @@ -44,7 +44,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.1 // indirect + github.com/quic-go/qtls-go1-20 v0.3.2 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index 49facab3..a98d33c6 100644 --- a/go.sum +++ b/go.sum @@ -112,10 +112,10 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg= -github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.37.6 h1:2IIUmQzT5YNxAiaPGjs++Z4hGOtIR0q79uS5qE9ccfY= -github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU= +github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= +github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= +github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= From c1db1f4dcec6a8df220d9069618965e0b7d288cd Mon Sep 17 00:00:00 2001 From: computerscot <125355930+computerscot@users.noreply.github.com> Date: Mon, 21 Aug 2023 11:27:13 -0700 Subject: [PATCH 33/71] Add "Xray REALITY with 'steal oneself'" example to README Step-by-step instructions for 'steal oneself' --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f4723d88..ecf67e7d 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ - [XTLS Vision](https://github.com/chika0801/Xray-install) - [REALITY (English)](https://cscot.pages.dev/2023/03/02/Xray-REALITY-tutorial/) - [XTLS-Iran-Reality (English)](https://github.com/SasukeFreestyle/XTLS-Iran-Reality) + - [Xray REALITY with 'steal oneself' (English)](https://computerscot.github.io/vless-xtls-utls-reality-steal-oneself.html) ## GUI Clients From cd1d00086087774320ac3961daf16df63445c716 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 20 Aug 2023 23:12:13 -0400 Subject: [PATCH 34/71] Docker build use 1.20 go --- .github/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index ad1e8c3d..a6678416 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM --platform=$BUILDPLATFORM golang:alpine AS build +FROM --platform=$BUILDPLATFORM golang:1.20-alpine AS build WORKDIR /src COPY . . ARG TARGETOS TARGETARCH From fce86aad332decf332a266b70ad9b39837c93739 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Wed, 23 Aug 2023 01:21:27 +0800 Subject: [PATCH 35/71] fix(common): strmatcher match domain safety --- common/strmatcher/ac_automaton_matcher.go | 6 +++++- common/strmatcher/strmatcher_test.go | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/common/strmatcher/ac_automaton_matcher.go b/common/strmatcher/ac_automaton_matcher.go index ab7c09bd..24be9dac 100644 --- a/common/strmatcher/ac_automaton_matcher.go +++ b/common/strmatcher/ac_automaton_matcher.go @@ -225,7 +225,11 @@ func (ac *ACAutomaton) Match(s string) bool { // 2. the match string is through a fail edge. NOT FULL MATCH // 2.1 Through a fail edge, but there exists a valid node. SUBSTR for i := len(s) - 1; i >= 0; i-- { - idx := char2Index[s[i]] + chr := int(s[i]) + if chr >= len(char2Index) { + return false + } + idx := char2Index[chr] fullMatch = fullMatch && ac.trie[node][idx].edgeType node = ac.trie[node][idx].nextNode switch ac.exists[node].matchType { diff --git a/common/strmatcher/strmatcher_test.go b/common/strmatcher/strmatcher_test.go index 2e48c1b7..408ae628 100644 --- a/common/strmatcher/strmatcher_test.go +++ b/common/strmatcher/strmatcher_test.go @@ -217,6 +217,10 @@ func TestACAutomaton(t *testing.T) { pattern: "vvgoogle.com", res: true, }, + { + pattern: "½", + res: false, + }, } for _, test := range cases2Output { if m := ac.Match(test.pattern); m != test.res { @@ -224,7 +228,6 @@ func TestACAutomaton(t *testing.T) { } } } - { cases3Input := []struct { pattern string From 229851f62144939d46f24f32cb1bf733d390d50a Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Thu, 24 Aug 2023 11:13:12 -0400 Subject: [PATCH 36/71] Revert "Docker build use 1.20 go" This reverts commit cd1d00086087774320ac3961daf16df63445c716. --- .github/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/docker/Dockerfile b/.github/docker/Dockerfile index a6678416..ad1e8c3d 100644 --- a/.github/docker/Dockerfile +++ b/.github/docker/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM --platform=$BUILDPLATFORM golang:1.20-alpine AS build +FROM --platform=$BUILDPLATFORM golang:alpine AS build WORKDIR /src COPY . . ARG TARGETOS TARGETARCH From d616f6160df2e63787673ec9abfe37becc2e1278 Mon Sep 17 00:00:00 2001 From: douglarek Date: Wed, 23 Aug 2023 22:30:46 +0800 Subject: [PATCH 37/71] Fix go 1.21 build, see https://github.com/XTLS/Xray-core/issues/2466 --- go.mod | 4 ++-- go.sum | 8 ++++---- proxy/wireguard/tun.go | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2625a6ab..29567642 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( golang.org/x/sys v0.11.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 - gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c + gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 h12.io/socks v1.0.3 lukechampine.com/blake3 v1.2.1 ) @@ -47,7 +47,7 @@ require ( github.com/quic-go/qtls-go1-20 v0.3.2 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect + golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/go.sum b/go.sum index a98d33c6..e0eb4c79 100644 --- a/go.sum +++ b/go.sum @@ -179,8 +179,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= +golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -284,8 +284,8 @@ gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= -gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4= -gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= +gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 h1:tE44CyJgxEGzoPtHs9GI7ddKdgEGCREQBP54AmaVM+I= +gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744/go.mod h1:lYEMhXbxgudVhALYsMQrBaUAjM3NMinh8mKL1CJv7rc= h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo= h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/proxy/wireguard/tun.go b/proxy/wireguard/tun.go index 4d1cb7f6..ed6e434f 100644 --- a/proxy/wireguard/tun.go +++ b/proxy/wireguard/tun.go @@ -14,7 +14,7 @@ import ( "github.com/sagernet/wireguard-go/tun" "github.com/xtls/xray-core/features/dns" - "gvisor.dev/gvisor/pkg/bufferv2" + "gvisor.dev/gvisor/pkg/buffer" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet" "gvisor.dev/gvisor/pkg/tcpip/header" @@ -30,7 +30,7 @@ type netTun struct { ep *channel.Endpoint stack *stack.Stack events chan tun.Event - incomingPacket chan *bufferv2.View + incomingPacket chan *buffer.View mtu int dnsClient dns.Client hasV4, hasV6 bool @@ -48,7 +48,7 @@ func CreateNetTUN(localAddresses []netip.Addr, dnsClient dns.Client, mtu int) (t ep: channel.New(1024, uint32(mtu), ""), stack: stack.New(opts), events: make(chan tun.Event, 10), - incomingPacket: make(chan *bufferv2.View), + incomingPacket: make(chan *buffer.View), dnsClient: dnsClient, mtu: mtu, } @@ -66,7 +66,7 @@ func CreateNetTUN(localAddresses []netip.Addr, dnsClient dns.Client, mtu int) (t } protoAddr := tcpip.ProtocolAddress{ Protocol: protoNumber, - AddressWithPrefix: tcpip.Address(ip.AsSlice()).WithPrefix(), + AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(), } tcpipErr := dev.stack.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}) if tcpipErr != nil { @@ -116,7 +116,7 @@ func (tun *netTun) Write(buf []byte, offset int) (int, error) { return 0, nil } - pkb := stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: bufferv2.MakeWithData(packet)}) + pkb := stack.NewPacketBuffer(stack.PacketBufferOptions{Payload: buffer.MakeWithData(packet)}) switch packet[0] >> 4 { case 4: tun.ep.InjectInbound(header.IPv4ProtocolNumber, pkb) @@ -172,7 +172,7 @@ func convertToFullAddr(endpoint netip.AddrPort) (tcpip.FullAddress, tcpip.Networ } return tcpip.FullAddress{ NIC: 1, - Addr: tcpip.Address(endpoint.Addr().AsSlice()), + Addr: tcpip.AddrFromSlice(endpoint.Addr().AsSlice()), Port: endpoint.Port(), }, protoNumber } From 1a69baed170a05675185782d11d1e40085fdbfc7 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Sat, 26 Aug 2023 06:26:27 +0000 Subject: [PATCH 38/71] Update workflows to use Go 1.21 --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03c18811..8978bef5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -169,7 +169,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version: '1.21' check-latest: true - name: Get project dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 55891af0..d4143b69 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version: '1.21' check-latest: true - name: Checkout codebase uses: actions/checkout@v3 From e02474ae1590789a05a84e66d0765ee34f062231 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Sat, 26 Aug 2023 07:05:21 +0000 Subject: [PATCH 39/71] Upgrade dependencies --- go.mod | 26 +++++++++++++------------- go.sum | 53 ++++++++++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index 29567642..89ea54a1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/xtls/xray-core -go 1.20 +go 1.21 require ( github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 @@ -10,10 +10,10 @@ require ( github.com/miekg/dns v1.1.55 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.38.0 - github.com/refraction-networking/utls v1.3.3 - github.com/sagernet/sing v0.2.7 - github.com/sagernet/sing-shadowsocks v0.2.2 + github.com/quic-go/quic-go v0.38.1 + github.com/refraction-networking/utls v1.4.3 + github.com/sagernet/sing v0.2.9 + github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.8.4 @@ -35,24 +35,24 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/gaukas/godicttls v0.0.3 // indirect + github.com/gaukas/godicttls v0.0.4 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect - github.com/klauspost/compress v1.16.6 // indirect + github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/onsi/ginkgo/v2 v2.11.0 // indirect + github.com/onsi/ginkgo/v2 v2.12.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.2 // indirect + github.com/quic-go/qtls-go1-20 v0.3.3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect - golang.org/x/mod v0.11.0 // indirect + golang.org/x/mod v0.12.0 // indirect golang.org/x/text v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.10.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + golang.org/x/tools v0.12.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e0eb4c79..4f11d8da 100644 --- a/go.sum +++ b/go.sum @@ -27,14 +27,15 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk= -github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= +github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk= +github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -60,8 +61,8 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= +github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -75,8 +76,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= -github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -95,9 +96,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= +github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -112,19 +114,19 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI= -github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.0 h1:T45lASr5q/TrVwt+jrVccmqHhPL2XuSyoCLVCpfOSLc= -github.com/quic-go/quic-go v0.38.0/go.mod h1:MPCuRq7KBK2hNcfKj/1iD1BGuN3eAYMeNxp3T42LRUg= -github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= -github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= +github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= +github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= +github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= +github.com/refraction-networking/utls v1.4.3 h1:BdWS3BSzCwWCFfMIXP3mjLAyQkdmog7diaD/OqFbAzM= +github.com/refraction-networking/utls v1.4.3/go.mod h1:4u9V/awOSBrRw6+federGmVJQfPtemEqLBXkML1b0bo= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sagernet/sing v0.2.7 h1:cOy0FfPS8q7m0aJ51wS7LRQAGc9wF+fWhHtBDj99wy8= -github.com/sagernet/sing v0.2.7/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= -github.com/sagernet/sing-shadowsocks v0.2.2 h1:ezSdVhrmIcwDXmCZF3bOJVMuVtTQWpda+1Op+Ie2TA4= -github.com/sagernet/sing-shadowsocks v0.2.2/go.mod h1:JIBWG6a7orB2HxBxYElViQFLUQxFVG7DuqIj8gD7uCQ= +github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo= +github.com/sagernet/sing v0.2.9/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= +github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI= github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U= @@ -185,8 +187,8 @@ golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -242,8 +244,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= -golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -260,8 +262,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -274,6 +276,7 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 2d5475f42896347af4beea5f529dfe2cf41b2200 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Sat, 26 Aug 2023 07:45:24 +0000 Subject: [PATCH 40/71] Update transport/internet/reality/reality.go Fixes https://github.com/XTLS/Xray-core/issues/2491 --- transport/internet/reality/reality.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/transport/internet/reality/reality.go b/transport/internet/reality/reality.go index e55f9417..b430cccc 100644 --- a/transport/internet/reality/reality.go +++ b/transport/internet/reality/reality.go @@ -5,6 +5,7 @@ import ( "context" "crypto/aes" "crypto/cipher" + "crypto/ecdh" "crypto/ed25519" "crypto/hmac" "crypto/rand" @@ -134,7 +135,8 @@ func UClient(c net.Conn, config *Config, ctx context.Context, dest net.Destinati if config.Show { fmt.Printf("REALITY localAddr: %v\thello.SessionId[:16]: %v\n", localAddr, hello.SessionId[:16]) } - uConn.AuthKey = uConn.HandshakeState.State13.EcdheParams.SharedKey(config.PublicKey) + publicKey, _ := ecdh.X25519().NewPublicKey(config.PublicKey) + uConn.AuthKey, _ = uConn.HandshakeState.State13.EcdheKey.ECDH(publicKey) if uConn.AuthKey == nil { return nil, errors.New("REALITY: SharedKey == nil") } From 10d6b065784efd3f33a02d6d5ad2a1fa162ff346 Mon Sep 17 00:00:00 2001 From: A1lo Date: Sat, 26 Aug 2023 16:23:54 +0800 Subject: [PATCH 41/71] fix(transport): correctly release UDS locker file (#2305) * fix(transport): correctly release UDS locker file * use callback function to do some jobs after create listener --- transport/internet/grpc/hub.go | 5 -- transport/internet/http/hub.go | 8 ---- transport/internet/system_listener.go | 69 +++++++++++++++++++-------- transport/internet/tcp/hub.go | 8 ---- transport/internet/websocket/hub.go | 8 ---- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/transport/internet/grpc/hub.go b/transport/internet/grpc/hub.go index d3dd6da5..e55f6f77 100644 --- a/transport/internet/grpc/hub.go +++ b/transport/internet/grpc/hub.go @@ -23,7 +23,6 @@ type Listener struct { handler internet.ConnHandler local net.Addr config *Config - locker *internet.FileLocker // for unix domain socket s *grpc.Server } @@ -110,10 +109,6 @@ func Listen(ctx context.Context, address net.Address, port net.Port, settings *i newError("failed to listen on ", address).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx)) return } - locker := ctx.Value(address.Domain()) - if locker != nil { - listener.locker = locker.(*internet.FileLocker) - } } else { // tcp streamListener, err = internet.ListenSystem(ctx, &net.TCPAddr{ IP: address.IP(), diff --git a/transport/internet/http/hub.go b/transport/internet/http/hub.go index 551f897e..f0260460 100644 --- a/transport/internet/http/hub.go +++ b/transport/internet/http/hub.go @@ -27,7 +27,6 @@ type Listener struct { handler internet.ConnHandler local net.Addr config *Config - locker *internet.FileLocker // for unix domain socket } func (l *Listener) Addr() net.Addr { @@ -35,9 +34,6 @@ func (l *Listener) Addr() net.Addr { } func (l *Listener) Close() error { - if l.locker != nil { - l.locker.Release() - } return l.server.Close() } @@ -180,10 +176,6 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti newError("failed to listen on ", address).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx)) return } - locker := ctx.Value(address.Domain()) - if locker != nil { - listener.locker = locker.(*internet.FileLocker) - } } else { // tcp streamListener, err = internet.ListenSystem(ctx, &net.TCPAddr{ IP: address.IP(), diff --git a/transport/internet/system_listener.go b/transport/internet/system_listener.go index 60979062..1d635897 100644 --- a/transport/internet/system_listener.go +++ b/transport/internet/system_listener.go @@ -21,6 +21,19 @@ type DefaultListener struct { controllers []control.Func } +type combinedListener struct { + net.Listener + locker *FileLocker // for unix domain socket +} + +func (cl *combinedListener) Close() error { + if cl.locker != nil { + cl.locker.Release() + cl.locker = nil + } + return cl.Listener.Close() +} + func getControlFunc(ctx context.Context, sockopt *SocketConfig, controllers []control.Func) func(network, address string, c syscall.RawConn) error { return func(network, address string, c syscall.RawConn) error { return c.Control(func(fd uintptr) { @@ -44,6 +57,10 @@ func getControlFunc(ctx context.Context, sockopt *SocketConfig, controllers []co func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (l net.Listener, err error) { var lc net.ListenConfig var network, address string + // callback is called after the Listen function returns + callback := func(l net.Listener, err error) (net.Listener, error) { + return l, err + } switch addr := addr.(type) { case *net.TCPAddr: @@ -58,23 +75,6 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S network = addr.Network() address = addr.Name - if s := strings.Split(address, ","); len(s) == 2 { - address = s[0] - perm, perr := strconv.ParseUint(s[1], 8, 32) - if perr != nil { - return nil, newError("failed to parse permission: " + s[1]).Base(perr) - } - - defer func(file string, permission os.FileMode) { - if err == nil { - cerr := os.Chmod(address, permission) - if cerr != nil { - err = newError("failed to set permission for " + file).Base(cerr) - } - } - }(address, os.FileMode(perm)) - } - if (runtime.GOOS == "linux" || runtime.GOOS == "android") && address[0] == '@' { // linux abstract unix domain socket is lockfree if len(address) > 1 && address[1] == '@' { @@ -84,19 +84,48 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S address = string(fullAddr) } } else { + // split permission from address + var filePerm *os.FileMode + if s := strings.Split(address, ","); len(s) == 2 { + address = s[0] + perm, perr := strconv.ParseUint(s[1], 8, 32) + if perr != nil { + return nil, newError("failed to parse permission: " + s[1]).Base(perr) + } + + mode := os.FileMode(perm) + filePerm = &mode + } // normal unix domain socket needs lock locker := &FileLocker{ path: address + ".lock", } - err := locker.Acquire() - if err != nil { + if err := locker.Acquire(); err != nil { return nil, err } - ctx = context.WithValue(ctx, address, locker) + + // set callback to combine listener and set permission + callback = func(l net.Listener, err error) (net.Listener, error) { + if err != nil { + locker.Release() + return l, err + } + l = &combinedListener{Listener: l, locker: locker} + if filePerm == nil { + return l, nil + } + err = os.Chmod(address, *filePerm) + if err != nil { + l.Close() + return nil, newError("failed to set permission for " + address).Base(err) + } + return l, nil + } } } l, err = lc.Listen(ctx, network, address) + l, err = callback(l, err) if sockopt != nil && sockopt.AcceptProxyProtocol { policyFunc := func(upstream net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil } l = &proxyproto.Listener{Listener: l, Policy: policyFunc} diff --git a/transport/internet/tcp/hub.go b/transport/internet/tcp/hub.go index 392228c6..d4b4f8b5 100644 --- a/transport/internet/tcp/hub.go +++ b/transport/internet/tcp/hub.go @@ -24,7 +24,6 @@ type Listener struct { authConfig internet.ConnectionAuthenticator config *Config addConn internet.ConnHandler - locker *internet.FileLocker // for unix domain socket } // ListenTCP creates a new Listener based on configurations. @@ -51,10 +50,6 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSe return nil, newError("failed to listen Unix Domain Socket on ", address).Base(err) } newError("listening Unix Domain Socket on ", address).WriteToLog(session.ExportIDToError(ctx)) - locker := ctx.Value(address.Domain()) - if locker != nil { - l.locker = locker.(*internet.FileLocker) - } } else { listener, err = internet.ListenSystem(ctx, &net.TCPAddr{ IP: address.IP(), @@ -133,9 +128,6 @@ func (v *Listener) Addr() net.Addr { // Close implements internet.Listener.Close. func (v *Listener) Close() error { - if v.locker != nil { - v.locker.Release() - } return v.listener.Close() } diff --git a/transport/internet/websocket/hub.go b/transport/internet/websocket/hub.go index c0cf3446..7951b1f4 100644 --- a/transport/internet/websocket/hub.go +++ b/transport/internet/websocket/hub.go @@ -75,7 +75,6 @@ type Listener struct { listener net.Listener config *Config addConn internet.ConnHandler - locker *internet.FileLocker // for unix domain socket } func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) { @@ -101,10 +100,6 @@ func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSet return nil, newError("failed to listen unix domain socket(for WS) on ", address).Base(err) } newError("listening unix domain socket(for WS) on ", address).WriteToLog(session.ExportIDToError(ctx)) - locker := ctx.Value(address.Domain()) - if locker != nil { - l.locker = locker.(*internet.FileLocker) - } } else { // tcp listener, err = internet.ListenSystem(ctx, &net.TCPAddr{ IP: address.IP(), @@ -153,9 +148,6 @@ func (ln *Listener) Addr() net.Addr { // Close implements net.Listener.Close(). func (ln *Listener) Close() error { - if ln.locker != nil { - ln.locker.Release() - } return ln.listener.Close() } From b24a4028f148a7171f161a7e4b4d693aaaaea3da Mon Sep 17 00:00:00 2001 From: cty Date: Sat, 26 Aug 2023 17:11:37 +0200 Subject: [PATCH 42/71] fix(app/router): fixed a bug in geoip matching with refactoring (#2489) * Refactor the IP address matching with netipx library * Add a regression test for previous bug Fixes https://github.com/XTLS/Xray-core/issues/1933 --------- Co-authored-by: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com> --- app/router/condition_geoip.go | 172 ++++++++--------------------- app/router/condition_geoip_test.go | 36 +++++- app/router/config.go | 39 ------- go.mod | 1 + go.sum | 2 + 5 files changed, 80 insertions(+), 170 deletions(-) diff --git a/app/router/condition_geoip.go b/app/router/condition_geoip.go index eb47be83..09c81fa8 100644 --- a/app/router/condition_geoip.go +++ b/app/router/condition_geoip.go @@ -1,81 +1,49 @@ package router import ( - "encoding/binary" - "sort" + "net/netip" + "strconv" "github.com/xtls/xray-core/common/net" + "go4.org/netipx" ) -type ipv6 struct { - a uint64 - b uint64 -} - type GeoIPMatcher struct { countryCode string reverseMatch bool - ip4 []uint32 - prefix4 []uint8 - ip6 []ipv6 - prefix6 []uint8 -} - -func normalize4(ip uint32, prefix uint8) uint32 { - return (ip >> (32 - prefix)) << (32 - prefix) -} - -func normalize6(ip ipv6, prefix uint8) ipv6 { - if prefix <= 64 { - ip.a = (ip.a >> (64 - prefix)) << (64 - prefix) - ip.b = 0 - } else { - ip.b = (ip.b >> (128 - prefix)) << (128 - prefix) - } - return ip + ip4 *netipx.IPSet + ip6 *netipx.IPSet } func (m *GeoIPMatcher) Init(cidrs []*CIDR) error { - ip4Count := 0 - ip6Count := 0 + var builder4, builder6 netipx.IPSetBuilder for _, cidr := range cidrs { - ip := cidr.Ip + ip := net.IP(cidr.GetIp()) + ipPrefixString := ip.String() + "/" + strconv.Itoa(int(cidr.GetPrefix())) + ipPrefix, err := netip.ParsePrefix(ipPrefixString) + if err != nil { + return err + } + switch len(ip) { - case 4: - ip4Count++ - case 16: - ip6Count++ - default: - return newError("unexpect ip length: ", len(ip)) + case net.IPv4len: + builder4.AddPrefix(ipPrefix) + case net.IPv6len: + builder6.AddPrefix(ipPrefix) } } - cidrList := CIDRList(cidrs) - sort.Sort(&cidrList) + if ip4, err := builder4.IPSet(); err != nil { + return err + } else { + m.ip4 = ip4 + } - m.ip4 = make([]uint32, 0, ip4Count) - m.prefix4 = make([]uint8, 0, ip4Count) - m.ip6 = make([]ipv6, 0, ip6Count) - m.prefix6 = make([]uint8, 0, ip6Count) - - for _, cidr := range cidrList { - ip := cidr.Ip - prefix := uint8(cidr.Prefix) - switch len(ip) { - case 4: - m.ip4 = append(m.ip4, normalize4(binary.BigEndian.Uint32(ip), prefix)) - m.prefix4 = append(m.prefix4, prefix) - case 16: - ip6 := ipv6{ - a: binary.BigEndian.Uint64(ip[0:8]), - b: binary.BigEndian.Uint64(ip[8:16]), - } - ip6 = normalize6(ip6, prefix) - - m.ip6 = append(m.ip6, ip6) - m.prefix6 = append(m.prefix6, prefix) - } + if ip6, err := builder6.IPSet(); err != nil { + return err + } else { + m.ip6 = ip6 } return nil @@ -85,91 +53,37 @@ func (m *GeoIPMatcher) SetReverseMatch(isReverseMatch bool) { m.reverseMatch = isReverseMatch } -func (m *GeoIPMatcher) match4(ip uint32) bool { - if len(m.ip4) == 0 { +func (m *GeoIPMatcher) match4(ip net.IP) bool { + nip, ok := netipx.FromStdIP(ip) + if !ok { return false } - if ip < m.ip4[0] { - return false - } - - size := uint32(len(m.ip4)) - l := uint32(0) - r := size - for l < r { - x := ((l + r) >> 1) - if ip < m.ip4[x] { - r = x - continue - } - - nip := normalize4(ip, m.prefix4[x]) - if nip == m.ip4[x] { - return true - } - - l = x + 1 - } - - return l > 0 && normalize4(ip, m.prefix4[l-1]) == m.ip4[l-1] + return m.ip4.Contains(nip) } -func less6(a ipv6, b ipv6) bool { - return a.a < b.a || (a.a == b.a && a.b < b.b) -} - -func (m *GeoIPMatcher) match6(ip ipv6) bool { - if len(m.ip6) == 0 { +func (m *GeoIPMatcher) match6(ip net.IP) bool { + nip, ok := netipx.FromStdIP(ip) + if !ok { return false } - if less6(ip, m.ip6[0]) { - return false - } - - size := uint32(len(m.ip6)) - l := uint32(0) - r := size - for l < r { - x := (l + r) / 2 - if less6(ip, m.ip6[x]) { - r = x - continue - } - - if normalize6(ip, m.prefix6[x]) == m.ip6[x] { - return true - } - - l = x + 1 - } - - return l > 0 && normalize6(ip, m.prefix6[l-1]) == m.ip6[l-1] + return m.ip6.Contains(nip) } // Match returns true if the given ip is included by the GeoIP. func (m *GeoIPMatcher) Match(ip net.IP) bool { + isMatched := false switch len(ip) { - case 4: - if m.reverseMatch { - return !m.match4(binary.BigEndian.Uint32(ip)) - } - return m.match4(binary.BigEndian.Uint32(ip)) - case 16: - if m.reverseMatch { - return !m.match6(ipv6{ - a: binary.BigEndian.Uint64(ip[0:8]), - b: binary.BigEndian.Uint64(ip[8:16]), - }) - } - return m.match6(ipv6{ - a: binary.BigEndian.Uint64(ip[0:8]), - b: binary.BigEndian.Uint64(ip[8:16]), - }) - default: - return false + case net.IPv4len: + isMatched = m.match4(ip) + case net.IPv6len: + isMatched = m.match6(ip) } + if m.reverseMatch { + return !isMatched + } + return isMatched } // GeoIPMatcherContainer is a container for GeoIPMatchers. It keeps unique copies of GeoIPMatcher by country code. diff --git a/app/router/condition_geoip_test.go b/app/router/condition_geoip_test.go index 1a730021..63bd222e 100644 --- a/app/router/condition_geoip_test.go +++ b/app/router/condition_geoip_test.go @@ -53,7 +53,7 @@ func TestGeoIPMatcherContainer(t *testing.T) { } func TestGeoIPMatcher(t *testing.T) { - cidrList := router.CIDRList{ + cidrList := []*router.CIDR{ {Ip: []byte{0, 0, 0, 0}, Prefix: 8}, {Ip: []byte{10, 0, 0, 0}, Prefix: 8}, {Ip: []byte{100, 64, 0, 0}, Prefix: 10}, @@ -124,8 +124,40 @@ func TestGeoIPMatcher(t *testing.T) { } } +func TestGeoIPMatcherRegression(t *testing.T) { + cidrList := []*router.CIDR{ + {Ip: []byte{98, 108, 20, 0}, Prefix: 22}, + {Ip: []byte{98, 108, 20, 0}, Prefix: 23}, + } + + matcher := &router.GeoIPMatcher{} + common.Must(matcher.Init(cidrList)) + + testCases := []struct { + Input string + Output bool + }{ + { + Input: "98.108.22.11", + Output: true, + }, + { + Input: "98.108.25.0", + Output: false, + }, + } + + for _, testCase := range testCases { + ip := net.ParseAddress(testCase.Input).IP() + actual := matcher.Match(ip) + if actual != testCase.Output { + t.Error("expect input", testCase.Input, "to be", testCase.Output, ", but actually", actual) + } + } +} + func TestGeoIPReverseMatcher(t *testing.T) { - cidrList := router.CIDRList{ + cidrList := []*router.CIDR{ {Ip: []byte{8, 8, 8, 8}, Prefix: 32}, {Ip: []byte{91, 108, 4, 0}, Prefix: 16}, } diff --git a/app/router/config.go b/app/router/config.go index 80b88781..f50f02a1 100644 --- a/app/router/config.go +++ b/app/router/config.go @@ -9,45 +9,6 @@ import ( "github.com/xtls/xray-core/features/routing" ) -// CIDRList is an alias of []*CIDR to provide sort.Interface. -type CIDRList []*CIDR - -// Len implements sort.Interface. -func (l *CIDRList) Len() int { - return len(*l) -} - -// Less implements sort.Interface. -func (l *CIDRList) Less(i int, j int) bool { - ci := (*l)[i] - cj := (*l)[j] - - if len(ci.Ip) < len(cj.Ip) { - return true - } - - if len(ci.Ip) > len(cj.Ip) { - return false - } - - for k := 0; k < len(ci.Ip); k++ { - if ci.Ip[k] < cj.Ip[k] { - return true - } - - if ci.Ip[k] > cj.Ip[k] { - return false - } - } - - return ci.Prefix < cj.Prefix -} - -// Swap implements sort.Interface. -func (l *CIDRList) Swap(i int, j int) { - (*l)[i], (*l)[j] = (*l)[j], (*l)[i] -} - type Rule struct { Tag string Balancer *Balancer diff --git a/go.mod b/go.mod index 89ea54a1..579e77da 100644 --- a/go.mod +++ b/go.mod @@ -47,6 +47,7 @@ require ( github.com/quic-go/qtls-go1-20 v0.3.3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect + go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/text v0.12.0 // indirect diff --git a/go.sum b/go.sum index 4f11d8da..da6346cf 100644 --- a/go.sum +++ b/go.sum @@ -173,6 +173,8 @@ go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ= +go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From d92002ad127f64bc1e740cb350eafd693ffadd6d Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Sun, 27 Aug 2023 05:55:58 +0000 Subject: [PATCH 43/71] Dialer: Set TimeoutOnly for `gctx` and `hctx` https://github.com/XTLS/Xray-core/issues/2232#issuecomment-1694570914 Thank @cty123 for testing Fixes https://github.com/XTLS/Xray-core/issues/2232 BTW: Use `uConn.HandshakeContext(ctx)` in REALITY --- transport/internet/grpc/dial.go | 12 +++++++----- transport/internet/http/dialer.go | 12 ++++++------ transport/internet/reality/reality.go | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/transport/internet/grpc/dial.go b/transport/internet/grpc/dial.go index 8fd544b5..16af63cd 100644 --- a/transport/internet/grpc/dial.go +++ b/transport/internet/grpc/dial.go @@ -98,16 +98,13 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in MinConnectTimeout: 5 * time.Second, }), grpc.WithContextDialer(func(gctx context.Context, s string) (gonet.Conn, error) { - gctx = session.ContextWithID(gctx, session.IDFromContext(ctx)) - gctx = session.ContextWithOutbound(gctx, session.OutboundFromContext(ctx)) - - rawHost, rawPort, err := net.SplitHostPort(s) select { case <-gctx.Done(): return nil, gctx.Err() default: } + rawHost, rawPort, err := net.SplitHostPort(s) if err != nil { return nil, err } @@ -119,9 +116,14 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in return nil, err } address := net.ParseAddress(rawHost) + + gctx = session.ContextWithID(gctx, session.IDFromContext(ctx)) + gctx = session.ContextWithOutbound(gctx, session.OutboundFromContext(ctx)) + gctx = session.ContextWithTimeoutOnly(gctx, true) + c, err := internet.DialSystem(gctx, net.TCPDestination(address, port), sockopt) if err == nil && realityConfig != nil { - return reality.UClient(c, realityConfig, ctx, dest) + return reality.UClient(c, realityConfig, gctx, dest) } return c, err }), diff --git a/transport/internet/http/dialer.go b/transport/internet/http/dialer.go index f2e55de8..1ea3a738 100644 --- a/transport/internet/http/dialer.go +++ b/transport/internet/http/dialer.go @@ -53,7 +53,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in } transport := &http2.Transport{ - DialTLS: func(network string, addr string, tlsConfig *gotls.Config) (net.Conn, error) { + DialTLSContext: func(hctx context.Context, string, addr string, tlsConfig *gotls.Config) (net.Conn, error) { rawHost, rawPort, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -67,18 +67,18 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in } address := net.ParseAddress(rawHost) - dctx := context.Background() - dctx = session.ContextWithID(dctx, session.IDFromContext(ctx)) - dctx = session.ContextWithOutbound(dctx, session.OutboundFromContext(ctx)) + hctx = session.ContextWithID(hctx, session.IDFromContext(ctx)) + hctx = session.ContextWithOutbound(hctx, session.OutboundFromContext(ctx)) + hctx = session.ContextWithTimeoutOnly(hctx, true) - pconn, err := internet.DialSystem(dctx, net.TCPDestination(address, port), sockopt) + pconn, err := internet.DialSystem(hctx, net.TCPDestination(address, port), sockopt) if err != nil { newError("failed to dial to " + addr).Base(err).AtError().WriteToLog() return nil, err } if realityConfigs != nil { - return reality.UClient(pconn, realityConfigs, ctx, dest) + return reality.UClient(pconn, realityConfigs, hctx, dest) } var cn tls.Interface diff --git a/transport/internet/reality/reality.go b/transport/internet/reality/reality.go index b430cccc..30d4e2ae 100644 --- a/transport/internet/reality/reality.go +++ b/transport/internet/reality/reality.go @@ -156,7 +156,7 @@ func UClient(c net.Conn, config *Config, ctx context.Context, dest net.Destinati aead.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw) copy(hello.Raw[39:], hello.SessionId) } - if err := uConn.Handshake(); err != nil { + if err := uConn.HandshakeContext(ctx); err != nil { return nil, err } if config.Show { From e013dce1df4bf341b2cb9c9fdef56c4ba3cbd44a Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:37:57 +0000 Subject: [PATCH 44/71] Upgrade github.com/xtls/reality to 20230828171259 https://github.com/XTLS/REALITY/commit/e426190d57f6443930a8f9cf3acfbb1a40b1576e --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 579e77da..711b8e47 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,8 @@ require ( github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.8.4 github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e - github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 + github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 + go4.org/netipx v0.0.0-20230824141953-6213f710f925 golang.org/x/crypto v0.12.0 golang.org/x/net v0.14.0 golang.org/x/sync v0.3.0 @@ -47,7 +48,6 @@ require ( github.com/quic-go/qtls-go1-20 v0.3.3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect - go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/text v0.12.0 // indirect diff --git a/go.sum b/go.sum index da6346cf..71abf747 100644 --- a/go.sum +++ b/go.sum @@ -166,8 +166,8 @@ github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983 h1:AMyzgjkh54WocjQSlCnT1LhDc/BKiUqtNOv40AkpURs= -github.com/xtls/reality v0.0.0-20230613075828-e07c3b04b983/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y= +github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 h1:T+YCYGfFdzyaKTDCdZn/hEiKvsw6yUfd+e4hze0rCUw= +github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= From b8bd243df5f6ff4929681c82ed945b27f1597d25 Mon Sep 17 00:00:00 2001 From: dyhkwong <50692134+dyhkwong@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:12:36 +0800 Subject: [PATCH 45/71] Fix buffer.UDP destination override (#2356) --- app/dispatcher/default.go | 107 ++++++++----------------------- app/proxyman/outbound/handler.go | 7 +- common/buf/override.go | 38 +++++++++++ common/session/session.go | 5 +- transport/pipe/impl.go | 5 -- transport/pipe/pipe.go | 7 -- 6 files changed, 75 insertions(+), 94 deletions(-) create mode 100644 common/buf/override.go diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 35307cef..5a71ad41 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -4,7 +4,6 @@ package dispatcher import ( "context" - "fmt" "strings" "sync" "time" @@ -135,77 +134,10 @@ func (*DefaultDispatcher) Start() error { // Close implements common.Closable. func (*DefaultDispatcher) Close() error { return nil } -func (d *DefaultDispatcher) getLink(ctx context.Context, network net.Network, sniffing session.SniffingRequest) (*transport.Link, *transport.Link) { - downOpt := pipe.OptionsFromContext(ctx) - upOpt := downOpt - - if network == net.Network_UDP { - var ip2domain *sync.Map // net.IP.String() => domain, this map is used by server side when client turn on fakedns - // Client will send domain address in the buffer.UDP.Address, server record all possible target IP addrs. - // When target replies, server will restore the domain and send back to client. - // Note: this map is not global but per connection context - upOpt = append(upOpt, pipe.OnTransmission(func(mb buf.MultiBuffer) buf.MultiBuffer { - for i, buffer := range mb { - if buffer.UDP == nil { - continue - } - addr := buffer.UDP.Address - if addr.Family().IsIP() { - if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && fkr0.IsIPInIPPool(addr) && sniffing.Enabled { - domain := fkr0.GetDomainFromFakeDNS(addr) - if len(domain) > 0 { - buffer.UDP.Address = net.DomainAddress(domain) - newError("[fakedns client] override with domain: ", domain, " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx)) - } else { - newError("[fakedns client] failed to find domain! :", addr.String(), " for xUDP buffer at ", i).AtWarning().WriteToLog(session.ExportIDToError(ctx)) - } - } - } else { - if ip2domain == nil { - ip2domain = new(sync.Map) - newError("[fakedns client] create a new map").WriteToLog(session.ExportIDToError(ctx)) - } - domain := addr.Domain() - ips, err := d.dns.LookupIP(domain, dns.IPOption{true, true, false}) - if err == nil { - for _, ip := range ips { - ip2domain.Store(ip.String(), domain) - } - newError("[fakedns client] candidate ip: "+fmt.Sprintf("%v", ips), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx)) - } else { - newError("[fakedns client] failed to look up IP for ", domain, " for xUDP buffer at ", i).Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - } - } - return mb - })) - downOpt = append(downOpt, pipe.OnTransmission(func(mb buf.MultiBuffer) buf.MultiBuffer { - for i, buffer := range mb { - if buffer.UDP == nil { - continue - } - addr := buffer.UDP.Address - if addr.Family().IsIP() { - if ip2domain == nil { - continue - } - if domain, found := ip2domain.Load(addr.IP().String()); found { - buffer.UDP.Address = net.DomainAddress(domain.(string)) - newError("[fakedns client] restore domain: ", domain.(string), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx)) - } - } else { - if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok { - fakeIp := fkr0.GetFakeIPForDomain(addr.Domain()) - buffer.UDP.Address = fakeIp[0] - newError("[fakedns client] restore FakeIP: ", buffer.UDP, fmt.Sprintf("%v", fakeIp), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx)) - } - } - } - return mb - })) - } - uplinkReader, uplinkWriter := pipe.New(upOpt...) - downlinkReader, downlinkWriter := pipe.New(downOpt...) +func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *transport.Link) { + opt := pipe.OptionsFromContext(ctx) + uplinkReader, uplinkWriter := pipe.New(opt...) + downlinkReader, downlinkWriter := pipe.New(opt...) inboundLink := &transport.Link{ Reader: downlinkReader, @@ -263,7 +195,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu protocolString = resComp.ProtocolForDomainResult() } for _, p := range request.OverrideDestinationForProtocol { - if strings.HasPrefix(protocolString, p) { + if strings.HasPrefix(protocolString, p) || strings.HasPrefix(protocolString, p) { return true } if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" && @@ -287,7 +219,8 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin panic("Dispatcher: Invalid destination.") } ob := &session.Outbound{ - Target: destination, + OriginalTarget: destination, + Target: destination, } ctx = session.ContextWithOutbound(ctx, ob) content := session.ContentFromContext(ctx) @@ -295,9 +228,8 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin content = new(session.Content) ctx = session.ContextWithContent(ctx, content) } - sniffingRequest := content.SniffingRequest - inbound, outbound := d.getLink(ctx, destination.Network, sniffingRequest) + inbound, outbound := d.getLink(ctx) if !sniffingRequest.Enabled { go d.routedDispatch(ctx, outbound, destination) } else { @@ -314,7 +246,15 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin domain := result.Domain() newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx)) destination.Address = net.ParseAddress(domain) - if sniffingRequest.RouteOnly && result.Protocol() != "fakedns" { + protocol := result.Protocol() + if resComp, ok := result.(SnifferResultComposite); ok { + protocol = resComp.ProtocolForDomainResult() + } + isFakeIP := false + if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && ob.Target.Address.Family().IsIP() && fkr0.IsIPInIPPool(ob.Target.Address) { + isFakeIP = true + } + if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP { ob.RouteTarget = destination } else { ob.Target = destination @@ -332,7 +272,8 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De return newError("Dispatcher: Invalid destination.") } ob := &session.Outbound{ - Target: destination, + OriginalTarget: destination, + Target: destination, } ctx = session.ContextWithOutbound(ctx, ob) content := session.ContentFromContext(ctx) @@ -356,7 +297,15 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De domain := result.Domain() newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx)) destination.Address = net.ParseAddress(domain) - if sniffingRequest.RouteOnly && result.Protocol() != "fakedns" { + protocol := result.Protocol() + if resComp, ok := result.(SnifferResultComposite); ok { + protocol = resComp.ProtocolForDomainResult() + } + isFakeIP := false + if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && ob.Target.Address.Family().IsIP() && fkr0.IsIPInIPPool(ob.Target.Address) { + isFakeIP = true + } + if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP { ob.RouteTarget = destination } else { ob.Target = destination diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index b477dd6b..adf6537a 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -8,6 +8,7 @@ import ( "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/mux" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net/cnc" @@ -166,6 +167,11 @@ func (h *Handler) Tag() string { // Dispatch implements proxy.Outbound.Dispatch. func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) { + outbound := session.OutboundFromContext(ctx) + if outbound.Target.Network == net.Network_UDP && outbound.OriginalTarget.Address != nil && outbound.OriginalTarget.Address != outbound.Target.Address { + link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: outbound.Target.Address, OriginalDest: outbound.OriginalTarget.Address} + link.Writer = &buf.EndpointOverrideWriter{Writer: link.Writer, Dest: outbound.Target.Address, OriginalDest: outbound.OriginalTarget.Address} + } if h.mux != nil { test := func(err error) { if err != nil { @@ -175,7 +181,6 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) { common.Interrupt(link.Writer) } } - outbound := session.OutboundFromContext(ctx) if outbound.Target.Network == net.Network_UDP && outbound.Target.Port == 443 { switch h.udp443 { case "reject": diff --git a/common/buf/override.go b/common/buf/override.go new file mode 100644 index 00000000..7b2f1554 --- /dev/null +++ b/common/buf/override.go @@ -0,0 +1,38 @@ +package buf + +import ( + "github.com/xtls/xray-core/common/net" +) + +type EndpointOverrideReader struct { + Reader + Dest net.Address + OriginalDest net.Address +} + +func (r *EndpointOverrideReader) ReadMultiBuffer() (MultiBuffer, error) { + mb, err := r.Reader.ReadMultiBuffer() + if err == nil { + for _, b := range mb { + if b.UDP != nil && b.UDP.Address == r.OriginalDest { + b.UDP.Address = r.Dest + } + } + } + return mb, err +} + +type EndpointOverrideWriter struct { + Writer + Dest net.Address + OriginalDest net.Address +} + +func (w *EndpointOverrideWriter) WriteMultiBuffer(mb MultiBuffer) error { + for _, b := range mb { + if b.UDP != nil && b.UDP.Address == w.Dest { + b.UDP.Address = w.OriginalDest + } + } + return w.Writer.WriteMultiBuffer(mb) +} diff --git a/common/session/session.go b/common/session/session.go index 83c48fde..b9609e86 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -55,8 +55,9 @@ type Inbound struct { // Outbound is the metadata of an outbound connection. type Outbound struct { // Target address of the outbound connection. - Target net.Destination - RouteTarget net.Destination + OriginalTarget net.Destination + Target net.Destination + RouteTarget net.Destination // Gateway address Gateway net.Address } diff --git a/transport/pipe/impl.go b/transport/pipe/impl.go index a60bc485..dbdb050e 100644 --- a/transport/pipe/impl.go +++ b/transport/pipe/impl.go @@ -24,7 +24,6 @@ const ( type pipeOption struct { limit int32 // maximum buffer size in bytes discardOverflow bool - onTransmission func(buffer buf.MultiBuffer) buf.MultiBuffer } func (o *pipeOption) isFull(curSize int32) bool { @@ -141,10 +140,6 @@ func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error { return nil } - if p.option.onTransmission != nil { - mb = p.option.onTransmission(mb) - } - for { err := p.writeMultiBufferInternal(mb) if err == nil { diff --git a/transport/pipe/pipe.go b/transport/pipe/pipe.go index 735cc091..f4b78303 100644 --- a/transport/pipe/pipe.go +++ b/transport/pipe/pipe.go @@ -3,7 +3,6 @@ package pipe import ( "context" - "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/signal" "github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/features/policy" @@ -26,12 +25,6 @@ func WithSizeLimit(limit int32) Option { } } -func OnTransmission(hook func(mb buf.MultiBuffer) buf.MultiBuffer) Option { - return func(option *pipeOption) { - option.onTransmission = hook - } -} - // DiscardOverflow returns an Option for Pipe to discard writes if full. func DiscardOverflow() Option { return func(opt *pipeOption) { From f7c20b85dcbd6c2e8acf2589dfaef8a448daf337 Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Tue, 29 Aug 2023 07:20:10 +0000 Subject: [PATCH 46/71] v1.8.4 --- core/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/core.go b/core/core.go index 4d704306..e1128775 100644 --- a/core/core.go +++ b/core/core.go @@ -21,7 +21,7 @@ import ( var ( Version_x byte = 1 Version_y byte = 8 - Version_z byte = 3 + Version_z byte = 4 ) var ( From 7264750e28be632773117d76e445af7d47398475 Mon Sep 17 00:00:00 2001 From: dyhkwong <50692134+dyhkwong@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:21:35 +0800 Subject: [PATCH 47/71] fix typo in default.go --- app/dispatcher/default.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 5a71ad41..aaa9b410 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -195,7 +195,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu protocolString = resComp.ProtocolForDomainResult() } for _, p := range request.OverrideDestinationForProtocol { - if strings.HasPrefix(protocolString, p) || strings.HasPrefix(protocolString, p) { + if strings.HasPrefix(protocolString, p) || strings.HasPrefix(p, protocolString) { return true } if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" && From 853a866622e6e8f63d3db4b29d7da1dbf5bb3207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:43:27 +0000 Subject: [PATCH 48/71] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6c51d0b5..b7a3292b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -11,7 +11,7 @@ jobs: permissions: packages: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Docker metadata id: meta uses: docker/metadata-action@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8978bef5..30b96142 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -158,7 +158,7 @@ jobs: CGO_ENABLED: 0 steps: - name: Checkout codebase - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Show workflow information run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d4143b69..0ab32cd4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: go-version: '1.21' check-latest: true - name: Checkout codebase - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Restore Cache uses: actions/cache/restore@v3 with: From c00e56c0dadf4ec69e0b76a858658cae9709430b Mon Sep 17 00:00:00 2001 From: yylt <34183906+yylt@users.noreply.github.com> Date: Fri, 8 Sep 2023 01:32:27 +0800 Subject: [PATCH 49/71] Add `tcpMptcp` to `sockopt` (#2520) --- infra/conf/transport_internet.go | 2 + transport/internet/config.pb.go | 58 ++++++++++++++++----------- transport/internet/config.proto | 2 + transport/internet/system_dialer.go | 3 ++ transport/internet/system_listener.go | 9 ++++- 5 files changed, 48 insertions(+), 26 deletions(-) diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 55cc8c2e..9e10feed 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -622,6 +622,7 @@ type SocketConfig struct { TCPUserTimeout int32 `json:"tcpUserTimeout"` V6only bool `json:"v6only"` Interface string `json:"interface"` + TcpMptcp bool `json:"tcpMptcp"` } // Build implements Buildable. @@ -677,6 +678,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) { TcpUserTimeout: c.TCPUserTimeout, V6Only: c.V6only, Interface: c.Interface, + TcpMptcp: c.TcpMptcp, }, nil } diff --git a/transport/internet/config.pb.go b/transport/internet/config.pb.go index a186199f..33519b63 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.23.1 +// protoc-gen-go v1.31.0 +// protoc v4.24.1 // source: transport/internet/config.proto package internet @@ -431,6 +431,7 @@ type SocketConfig struct { TcpUserTimeout int32 `protobuf:"varint,16,opt,name=tcp_user_timeout,json=tcpUserTimeout,proto3" json:"tcp_user_timeout,omitempty"` TcpMaxSeg int32 `protobuf:"varint,17,opt,name=tcp_max_seg,json=tcpMaxSeg,proto3" json:"tcp_max_seg,omitempty"` TcpNoDelay bool `protobuf:"varint,18,opt,name=tcp_no_delay,json=tcpNoDelay,proto3" json:"tcp_no_delay,omitempty"` + TcpMptcp bool `protobuf:"varint,19,opt,name=tcp_mptcp,json=tcpMptcp,proto3" json:"tcp_mptcp,omitempty"` } func (x *SocketConfig) Reset() { @@ -591,6 +592,13 @@ func (x *SocketConfig) GetTcpNoDelay() bool { return false } +func (x *SocketConfig) GetTcpMptcp() bool { + if x != nil { + return x.TcpMptcp + } + return false +} + var File_transport_internet_config_proto protoreflect.FileDescriptor var file_transport_internet_config_proto_rawDesc = []byte{ @@ -643,7 +651,7 @@ var file_transport_internet_config_proto_rawDesc = []byte{ 0x12, 0x30, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x22, 0xb4, 0x06, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x78, 0x79, 0x22, 0xd1, 0x06, 0x0a, 0x0c, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x74, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x06, 0x74, 0x70, 0x72, @@ -691,27 +699,29 @@ var file_transport_internet_config_proto_rawDesc = []byte{ 0x78, 0x5f, 0x73, 0x65, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x63, 0x70, 0x4d, 0x61, 0x78, 0x53, 0x65, 0x67, 0x12, 0x20, 0x0a, 0x0c, 0x74, 0x63, 0x70, 0x5f, 0x6e, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x74, 0x63, - 0x70, 0x4e, 0x6f, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, - 0x0a, 0x0a, 0x06, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, - 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5a, 0x0a, 0x11, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, - 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, - 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65, - 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, - 0x50, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x10, 0x05, 0x2a, 0x41, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, - 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x03, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, - 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, - 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, - 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x4e, 0x6f, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x63, 0x70, 0x5f, + 0x6d, 0x70, 0x74, 0x63, 0x70, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x63, 0x70, + 0x4d, 0x70, 0x74, 0x63, 0x70, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, + 0x6f, 0x64, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x66, 0x66, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, + 0x54, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5a, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x07, 0x0a, 0x03, 0x54, + 0x43, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, + 0x04, 0x4d, 0x4b, 0x43, 0x50, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x65, 0x62, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x04, + 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, + 0x10, 0x05, 0x2a, 0x41, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, 0x12, + 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, + 0x49, 0x50, 0x36, 0x10, 0x03, 0x42, 0x67, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, + 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0xaa, 0x02, 0x17, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/transport/internet/config.proto b/transport/internet/config.proto index 7fdc8ca2..550d00ec 100644 --- a/transport/internet/config.proto +++ b/transport/internet/config.proto @@ -110,4 +110,6 @@ message SocketConfig { int32 tcp_max_seg = 17; bool tcp_no_delay = 18; + + bool tcp_mptcp = 19; } diff --git a/transport/internet/system_dialer.go b/transport/internet/system_dialer.go index 5a68144d..5304595f 100644 --- a/transport/internet/system_dialer.go +++ b/transport/internet/system_dialer.go @@ -81,6 +81,9 @@ func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest ne } if sockopt != nil || len(d.controllers) > 0 { + if sockopt != nil && sockopt.TcpMptcp { + dialer.SetMultipathTCP(true) + } dialer.Control = func(network, address string, c syscall.RawConn) error { for _, ctl := range d.controllers { if err := ctl(network, address, c); err != nil { diff --git a/transport/internet/system_listener.go b/transport/internet/system_listener.go index 1d635897..6593f4bc 100644 --- a/transport/internet/system_listener.go +++ b/transport/internet/system_listener.go @@ -67,8 +67,13 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S network = addr.Network() address = addr.String() lc.Control = getControlFunc(ctx, sockopt, dl.controllers) - if sockopt != nil && (sockopt.TcpKeepAliveInterval != 0 || sockopt.TcpKeepAliveIdle != 0) { - lc.KeepAlive = time.Duration(-1) + if sockopt != nil { + if sockopt.TcpKeepAliveInterval != 0 || sockopt.TcpKeepAliveIdle != 0 { + lc.KeepAlive = time.Duration(-1) + } + if sockopt.TcpMptcp { + lc.SetMultipathTCP(true) + } } case *net.UnixAddr: lc.Control = nil From ae2fa30e01fceb2d4565ca1320d00e2515399f05 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 18 Jun 2023 09:12:11 -0400 Subject: [PATCH 50/71] Add Vless tests --- testing/scenarios/vless_test.go | 518 ++++++++++++++++++++++++++++++++ 1 file changed, 518 insertions(+) create mode 100644 testing/scenarios/vless_test.go diff --git a/testing/scenarios/vless_test.go b/testing/scenarios/vless_test.go new file mode 100644 index 00000000..84d82643 --- /dev/null +++ b/testing/scenarios/vless_test.go @@ -0,0 +1,518 @@ +package scenarios + +import ( + // "encoding/base64" + // "encoding/hex" + "testing" + "time" + + "github.com/xtls/xray-core/app/log" + "github.com/xtls/xray-core/app/proxyman" + "github.com/xtls/xray-core/common" + clog "github.com/xtls/xray-core/common/log" + "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/common/protocol/tls/cert" + "github.com/xtls/xray-core/common/serial" + "github.com/xtls/xray-core/common/uuid" + core "github.com/xtls/xray-core/core" + "github.com/xtls/xray-core/proxy/dokodemo" + "github.com/xtls/xray-core/proxy/freedom" + "github.com/xtls/xray-core/proxy/vless" + "github.com/xtls/xray-core/proxy/vless/inbound" + "github.com/xtls/xray-core/proxy/vless/outbound" + "github.com/xtls/xray-core/testing/servers/tcp" + "github.com/xtls/xray-core/transport/internet" + // "github.com/xtls/xray-core/transport/internet/reality" + transtcp "github.com/xtls/xray-core/transport/internet/tcp" + "github.com/xtls/xray-core/transport/internet/tls" + "golang.org/x/sync/errgroup" +) + +func TestVless(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := tcp.PickPort() + serverConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + Clients: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Vnext: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + }), + }, + }, + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + common.Must(err) + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) + } + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +func TestVlessTls(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := tcp.PickPort() + serverConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, + }), + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + Clients: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Vnext: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + }), + }, + }, + }, + }, + }), + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&transtcp.Config{}), + }, + }, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + AllowInsecure: true, + }), + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + common.Must(err) + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) + } + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +func TestVlessXtlsVision(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := tcp.PickPort() + serverConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, + }), + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + Clients: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + Flow: vless.XRV, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Vnext: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + Flow: vless.XRV, + }), + }, + }, + }, + }, + }), + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&transtcp.Config{}), + }, + }, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + AllowInsecure: true, + }), + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + common.Must(err) + defer CloseAllServers(servers) + + var errg errgroup.Group + for i := 0; i < 10; i++ { + errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) + } + if err := errg.Wait(); err != nil { + t.Error(err) + } +} + +// func TestVlessXtlsVisionReality(t *testing.T) { +// tcpServer := tcp.Server{ +// MsgProcessor: xor, +// } +// dest, err := tcpServer.Start() +// common.Must(err) +// defer tcpServer.Close() + +// userID := protocol.NewID(uuid.New()) +// serverPort := tcp.PickPort() +// privateKey, _ := base64.RawURLEncoding.DecodeString("aGSYystUbf59_9_6LKRxD27rmSW_-2_nyd9YG_Gwbks") +// publicKey, _ := base64.RawURLEncoding.DecodeString("E59WjnvZcQMu7tR7_BgyhycuEdBS-CtKxfImRCdAvFM") +// shortIds := make([][]byte, 1) +// shortIds[0] = make([]byte, 8) +// hex.Decode(shortIds[0], []byte("0123456789abcdef")) +// serverConfig := &core.Config{ +// App: []*serial.TypedMessage{ +// serial.ToTypedMessage(&log.Config{ +// ErrorLogLevel: clog.Severity_Debug, +// ErrorLogType: log.LogType_Console, +// }), +// }, +// Inbound: []*core.InboundHandlerConfig{ +// { +// ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ +// PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, +// Listen: net.NewIPOrDomain(net.LocalHostIP), +// StreamSettings: &internet.StreamConfig{ +// Protocol: internet.TransportProtocol_TCP, +// SecurityType: serial.GetMessageType(&reality.Config{}), +// SecuritySettings: []*serial.TypedMessage{ +// serial.ToTypedMessage(&reality.Config{ +// Show: true, +// Dest: "www.google.com:443", // use google for now, may fail in some region +// ServerNames: []string{"www.google.com"}, +// PrivateKey: privateKey, +// ShortIds: shortIds, +// }), +// }, +// }, +// }), +// ProxySettings: serial.ToTypedMessage(&inbound.Config{ +// Clients: []*protocol.User{ +// { +// Account: serial.ToTypedMessage(&vless.Account{ +// Id: userID.String(), +// Flow: vless.XRV, +// }), +// }, +// }, +// }), +// }, +// }, +// Outbound: []*core.OutboundHandlerConfig{ +// { +// ProxySettings: serial.ToTypedMessage(&freedom.Config{}), +// }, +// }, +// } + +// clientPort := tcp.PickPort() +// clientConfig := &core.Config{ +// App: []*serial.TypedMessage{ +// serial.ToTypedMessage(&log.Config{ +// ErrorLogLevel: clog.Severity_Debug, +// ErrorLogType: log.LogType_Console, +// }), +// }, +// Inbound: []*core.InboundHandlerConfig{ +// { +// ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ +// PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, +// Listen: net.NewIPOrDomain(net.LocalHostIP), +// }), +// ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ +// Address: net.NewIPOrDomain(dest.Address), +// Port: uint32(dest.Port), +// NetworkList: &net.NetworkList{ +// Network: []net.Network{net.Network_TCP}, +// }, +// }), +// }, +// }, +// Outbound: []*core.OutboundHandlerConfig{ +// { +// ProxySettings: serial.ToTypedMessage(&outbound.Config{ +// Vnext: []*protocol.ServerEndpoint{ +// { +// Address: net.NewIPOrDomain(net.LocalHostIP), +// Port: uint32(serverPort), +// User: []*protocol.User{ +// { +// Account: serial.ToTypedMessage(&vless.Account{ +// Id: userID.String(), +// Flow: vless.XRV, +// }), +// }, +// }, +// }, +// }, +// }), +// SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ +// StreamSettings: &internet.StreamConfig{ +// Protocol: internet.TransportProtocol_TCP, +// TransportSettings: []*internet.TransportConfig{ +// { +// Protocol: internet.TransportProtocol_TCP, +// Settings: serial.ToTypedMessage(&transtcp.Config{}), +// }, +// }, +// SecurityType: serial.GetMessageType(&reality.Config{}), +// SecuritySettings: []*serial.TypedMessage{ +// serial.ToTypedMessage(&reality.Config{ +// Show: true, +// Fingerprint: "chrome", +// ServerName: "www.google.com", +// PublicKey: publicKey, +// ShortId: shortIds[0], +// SpiderX: "/", +// }), +// }, +// }, +// }), +// }, +// }, +// } + +// servers, err := InitializeServerConfigs(serverConfig, clientConfig) +// common.Must(err) +// defer CloseAllServers(servers) + +// var errg errgroup.Group +// for i := 0; i < 1; i++ { +// errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) +// } +// if err := errg.Wait(); err != nil { +// t.Error(err) +// } +// } From efd32b0fb2a4f1b2d2e98b21916cfd9aa0e0b497 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Wed, 3 May 2023 22:21:45 -0400 Subject: [PATCH 51/71] Enable splice for freedom outbound (downlink only) - Add outbound name - Add outbound conn in ctx - Refactor splice: it can be turn on from all inbounds and outbounds - Refactor splice: Add splice copy to vless inbound - Fix http error test - Add freedom splice toggle via env var - Populate outbound obj in context - Use CanSpliceCopy to mark a connection - Turn off splice by default --- app/dispatcher/default.go | 20 +++--- app/proxyman/inbound/worker.go | 6 +- app/proxyman/outbound/handler.go | 7 +- common/buf/copy.go | 12 ++++ common/session/session.go | 14 ++++ proxy/blackhole/blackhole.go | 6 ++ proxy/dns/dns.go | 1 + proxy/dokodemo/dokodemo.go | 9 ++- proxy/errors.generated.go | 9 +++ proxy/freedom/freedom.go | 27 ++++++-- proxy/http/client.go | 5 ++ proxy/http/server.go | 9 ++- proxy/loopback/loopback.go | 1 + proxy/proxy.go | 86 +++++++++++++++++++++++++ proxy/shadowsocks/client.go | 5 ++ proxy/shadowsocks/server.go | 10 ++- proxy/shadowsocks_2022/inbound.go | 1 + proxy/shadowsocks_2022/inbound_multi.go | 1 + proxy/shadowsocks_2022/inbound_relay.go | 1 + proxy/shadowsocks_2022/outbound.go | 2 + proxy/socks/client.go | 5 ++ proxy/socks/server.go | 10 +-- proxy/trojan/client.go | 5 ++ proxy/trojan/server.go | 4 +- proxy/vless/encoding/encoding.go | 68 ++++++------------- proxy/vless/inbound/inbound.go | 35 ++-------- proxy/vless/outbound/outbound.go | 47 ++++++-------- proxy/vmess/inbound/inbound.go | 4 +- proxy/vmess/outbound/outbound.go | 16 +++-- proxy/wireguard/wireguard.go | 14 ++-- testing/scenarios/http_test.go | 6 +- testing/scenarios/vmess_test.go | 4 +- 32 files changed, 282 insertions(+), 168 deletions(-) create mode 100644 proxy/errors.generated.go diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index aaa9b410..bfc43608 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -218,11 +218,13 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin if !destination.IsValid() { panic("Dispatcher: Invalid destination.") } - ob := &session.Outbound{ - OriginalTarget: destination, - Target: destination, + ob := session.OutboundFromContext(ctx) + if ob == nil { + ob = &session.Outbound{} + ctx = session.ContextWithOutbound(ctx, ob) } - ctx = session.ContextWithOutbound(ctx, ob) + ob.OriginalTarget = destination + ob.Target = destination content := session.ContentFromContext(ctx) if content == nil { content = new(session.Content) @@ -271,11 +273,13 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De if !destination.IsValid() { return newError("Dispatcher: Invalid destination.") } - ob := &session.Outbound{ - OriginalTarget: destination, - Target: destination, + ob := session.OutboundFromContext(ctx) + if ob == nil { + ob = &session.Outbound{} + ctx = session.ContextWithOutbound(ctx, ob) } - ctx = session.ContextWithOutbound(ctx, ob) + ob.OriginalTarget = destination + ob.Target = destination content := session.ContentFromContext(ctx) if content == nil { content = new(session.Content) diff --git a/app/proxyman/inbound/worker.go b/app/proxyman/inbound/worker.go index 8ed4090a..1fe86655 100644 --- a/app/proxyman/inbound/worker.go +++ b/app/proxyman/inbound/worker.go @@ -60,6 +60,7 @@ func (w *tcpWorker) callback(conn stat.Connection) { sid := session.NewID() ctx = session.ContextWithID(ctx, sid) + var outbound = &session.Outbound{} if w.recvOrigDest { var dest net.Destination switch getTProxyType(w.stream) { @@ -74,11 +75,10 @@ func (w *tcpWorker) callback(conn stat.Connection) { dest = net.DestinationFromAddr(conn.LocalAddr()) } if dest.IsValid() { - ctx = session.ContextWithOutbound(ctx, &session.Outbound{ - Target: dest, - }) + outbound.Target = dest } } + ctx = session.ContextWithOutbound(ctx, outbound) if w.uplinkCounter != nil || w.downlinkCounter != nil { conn = &stat.CounterConnection{ diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index adf6537a..d290b016 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -274,7 +274,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti } conn, err := internet.Dial(ctx, dest, h.streamSettings) - return h.getStatCouterConnection(conn), err + conn = h.getStatCouterConnection(conn) + outbound := session.OutboundFromContext(ctx) + if outbound != nil { + outbound.Conn = conn + } + return conn, err } func (h *Handler) getStatCouterConnection(conn stat.Connection) stat.Connection { diff --git a/common/buf/copy.go b/common/buf/copy.go index 601771be..3096dc57 100644 --- a/common/buf/copy.go +++ b/common/buf/copy.go @@ -6,6 +6,7 @@ import ( "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/signal" + "github.com/xtls/xray-core/features/stats" ) type dataHandler func(MultiBuffer) @@ -40,6 +41,17 @@ func CountSize(sc *SizeCounter) CopyOption { } } +// AddToStatCounter a CopyOption add to stat counter +func AddToStatCounter(sc stats.Counter) CopyOption { + return func(handler *copyHandler) { + handler.onData = append(handler.onData, func(b MultiBuffer) { + if sc != nil { + sc.Add(int64(b.Len())) + } + }) + } +} + type readError struct { error } diff --git a/common/session/session.go b/common/session/session.go index b9609e86..4af61015 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -50,6 +50,16 @@ type Inbound struct { Conn net.Conn // Timer of the inbound buf copier. May be nil. Timer *signal.ActivityTimer + // CanSpliceCopy is a property for this connection, set by both inbound and outbound + // 1 = can, 2 = after processing protocol info should be able to, 3 = cannot + CanSpliceCopy int +} + +func(i *Inbound) SetCanSpliceCopy(canSpliceCopy int) int { + if canSpliceCopy > i.CanSpliceCopy { + i.CanSpliceCopy = canSpliceCopy + } + return i.CanSpliceCopy } // Outbound is the metadata of an outbound connection. @@ -60,6 +70,10 @@ type Outbound struct { RouteTarget net.Destination // Gateway address Gateway net.Address + // Name of the outbound proxy that handles the connection. + Name string + // Conn is actually internet.Connection. May be nil. It is currently nil for outbound with proxySettings + Conn net.Conn } // SniffingRequest controls the behavior of content sniffing. diff --git a/proxy/blackhole/blackhole.go b/proxy/blackhole/blackhole.go index b17c60c4..4b819417 100644 --- a/proxy/blackhole/blackhole.go +++ b/proxy/blackhole/blackhole.go @@ -8,6 +8,7 @@ import ( "time" "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" ) @@ -30,6 +31,11 @@ func New(ctx context.Context, config *Config) (*Handler, error) { // Process implements OutboundHandler.Dispatch(). func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { + outbound := session.OutboundFromContext(ctx) + if outbound != nil { + outbound.Name = "blackhole" + } + nBytes := h.response.WriteTo(link.Writer) if nBytes > 0 { // Sleep a little here to make sure the response is sent to client. diff --git a/proxy/dns/dns.go b/proxy/dns/dns.go index d8a3244d..415fe991 100644 --- a/proxy/dns/dns.go +++ b/proxy/dns/dns.go @@ -96,6 +96,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, d internet. if outbound == nil || !outbound.Target.IsValid() { return newError("invalid outbound") } + outbound.Name = "dns" srcNetwork := outbound.Target.Network diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 42d8256f..4a4735e8 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -102,11 +102,10 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st } inbound := session.InboundFromContext(ctx) - if inbound != nil { - inbound.Name = "dokodemo-door" - inbound.User = &protocol.MemoryUser{ - Level: d.config.UserLevel, - } + inbound.Name = "dokodemo-door" + inbound.SetCanSpliceCopy(1) + inbound.User = &protocol.MemoryUser{ + Level: d.config.UserLevel, } ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ diff --git a/proxy/errors.generated.go b/proxy/errors.generated.go new file mode 100644 index 00000000..1a643896 --- /dev/null +++ b/proxy/errors.generated.go @@ -0,0 +1,9 @@ +package proxy + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index c6907b4c..808f837f 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -13,6 +13,7 @@ import ( "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/net" + "github.com/xtls/xray-core/common/platform" "github.com/xtls/xray-core/common/retry" "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/signal" @@ -21,11 +22,14 @@ import ( "github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/stats" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/stat" ) +var useSplice bool + func init() { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { h := new(Handler) @@ -36,6 +40,12 @@ func init() { } return h, nil })) + const defaultFlagValue = "NOT_DEFINED_AT_ALL" + value := platform.NewEnvFlag("xray.buf.splice").GetValue(func() string { return defaultFlagValue }) + switch value { + case "auto", "enable": + useSplice = true + } } // Handler handles Freedom connections. @@ -107,6 +117,11 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified.") } + outbound.Name = "freedom" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(1) + } destination := outbound.Target UDPOverride := net.UDPDestination(nil, 0) if h.config.DestinationOverride != nil { @@ -195,17 +210,17 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte responseDone := func() error { defer timer.SetTimeout(plcy.Timeouts.UplinkOnly) - - var reader buf.Reader if destination.Network == net.Network_TCP { - reader = buf.NewReader(conn) - } else { - reader = NewPacketReader(conn, UDPOverride) + var writeConn net.Conn + if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil && useSplice { + writeConn = inbound.Conn + } + return proxy.CopyRawConnIfExist(ctx, conn, writeConn, link.Writer, timer) } + reader := NewPacketReader(conn, UDPOverride) if err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil { return newError("failed to process response").Base(err) } - return nil } diff --git a/proxy/http/client.go b/proxy/http/client.go index f597a502..302e521d 100644 --- a/proxy/http/client.go +++ b/proxy/http/client.go @@ -73,6 +73,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified.") } + outbound.Name = "http" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(2) + } target := outbound.Target targetAddr := target.NetAddr() diff --git a/proxy/http/server.go b/proxy/http/server.go index 6b00fe2b..511d9b08 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -84,11 +84,10 @@ type readerOnly struct { func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error { inbound := session.InboundFromContext(ctx) - if inbound != nil { - inbound.Name = "http" - inbound.User = &protocol.MemoryUser{ - Level: s.config.UserLevel, - } + inbound.Name = "http" + inbound.SetCanSpliceCopy(2) + inbound.User = &protocol.MemoryUser{ + Level: s.config.UserLevel, } reader := bufio.NewReaderSize(readerOnly{conn}, buf.Size) diff --git a/proxy/loopback/loopback.go b/proxy/loopback/loopback.go index 946847f3..30c39bd9 100644 --- a/proxy/loopback/loopback.go +++ b/proxy/loopback/loopback.go @@ -26,6 +26,7 @@ func (l *Loopback) Process(ctx context.Context, link *transport.Link, _ internet if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified.") } + outbound.Name = "loopback" destination := outbound.Target newError("opening connection to ", destination).WriteToLog(session.ExportIDToError(ctx)) diff --git a/proxy/proxy.go b/proxy/proxy.go index fb52605c..12b9631b 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -7,13 +7,24 @@ package proxy import ( "context" + gotls "crypto/tls" + "io" + "runtime" + "github.com/pires/go-proxyproto" + "github.com/xtls/xray-core/common/buf" + "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/common/session" + "github.com/xtls/xray-core/common/signal" "github.com/xtls/xray-core/features/routing" + "github.com/xtls/xray-core/features/stats" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" + "github.com/xtls/xray-core/transport/internet/reality" "github.com/xtls/xray-core/transport/internet/stat" + "github.com/xtls/xray-core/transport/internet/tls" ) // An Inbound processes inbound connections. @@ -47,3 +58,78 @@ type GetInbound interface { type GetOutbound interface { GetOutbound() Outbound } + +// UnwrapRawConn support unwrap stats, tls, utls, reality and proxyproto conn and get raw tcp conn from it +func UnwrapRawConn(conn net.Conn) (net.Conn, stats.Counter, stats.Counter) { + var readCounter, writerCounter stats.Counter + if conn != nil { + statConn, ok := conn.(*stat.CounterConnection) + if ok { + conn = statConn.Connection + readCounter = statConn.ReadCounter + writerCounter = statConn.WriteCounter + } + if xc, ok := conn.(*gotls.Conn); ok { + conn = xc.NetConn() + } else if utlsConn, ok := conn.(*tls.UConn); ok { + conn = utlsConn.NetConn() + } else if realityConn, ok := conn.(*reality.Conn); ok { + conn = realityConn.NetConn() + } else if realityUConn, ok := conn.(*reality.UConn); ok { + conn = realityUConn.NetConn() + } + if pc, ok := conn.(*proxyproto.Conn); ok { + conn = pc.Raw() + // 8192 > 4096, there is no need to process pc's bufReader + } + } + return conn, readCounter, writerCounter +} + +// CopyRawConnIfExist use the most efficient copy method. +// - If caller don't want to turn on splice, do not pass in both reader conn and writer conn +// - writer are from *transport.Link +func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net.Conn, writer buf.Writer, timer signal.ActivityUpdater) error { + readerConn, readCounter, _ := UnwrapRawConn(readerConn) + writerConn, _, writeCounter := UnwrapRawConn(writerConn) + reader := buf.NewReader(readerConn) + if inbound := session.InboundFromContext(ctx); inbound != nil { + if tc, ok := writerConn.(*net.TCPConn); ok && readerConn != nil && writerConn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") { + for inbound.CanSpliceCopy != 3 { + if inbound.CanSpliceCopy == 1 { + newError("CopyRawConn splice").WriteToLog(session.ExportIDToError(ctx)) + runtime.Gosched() // necessary + w, err := tc.ReadFrom(readerConn) + if readCounter != nil { + readCounter.Add(w) + } + if writeCounter != nil { + writeCounter.Add(w) + } + if err != nil && errors.Cause(err) != io.EOF { + return err + } + return nil + } + buffer, err := reader.ReadMultiBuffer() + if !buffer.IsEmpty() { + if readCounter != nil { + readCounter.Add(int64(buffer.Len())) + } + timer.Update() + if werr := writer.WriteMultiBuffer(buffer); werr != nil { + return werr + } + } + if err != nil { + return err + } + } + } + } + newError("CopyRawConn readv").WriteToLog(session.ExportIDToError(ctx)) + if err := buf.Copy(reader, writer, buf.UpdateActivity(timer), buf.AddToStatCounter(readCounter)); err != nil { + return newError("failed to process response").Base(err) + } + return nil +} diff --git a/proxy/shadowsocks/client.go b/proxy/shadowsocks/client.go index e22b11c7..57d8f81c 100644 --- a/proxy/shadowsocks/client.go +++ b/proxy/shadowsocks/client.go @@ -53,6 +53,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified") } + outbound.Name = "shadowsocks" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(3) + } destination := outbound.Target network := destination.Network diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index 1d89db5e..2975ba70 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -71,6 +71,10 @@ func (s *Server) Network() []net.Network { } func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error { + inbound := session.InboundFromContext(ctx) + inbound.Name = "shadowsocks" + inbound.SetCanSpliceCopy(3) + switch network { case net.Network_TCP: return s.handleConnection(ctx, conn, dispatcher) @@ -110,13 +114,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn stat.Connection, dis }) inbound := session.InboundFromContext(ctx) - if inbound == nil { - panic("no inbound metadata") - } - inbound.Name = "shadowsocks" - var dest *net.Destination - reader := buf.NewPacketReader(conn) for { mpayload, err := reader.ReadMultiBuffer() diff --git a/proxy/shadowsocks_2022/inbound.go b/proxy/shadowsocks_2022/inbound.go index bb298c09..246fc7f1 100644 --- a/proxy/shadowsocks_2022/inbound.go +++ b/proxy/shadowsocks_2022/inbound.go @@ -66,6 +66,7 @@ func (i *Inbound) Network() []net.Network { func (i *Inbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error { inbound := session.InboundFromContext(ctx) inbound.Name = "shadowsocks-2022" + inbound.SetCanSpliceCopy(3) var metadata M.Metadata if inbound.Source.IsValid() { diff --git a/proxy/shadowsocks_2022/inbound_multi.go b/proxy/shadowsocks_2022/inbound_multi.go index c9927476..c3832a91 100644 --- a/proxy/shadowsocks_2022/inbound_multi.go +++ b/proxy/shadowsocks_2022/inbound_multi.go @@ -155,6 +155,7 @@ func (i *MultiUserInbound) Network() []net.Network { func (i *MultiUserInbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error { inbound := session.InboundFromContext(ctx) inbound.Name = "shadowsocks-2022-multi" + inbound.SetCanSpliceCopy(3) var metadata M.Metadata if inbound.Source.IsValid() { diff --git a/proxy/shadowsocks_2022/inbound_relay.go b/proxy/shadowsocks_2022/inbound_relay.go index c3f8e675..e2cb7d50 100644 --- a/proxy/shadowsocks_2022/inbound_relay.go +++ b/proxy/shadowsocks_2022/inbound_relay.go @@ -87,6 +87,7 @@ func (i *RelayInbound) Network() []net.Network { func (i *RelayInbound) Process(ctx context.Context, network net.Network, connection stat.Connection, dispatcher routing.Dispatcher) error { inbound := session.InboundFromContext(ctx) inbound.Name = "shadowsocks-2022-relay" + inbound.SetCanSpliceCopy(3) var metadata M.Metadata if inbound.Source.IsValid() { diff --git a/proxy/shadowsocks_2022/outbound.go b/proxy/shadowsocks_2022/outbound.go index 151ea0e2..a06daac7 100644 --- a/proxy/shadowsocks_2022/outbound.go +++ b/proxy/shadowsocks_2022/outbound.go @@ -66,12 +66,14 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int inbound := session.InboundFromContext(ctx) if inbound != nil { inboundConn = inbound.Conn + inbound.SetCanSpliceCopy(3) } outbound := session.OutboundFromContext(ctx) if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified") } + outbound.Name = "shadowsocks-2022" destination := outbound.Target network := destination.Network diff --git a/proxy/socks/client.go b/proxy/socks/client.go index 1993aa0b..82591be4 100644 --- a/proxy/socks/client.go +++ b/proxy/socks/client.go @@ -61,6 +61,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified.") } + outbound.Name = "socks" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(2) + } // Destination of the inner request. destination := outbound.Target diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 184ecd08..6964fdf2 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -63,11 +63,11 @@ func (s *Server) Network() []net.Network { // Process implements proxy.Inbound. func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error { - if inbound := session.InboundFromContext(ctx); inbound != nil { - inbound.Name = "socks" - inbound.User = &protocol.MemoryUser{ - Level: s.config.UserLevel, - } + inbound := session.InboundFromContext(ctx) + inbound.Name = "socks" + inbound.SetCanSpliceCopy(2) + inbound.User = &protocol.MemoryUser{ + Level: s.config.UserLevel, } switch network { diff --git a/proxy/trojan/client.go b/proxy/trojan/client.go index 0c6f16d3..d6b95fc0 100644 --- a/proxy/trojan/client.go +++ b/proxy/trojan/client.go @@ -54,6 +54,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified") } + outbound.Name = "trojan" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(3) + } destination := outbound.Target network := destination.Network diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index 41245ba4..5c3fcd91 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -214,10 +214,8 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con } inbound := session.InboundFromContext(ctx) - if inbound == nil { - panic("no inbound metadata") - } inbound.Name = "trojan" + inbound.SetCanSpliceCopy(3) inbound.User = user sessionPolicy = s.policyManager.ForLevel(user.Level) diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index cf962492..48bda497 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -8,9 +8,7 @@ import ( "crypto/rand" "io" "math/big" - "runtime" "strconv" - "syscall" "time" "github.com/xtls/xray-core/common/buf" @@ -20,10 +18,8 @@ import ( "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/signal" "github.com/xtls/xray-core/features/stats" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/proxy/vless" - "github.com/xtls/xray-core/transport/internet/reality" - "github.com/xtls/xray-core/transport/internet/stat" - "github.com/xtls/xray-core/transport/internet/tls" ) const ( @@ -206,13 +202,11 @@ func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*A } // XtlsRead filter and read xtls protocol -func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, rawConn syscall.RawConn, - input *bytes.Reader, rawInput *bytes.Buffer, - counter stats.Counter, ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool, +func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, + ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32, ) error { err := func() error { - var ct stats.Counter withinPaddingBuffers := true shouldSwitchToDirectCopy := false var remainingContent int32 = -1 @@ -220,40 +214,14 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater currentCommand := 0 for { if shouldSwitchToDirectCopy { - shouldSwitchToDirectCopy = false - if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") { - if _, ok := inbound.User.Account.(*vless.MemoryAccount); inbound.User.Account == nil || ok { - iConn := inbound.Conn - statConn, ok := iConn.(*stat.CounterConnection) - if ok { - iConn = statConn.Connection - } - if tlsConn, ok := iConn.(*tls.Conn); ok { - iConn = tlsConn.NetConn() - } else if realityConn, ok := iConn.(*reality.Conn); ok { - iConn = realityConn.NetConn() - } - if tc, ok := iConn.(*net.TCPConn); ok { - newError("XtlsRead splice").WriteToLog(session.ExportIDToError(ctx)) - runtime.Gosched() // necessary - w, err := tc.ReadFrom(conn) - if counter != nil { - counter.Add(w) - } - if statConn != nil && statConn.WriteCounter != nil { - statConn.WriteCounter.Add(w) - } - return err - } + var writerConn net.Conn + if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil { + writerConn = inbound.Conn + if inbound.CanSpliceCopy == 2 { + inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter } } - if rawConn != nil { - reader = buf.NewReadVReader(conn, rawConn, nil) - } else { - reader = buf.NewReader(conn) - } - ct = counter - newError("XtlsRead readV").WriteToLog(session.ExportIDToError(ctx)) + return proxy.CopyRawConnIfExist(ctx, conn, writerConn, writer, timer) } buffer, err := reader.ReadMultiBuffer() if !buffer.IsEmpty() { @@ -292,9 +260,6 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater if *numberOfPacketToFilter > 0 { XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx) } - if ct != nil { - ct.Add(int64(buffer.Len())) - } timer.Update() if werr := writer.WriteMultiBuffer(buffer); werr != nil { return werr @@ -312,7 +277,7 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater } // XtlsWrite filter and write xtls protocol -func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, counter stats.Counter, +func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, ctx context.Context, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32, ) error { @@ -349,18 +314,21 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate } if shouldSwitchToDirectCopy { encryptBuffer, directBuffer := buf.SplitMulti(buffer, xtlsSpecIndex+1) - length := encryptBuffer.Len() if !encryptBuffer.IsEmpty() { timer.Update() if werr := writer.WriteMultiBuffer(encryptBuffer); werr != nil { return werr } } - buffer = directBuffer - writer = buf.NewWriter(conn) - ct = counter - newError("XtlsWrite writeV ", xtlsSpecIndex, " ", length, " ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay + + if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { + inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter + } + buffer = directBuffer + rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) + writer = buf.NewWriter(rawConn) + ct = writerCounter } } if !buffer.IsEmpty() { diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 8653e1e3..388aeecb 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -10,11 +10,9 @@ import ( "reflect" "strconv" "strings" - "syscall" "time" "unsafe" - "github.com/pires/go-proxyproto" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/errors" @@ -30,7 +28,6 @@ import ( feature_inbound "github.com/xtls/xray-core/features/inbound" "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/routing" - "github.com/xtls/xray-core/features/stats" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/encoding" "github.com/xtls/xray-core/transport/internet/reality" @@ -182,8 +179,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s sid := session.ExportIDToError(ctx) iConn := connection - statConn, ok := iConn.(*stat.CounterConnection) - if ok { + if statConn, ok := iConn.(*stat.CounterConnection); ok { iConn = statConn.Connection } @@ -447,14 +443,12 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s // Flow: requestAddons.Flow, } - var netConn net.Conn - var rawConn syscall.RawConn var input *bytes.Reader var rawInput *bytes.Buffer - switch requestAddons.Flow { case vless.XRV: if account.Flow == requestAddons.Flow { + inbound.SetCanSpliceCopy(2) switch request.Command { case protocol.RequestCommandUDP: return newError(requestAddons.Flow + " doesn't support UDP").AtWarning() @@ -467,23 +461,14 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s if tlsConn.ConnectionState().Version != gotls.VersionTLS13 { return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, tlsConn.ConnectionState().Version).AtWarning() } - netConn = tlsConn.NetConn() t = reflect.TypeOf(tlsConn.Conn).Elem() p = uintptr(unsafe.Pointer(tlsConn.Conn)) } else if realityConn, ok := iConn.(*reality.Conn); ok { - netConn = realityConn.NetConn() t = reflect.TypeOf(realityConn.Conn).Elem() p = uintptr(unsafe.Pointer(realityConn.Conn)) } else { return newError("XTLS only supports TLS and REALITY directly for now.").AtWarning() } - if pc, ok := netConn.(*proxyproto.Conn); ok { - netConn = pc.Raw() - // 8192 > 4096, there is no need to process pc's bufReader - } - if sc, ok := netConn.(syscall.Conn); ok { - rawConn, _ = sc.SyscallConn() - } i, _ := t.FieldByName("input") r, _ := t.FieldByName("rawInput") input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset)) @@ -493,6 +478,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s return newError(account.ID.String() + " is not able to use " + requestAddons.Flow).AtWarning() } case "": + inbound.SetCanSpliceCopy(3) if account.Flow == vless.XRV && (request.Command == protocol.RequestCommandTCP || isMuxAndNotXUDP(request, first)) { return newError(account.ID.String() + " is not able to use \"\". Note that the pure TLS proxy has certain TLS in TLS characters.").AtWarning() } @@ -540,13 +526,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s var err error if requestAddons.Flow == vless.XRV { - var counter stats.Counter - if statConn != nil { - counter = statConn.ReadCounter - } - // TODO enable splice - ctx = session.ContextWithInbound(ctx, nil) - err = encoding.XtlsRead(clientReader, serverWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(), + ctx1 := session.ContextWithInbound(ctx, nil) // TODO enable splice + err = encoding.XtlsRead(clientReader, serverWriter, timer, connection, input, rawInput, ctx1, account.ID.Bytes(), &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer @@ -592,11 +573,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s var err error if requestAddons.Flow == vless.XRV { - var counter stats.Counter - if statConn != nil { - counter = statConn.WriteCounter - } - err = encoding.XtlsWrite(serverReader, clientWriter, timer, netConn, counter, ctx, &numberOfPacketToFilter, + err = encoding.XtlsWrite(serverReader, clientWriter, timer, connection, ctx, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 12962a47..bc2e6625 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -7,7 +7,6 @@ import ( "context" gotls "crypto/tls" "reflect" - "syscall" "time" "unsafe" @@ -23,7 +22,6 @@ import ( "github.com/xtls/xray-core/common/xudp" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/policy" - "github.com/xtls/xray-core/features/stats" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/encoding" "github.com/xtls/xray-core/transport" @@ -71,9 +69,15 @@ func New(ctx context.Context, config *Config) (*Handler, error) { // Process implements proxy.Outbound.Process(). func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { + outbound := session.OutboundFromContext(ctx) + if outbound == nil || !outbound.Target.IsValid() { + return newError("target not specified").AtError() + } + outbound.Name = "vless" + inbound := session.InboundFromContext(ctx) + var rec *protocol.ServerSpec var conn stat.Connection - if err := retry.ExponentialBackoff(5, 200).On(func() error { rec = h.serverPicker.PickServer() var err error @@ -88,16 +92,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte defer conn.Close() iConn := conn - statConn, ok := iConn.(*stat.CounterConnection) - if ok { + if statConn, ok := iConn.(*stat.CounterConnection); ok { iConn = statConn.Connection } - - outbound := session.OutboundFromContext(ctx) - if outbound == nil || !outbound.Target.IsValid() { - return newError("target not specified").AtError() - } - target := outbound.Target newError("tunneling request to ", target, " via ", rec.Destination().NetAddr()).AtInfo().WriteToLog(session.ExportIDToError(ctx)) @@ -123,8 +120,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte Flow: account.Flow, } - var netConn net.Conn - var rawConn syscall.RawConn var input *bytes.Reader var rawInput *bytes.Buffer allowUDP443 := false @@ -134,6 +129,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte requestAddons.Flow = requestAddons.Flow[:16] fallthrough case vless.XRV: + if inbound != nil { + inbound.SetCanSpliceCopy(2) + } switch request.Command { case protocol.RequestCommandUDP: if !allowUDP443 && request.Port == 443 { @@ -146,28 +144,26 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte var t reflect.Type var p uintptr if tlsConn, ok := iConn.(*tls.Conn); ok { - netConn = tlsConn.NetConn() t = reflect.TypeOf(tlsConn.Conn).Elem() p = uintptr(unsafe.Pointer(tlsConn.Conn)) } else if utlsConn, ok := iConn.(*tls.UConn); ok { - netConn = utlsConn.NetConn() t = reflect.TypeOf(utlsConn.Conn).Elem() p = uintptr(unsafe.Pointer(utlsConn.Conn)) } else if realityConn, ok := iConn.(*reality.UConn); ok { - netConn = realityConn.NetConn() t = reflect.TypeOf(realityConn.Conn).Elem() p = uintptr(unsafe.Pointer(realityConn.Conn)) } else { return newError("XTLS only supports TLS and REALITY directly for now.").AtWarning() } - if sc, ok := netConn.(syscall.Conn); ok { - rawConn, _ = sc.SyscallConn() - } i, _ := t.FieldByName("input") r, _ := t.FieldByName("rawInput") input = (*bytes.Reader)(unsafe.Pointer(p + i.Offset)) rawInput = (*bytes.Buffer)(unsafe.Pointer(p + r.Offset)) } + default: + if inbound != nil { + inbound.SetCanSpliceCopy(3) + } } var newCtx context.Context @@ -257,11 +253,8 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte return newError(`failed to use `+requestAddons.Flow+`, found outer tls version `, utlsConn.ConnectionState().Version).AtWarning() } } - var counter stats.Counter - if statConn != nil { - counter = statConn.WriteCounter - } - err = encoding.XtlsWrite(clientReader, serverWriter, timer, netConn, counter, ctx, &numberOfPacketToFilter, + ctx1 := session.ContextWithOutbound(ctx, nil) // TODO enable splice + err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, ctx1, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer @@ -293,11 +286,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } if requestAddons.Flow == vless.XRV { - var counter stats.Counter - if statConn != nil { - counter = statConn.ReadCounter - } - err = encoding.XtlsRead(serverReader, clientWriter, timer, netConn, rawConn, input, rawInput, counter, ctx, account.ID.Bytes(), + err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, ctx, account.ID.Bytes(), &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index f48a26e1..679ea5da 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -256,10 +256,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s } inbound := session.InboundFromContext(ctx) - if inbound == nil { - panic("no inbound metadata") - } inbound.Name = "vmess" + inbound.SetCanSpliceCopy(3) inbound.User = request.User sessionPolicy = h.policyManager.ForLevel(request.User.Level) diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index fc77f07f..5e228d68 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -60,9 +60,18 @@ func New(ctx context.Context, config *Config) (*Handler, error) { // Process implements proxy.Outbound.Process(). func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { + outbound := session.OutboundFromContext(ctx) + if outbound == nil || !outbound.Target.IsValid() { + return newError("target not specified").AtError() + } + outbound.Name = "vmess" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(3) + } + var rec *protocol.ServerSpec var conn stat.Connection - err := retry.ExponentialBackoff(5, 200).On(func() error { rec = h.serverPicker.PickServer() rawConn, err := dialer.Dial(ctx, rec.Destination()) @@ -78,11 +87,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } defer conn.Close() - outbound := session.OutboundFromContext(ctx) - if outbound == nil || !outbound.Target.IsValid() { - return newError("target not specified").AtError() - } - target := outbound.Target newError("tunneling request to ", target, " via ", rec.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx)) diff --git a/proxy/wireguard/wireguard.go b/proxy/wireguard/wireguard.go index 53e7dcd5..899dcac5 100644 --- a/proxy/wireguard/wireguard.go +++ b/proxy/wireguard/wireguard.go @@ -75,6 +75,16 @@ func New(ctx context.Context, conf *DeviceConfig) (*Handler, error) { // Process implements OutboundHandler.Dispatch(). func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error { + outbound := session.OutboundFromContext(ctx) + if outbound == nil || !outbound.Target.IsValid() { + return newError("target not specified") + } + outbound.Name = "wireguard" + inbound := session.InboundFromContext(ctx) + if inbound != nil { + inbound.SetCanSpliceCopy(3) + } + if h.bind == nil || h.bind.dialer != dialer || h.net == nil { log.Record(&log.GeneralMessage{ Severity: log.Severity_Info, @@ -101,10 +111,6 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte h.bind = bind } - outbound := session.OutboundFromContext(ctx) - if outbound == nil || !outbound.Target.IsValid() { - return newError("target not specified") - } // Destination of the inner request. destination := outbound.Target command := protocol.RequestCommandTCP diff --git a/testing/scenarios/http_test.go b/testing/scenarios/http_test.go index d6a765bb..b9b112ff 100644 --- a/testing/scenarios/http_test.go +++ b/testing/scenarios/http_test.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/url" + "strings" "testing" "time" @@ -128,9 +129,8 @@ func TestHttpError(t *testing.T) { } resp, err := client.Get("http://127.0.0.1:" + dest.Port.String()) - common.Must(err) - if resp.StatusCode != 503 { - t.Error("status: ", resp.StatusCode) + if resp != nil && resp.StatusCode != 503 || err != nil && !strings.Contains(err.Error(), "malformed HTTP status code") { + t.Error("should not receive http response", err) } } } diff --git a/testing/scenarios/vmess_test.go b/testing/scenarios/vmess_test.go index 9f2b0abc..2239b13c 100644 --- a/testing/scenarios/vmess_test.go +++ b/testing/scenarios/vmess_test.go @@ -1174,10 +1174,10 @@ func TestVMessGCMMuxUDP(t *testing.T) { servers, err := InitializeServerConfigs(serverConfig, clientConfig) common.Must(err) - for range "abcd" { + for range "ab" { var errg errgroup.Group for i := 0; i < 16; i++ { - errg.Go(testTCPConn(clientPort, 10240, time.Second*20)) + errg.Go(testTCPConn(clientPort, 1024, time.Second*10)) errg.Go(testUDPConn(clientUDPPort, 1024, time.Second*10)) } if err := errg.Wait(); err != nil { From d6d225c6981812f024f90adab8cefc26a5ac0937 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sat, 2 Sep 2023 11:37:50 -0400 Subject: [PATCH 52/71] Refactor Vision reader writer - Vision now use traffic states to capture two-way info about a connection - XTLS is de-couple with Vision, it only read traffic states to switch to direct copy mode - fix a edge case error when Vision unpadding read 5 command bytes --- proxy/proxy.go | 386 +++++++++++++++++++++++++++++++ proxy/vless/encoding/addons.go | 19 +- proxy/vless/encoding/encoding.go | 356 +++------------------------- proxy/vless/inbound/inbound.go | 25 +- proxy/vless/outbound/outbound.go | 28 +-- 5 files changed, 440 insertions(+), 374 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index 12b9631b..142acb77 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -6,10 +6,14 @@ package proxy import ( + "bytes" "context" + "crypto/rand" gotls "crypto/tls" "io" + "math/big" "runtime" + "strconv" "github.com/pires/go-proxyproto" "github.com/xtls/xray-core/common/buf" @@ -27,6 +31,30 @@ import ( "github.com/xtls/xray-core/transport/internet/tls" ) +var ( + Tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04} + TlsClientHandShakeStart = []byte{0x16, 0x03} + TlsServerHandShakeStart = []byte{0x16, 0x03, 0x03} + TlsApplicationDataStart = []byte{0x17, 0x03, 0x03} + + Tls13CipherSuiteDic = map[uint16]string{ + 0x1301: "TLS_AES_128_GCM_SHA256", + 0x1302: "TLS_AES_256_GCM_SHA384", + 0x1303: "TLS_CHACHA20_POLY1305_SHA256", + 0x1304: "TLS_AES_128_CCM_SHA256", + 0x1305: "TLS_AES_128_CCM_8_SHA256", + } +) + +const ( + TlsHandshakeTypeClientHello byte = 0x01 + TlsHandshakeTypeServerHello byte = 0x02 + + CommandPaddingContinue byte = 0x00 + CommandPaddingEnd byte = 0x01 + CommandPaddingDirect byte = 0x02 +) + // An Inbound processes inbound connections. type Inbound interface { // Network returns a list of networks that this inbound supports. Connections with not-supported networks will not be passed into Process(). @@ -59,6 +87,364 @@ type GetOutbound interface { GetOutbound() Outbound } +// TrafficState is used to track uplink and downlink of one connection +// It is used by XTLS to determine if switch to raw copy mode, It is used by Vision to calculate padding +type TrafficState struct { + UserUUID []byte + NumberOfPacketToFilter int + EnableXtls bool + IsTLS12orAbove bool + IsTLS bool + Cipher uint16 + RemainingServerHello int32 + + // reader link state + WithinPaddingBuffers bool + ReaderSwitchToDirectCopy bool + RemainingCommand int32 + RemainingContent int32 + RemainingPadding int32 + CurrentCommand int + + // write link state + IsPadding bool + WriterSwitchToDirectCopy bool +} + +func NewTrafficState(userUUID []byte) *TrafficState { + return &TrafficState{ + UserUUID: userUUID, + NumberOfPacketToFilter: 8, + EnableXtls: false, + IsTLS12orAbove: false, + IsTLS: false, + Cipher: 0, + RemainingServerHello: -1, + WithinPaddingBuffers: true, + ReaderSwitchToDirectCopy: false, + RemainingCommand: -1, + RemainingContent: -1, + RemainingPadding: -1, + CurrentCommand: 0, + IsPadding: true, + WriterSwitchToDirectCopy: false, + } +} + +// VisionReader is used to read xtls vision protocol +// Note Vision probably only make sense as the inner most layer of reader, since it need assess traffic state from origin proxy traffic +type VisionReader struct { + buf.Reader + trafficState *TrafficState + ctx context.Context +} + +func NewVisionReader(reader buf.Reader, state *TrafficState, context context.Context) *VisionReader { + return &VisionReader{ + Reader: reader, + trafficState: state, + ctx: context, + } +} + +func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) { + buffer, err := w.Reader.ReadMultiBuffer() + if !buffer.IsEmpty() { + if w.trafficState.WithinPaddingBuffers || w.trafficState.NumberOfPacketToFilter > 0 { + mb2 := make(buf.MultiBuffer, 0, len(buffer)) + for _, b := range buffer { + newbuffer := XtlsUnpadding(b, w.trafficState, w.ctx) + if newbuffer.Len() > 0 { + mb2 = append(mb2, newbuffer) + } + } + buffer = mb2 + if w.trafficState.RemainingContent == 0 && w.trafficState.RemainingPadding == 0 { + if w.trafficState.CurrentCommand == 1 { + w.trafficState.WithinPaddingBuffers = false + } else if w.trafficState.CurrentCommand == 2 { + w.trafficState.WithinPaddingBuffers = false + w.trafficState.ReaderSwitchToDirectCopy = true + } else if w.trafficState.CurrentCommand == 0 { + w.trafficState.WithinPaddingBuffers = true + } else { + newError("XtlsRead unknown command ", w.trafficState.CurrentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(w.ctx)) + } + } else if w.trafficState.RemainingContent > 0 || w.trafficState.RemainingPadding > 0 { + w.trafficState.WithinPaddingBuffers = true + } else { + w.trafficState.WithinPaddingBuffers = false + } + } + if w.trafficState.NumberOfPacketToFilter > 0 { + XtlsFilterTls(buffer, w.trafficState, w.ctx) + } + } + return buffer, err +} + +// VisionWriter is used to write xtls vision protocol +// Note Vision probably only make sense as the inner most layer of writer, since it need assess traffic state from origin proxy traffic +type VisionWriter struct { + buf.Writer + trafficState *TrafficState + ctx context.Context + writeOnceUserUUID []byte +} + +func NewVisionWriter(writer buf.Writer, state *TrafficState, context context.Context) *VisionWriter { + w := make([]byte, len(state.UserUUID)) + copy(w, state.UserUUID) + return &VisionWriter{ + Writer: writer, + trafficState: state, + ctx: context, + writeOnceUserUUID: w, + } +} + +func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { + if w.trafficState.NumberOfPacketToFilter > 0 { + XtlsFilterTls(mb, w.trafficState, w.ctx) + } + if w.trafficState.IsPadding { + if len(mb) == 1 && mb[0] == nil { + mb[0] = XtlsPadding(nil, CommandPaddingContinue, &w.writeOnceUserUUID, true, w.ctx) // we do a long padding to hide vless header + return w.Writer.WriteMultiBuffer(mb) + } + mb = ReshapeMultiBuffer(w.ctx, mb) + longPadding := w.trafficState.IsTLS + for i, b := range mb { + if w.trafficState.IsTLS && b.Len() >= 6 && bytes.Equal(TlsApplicationDataStart, b.BytesTo(3)) { + if w.trafficState.EnableXtls { + w.trafficState.WriterSwitchToDirectCopy = true + } + var command byte = CommandPaddingContinue + if i == len(mb) - 1 { + command = CommandPaddingEnd + if w.trafficState.EnableXtls { + command = CommandPaddingDirect + } + } + mb[i] = XtlsPadding(b, command, &w.writeOnceUserUUID, true, w.ctx) + w.trafficState.IsPadding = false // padding going to end + longPadding = false + continue + } else if !w.trafficState.IsTLS12orAbove && w.trafficState.NumberOfPacketToFilter <= 1 { // For compatibility with earlier vision receiver, we finish padding 1 packet early + w.trafficState.IsPadding = false + mb[i] = XtlsPadding(b, CommandPaddingEnd, &w.writeOnceUserUUID, longPadding, w.ctx) + break + } + var command byte = CommandPaddingContinue + if i == len(mb) - 1 && !w.trafficState.IsPadding { + command = CommandPaddingEnd + if w.trafficState.EnableXtls { + command = CommandPaddingDirect + } + } + mb[i] = XtlsPadding(b, command, &w.writeOnceUserUUID, longPadding, w.ctx) + } + } + return w.Writer.WriteMultiBuffer(mb) +} + +// ReshapeMultiBuffer prepare multi buffer for padding stucture (max 21 bytes) +func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer { + needReshape := 0 + for _, b := range buffer { + if b.Len() >= buf.Size-21 { + needReshape += 1 + } + } + if needReshape == 0 { + return buffer + } + mb2 := make(buf.MultiBuffer, 0, len(buffer)+needReshape) + toPrint := "" + for i, buffer1 := range buffer { + if buffer1.Len() >= buf.Size-21 { + index := int32(bytes.LastIndex(buffer1.Bytes(), TlsApplicationDataStart)) + if index <= 0 || index > buf.Size-21 { + index = buf.Size / 2 + } + buffer2 := buf.New() + buffer2.Write(buffer1.BytesFrom(index)) + buffer1.Resize(0, index) + mb2 = append(mb2, buffer1, buffer2) + toPrint += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len())) + } else { + mb2 = append(mb2, buffer1) + toPrint += " " + strconv.Itoa(int(buffer1.Len())) + } + buffer[i] = nil + } + buffer = buffer[:0] + newError("ReshapeMultiBuffer ", toPrint).WriteToLog(session.ExportIDToError(ctx)) + return mb2 +} + +// XtlsPadding add padding to eliminate length siganature during tls handshake +func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, longPadding bool, ctx context.Context) *buf.Buffer { + var contentLen int32 = 0 + var paddingLen int32 = 0 + if b != nil { + contentLen = b.Len() + } + if contentLen < 900 && longPadding { + l, err := rand.Int(rand.Reader, big.NewInt(500)) + if err != nil { + newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx)) + } + paddingLen = int32(l.Int64()) + 900 - contentLen + } else { + l, err := rand.Int(rand.Reader, big.NewInt(256)) + if err != nil { + newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx)) + } + paddingLen = int32(l.Int64()) + } + if paddingLen > buf.Size-21-contentLen { + paddingLen = buf.Size - 21 - contentLen + } + newbuffer := buf.New() + if userUUID != nil { + newbuffer.Write(*userUUID) + *userUUID = nil + } + newbuffer.Write([]byte{command, byte(contentLen >> 8), byte(contentLen), byte(paddingLen >> 8), byte(paddingLen)}) + if b != nil { + newbuffer.Write(b.Bytes()) + b.Release() + b = nil + } + newbuffer.Extend(paddingLen) + newError("XtlsPadding ", contentLen, " ", paddingLen, " ", command).WriteToLog(session.ExportIDToError(ctx)) + return newbuffer +} + +// XtlsUnpadding remove padding and parse command +func XtlsUnpadding(b *buf.Buffer, s *TrafficState, ctx context.Context) *buf.Buffer { + if s.RemainingCommand == -1 && s.RemainingContent == -1 && s.RemainingPadding == -1 { // inital state + if b.Len() >= 21 && bytes.Equal(s.UserUUID, b.BytesTo(16)) { + b.Advance(16) + s.RemainingCommand = 5 + } else { + return b + } + } + newbuffer := buf.New() + for b.Len() > 0 { + if s.RemainingCommand > 0 { + data, err := b.ReadByte() + if err != nil { + return newbuffer + } + switch s.RemainingCommand { + case 5: + s.CurrentCommand = int(data) + case 4: + s.RemainingContent = int32(data)<<8 + case 3: + s.RemainingContent = s.RemainingContent | int32(data) + case 2: + s.RemainingPadding = int32(data)<<8 + case 1: + s.RemainingPadding = s.RemainingPadding | int32(data) + newError("Xtls Unpadding new block, content ", s.RemainingContent, " padding ", s.RemainingPadding, " command ", s.CurrentCommand).WriteToLog(session.ExportIDToError(ctx)) + } + s.RemainingCommand-- + } else if s.RemainingContent > 0 { + len := s.RemainingContent + if b.Len() < len { + len = b.Len() + } + data, err := b.ReadBytes(len) + if err != nil { + return newbuffer + } + newbuffer.Write(data) + s.RemainingContent -= len + } else { // remainingPadding > 0 + len := s.RemainingPadding + if b.Len() < len { + len = b.Len() + } + b.Advance(len) + s.RemainingPadding -= len + } + if s.RemainingCommand <= 0 && s.RemainingContent <= 0 && s.RemainingPadding <= 0 { // this block done + if s.CurrentCommand == 0 { + s.RemainingCommand = 5 + } else { + s.RemainingCommand = -1 // set to initial state + s.RemainingContent = -1 + s.RemainingPadding = -1 + if b.Len() > 0 { // shouldn't happen + newbuffer.Write(b.Bytes()) + } + break + } + } + } + b.Release() + b = nil + return newbuffer +} + +// XtlsFilterTls filter and recognize tls 1.3 and other info +func XtlsFilterTls(buffer buf.MultiBuffer, trafficState *TrafficState, ctx context.Context) { + for _, b := range buffer { + if b == nil { + continue + } + trafficState.NumberOfPacketToFilter-- + if b.Len() >= 6 { + startsBytes := b.BytesTo(6) + if bytes.Equal(TlsServerHandShakeStart, startsBytes[:3]) && startsBytes[5] == TlsHandshakeTypeServerHello { + trafficState.RemainingServerHello = (int32(startsBytes[3])<<8 | int32(startsBytes[4])) + 5 + trafficState.IsTLS12orAbove = true + trafficState.IsTLS = true + if b.Len() >= 79 && trafficState.RemainingServerHello >= 79 { + sessionIdLen := int32(b.Byte(43)) + cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3) + trafficState.Cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1]) + } else { + newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", trafficState.RemainingServerHello).WriteToLog(session.ExportIDToError(ctx)) + } + } else if bytes.Equal(TlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == TlsHandshakeTypeClientHello { + trafficState.IsTLS = true + newError("XtlsFilterTls found tls client hello! ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) + } + } + if trafficState.RemainingServerHello > 0 { + end := trafficState.RemainingServerHello + if end > b.Len() { + end = b.Len() + } + trafficState.RemainingServerHello -= b.Len() + if bytes.Contains(b.BytesTo(end), Tls13SupportedVersions) { + v, ok := Tls13CipherSuiteDic[trafficState.Cipher] + if !ok { + v = "Old cipher: " + strconv.FormatUint(uint64(trafficState.Cipher), 16) + } else if v != "TLS_AES_128_CCM_8_SHA256" { + trafficState.EnableXtls = true + } + newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx)) + trafficState.NumberOfPacketToFilter = 0 + return + } else if trafficState.RemainingServerHello <= 0 { + newError("XtlsFilterTls found tls 1.2! ", b.Len()).WriteToLog(session.ExportIDToError(ctx)) + trafficState.NumberOfPacketToFilter = 0 + return + } + newError("XtlsFilterTls inconclusive server hello ", b.Len(), " ", trafficState.RemainingServerHello).WriteToLog(session.ExportIDToError(ctx)) + } + if trafficState.NumberOfPacketToFilter <= 0 { + newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) + } + } +} + // UnwrapRawConn support unwrap stats, tls, utls, reality and proxyproto conn and get raw tcp conn from it func UnwrapRawConn(conn net.Conn) (net.Conn, stats.Counter, stats.Counter) { var readCounter, writerCounter stats.Counter diff --git a/proxy/vless/encoding/addons.go b/proxy/vless/encoding/addons.go index fc8ddc2a..e3e5071b 100644 --- a/proxy/vless/encoding/addons.go +++ b/proxy/vless/encoding/addons.go @@ -1,10 +1,12 @@ package encoding import ( + "context" "io" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/protocol" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/proxy/vless" "google.golang.org/protobuf/proto" ) @@ -58,14 +60,19 @@ func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) { } // EncodeBodyAddons returns a Writer that auto-encrypt content written by caller. -func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, addons *Addons) buf.Writer { - switch addons.Flow { - default: - if request.Command == protocol.RequestCommandUDP { - return NewMultiLengthPacketWriter(writer.(buf.Writer)) +func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons, state *proxy.TrafficState, context context.Context) buf.Writer { + if request.Command == protocol.RequestCommandUDP { + w := writer.(buf.Writer) + if requestAddons.Flow == vless.XRV { + w = proxy.NewVisionWriter(w, state, context) } + return NewMultiLengthPacketWriter(w) } - return buf.NewWriter(writer) + w := buf.NewWriter(writer) + if requestAddons.Flow == vless.XRV { + w = proxy.NewVisionWriter(w, state, context) + } + return w } // DecodeBodyAddons returns a Reader from which caller can fetch decrypted body. diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index 48bda497..b7fb66f5 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -5,11 +5,7 @@ package encoding import ( "bytes" "context" - "crypto/rand" "io" - "math/big" - "strconv" - "time" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/errors" @@ -26,30 +22,6 @@ const ( Version = byte(0) ) -var ( - tls13SupportedVersions = []byte{0x00, 0x2b, 0x00, 0x02, 0x03, 0x04} - tlsClientHandShakeStart = []byte{0x16, 0x03} - tlsServerHandShakeStart = []byte{0x16, 0x03, 0x03} - tlsApplicationDataStart = []byte{0x17, 0x03, 0x03} - - Tls13CipherSuiteDic = map[uint16]string{ - 0x1301: "TLS_AES_128_GCM_SHA256", - 0x1302: "TLS_AES_256_GCM_SHA384", - 0x1303: "TLS_CHACHA20_POLY1305_SHA256", - 0x1304: "TLS_AES_128_CCM_SHA256", - 0x1305: "TLS_AES_128_CCM_8_SHA256", - } -) - -const ( - tlsHandshakeTypeClientHello byte = 0x01 - tlsHandshakeTypeServerHello byte = 0x02 - - CommandPaddingContinue byte = 0x00 - CommandPaddingEnd byte = 0x01 - CommandPaddingDirect byte = 0x02 -) - var addrParser = protocol.NewAddressParser( protocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4), protocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain), @@ -202,18 +174,11 @@ func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*A } // XtlsRead filter and read xtls protocol -func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, - ctx context.Context, userUUID []byte, numberOfPacketToFilter *int, enableXtls *bool, - isTLS12orAbove *bool, isTLS *bool, cipher *uint16, remainingServerHello *int32, -) error { +func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, input *bytes.Reader, rawInput *bytes.Buffer, trafficState *proxy.TrafficState, ctx context.Context) error { err := func() error { - withinPaddingBuffers := true - shouldSwitchToDirectCopy := false - var remainingContent int32 = -1 - var remainingPadding int32 = -1 - currentCommand := 0 + visionReader := proxy.NewVisionReader(reader, trafficState, ctx) for { - if shouldSwitchToDirectCopy { + if trafficState.ReaderSwitchToDirectCopy { var writerConn net.Conn if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Conn != nil { writerConn = inbound.Conn @@ -223,44 +188,22 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater } return proxy.CopyRawConnIfExist(ctx, conn, writerConn, writer, timer) } - buffer, err := reader.ReadMultiBuffer() + buffer, err := visionReader.ReadMultiBuffer() if !buffer.IsEmpty() { - if withinPaddingBuffers || *numberOfPacketToFilter > 0 { - buffer = XtlsUnpadding(ctx, buffer, userUUID, &remainingContent, &remainingPadding, ¤tCommand) - if remainingContent == 0 && remainingPadding == 0 { - if currentCommand == 1 { - withinPaddingBuffers = false - remainingContent = -1 - remainingPadding = -1 // set to initial state to parse the next padding - } else if currentCommand == 2 { - withinPaddingBuffers = false - shouldSwitchToDirectCopy = true - // XTLS Vision processes struct TLS Conn's input and rawInput - if inputBuffer, err := buf.ReadFrom(input); err == nil { - if !inputBuffer.IsEmpty() { - buffer, _ = buf.MergeMulti(buffer, inputBuffer) - } - } - if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil { - if !rawInputBuffer.IsEmpty() { - buffer, _ = buf.MergeMulti(buffer, rawInputBuffer) - } - } - } else if currentCommand == 0 { - withinPaddingBuffers = true - } else { - newError("XtlsRead unknown command ", currentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) + timer.Update() + if trafficState.ReaderSwitchToDirectCopy { + // XTLS Vision processes struct TLS Conn's input and rawInput + if inputBuffer, err := buf.ReadFrom(input); err == nil { + if !inputBuffer.IsEmpty() { + buffer, _ = buf.MergeMulti(buffer, inputBuffer) + } + } + if rawInputBuffer, err := buf.ReadFrom(rawInput); err == nil { + if !rawInputBuffer.IsEmpty() { + buffer, _ = buf.MergeMulti(buffer, rawInputBuffer) } - } else if remainingContent > 0 || remainingPadding > 0 { - withinPaddingBuffers = true - } else { - withinPaddingBuffers = false } } - if *numberOfPacketToFilter > 0 { - XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx) - } - timer.Update() if werr := writer.WriteMultiBuffer(buffer); werr != nil { return werr } @@ -277,68 +220,27 @@ func XtlsRead(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater } // XtlsWrite filter and write xtls protocol -func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, - ctx context.Context, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool, - cipher *uint16, remainingServerHello *int32, -) error { +func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, conn net.Conn, trafficState *proxy.TrafficState, ctx context.Context) error { err := func() error { var ct stats.Counter - isPadding := true - shouldSwitchToDirectCopy := false for { buffer, err := reader.ReadMultiBuffer() + if trafficState.WriterSwitchToDirectCopy { + if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { + inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter + } + rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) + writer = buf.NewWriter(rawConn) + ct = writerCounter + trafficState.WriterSwitchToDirectCopy = false + } if !buffer.IsEmpty() { - if *numberOfPacketToFilter > 0 { - XtlsFilterTls(buffer, numberOfPacketToFilter, enableXtls, isTLS12orAbove, isTLS, cipher, remainingServerHello, ctx) + if ct != nil { + ct.Add(int64(buffer.Len())) } - if isPadding { - buffer = ReshapeMultiBuffer(ctx, buffer) - var xtlsSpecIndex int - for i, b := range buffer { - if *isTLS && b.Len() >= 6 && bytes.Equal(tlsApplicationDataStart, b.BytesTo(3)) { - var command byte = CommandPaddingEnd - if *enableXtls { - shouldSwitchToDirectCopy = true - xtlsSpecIndex = i - command = CommandPaddingDirect - } - isPadding = false - buffer[i] = XtlsPadding(b, command, nil, *isTLS, ctx) - break - } else if !*isTLS12orAbove && *numberOfPacketToFilter <= 1 { // For compatibility with earlier vision receiver, we finish padding 1 packet early - isPadding = false - buffer[i] = XtlsPadding(b, CommandPaddingEnd, nil, *isTLS, ctx) - break - } - buffer[i] = XtlsPadding(b, CommandPaddingContinue, nil, *isTLS, ctx) - } - if shouldSwitchToDirectCopy { - encryptBuffer, directBuffer := buf.SplitMulti(buffer, xtlsSpecIndex+1) - if !encryptBuffer.IsEmpty() { - timer.Update() - if werr := writer.WriteMultiBuffer(encryptBuffer); werr != nil { - return werr - } - } - time.Sleep(5 * time.Millisecond) // for some device, the first xtls direct packet fails without this delay - - if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { - inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter - } - buffer = directBuffer - rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) - writer = buf.NewWriter(rawConn) - ct = writerCounter - } - } - if !buffer.IsEmpty() { - if ct != nil { - ct.Add(int64(buffer.Len())) - } - timer.Update() - if werr := writer.WriteMultiBuffer(buffer); werr != nil { - return werr - } + timer.Update() + if werr := writer.WriteMultiBuffer(buffer); werr != nil { + return werr } } if err != nil { @@ -351,201 +253,3 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate } return nil } - -// XtlsFilterTls filter and recognize tls 1.3 and other info -func XtlsFilterTls(buffer buf.MultiBuffer, numberOfPacketToFilter *int, enableXtls *bool, isTLS12orAbove *bool, isTLS *bool, - cipher *uint16, remainingServerHello *int32, ctx context.Context, -) { - for _, b := range buffer { - *numberOfPacketToFilter-- - if b.Len() >= 6 { - startsBytes := b.BytesTo(6) - if bytes.Equal(tlsServerHandShakeStart, startsBytes[:3]) && startsBytes[5] == tlsHandshakeTypeServerHello { - *remainingServerHello = (int32(startsBytes[3])<<8 | int32(startsBytes[4])) + 5 - *isTLS12orAbove = true - *isTLS = true - if b.Len() >= 79 && *remainingServerHello >= 79 { - sessionIdLen := int32(b.Byte(43)) - cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3) - *cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1]) - } else { - newError("XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx)) - } - } else if bytes.Equal(tlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == tlsHandshakeTypeClientHello { - *isTLS = true - newError("XtlsFilterTls found tls client hello! ", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) - } - } - if *remainingServerHello > 0 { - end := *remainingServerHello - if end > b.Len() { - end = b.Len() - } - *remainingServerHello -= b.Len() - if bytes.Contains(b.BytesTo(end), tls13SupportedVersions) { - v, ok := Tls13CipherSuiteDic[*cipher] - if !ok { - v = "Old cipher: " + strconv.FormatUint(uint64(*cipher), 16) - } else if v != "TLS_AES_128_CCM_8_SHA256" { - *enableXtls = true - } - newError("XtlsFilterTls found tls 1.3! ", b.Len(), " ", v).WriteToLog(session.ExportIDToError(ctx)) - *numberOfPacketToFilter = 0 - return - } else if *remainingServerHello <= 0 { - newError("XtlsFilterTls found tls 1.2! ", b.Len()).WriteToLog(session.ExportIDToError(ctx)) - *numberOfPacketToFilter = 0 - return - } - newError("XtlsFilterTls inconclusive server hello ", b.Len(), " ", *remainingServerHello).WriteToLog(session.ExportIDToError(ctx)) - } - if *numberOfPacketToFilter <= 0 { - newError("XtlsFilterTls stop filtering", buffer.Len()).WriteToLog(session.ExportIDToError(ctx)) - } - } -} - -// ReshapeMultiBuffer prepare multi buffer for padding stucture (max 21 bytes) -func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBuffer { - needReshape := 0 - for _, b := range buffer { - if b.Len() >= buf.Size-21 { - needReshape += 1 - } - } - if needReshape == 0 { - return buffer - } - mb2 := make(buf.MultiBuffer, 0, len(buffer)+needReshape) - toPrint := "" - for i, buffer1 := range buffer { - if buffer1.Len() >= buf.Size-21 { - index := int32(bytes.LastIndex(buffer1.Bytes(), tlsApplicationDataStart)) - if index <= 0 || index > buf.Size-21 { - index = buf.Size / 2 - } - buffer2 := buf.New() - buffer2.Write(buffer1.BytesFrom(index)) - buffer1.Resize(0, index) - mb2 = append(mb2, buffer1, buffer2) - toPrint += " " + strconv.Itoa(int(buffer1.Len())) + " " + strconv.Itoa(int(buffer2.Len())) - } else { - mb2 = append(mb2, buffer1) - toPrint += " " + strconv.Itoa(int(buffer1.Len())) - } - buffer[i] = nil - } - buffer = buffer[:0] - newError("ReshapeMultiBuffer ", toPrint).WriteToLog(session.ExportIDToError(ctx)) - return mb2 -} - -// XtlsPadding add padding to eliminate length siganature during tls handshake -func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, longPadding bool, ctx context.Context) *buf.Buffer { - var contentLen int32 = 0 - var paddingLen int32 = 0 - if b != nil { - contentLen = b.Len() - } - if contentLen < 900 && longPadding { - l, err := rand.Int(rand.Reader, big.NewInt(500)) - if err != nil { - newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - paddingLen = int32(l.Int64()) + 900 - contentLen - } else { - l, err := rand.Int(rand.Reader, big.NewInt(256)) - if err != nil { - newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx)) - } - paddingLen = int32(l.Int64()) - } - if paddingLen > buf.Size-21-contentLen { - paddingLen = buf.Size - 21 - contentLen - } - newbuffer := buf.New() - if userUUID != nil { - newbuffer.Write(*userUUID) - *userUUID = nil - } - newbuffer.Write([]byte{command, byte(contentLen >> 8), byte(contentLen), byte(paddingLen >> 8), byte(paddingLen)}) - if b != nil { - newbuffer.Write(b.Bytes()) - b.Release() - b = nil - } - newbuffer.Extend(paddingLen) - newError("XtlsPadding ", contentLen, " ", paddingLen, " ", command).WriteToLog(session.ExportIDToError(ctx)) - return newbuffer -} - -// XtlsUnpadding remove padding and parse command -func XtlsUnpadding(ctx context.Context, buffer buf.MultiBuffer, userUUID []byte, remainingContent *int32, remainingPadding *int32, currentCommand *int) buf.MultiBuffer { - posindex := 0 - var posByte int32 = 0 - if *remainingContent == -1 && *remainingPadding == -1 { - for i, b := range buffer { - if b.Len() >= 21 && bytes.Equal(userUUID, b.BytesTo(16)) { - posindex = i - posByte = 16 - *remainingContent = 0 - *remainingPadding = 0 - *currentCommand = 0 - break - } - } - } - if *remainingContent == -1 && *remainingPadding == -1 { - return buffer - } - mb2 := make(buf.MultiBuffer, 0, len(buffer)) - for i := 0; i < posindex; i++ { - newbuffer := buf.New() - newbuffer.Write(buffer[i].Bytes()) - mb2 = append(mb2, newbuffer) - } - for i := posindex; i < len(buffer); i++ { - b := buffer[i] - for posByte < b.Len() { - if *remainingContent <= 0 && *remainingPadding <= 0 { - if *currentCommand == 1 { // possible buffer after padding, no need to worry about xtls (command 2) - len := b.Len() - posByte - newbuffer := buf.New() - newbuffer.Write(b.BytesRange(posByte, posByte+len)) - mb2 = append(mb2, newbuffer) - posByte += len - } else { - paddingInfo := b.BytesRange(posByte, posByte+5) - *currentCommand = int(paddingInfo[0]) - *remainingContent = int32(paddingInfo[1])<<8 | int32(paddingInfo[2]) - *remainingPadding = int32(paddingInfo[3])<<8 | int32(paddingInfo[4]) - newError("Xtls Unpadding new block", i, " ", posByte, " content ", *remainingContent, " padding ", *remainingPadding, " ", paddingInfo[0]).WriteToLog(session.ExportIDToError(ctx)) - posByte += 5 - } - } else if *remainingContent > 0 { - len := *remainingContent - if b.Len() < posByte+*remainingContent { - len = b.Len() - posByte - } - newbuffer := buf.New() - newbuffer.Write(b.BytesRange(posByte, posByte+len)) - mb2 = append(mb2, newbuffer) - *remainingContent -= len - posByte += len - } else { // remainingPadding > 0 - len := *remainingPadding - if b.Len() < posByte+*remainingPadding { - len = b.Len() - posByte - } - *remainingPadding -= len - posByte += len - } - if posByte == b.Len() { - posByte = 0 - break - } - } - } - buf.ReleaseMulti(buffer) - return mb2 -} diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 388aeecb..4cd3fcb1 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -28,6 +28,7 @@ import ( feature_inbound "github.com/xtls/xray-core/features/inbound" "github.com/xtls/xray-core/features/policy" "github.com/xtls/xray-core/features/routing" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/encoding" "github.com/xtls/xray-core/transport/internet/reality" @@ -510,13 +511,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s serverReader := link.Reader // .(*pipe.Reader) serverWriter := link.Writer // .(*pipe.Writer) - enableXtls := false - isTLS12orAbove := false - isTLS := false - var cipher uint16 = 0 - var remainingServerHello int32 = -1 - numberOfPacketToFilter := 8 - + trafficState := proxy.NewTrafficState(account.ID.Bytes()) postRequest := func() error { defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) @@ -527,8 +522,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s if requestAddons.Flow == vless.XRV { ctx1 := session.ContextWithInbound(ctx, nil) // TODO enable splice - err = encoding.XtlsRead(clientReader, serverWriter, timer, connection, input, rawInput, ctx1, account.ID.Bytes(), - &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) + err = encoding.XtlsRead(clientReader, serverWriter, timer, connection, input, rawInput, trafficState, ctx1) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)) @@ -550,19 +544,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s } // default: clientWriter := bufferWriter - clientWriter := encoding.EncodeBodyAddons(bufferWriter, request, responseAddons) - userUUID := account.ID.Bytes() + clientWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons, trafficState, ctx) multiBuffer, err1 := serverReader.ReadMultiBuffer() if err1 != nil { return err1 // ... } - if requestAddons.Flow == vless.XRV { - encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx) - multiBuffer = encoding.ReshapeMultiBuffer(ctx, multiBuffer) - for i, b := range multiBuffer { - multiBuffer[i] = encoding.XtlsPadding(b, encoding.CommandPaddingContinue, &userUUID, isTLS, ctx) - } - } if err := clientWriter.WriteMultiBuffer(multiBuffer); err != nil { return err // ... } @@ -573,8 +559,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s var err error if requestAddons.Flow == vless.XRV { - err = encoding.XtlsWrite(serverReader, clientWriter, timer, connection, ctx, &numberOfPacketToFilter, - &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) + err = encoding.XtlsWrite(serverReader, clientWriter, timer, connection, trafficState, ctx) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index bc2e6625..cd30617c 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -22,6 +22,7 @@ import ( "github.com/xtls/xray-core/common/xudp" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/policy" + "github.com/xtls/xray-core/proxy" "github.com/xtls/xray-core/proxy/vless" "github.com/xtls/xray-core/proxy/vless/encoding" "github.com/xtls/xray-core/transport" @@ -183,13 +184,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte clientReader := link.Reader // .(*pipe.Reader) clientWriter := link.Writer // .(*pipe.Writer) - enableXtls := false - isTLS12orAbove := false - isTLS := false - var cipher uint16 = 0 - var remainingServerHello int32 = -1 - numberOfPacketToFilter := 8 - + trafficState := proxy.NewTrafficState(account.ID.Bytes()) if request.Command == protocol.RequestCommandUDP && h.cone && request.Port != 53 && request.Port != 443 { request.Command = protocol.RequestCommandMux request.Address = net.DomainAddress("v1.mux.cool") @@ -205,22 +200,14 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } // default: serverWriter := bufferWriter - serverWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons) + serverWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons, trafficState, ctx) if request.Command == protocol.RequestCommandMux && request.Port == 666 { serverWriter = xudp.NewPacketWriter(serverWriter, target, xudp.GetGlobalID(ctx)) } - userUUID := account.ID.Bytes() timeoutReader, ok := clientReader.(buf.TimeoutReader) if ok { multiBuffer, err1 := timeoutReader.ReadMultiBufferTimeout(time.Millisecond * 500) if err1 == nil { - if requestAddons.Flow == vless.XRV { - encoding.XtlsFilterTls(multiBuffer, &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello, ctx) - multiBuffer = encoding.ReshapeMultiBuffer(ctx, multiBuffer) - for i, b := range multiBuffer { - multiBuffer[i] = encoding.XtlsPadding(b, encoding.CommandPaddingContinue, &userUUID, isTLS, ctx) - } - } if err := serverWriter.WriteMultiBuffer(multiBuffer); err != nil { return err // ... } @@ -228,10 +215,9 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte return err1 } else if requestAddons.Flow == vless.XRV { mb := make(buf.MultiBuffer, 1) - mb[0] = encoding.XtlsPadding(nil, encoding.CommandPaddingContinue, &userUUID, true, ctx) // we do a long padding to hide vless header newError("Insert padding with empty content to camouflage VLESS header ", mb.Len()).WriteToLog(session.ExportIDToError(ctx)) if err := serverWriter.WriteMultiBuffer(mb); err != nil { - return err + return err // ... } } } else { @@ -254,8 +240,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } } ctx1 := session.ContextWithOutbound(ctx, nil) // TODO enable splice - err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, ctx1, &numberOfPacketToFilter, - &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) + err = encoding.XtlsWrite(clientReader, serverWriter, timer, conn, trafficState, ctx1) } else { // from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBufer err = buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)) @@ -286,8 +271,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte } if requestAddons.Flow == vless.XRV { - err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, ctx, account.ID.Bytes(), - &numberOfPacketToFilter, &enableXtls, &isTLS12orAbove, &isTLS, &cipher, &remainingServerHello) + err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, input, rawInput, trafficState, ctx) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBufer err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) From 490591efcc04fa27719d4f995e37580a971f2352 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:16:02 +0000 Subject: [PATCH 53/71] Bump docker/login-action from 2 to 3 Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b7a3292b..39d0ef31 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,7 +23,7 @@ jobs: type=ref,event=pr type=semver,pattern={{version}} - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} From 852a7d41620bf8a16c113eddb22e47ba89cf9a3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:16:05 +0000 Subject: [PATCH 54/71] Bump docker/setup-buildx-action from 2 to 3 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 39d0ef31..a35d2b70 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ jobs: name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Build and push uses: docker/build-push-action@v4 with: From 850f617a6f940d026d34ffad92755c761caf34d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:16:09 +0000 Subject: [PATCH 55/71] Bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a35d2b70..0ced18da 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -35,7 +35,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 From e66797e79a95871a1937bd366ce17821e9945b5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:16:13 +0000 Subject: [PATCH 56/71] Bump docker/setup-qemu-action from 2 to 3 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0ced18da..d3c157ca 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -31,7 +31,7 @@ jobs: - # Add support for more platforms with QEMU (optional) # https://github.com/docker/setup-qemu-action name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push From 92bec537f1d7b7dd414e00d947694adc7b0fef4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:16:17 +0000 Subject: [PATCH 57/71] Bump docker/metadata-action from 4 to 5 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4 to 5. - [Release notes](https://github.com/docker/metadata-action/releases) - [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md) - [Commits](https://github.com/docker/metadata-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d3c157ca..b839d986 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v4 - name: Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository_owner }}/xray-core flavor: latest=true From 585d5ba7c8b64f6da60837546a70bbcfd2350c64 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 17 Sep 2023 12:55:54 -0400 Subject: [PATCH 58/71] Fix Vision reader --- proxy/proxy.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index 142acb77..f07af8c3 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -159,21 +159,15 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) { } } buffer = mb2 - if w.trafficState.RemainingContent == 0 && w.trafficState.RemainingPadding == 0 { - if w.trafficState.CurrentCommand == 1 { - w.trafficState.WithinPaddingBuffers = false - } else if w.trafficState.CurrentCommand == 2 { - w.trafficState.WithinPaddingBuffers = false - w.trafficState.ReaderSwitchToDirectCopy = true - } else if w.trafficState.CurrentCommand == 0 { - w.trafficState.WithinPaddingBuffers = true - } else { - newError("XtlsRead unknown command ", w.trafficState.CurrentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(w.ctx)) - } - } else if w.trafficState.RemainingContent > 0 || w.trafficState.RemainingPadding > 0 { + if w.trafficState.RemainingContent > 0 || w.trafficState.RemainingPadding > 0 || w.trafficState.CurrentCommand == 0 { w.trafficState.WithinPaddingBuffers = true - } else { + } else if w.trafficState.CurrentCommand == 1 { w.trafficState.WithinPaddingBuffers = false + } else if w.trafficState.CurrentCommand == 2 { + w.trafficState.WithinPaddingBuffers = false + w.trafficState.ReaderSwitchToDirectCopy = true + } else { + newError("XtlsRead unknown command ", w.trafficState.CurrentCommand, buffer.Len()).WriteToLog(session.ExportIDToError(w.ctx)) } } if w.trafficState.NumberOfPacketToFilter > 0 { From 8b0b8793ed4d3be9a1baa2911f4b149d82aae574 Mon Sep 17 00:00:00 2001 From: 0xland <98829546+0xland@users.noreply.github.com> Date: Mon, 18 Sep 2023 03:35:42 +0100 Subject: [PATCH 59/71] Add Streisand to README/GUI Clients --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ecf67e7d..a91c4373 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ - iOS & macOS arm64 - [Mango](https://github.com/arror/Mango) - [FoXray](https://apps.apple.com/app/foxray/id6448898396) + - [Streisand](https://apps.apple.com/app/streisand/id6450534064) - macOS arm64 & x64 - [V2rayU](https://github.com/yanue/V2rayU) - [V2RayXS](https://github.com/tzmax/V2RayXS) From 444db2acfffa82b85f94aada2a8092ace07349e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:57:24 +0000 Subject: [PATCH 60/71] Bump golang.org/x/crypto from 0.12.0 to 0.13.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.12.0 to 0.13.0. - [Commits](https://github.com/golang/crypto/compare/v0.12.0...v0.13.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 711b8e47..beb23f1f 100644 --- a/go.mod +++ b/go.mod @@ -20,10 +20,10 @@ require ( github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 go4.org/netipx v0.0.0-20230824141953-6213f710f925 - golang.org/x/crypto v0.12.0 + golang.org/x/crypto v0.13.0 golang.org/x/net v0.14.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.11.0 + golang.org/x/sys v0.12.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 @@ -50,7 +50,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index 71abf747..36d47ce3 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= @@ -227,14 +227,14 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= From 6ec82a6792dd89893b5b64eb4d1696bd8eb72cf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:04:04 +0000 Subject: [PATCH 61/71] Bump github.com/miekg/dns from 1.1.55 to 1.1.56 Bumps [github.com/miekg/dns](https://github.com/miekg/dns) from 1.1.55 to 1.1.56. - [Changelog](https://github.com/miekg/dns/blob/master/Makefile.release) - [Commits](https://github.com/miekg/dns/compare/v1.1.55...v1.1.56) --- updated-dependencies: - dependency-name: github.com/miekg/dns dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index beb23f1f..137b090f 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.9 github.com/gorilla/websocket v1.5.0 - github.com/miekg/dns v1.1.55 + github.com/miekg/dns v1.1.56 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 github.com/quic-go/quic-go v0.38.1 @@ -21,7 +21,7 @@ require ( github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 go4.org/netipx v0.0.0-20230824141953-6213f710f925 golang.org/x/crypto v0.13.0 - golang.org/x/net v0.14.0 + golang.org/x/net v0.15.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.12.0 google.golang.org/grpc v1.57.0 @@ -52,7 +52,7 @@ require ( golang.org/x/mod v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.0 // indirect + golang.org/x/tools v0.13.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 36d47ce3..bb87c79f 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,8 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= @@ -202,8 +202,8 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -246,8 +246,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 36321b8750846eaf1e64747cc0be88878edc0e76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:04:05 +0000 Subject: [PATCH 62/71] Bump google.golang.org/grpc from 1.57.0 to 1.58.1 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.58.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.58.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 137b090f..e98a6f11 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( golang.org/x/net v0.15.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.12.0 - google.golang.org/grpc v1.57.0 + google.golang.org/grpc v1.58.1 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 h12.io/socks v1.0.3 diff --git a/go.sum b/go.sum index bb87c79f..d4b097b9 100644 --- a/go.sum +++ b/go.sum @@ -270,8 +270,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= +google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From cf575be678682b9e1aa02d3c8ec8f7b03874d1b0 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:34:30 -0400 Subject: [PATCH 63/71] Fix unwrap tls conn --- proxy/proxy.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index f07af8c3..a14ddace 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -9,7 +9,6 @@ import ( "bytes" "context" "crypto/rand" - gotls "crypto/tls" "io" "math/big" "runtime" @@ -449,7 +448,7 @@ func UnwrapRawConn(conn net.Conn) (net.Conn, stats.Counter, stats.Counter) { readCounter = statConn.ReadCounter writerCounter = statConn.WriteCounter } - if xc, ok := conn.(*gotls.Conn); ok { + if xc, ok := conn.(*tls.Conn); ok { conn = xc.NetConn() } else if utlsConn, ok := conn.(*tls.UConn); ok { conn = utlsConn.NetConn() From 4f6042c69f41b7b9632ae421fc99c14532319cd5 Mon Sep 17 00:00:00 2001 From: cty123 Date: Tue, 19 Sep 2023 23:03:19 +0200 Subject: [PATCH 64/71] feat(dns): Support DNS queryStrategy config per NameServer. --- app/dns/config.pb.go | 183 +++++++++++++++++--------------- app/dns/config.proto | 1 + app/dns/nameserver.go | 46 ++++++-- app/dns/nameserver_doh.go | 38 ++++--- app/dns/nameserver_doh_test.go | 50 ++++++++- app/dns/nameserver_quic.go | 30 +++--- app/dns/nameserver_quic_test.go | 48 ++++++++- app/dns/nameserver_tcp.go | 47 ++++---- app/dns/nameserver_tcp_test.go | 52 ++++++++- infra/conf/dns.go | 52 +++++---- 10 files changed, 379 insertions(+), 168 deletions(-) diff --git a/app/dns/config.pb.go b/app/dns/config.pb.go index d5bc18d2..8a066a9e 100644 --- a/app/dns/config.pb.go +++ b/app/dns/config.pb.go @@ -134,6 +134,7 @@ type NameServer struct { PrioritizedDomain []*NameServer_PriorityDomain `protobuf:"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3" json:"prioritized_domain,omitempty"` Geoip []*router.GeoIP `protobuf:"bytes,3,rep,name=geoip,proto3" json:"geoip,omitempty"` OriginalRules []*NameServer_OriginalRule `protobuf:"bytes,4,rep,name=original_rules,json=originalRules,proto3" json:"original_rules,omitempty"` + QueryStrategy QueryStrategy `protobuf:"varint,7,opt,name=query_strategy,json=queryStrategy,proto3,enum=xray.app.dns.QueryStrategy" json:"query_strategy,omitempty"` } func (x *NameServer) Reset() { @@ -210,6 +211,13 @@ func (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule { return nil } +func (x *NameServer) GetQueryStrategy() QueryStrategy { + if x != nil { + return x.QueryStrategy + } + return QueryStrategy_USE_IP +} + type Config struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -538,7 +546,7 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xee, 0x03, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x04, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, @@ -559,77 +567,81 @@ var file_app_dns_config_proto_rawDesc = []byte{ 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x5e, - 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, - 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, - 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xef, 0x05, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x3f, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, - 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x39, 0x0a, - 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, - 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, - 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, - 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, - 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, - 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, - 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x36, - 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, - 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, - 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, - 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, - 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, - 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, - 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, - 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, - 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, - 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, - 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, - 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, - 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x42, + 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, + 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, + 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, + 0x67, 0x79, 0x1a, 0x5e, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, + 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xef, 0x05, 0x0a, 0x06, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, + 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, + 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x39, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, + 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, + 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f, + 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x45, 0x0a, 0x12, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, + 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, + 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, + 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01, + 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, + 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, + 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44, + 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -664,19 +676,20 @@ var file_app_dns_config_proto_depIdxs = []int32{ 4, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain 9, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP 5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule - 8, // 4: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint - 2, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer - 6, // 6: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry - 7, // 7: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping - 1, // 8: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy - 0, // 9: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType - 10, // 10: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain - 0, // 11: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 1, // 4: xray.app.dns.NameServer.query_strategy:type_name -> xray.app.dns.QueryStrategy + 8, // 5: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint + 2, // 6: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer + 6, // 7: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry + 7, // 8: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping + 1, // 9: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy + 0, // 10: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType + 10, // 11: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain + 0, // 12: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_app_dns_config_proto_init() } diff --git a/app/dns/config.proto b/app/dns/config.proto index e2059e38..2c420651 100644 --- a/app/dns/config.proto +++ b/app/dns/config.proto @@ -28,6 +28,7 @@ message NameServer { repeated PriorityDomain prioritized_domain = 2; repeated xray.app.router.GeoIP geoip = 3; repeated OriginalRule original_rules = 4; + QueryStrategy query_strategy = 7; } enum DomainMatchingType { diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index d6f9b272..d5423b84 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -35,7 +35,7 @@ type Client struct { var errExpectedIPNonMatch = errors.New("expectIPs not match") // NewServer creates a name server object according to the network destination url. -func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, error) { +func NewServer(dest net.Destination, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (Server, error) { if address := dest.Address; address.Family().IsDomain() { u, err := url.Parse(address.Domain()) if err != nil { @@ -45,15 +45,15 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err case strings.EqualFold(u.String(), "localhost"): return NewLocalNameServer(), nil case strings.EqualFold(u.Scheme, "https"): // DOH Remote mode - return NewDoHNameServer(u, dispatcher) + return NewDoHNameServer(u, dispatcher, queryStrategy) case strings.EqualFold(u.Scheme, "https+local"): // DOH Local mode - return NewDoHLocalNameServer(u), nil + return NewDoHLocalNameServer(u, queryStrategy), nil case strings.EqualFold(u.Scheme, "quic+local"): // DNS-over-QUIC Local mode - return NewQUICNameServer(u) + return NewQUICNameServer(u, queryStrategy) case strings.EqualFold(u.Scheme, "tcp"): // DNS-over-TCP Remote mode - return NewTCPNameServer(u, dispatcher) + return NewTCPNameServer(u, dispatcher, queryStrategy) case strings.EqualFold(u.Scheme, "tcp+local"): // DNS-over-TCP Local mode - return NewTCPLocalNameServer(u) + return NewTCPLocalNameServer(u, queryStrategy) case strings.EqualFold(u.String(), "fakedns"): return NewFakeDNSServer(), nil } @@ -68,12 +68,19 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err } // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. -func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container router.GeoIPMatcherContainer, matcherInfos *[]*DomainMatcherInfo, updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo) error) (*Client, error) { +func NewClient( + ctx context.Context, + ns *NameServer, + clientIP net.IP, + container router.GeoIPMatcherContainer, + matcherInfos *[]*DomainMatcherInfo, + updateDomainRule func(strmatcher.Matcher, int, []*DomainMatcherInfo) error, +) (*Client, error) { client := &Client{} err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { // Create a new server for each client for now - server, err := NewServer(ns.Address.AsDestination(), dispatcher) + server, err := NewServer(ns.Address.AsDestination(), dispatcher, ns.GetQueryStrategy()) if err != nil { return newError("failed to create nameserver").Base(err).AtWarning() } @@ -160,7 +167,7 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container r func NewSimpleClient(ctx context.Context, endpoint *net.Endpoint, clientIP net.IP) (*Client, error) { client := &Client{} err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { - server, err := NewServer(endpoint.AsDestination(), dispatcher) + server, err := NewServer(endpoint.AsDestination(), dispatcher, QueryStrategy_USE_IP) if err != nil { return newError("failed to create nameserver").Base(err).AtWarning() } @@ -218,3 +225,24 @@ func (c *Client) MatchExpectedIPs(domain string, ips []net.IP) ([]net.IP, error) newError("domain ", domain, " expectIPs ", newIps, " matched at server ", c.Name()).AtDebug().WriteToLog() return newIps, nil } + +func ResolveIpOptionOverride(queryStrategy QueryStrategy, ipOption dns.IPOption) dns.IPOption { + switch queryStrategy { + case QueryStrategy_USE_IP: + return ipOption + case QueryStrategy_USE_IP4: + return dns.IPOption{ + IPv4Enable: ipOption.IPv4Enable, + IPv6Enable: false, + FakeEnable: false, + } + case QueryStrategy_USE_IP6: + return dns.IPOption{ + IPv4Enable: false, + IPv6Enable: ipOption.IPv6Enable, + FakeEnable: false, + } + default: + return ipOption + } +} diff --git a/app/dns/nameserver_doh.go b/app/dns/nameserver_doh.go index fecc5efb..8657e3fb 100644 --- a/app/dns/nameserver_doh.go +++ b/app/dns/nameserver_doh.go @@ -31,19 +31,20 @@ import ( type DoHNameServer struct { dispatcher routing.Dispatcher sync.RWMutex - ips map[string]*record - pub *pubsub.Service - cleanup *task.Periodic - reqID uint32 - httpClient *http.Client - dohURL string - name string + ips map[string]*record + pub *pubsub.Service + cleanup *task.Periodic + reqID uint32 + httpClient *http.Client + dohURL string + name string + queryStrategy QueryStrategy } // NewDoHNameServer creates DOH server object for remote resolving. -func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher) (*DoHNameServer, error) { +func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) { newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog() - s := baseDOHNameServer(url, "DOH") + s := baseDOHNameServer(url, "DOH", queryStrategy) s.dispatcher = dispatcher tr := &http.Transport{ @@ -90,9 +91,9 @@ func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher) (*DoHNameServ } // NewDoHLocalNameServer creates DOH client object for local resolving -func NewDoHLocalNameServer(url *url.URL) *DoHNameServer { +func NewDoHLocalNameServer(url *url.URL, queryStrategy QueryStrategy) *DoHNameServer { url.Scheme = "https" - s := baseDOHNameServer(url, "DOHL") + s := baseDOHNameServer(url, "DOHL", queryStrategy) tr := &http.Transport{ IdleConnTimeout: 90 * time.Second, ForceAttemptHTTP2: true, @@ -122,12 +123,13 @@ func NewDoHLocalNameServer(url *url.URL) *DoHNameServer { return s } -func baseDOHNameServer(url *url.URL, prefix string) *DoHNameServer { +func baseDOHNameServer(url *url.URL, prefix string, queryStrategy QueryStrategy) *DoHNameServer { s := &DoHNameServer{ - ips: make(map[string]*record), - pub: pubsub.NewService(), - name: prefix + "//" + url.Host, - dohURL: url.String(), + ips: make(map[string]*record), + pub: pubsub.NewService(), + name: prefix + "//" + url.Host, + dohURL: url.String(), + queryStrategy: queryStrategy, } s.cleanup = &task.Periodic{ Interval: time.Minute, @@ -353,6 +355,10 @@ func (s *DoHNameServer) findIPsForDomain(domain string, option dns_feature.IPOpt // QueryIP implements Server. func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) { // nolint: dupl fqdn := Fqdn(domain) + option = ResolveIpOptionOverride(s.queryStrategy, option) + if !option.IPv4Enable && !option.IPv6Enable { + return nil, dns_feature.ErrEmptyResponse + } if disableCache { newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog() diff --git a/app/dns/nameserver_doh_test.go b/app/dns/nameserver_doh_test.go index f5cae5a6..ae4f9cc7 100644 --- a/app/dns/nameserver_doh_test.go +++ b/app/dns/nameserver_doh_test.go @@ -17,7 +17,7 @@ func TestDOHNameServer(t *testing.T) { url, err := url.Parse("https+local://1.1.1.1/dns-query") common.Must(err) - s := NewDoHLocalNameServer(url) + s := NewDoHLocalNameServer(url, QueryStrategy_USE_IP) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ IPv4Enable: true, @@ -34,7 +34,7 @@ func TestDOHNameServerWithCache(t *testing.T) { url, err := url.Parse("https+local://1.1.1.1/dns-query") common.Must(err) - s := NewDoHLocalNameServer(url) + s := NewDoHLocalNameServer(url, QueryStrategy_USE_IP) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ IPv4Enable: true, @@ -57,3 +57,49 @@ func TestDOHNameServerWithCache(t *testing.T) { t.Fatal(r) } } + +func TestDOHNameServerWithIPv4Override(t *testing.T) { + url, err := url.Parse("https+local://1.1.1.1/dns-query") + common.Must(err) + + s := NewDoHLocalNameServer(url, QueryStrategy_USE_IP4) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv4len { + t.Error("expect only IPv4 response from DNS query") + } + } +} + +func TestDOHNameServerWithIPv6Override(t *testing.T) { + url, err := url.Parse("https+local://1.1.1.1/dns-query") + common.Must(err) + + s := NewDoHLocalNameServer(url, QueryStrategy_USE_IP6) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv6len { + t.Error("expect only IPv6 response from DNS query") + } + } +} diff --git a/app/dns/nameserver_quic.go b/app/dns/nameserver_quic.go index e82a6a3d..9e702564 100644 --- a/app/dns/nameserver_quic.go +++ b/app/dns/nameserver_quic.go @@ -31,17 +31,18 @@ const handshakeTimeout = time.Second * 8 // QUICNameServer implemented DNS over QUIC type QUICNameServer struct { sync.RWMutex - ips map[string]*record - pub *pubsub.Service - cleanup *task.Periodic - reqID uint32 - name string - destination *net.Destination - connection quic.Connection + ips map[string]*record + pub *pubsub.Service + cleanup *task.Periodic + reqID uint32 + name string + destination *net.Destination + connection quic.Connection + queryStrategy QueryStrategy } // NewQUICNameServer creates DNS-over-QUIC client object for local resolving -func NewQUICNameServer(url *url.URL) (*QUICNameServer, error) { +func NewQUICNameServer(url *url.URL, queryStrategy QueryStrategy) (*QUICNameServer, error) { newError("DNS: created Local DNS-over-QUIC client for ", url.String()).AtInfo().WriteToLog() var err error @@ -55,10 +56,11 @@ func NewQUICNameServer(url *url.URL) (*QUICNameServer, error) { dest := net.UDPDestination(net.ParseAddress(url.Hostname()), port) s := &QUICNameServer{ - ips: make(map[string]*record), - pub: pubsub.NewService(), - name: url.String(), - destination: &dest, + ips: make(map[string]*record), + pub: pubsub.NewService(), + name: url.String(), + destination: &dest, + queryStrategy: queryStrategy, } s.cleanup = &task.Periodic{ Interval: time.Minute, @@ -269,6 +271,10 @@ func (s *QUICNameServer) findIPsForDomain(domain string, option dns_feature.IPOp // QueryIP is called from dns.Server->queryIPTimeout func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) { fqdn := Fqdn(domain) + option = ResolveIpOptionOverride(s.queryStrategy, option) + if !option.IPv4Enable && !option.IPv6Enable { + return nil, dns_feature.ErrEmptyResponse + } if disableCache { newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog() diff --git a/app/dns/nameserver_quic_test.go b/app/dns/nameserver_quic_test.go index cf445b43..ef50d7d9 100644 --- a/app/dns/nameserver_quic_test.go +++ b/app/dns/nameserver_quic_test.go @@ -16,7 +16,7 @@ import ( func TestQUICNameServer(t *testing.T) { url, err := url.Parse("quic://dns.adguard.com") common.Must(err) - s, err := NewQUICNameServer(url) + s, err := NewQUICNameServer(url, QueryStrategy_USE_IP) common.Must(err) ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns.IPOption{ @@ -40,3 +40,49 @@ func TestQUICNameServer(t *testing.T) { t.Fatal(r) } } + +func TestQUICNameServerWithIPv4Override(t *testing.T) { + url, err := url.Parse("quic://dns.adguard.com") + common.Must(err) + s, err := NewQUICNameServer(url, QueryStrategy_USE_IP4) + common.Must(err) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv4len { + t.Error("expect only IPv4 response from DNS query") + } + } +} + +func TestQUICNameServerWithIPv6Override(t *testing.T) { + url, err := url.Parse("quic://dns.adguard.com") + common.Must(err) + s, err := NewQUICNameServer(url, QueryStrategy_USE_IP6) + common.Must(err) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv6len { + t.Error("expect only IPv6 response from DNS query") + } + } +} diff --git a/app/dns/nameserver_tcp.go b/app/dns/nameserver_tcp.go index cf63ac21..4ed723e1 100644 --- a/app/dns/nameserver_tcp.go +++ b/app/dns/nameserver_tcp.go @@ -27,18 +27,23 @@ import ( // TCPNameServer implemented DNS over TCP (RFC7766). type TCPNameServer struct { sync.RWMutex - name string - destination *net.Destination - ips map[string]*record - pub *pubsub.Service - cleanup *task.Periodic - reqID uint32 - dial func(context.Context) (net.Conn, error) + name string + destination *net.Destination + ips map[string]*record + pub *pubsub.Service + cleanup *task.Periodic + reqID uint32 + dial func(context.Context) (net.Conn, error) + queryStrategy QueryStrategy } // NewTCPNameServer creates DNS over TCP server object for remote resolving. -func NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServer, error) { - s, err := baseTCPNameServer(url, "TCP") +func NewTCPNameServer( + url *url.URL, + dispatcher routing.Dispatcher, + queryStrategy QueryStrategy, +) (*TCPNameServer, error) { + s, err := baseTCPNameServer(url, "TCP", queryStrategy) if err != nil { return nil, err } @@ -59,8 +64,8 @@ func NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServ } // NewTCPLocalNameServer creates DNS over TCP client object for local resolving -func NewTCPLocalNameServer(url *url.URL) (*TCPNameServer, error) { - s, err := baseTCPNameServer(url, "TCPL") +func NewTCPLocalNameServer(url *url.URL, queryStrategy QueryStrategy) (*TCPNameServer, error) { + s, err := baseTCPNameServer(url, "TCPL", queryStrategy) if err != nil { return nil, err } @@ -72,22 +77,22 @@ func NewTCPLocalNameServer(url *url.URL) (*TCPNameServer, error) { return s, nil } -func baseTCPNameServer(url *url.URL, prefix string) (*TCPNameServer, error) { - var err error +func baseTCPNameServer(url *url.URL, prefix string, queryStrategy QueryStrategy) (*TCPNameServer, error) { port := net.Port(53) if url.Port() != "" { - port, err = net.PortFromString(url.Port()) - if err != nil { + var err error + if port, err = net.PortFromString(url.Port()); err != nil { return nil, err } } dest := net.TCPDestination(net.ParseAddress(url.Hostname()), port) s := &TCPNameServer{ - destination: &dest, - ips: make(map[string]*record), - pub: pubsub.NewService(), - name: prefix + "//" + dest.NetAddr(), + destination: &dest, + ips: make(map[string]*record), + pub: pubsub.NewService(), + name: prefix + "//" + dest.NetAddr(), + queryStrategy: queryStrategy, } s.cleanup = &task.Periodic{ Interval: time.Minute, @@ -308,6 +313,10 @@ func (s *TCPNameServer) findIPsForDomain(domain string, option dns_feature.IPOpt // QueryIP implements Server. func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) { fqdn := Fqdn(domain) + option = ResolveIpOptionOverride(s.queryStrategy, option) + if !option.IPv4Enable && !option.IPv6Enable { + return nil, dns_feature.ErrEmptyResponse + } if disableCache { newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog() diff --git a/app/dns/nameserver_tcp_test.go b/app/dns/nameserver_tcp_test.go index da362355..6b2b2465 100644 --- a/app/dns/nameserver_tcp_test.go +++ b/app/dns/nameserver_tcp_test.go @@ -16,7 +16,7 @@ import ( func TestTCPLocalNameServer(t *testing.T) { url, err := url.Parse("tcp+local://8.8.8.8") common.Must(err) - s, err := NewTCPLocalNameServer(url) + s, err := NewTCPLocalNameServer(url, QueryStrategy_USE_IP) common.Must(err) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ @@ -33,7 +33,7 @@ func TestTCPLocalNameServer(t *testing.T) { func TestTCPLocalNameServerWithCache(t *testing.T) { url, err := url.Parse("tcp+local://8.8.8.8") common.Must(err) - s, err := NewTCPLocalNameServer(url) + s, err := NewTCPLocalNameServer(url, QueryStrategy_USE_IP) common.Must(err) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ @@ -57,3 +57,51 @@ func TestTCPLocalNameServerWithCache(t *testing.T) { t.Fatal(r) } } + +func TestTCPLocalNameServerWithIPv4Override(t *testing.T) { + url, err := url.Parse("tcp+local://8.8.8.8") + common.Must(err) + s, err := NewTCPLocalNameServer(url, QueryStrategy_USE_IP4) + common.Must(err) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv4len { + t.Error("expect only IPv4 response from DNS query") + } + } +} + +func TestTCPLocalNameServerWithIPv6Override(t *testing.T) { + url, err := url.Parse("tcp+local://8.8.8.8") + common.Must(err) + s, err := NewTCPLocalNameServer(url, QueryStrategy_USE_IP6) + common.Must(err) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + ips, err := s.QueryIP(ctx, "google.com", net.IP(nil), dns_feature.IPOption{ + IPv4Enable: true, + IPv6Enable: true, + }, false) + cancel() + common.Must(err) + + if len(ips) == 0 { + t.Error("expect some ips, but got 0") + } + + for _, ip := range ips { + if len(ip) != net.IPv6len { + t.Error("expect only IPv6 response from DNS query") + } + } +} diff --git a/infra/conf/dns.go b/infra/conf/dns.go index 3265b819..a0f3155c 100644 --- a/infra/conf/dns.go +++ b/infra/conf/dns.go @@ -11,12 +11,13 @@ import ( ) type NameServerConfig struct { - Address *Address - ClientIP *Address - Port uint16 - SkipFallback bool - Domains []string - ExpectIPs StringList + Address *Address + ClientIP *Address + Port uint16 + SkipFallback bool + Domains []string + ExpectIPs StringList + QueryStrategy string } func (c *NameServerConfig) UnmarshalJSON(data []byte) error { @@ -27,12 +28,13 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { } var advanced struct { - Address *Address `json:"address"` - ClientIP *Address `json:"clientIp"` - Port uint16 `json:"port"` - SkipFallback bool `json:"skipFallback"` - Domains []string `json:"domains"` - ExpectIPs StringList `json:"expectIps"` + Address *Address `json:"address"` + ClientIP *Address `json:"clientIp"` + Port uint16 `json:"port"` + SkipFallback bool `json:"skipFallback"` + Domains []string `json:"domains"` + ExpectIPs StringList `json:"expectIps"` + QueryStrategy string `json:"queryStrategy"` } if err := json.Unmarshal(data, &advanced); err == nil { c.Address = advanced.Address @@ -41,6 +43,7 @@ func (c *NameServerConfig) UnmarshalJSON(data []byte) error { c.SkipFallback = advanced.SkipFallback c.Domains = advanced.Domains c.ExpectIPs = advanced.ExpectIPs + c.QueryStrategy = advanced.QueryStrategy return nil } @@ -112,6 +115,7 @@ func (c *NameServerConfig) Build() (*dns.NameServer, error) { PrioritizedDomain: domains, Geoip: geoipList, OriginalRules: originalRules, + QueryStrategy: resolveQueryStrategy(c.QueryStrategy), }, nil } @@ -311,6 +315,7 @@ func (c *DNSConfig) Build() (*dns.Config, error) { DisableCache: c.DisableCache, DisableFallback: c.DisableFallback, DisableFallbackIfMatch: c.DisableFallbackIfMatch, + QueryStrategy: resolveQueryStrategy(c.QueryStrategy), } if c.ClientIP != nil { @@ -320,16 +325,6 @@ func (c *DNSConfig) Build() (*dns.Config, error) { config.ClientIp = []byte(c.ClientIP.IP()) } - config.QueryStrategy = dns.QueryStrategy_USE_IP - switch strings.ToLower(c.QueryStrategy) { - case "useip", "use_ip", "use-ip": - config.QueryStrategy = dns.QueryStrategy_USE_IP - case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4": - config.QueryStrategy = dns.QueryStrategy_USE_IP4 - case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6": - config.QueryStrategy = dns.QueryStrategy_USE_IP6 - } - for _, server := range c.Servers { ns, err := server.Build() if err != nil { @@ -348,3 +343,16 @@ func (c *DNSConfig) Build() (*dns.Config, error) { return config, nil } + +func resolveQueryStrategy(queryStrategy string) dns.QueryStrategy { + switch strings.ToLower(queryStrategy) { + case "useip", "use_ip", "use-ip": + return dns.QueryStrategy_USE_IP + case "useip4", "useipv4", "use_ip4", "use_ipv4", "use_ip_v4", "use-ip4", "use-ipv4", "use-ip-v4": + return dns.QueryStrategy_USE_IP4 + case "useip6", "useipv6", "use_ip6", "use_ipv6", "use_ip_v6", "use-ip6", "use-ipv6", "use-ip-v6": + return dns.QueryStrategy_USE_IP6 + default: + return dns.QueryStrategy_USE_IP + } +} From 07ae08126c74df9492f38bceb00cc2a37149466c Mon Sep 17 00:00:00 2001 From: Hossin Asaadi Date: Wed, 20 Sep 2023 19:08:48 +0400 Subject: [PATCH 65/71] binding socket interface to sockopt_darwin.go --- transport/internet/sockopt_darwin.go | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/transport/internet/sockopt_darwin.go b/transport/internet/sockopt_darwin.go index 37ced27b..d8724c77 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -1,6 +1,7 @@ package internet import ( + network "net" "os" "syscall" "unsafe" @@ -106,6 +107,14 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf return err } } + if config.Interface != "" { + InterfaceIndex := getInterfaceIndexByName(config.Interface) + if InterfaceIndex != 0 { + if err := unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, InterfaceIndex); err != nil { + return newError("failed to set Interface").Base(err) + } + } + } if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 { @@ -148,6 +157,15 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) return err } } + if config.Interface != "" { + InterfaceIndex := getInterfaceIndexByName(config.Interface) + if InterfaceIndex != 0 { + if err := unix.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, InterfaceIndex); err != nil { + return newError("failed to set Interface").Base(err) + } + } + } + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if config.TcpKeepAliveIdle > 0 { if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveInterval)); err != nil { @@ -183,3 +201,24 @@ func setReuseAddr(fd uintptr) error { func setReusePort(fd uintptr) error { return nil } +func getInterfaceIndexByName(name string) int { + ifaces, err := network.Interfaces() + if err == nil { + for _, iface := range ifaces { + if (iface.Flags&network.FlagUp == network.FlagUp) && (iface.Flags&network.FlagLoopback != network.FlagLoopback) { + addrs, _ := iface.Addrs() + for _, addr := range addrs { + if ipnet, ok := addr.(*network.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + if iface.Name == name { + return iface.Index + } + } + } + } + } + + } + } + return 0 +} From 1a72e55ea5f98305e29217abdfe2491038e8ff5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Sep 2023 00:05:17 +0000 Subject: [PATCH 66/71] Bump github.com/refraction-networking/utls from 1.4.3 to 1.5.3 Bumps [github.com/refraction-networking/utls](https://github.com/refraction-networking/utls) from 1.4.3 to 1.5.3. - [Release notes](https://github.com/refraction-networking/utls/releases) - [Commits](https://github.com/refraction-networking/utls/compare/v1.4.3...v1.5.3) --- updated-dependencies: - dependency-name: github.com/refraction-networking/utls dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e98a6f11..3122c4d2 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 github.com/quic-go/quic-go v0.38.1 - github.com/refraction-networking/utls v1.4.3 + github.com/refraction-networking/utls v1.5.3 github.com/sagernet/sing v0.2.9 github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c @@ -33,6 +33,7 @@ require ( require ( github.com/andybalholm/brotli v1.0.5 // indirect + github.com/cloudflare/circl v1.3.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/francoispqt/gojay v1.2.13 // indirect diff --git a/go.sum b/go.sum index d4b097b9..148c924d 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -118,8 +120,8 @@ github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eU github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= -github.com/refraction-networking/utls v1.4.3 h1:BdWS3BSzCwWCFfMIXP3mjLAyQkdmog7diaD/OqFbAzM= -github.com/refraction-networking/utls v1.4.3/go.mod h1:4u9V/awOSBrRw6+federGmVJQfPtemEqLBXkML1b0bo= +github.com/refraction-networking/utls v1.5.3 h1:Ds5Ocg1+MC1ahNx5iBEcHe0jHeLaA/fLey61EENm7ro= +github.com/refraction-networking/utls v1.5.3/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= From db3ac2a97708860a31c88e853ed7c5eb436c4527 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 00:24:12 +0000 Subject: [PATCH 67/71] Bump google.golang.org/grpc from 1.58.1 to 1.58.2 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.1 to 1.58.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.58.1...v1.58.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3122c4d2..514be06e 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( golang.org/x/net v0.15.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.12.0 - google.golang.org/grpc v1.58.1 + google.golang.org/grpc v1.58.2 google.golang.org/protobuf v1.31.0 gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 h12.io/socks v1.0.3 diff --git a/go.sum b/go.sum index 148c924d..3a5510a1 100644 --- a/go.sum +++ b/go.sum @@ -272,8 +272,8 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 27450c95bdc1a4b8de7b731016ca9f89cf618091 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:37:07 +0000 Subject: [PATCH 68/71] Bump github.com/sagernet/sing from 0.2.9 to 0.2.11 Bumps [github.com/sagernet/sing](https://github.com/sagernet/sing) from 0.2.9 to 0.2.11. - [Commits](https://github.com/sagernet/sing/compare/v0.2.9...v0.2.11) --- updated-dependencies: - dependency-name: github.com/sagernet/sing dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 514be06e..fce75789 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/pires/go-proxyproto v0.7.0 github.com/quic-go/quic-go v0.38.1 github.com/refraction-networking/utls v1.5.3 - github.com/sagernet/sing v0.2.9 + github.com/sagernet/sing v0.2.11 github.com/sagernet/sing-shadowsocks v0.2.4 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb diff --git a/go.sum b/go.sum index 3a5510a1..d59ab8a8 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/refraction-networking/utls v1.5.3/go.mod h1:SPuDbBmgLGp8s+HLNc83Fuavw github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo= -github.com/sagernet/sing v0.2.9/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing v0.2.11 h1:mu0S6d8y/xSVxilOqRd32Fmire5SZz9nT3t9NEHwUMY= +github.com/sagernet/sing v0.2.11/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= From 57ed75eb6708b53054e56ae124cd1c471e4f4482 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:38:33 +0000 Subject: [PATCH 69/71] Bump github.com/sagernet/sing-shadowsocks from 0.2.4 to 0.2.5 Bumps [github.com/sagernet/sing-shadowsocks](https://github.com/sagernet/sing-shadowsocks) from 0.2.4 to 0.2.5. - [Commits](https://github.com/sagernet/sing-shadowsocks/compare/v0.2.4...v0.2.5) --- updated-dependencies: - dependency-name: github.com/sagernet/sing-shadowsocks dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fce75789..84029947 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/quic-go/quic-go v0.38.1 github.com/refraction-networking/utls v1.5.3 github.com/sagernet/sing v0.2.11 - github.com/sagernet/sing-shadowsocks v0.2.4 + github.com/sagernet/sing-shadowsocks v0.2.5 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index d59ab8a8..7cf12912 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstv github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sagernet/sing v0.2.11 h1:mu0S6d8y/xSVxilOqRd32Fmire5SZz9nT3t9NEHwUMY= github.com/sagernet/sing v0.2.11/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= -github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY= -github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM= +github.com/sagernet/sing-shadowsocks v0.2.5 h1:qxIttos4xu6ii7MTVJYA8EFQR7Q3KG6xMqmLJIFtBaY= +github.com/sagernet/sing-shadowsocks v0.2.5/go.mod h1:MGWGkcU2xW2G2mfArT9/QqpVLOGU+dBaahZCtPHdt7A= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI= github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U= From 772936906a9cedfbd32ece09ce83ff1606728cf0 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Fri, 29 Sep 2023 22:30:24 -0400 Subject: [PATCH 70/71] Add reality test --- testing/scenarios/vless_test.go | 277 ++++++++++++++++---------------- 1 file changed, 139 insertions(+), 138 deletions(-) diff --git a/testing/scenarios/vless_test.go b/testing/scenarios/vless_test.go index 84d82643..ddb0bdb7 100644 --- a/testing/scenarios/vless_test.go +++ b/testing/scenarios/vless_test.go @@ -1,8 +1,8 @@ package scenarios import ( - // "encoding/base64" - // "encoding/hex" + "encoding/base64" + "encoding/hex" "testing" "time" @@ -23,7 +23,7 @@ import ( "github.com/xtls/xray-core/proxy/vless/outbound" "github.com/xtls/xray-core/testing/servers/tcp" "github.com/xtls/xray-core/transport/internet" - // "github.com/xtls/xray-core/transport/internet/reality" + "github.com/xtls/xray-core/transport/internet/reality" transtcp "github.com/xtls/xray-core/transport/internet/tcp" "github.com/xtls/xray-core/transport/internet/tls" "golang.org/x/sync/errgroup" @@ -377,142 +377,143 @@ func TestVlessXtlsVision(t *testing.T) { } } -// func TestVlessXtlsVisionReality(t *testing.T) { -// tcpServer := tcp.Server{ -// MsgProcessor: xor, -// } -// dest, err := tcpServer.Start() -// common.Must(err) -// defer tcpServer.Close() +func TestVlessXtlsVisionReality(t *testing.T) { + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + common.Must(err) + defer tcpServer.Close() -// userID := protocol.NewID(uuid.New()) -// serverPort := tcp.PickPort() -// privateKey, _ := base64.RawURLEncoding.DecodeString("aGSYystUbf59_9_6LKRxD27rmSW_-2_nyd9YG_Gwbks") -// publicKey, _ := base64.RawURLEncoding.DecodeString("E59WjnvZcQMu7tR7_BgyhycuEdBS-CtKxfImRCdAvFM") -// shortIds := make([][]byte, 1) -// shortIds[0] = make([]byte, 8) -// hex.Decode(shortIds[0], []byte("0123456789abcdef")) -// serverConfig := &core.Config{ -// App: []*serial.TypedMessage{ -// serial.ToTypedMessage(&log.Config{ -// ErrorLogLevel: clog.Severity_Debug, -// ErrorLogType: log.LogType_Console, -// }), -// }, -// Inbound: []*core.InboundHandlerConfig{ -// { -// ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ -// PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, -// Listen: net.NewIPOrDomain(net.LocalHostIP), -// StreamSettings: &internet.StreamConfig{ -// Protocol: internet.TransportProtocol_TCP, -// SecurityType: serial.GetMessageType(&reality.Config{}), -// SecuritySettings: []*serial.TypedMessage{ -// serial.ToTypedMessage(&reality.Config{ -// Show: true, -// Dest: "www.google.com:443", // use google for now, may fail in some region -// ServerNames: []string{"www.google.com"}, -// PrivateKey: privateKey, -// ShortIds: shortIds, -// }), -// }, -// }, -// }), -// ProxySettings: serial.ToTypedMessage(&inbound.Config{ -// Clients: []*protocol.User{ -// { -// Account: serial.ToTypedMessage(&vless.Account{ -// Id: userID.String(), -// Flow: vless.XRV, -// }), -// }, -// }, -// }), -// }, -// }, -// Outbound: []*core.OutboundHandlerConfig{ -// { -// ProxySettings: serial.ToTypedMessage(&freedom.Config{}), -// }, -// }, -// } + userID := protocol.NewID(uuid.New()) + serverPort := tcp.PickPort() + privateKey, _ := base64.RawURLEncoding.DecodeString("aGSYystUbf59_9_6LKRxD27rmSW_-2_nyd9YG_Gwbks") + publicKey, _ := base64.RawURLEncoding.DecodeString("E59WjnvZcQMu7tR7_BgyhycuEdBS-CtKxfImRCdAvFM") + shortIds := make([][]byte, 1) + shortIds[0] = make([]byte, 8) + hex.Decode(shortIds[0], []byte("0123456789abcdef")) + serverConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + SecurityType: serial.GetMessageType(&reality.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&reality.Config{ + Show: true, + Dest: "www.google.com:443", // use google for now, may fail in some region + ServerNames: []string{"www.google.com"}, + PrivateKey: privateKey, + ShortIds: shortIds, + Type: "tcp", + }), + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + Clients: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + Flow: vless.XRV, + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } -// clientPort := tcp.PickPort() -// clientConfig := &core.Config{ -// App: []*serial.TypedMessage{ -// serial.ToTypedMessage(&log.Config{ -// ErrorLogLevel: clog.Severity_Debug, -// ErrorLogType: log.LogType_Console, -// }), -// }, -// Inbound: []*core.InboundHandlerConfig{ -// { -// ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ -// PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, -// Listen: net.NewIPOrDomain(net.LocalHostIP), -// }), -// ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ -// Address: net.NewIPOrDomain(dest.Address), -// Port: uint32(dest.Port), -// NetworkList: &net.NetworkList{ -// Network: []net.Network{net.Network_TCP}, -// }, -// }), -// }, -// }, -// Outbound: []*core.OutboundHandlerConfig{ -// { -// ProxySettings: serial.ToTypedMessage(&outbound.Config{ -// Vnext: []*protocol.ServerEndpoint{ -// { -// Address: net.NewIPOrDomain(net.LocalHostIP), -// Port: uint32(serverPort), -// User: []*protocol.User{ -// { -// Account: serial.ToTypedMessage(&vless.Account{ -// Id: userID.String(), -// Flow: vless.XRV, -// }), -// }, -// }, -// }, -// }, -// }), -// SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ -// StreamSettings: &internet.StreamConfig{ -// Protocol: internet.TransportProtocol_TCP, -// TransportSettings: []*internet.TransportConfig{ -// { -// Protocol: internet.TransportProtocol_TCP, -// Settings: serial.ToTypedMessage(&transtcp.Config{}), -// }, -// }, -// SecurityType: serial.GetMessageType(&reality.Config{}), -// SecuritySettings: []*serial.TypedMessage{ -// serial.ToTypedMessage(&reality.Config{ -// Show: true, -// Fingerprint: "chrome", -// ServerName: "www.google.com", -// PublicKey: publicKey, -// ShortId: shortIds[0], -// SpiderX: "/", -// }), -// }, -// }, -// }), -// }, -// }, -// } + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, + }), + }, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}}, + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Vnext: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vless.Account{ + Id: userID.String(), + Flow: vless.XRV, + }), + }, + }, + }, + }, + }), + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_TCP, + TransportSettings: []*internet.TransportConfig{ + { + Protocol: internet.TransportProtocol_TCP, + Settings: serial.ToTypedMessage(&transtcp.Config{}), + }, + }, + SecurityType: serial.GetMessageType(&reality.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&reality.Config{ + Show: true, + Fingerprint: "chrome", + ServerName: "www.google.com", + PublicKey: publicKey, + ShortId: shortIds[0], + SpiderX: "/", + }), + }, + }, + }), + }, + }, + } -// servers, err := InitializeServerConfigs(serverConfig, clientConfig) -// common.Must(err) -// defer CloseAllServers(servers) + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + common.Must(err) + defer CloseAllServers(servers) -// var errg errgroup.Group -// for i := 0; i < 1; i++ { -// errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) -// } -// if err := errg.Wait(); err != nil { -// t.Error(err) -// } -// } + var errg errgroup.Group + for i := 0; i < 1; i++ { + errg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30)) + } + if err := errg.Wait(); err != nil { + t.Error(err) + } +} From e244db76fbf871cc61f2f4d99f2676be27c2d9e8 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Fri, 29 Sep 2023 22:56:57 -0400 Subject: [PATCH 71/71] Update all dependencies --- go.mod | 17 ++++++++-------- go.sum | 34 ++++++++++++++++--------------- transport/internet/quic/dialer.go | 2 +- transport/internet/quic/hub.go | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 84029947..a9dae3b6 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/miekg/dns v1.1.56 github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.7.0 - github.com/quic-go/quic-go v0.38.1 + github.com/quic-go/quic-go v0.39.0 github.com/refraction-networking/utls v1.5.3 - github.com/sagernet/sing v0.2.11 + github.com/sagernet/sing v0.2.12 github.com/sagernet/sing-shadowsocks v0.2.5 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb @@ -41,20 +41,21 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect + github.com/klauspost/compress v1.17.0 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/onsi/ginkgo/v2 v2.12.0 // indirect + github.com/onsi/ginkgo/v2 v2.12.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/quic-go/qtls-go1-20 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.3.4 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect + go.uber.org/mock v0.3.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 7cf12912..faa51913 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,8 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ= -github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -78,8 +78,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -98,8 +98,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= -github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= @@ -116,17 +116,17 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= -github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= -github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= +github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= +github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.39.0 h1:AgP40iThFMY0bj8jGxROhw3S0FMGa8ryqsmi9tBH3So= +github.com/quic-go/quic-go v0.39.0/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/refraction-networking/utls v1.5.3 h1:Ds5Ocg1+MC1ahNx5iBEcHe0jHeLaA/fLey61EENm7ro= github.com/refraction-networking/utls v1.5.3/go.mod h1:SPuDbBmgLGp8s+HLNc83FuavwZCFoMmExj+ltUHiHUw= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sagernet/sing v0.2.11 h1:mu0S6d8y/xSVxilOqRd32Fmire5SZz9nT3t9NEHwUMY= -github.com/sagernet/sing v0.2.11/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= +github.com/sagernet/sing v0.2.12 h1:wwdLm3c4qvU4hW8tNtadh60V5z2FGlDZSYYGRzHhD74= +github.com/sagernet/sing v0.2.12/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= github.com/sagernet/sing-shadowsocks v0.2.5 h1:qxIttos4xu6ii7MTVJYA8EFQR7Q3KG6xMqmLJIFtBaY= github.com/sagernet/sing-shadowsocks v0.2.5/go.mod h1:MGWGkcU2xW2G2mfArT9/QqpVLOGU+dBaahZCtPHdt7A= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= @@ -174,6 +174,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ= go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= @@ -185,8 +187,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= -golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -266,8 +268,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= diff --git a/transport/internet/quic/dialer.go b/transport/internet/quic/dialer.go index f6083561..1358dac7 100644 --- a/transport/internet/quic/dialer.go +++ b/transport/internet/quic/dialer.go @@ -142,7 +142,7 @@ func (s *clientConnections) openConnection(ctx context.Context, destAddr net.Add KeepAlivePeriod: 0, HandshakeIdleTimeout: time.Second * 8, MaxIdleTimeout: time.Second * 300, - Tracer: func(ctx context.Context, p logging.Perspective, ci quic.ConnectionID) logging.ConnectionTracer { + Tracer: func(ctx context.Context, p logging.Perspective, ci quic.ConnectionID) *logging.ConnectionTracer { return qlog.NewConnectionTracer(&QlogWriter{connID: ci}, p, ci) }, } diff --git a/transport/internet/quic/hub.go b/transport/internet/quic/hub.go index 8bab5bf3..7f7ea86f 100644 --- a/transport/internet/quic/hub.go +++ b/transport/internet/quic/hub.go @@ -108,7 +108,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, streamSetti MaxIdleTimeout: time.Second * 300, MaxIncomingStreams: 32, MaxIncomingUniStreams: -1, - Tracer: func(ctx context.Context, p logging.Perspective, ci quic.ConnectionID) logging.ConnectionTracer { + Tracer: func(ctx context.Context, p logging.Perspective, ci quic.ConnectionID) *logging.ConnectionTracer { return qlog.NewConnectionTracer(&QlogWriter{connID: ci}, p, ci) }, }