From 3eb6ac98eb212d1c8548d5e032b449ff63b7b627 Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Tue, 31 May 2022 15:59:21 +0800 Subject: [PATCH] xray-core: fix build in go 1.17 Signed-off-by: Tianling Shen --- ...0-Fix-build-in-legacy-golang-version.patch | 628 ++++++++++++++++++ 1 file changed, 628 insertions(+) create mode 100644 net/xray-core/patches/010-Fix-build-in-legacy-golang-version.patch diff --git a/net/xray-core/patches/010-Fix-build-in-legacy-golang-version.patch b/net/xray-core/patches/010-Fix-build-in-legacy-golang-version.patch new file mode 100644 index 0000000000..1aa5d48c40 --- /dev/null +++ b/net/xray-core/patches/010-Fix-build-in-legacy-golang-version.patch @@ -0,0 +1,628 @@ +From f1d753f0693b3845ace8962bd9a34343f472631d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= +Date: Tue, 31 May 2022 15:55:38 +0800 +Subject: [PATCH] Fix build in legacy golang version + +--- + infra/conf/shadowsocks.go | 2 + + infra/conf/shadowsocks_legacy.go | 152 +++++++++++++++ + proxy/shadowsocks_2022/inbound.go | 2 + + proxy/shadowsocks_2022/inbound_multi.go | 2 + + proxy/shadowsocks_2022/outbound.go | 2 + + proxy/shadowsocks_2022/shadowsocks_2022.go | 2 + + testing/scenarios/shadowsocks_2022_test.go | 209 +++++++++++++++++++++ + testing/scenarios/shadowsocks_test.go | 190 ------------------- + 8 files changed, 371 insertions(+), 190 deletions(-) + create mode 100644 infra/conf/shadowsocks_legacy.go + create mode 100644 testing/scenarios/shadowsocks_2022_test.go + +--- a/infra/conf/shadowsocks.go ++++ b/infra/conf/shadowsocks.go +@@ -1,3 +1,5 @@ ++//go:build go1.18 ++ + package conf + + import ( +--- /dev/null ++++ b/infra/conf/shadowsocks_legacy.go +@@ -0,0 +1,152 @@ ++//go:build !go1.18 ++package conf ++ ++import ( ++ "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/shadowsocks" ++) ++ ++func cipherFromString(c string) shadowsocks.CipherType { ++ switch strings.ToLower(c) { ++ case "aes-128-gcm", "aead_aes_128_gcm": ++ return shadowsocks.CipherType_AES_128_GCM ++ case "aes-256-gcm", "aead_aes_256_gcm": ++ return shadowsocks.CipherType_AES_256_GCM ++ case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": ++ return shadowsocks.CipherType_CHACHA20_POLY1305 ++ case "xchacha20-poly1305", "aead_xchacha20_poly1305", "xchacha20-ietf-poly1305": ++ return shadowsocks.CipherType_XCHACHA20_POLY1305 ++ case "none", "plain": ++ return shadowsocks.CipherType_NONE ++ default: ++ return shadowsocks.CipherType_UNKNOWN ++ } ++} ++ ++type ShadowsocksUserConfig struct { ++ Cipher string `json:"method"` ++ Password string `json:"password"` ++ Level byte `json:"level"` ++ Email string `json:"email"` ++} ++ ++type ShadowsocksServerConfig struct { ++ Cipher string `json:"method"` ++ Password string `json:"password"` ++ Level byte `json:"level"` ++ Email string `json:"email"` ++ Users []*ShadowsocksUserConfig `json:"clients"` ++ NetworkList *NetworkList `json:"network"` ++ IVCheck bool `json:"ivCheck"` ++} ++ ++func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { ++ config := new(shadowsocks.ServerConfig) ++ config.Network = v.NetworkList.Build() ++ ++ if v.Users != nil { ++ for _, user := range v.Users { ++ account := &shadowsocks.Account{ ++ Password: user.Password, ++ CipherType: cipherFromString(user.Cipher), ++ IvCheck: v.IVCheck, ++ } ++ if account.Password == "" { ++ return nil, newError("Shadowsocks password is not specified.") ++ } ++ if account.CipherType < shadowsocks.CipherType_AES_128_GCM || ++ account.CipherType > shadowsocks.CipherType_XCHACHA20_POLY1305 { ++ return nil, newError("unsupported cipher method: ", user.Cipher) ++ } ++ config.Users = append(config.Users, &protocol.User{ ++ Email: user.Email, ++ Level: uint32(user.Level), ++ Account: serial.ToTypedMessage(account), ++ }) ++ } ++ } else { ++ account := &shadowsocks.Account{ ++ Password: v.Password, ++ CipherType: cipherFromString(v.Cipher), ++ IvCheck: v.IVCheck, ++ } ++ if account.Password == "" { ++ return nil, newError("Shadowsocks password is not specified.") ++ } ++ if account.CipherType == shadowsocks.CipherType_UNKNOWN { ++ return nil, newError("unknown cipher method: ", v.Cipher) ++ } ++ config.Users = append(config.Users, &protocol.User{ ++ Email: v.Email, ++ Level: uint32(v.Level), ++ Account: serial.ToTypedMessage(account), ++ }) ++ } ++ ++ return config, nil ++} ++ ++type ShadowsocksServerTarget struct { ++ Address *Address `json:"address"` ++ Port uint16 `json:"port"` ++ Cipher string `json:"method"` ++ Password string `json:"password"` ++ Email string `json:"email"` ++ Level byte `json:"level"` ++ IVCheck bool `json:"ivCheck"` ++} ++ ++type ShadowsocksClientConfig struct { ++ Servers []*ShadowsocksServerTarget `json:"servers"` ++} ++ ++func (v *ShadowsocksClientConfig) Build() (proto.Message, error) { ++ if len(v.Servers) == 0 { ++ return nil, newError("0 Shadowsocks server configured.") ++ } ++ ++ config := new(shadowsocks.ClientConfig) ++ serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers)) ++ for idx, server := range v.Servers { ++ if server.Address == nil { ++ return nil, newError("Shadowsocks server address is not set.") ++ } ++ if server.Port == 0 { ++ return nil, newError("Invalid Shadowsocks port.") ++ } ++ if server.Password == "" { ++ return nil, newError("Shadowsocks password is not specified.") ++ } ++ account := &shadowsocks.Account{ ++ Password: server.Password, ++ } ++ account.CipherType = cipherFromString(server.Cipher) ++ if account.CipherType == shadowsocks.CipherType_UNKNOWN { ++ return nil, newError("unknown cipher method: ", server.Cipher) ++ } ++ ++ account.IvCheck = server.IVCheck ++ ++ ss := &protocol.ServerEndpoint{ ++ Address: server.Address.Build(), ++ Port: uint32(server.Port), ++ User: []*protocol.User{ ++ { ++ Level: uint32(server.Level), ++ Email: server.Email, ++ Account: serial.ToTypedMessage(account), ++ }, ++ }, ++ } ++ ++ serverSpecs[idx] = ss ++ } ++ ++ config.Server = serverSpecs ++ ++ return config, nil ++} +--- a/proxy/shadowsocks_2022/inbound.go ++++ b/proxy/shadowsocks_2022/inbound.go +@@ -1,3 +1,5 @@ ++//go:build go1.18 ++ + package shadowsocks_2022 + + import ( +--- a/proxy/shadowsocks_2022/inbound_multi.go ++++ b/proxy/shadowsocks_2022/inbound_multi.go +@@ -1,3 +1,5 @@ ++//go:build go1.18 ++ + package shadowsocks_2022 + + import ( +--- a/proxy/shadowsocks_2022/outbound.go ++++ b/proxy/shadowsocks_2022/outbound.go +@@ -1,3 +1,5 @@ ++//go:build go1.18 ++ + package shadowsocks_2022 + + import ( +--- a/proxy/shadowsocks_2022/shadowsocks_2022.go ++++ b/proxy/shadowsocks_2022/shadowsocks_2022.go +@@ -1,3 +1,5 @@ ++//go:build go1.18 ++ + package shadowsocks_2022 + + import ( +--- /dev/null ++++ b/testing/scenarios/shadowsocks_2022_test.go +@@ -0,0 +1,209 @@ ++package scenarios ++ ++import ( ++ "crypto/rand" ++ "encoding/base64" ++ "github.com/sagernet/sing-shadowsocks/shadowaead_2022" ++ "github.com/xtls/xray-core/proxy/shadowsocks_2022" ++ "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/serial" ++ "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/testing/servers/tcp" ++ "github.com/xtls/xray-core/testing/servers/udp" ++ "golang.org/x/sync/errgroup" ++) ++ ++func TestShadowsocks2022Tcp(t *testing.T) { ++ for _, method := range shadowaead_2022.List { ++ password := make([]byte, 32) ++ rand.Read(password) ++ t.Run(method, func(t *testing.T) { ++ testShadowsocks2022Tcp(t, method, base64.StdEncoding.EncodeToString(password)) ++ }) ++ } ++} ++ ++func TestShadowsocks2022Udp(t *testing.T) { ++ for _, method := range shadowaead_2022.List { ++ password := make([]byte, 32) ++ rand.Read(password) ++ t.Run(method, func(t *testing.T) { ++ testShadowsocks2022Udp(t, method, base64.StdEncoding.EncodeToString(password)) ++ }) ++ } ++} ++ ++func testShadowsocks2022Tcp(t *testing.T, method string, password string) { ++ tcpServer := tcp.Server{ ++ MsgProcessor: xor, ++ } ++ dest, err := tcpServer.Start() ++ common.Must(err) ++ defer tcpServer.Close() ++ ++ 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(&shadowsocks_2022.ServerConfig{ ++ Method: method, ++ Key: password, ++ Network: []net.Network{net.Network_TCP}, ++ }), ++ }, ++ }, ++ 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), ++ Networks: []net.Network{net.Network_TCP}, ++ }), ++ }, ++ }, ++ Outbound: []*core.OutboundHandlerConfig{ ++ { ++ ProxySettings: serial.ToTypedMessage(&shadowsocks_2022.ClientConfig{ ++ Address: net.NewIPOrDomain(net.LocalHostIP), ++ Port: uint32(serverPort), ++ Method: method, ++ Key: password, ++ }), ++ }, ++ }, ++ } ++ ++ servers, err := InitializeServerConfigs(serverConfig, clientConfig) ++ common.Must(err) ++ defer CloseAllServers(servers) ++ ++ var errGroup errgroup.Group ++ for i := 0; i < 10; i++ { ++ errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) ++ } ++ ++ if err := errGroup.Wait(); err != nil { ++ t.Error(err) ++ } ++} ++ ++func testShadowsocks2022Udp(t *testing.T, method string, password string) { ++ udpServer := udp.Server{ ++ MsgProcessor: xor, ++ } ++ udpDest, err := udpServer.Start() ++ common.Must(err) ++ defer udpServer.Close() ++ ++ serverPort := udp.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(&shadowsocks_2022.ServerConfig{ ++ Method: method, ++ Key: password, ++ Network: []net.Network{net.Network_UDP}, ++ }), ++ }, ++ }, ++ Outbound: []*core.OutboundHandlerConfig{ ++ { ++ ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ++ }, ++ }, ++ } ++ ++ udpClientPort := udp.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(udpClientPort)}}, ++ Listen: net.NewIPOrDomain(net.LocalHostIP), ++ }), ++ ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ ++ Address: net.NewIPOrDomain(udpDest.Address), ++ Port: uint32(udpDest.Port), ++ Networks: []net.Network{net.Network_UDP}, ++ }), ++ }, ++ }, ++ Outbound: []*core.OutboundHandlerConfig{ ++ { ++ ProxySettings: serial.ToTypedMessage(&shadowsocks_2022.ClientConfig{ ++ Address: net.NewIPOrDomain(net.LocalHostIP), ++ Port: uint32(serverPort), ++ Method: method, ++ Key: password, ++ }), ++ }, ++ }, ++ } ++ ++ servers, err := InitializeServerConfigs(serverConfig, clientConfig) ++ common.Must(err) ++ defer CloseAllServers(servers) ++ ++ var errGroup errgroup.Group ++ for i := 0; i < 10; i++ { ++ errGroup.Go(testUDPConn(udpClientPort, 1024, time.Second*5)) ++ } ++ ++ if err := errGroup.Wait(); err != nil { ++ t.Error(err) ++ } ++} +--- a/testing/scenarios/shadowsocks_test.go ++++ b/testing/scenarios/shadowsocks_test.go +@@ -1,10 +1,6 @@ + package scenarios + + import ( +- "crypto/rand" +- "encoding/base64" +- "github.com/sagernet/sing-shadowsocks/shadowaead_2022" +- "github.com/xtls/xray-core/proxy/shadowsocks_2022" + "testing" + "time" + +@@ -489,189 +485,3 @@ func TestShadowsocksNone(t *testing.T) { + t.Fatal(err) + } + } +- +-func TestShadowsocks2022Tcp(t *testing.T) { +- for _, method := range shadowaead_2022.List { +- password := make([]byte, 32) +- rand.Read(password) +- t.Run(method, func(t *testing.T) { +- testShadowsocks2022Tcp(t, method, base64.StdEncoding.EncodeToString(password)) +- }) +- } +-} +- +-func TestShadowsocks2022Udp(t *testing.T) { +- for _, method := range shadowaead_2022.List { +- password := make([]byte, 32) +- rand.Read(password) +- t.Run(method, func(t *testing.T) { +- testShadowsocks2022Udp(t, method, base64.StdEncoding.EncodeToString(password)) +- }) +- } +-} +- +-func testShadowsocks2022Tcp(t *testing.T, method string, password string) { +- tcpServer := tcp.Server{ +- MsgProcessor: xor, +- } +- dest, err := tcpServer.Start() +- common.Must(err) +- defer tcpServer.Close() +- +- 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(&shadowsocks_2022.ServerConfig{ +- Method: method, +- Key: password, +- Network: []net.Network{net.Network_TCP}, +- }), +- }, +- }, +- 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), +- Networks: []net.Network{net.Network_TCP}, +- }), +- }, +- }, +- Outbound: []*core.OutboundHandlerConfig{ +- { +- ProxySettings: serial.ToTypedMessage(&shadowsocks_2022.ClientConfig{ +- Address: net.NewIPOrDomain(net.LocalHostIP), +- Port: uint32(serverPort), +- Method: method, +- Key: password, +- }), +- }, +- }, +- } +- +- servers, err := InitializeServerConfigs(serverConfig, clientConfig) +- common.Must(err) +- defer CloseAllServers(servers) +- +- var errGroup errgroup.Group +- for i := 0; i < 10; i++ { +- errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) +- } +- +- if err := errGroup.Wait(); err != nil { +- t.Error(err) +- } +-} +- +-func testShadowsocks2022Udp(t *testing.T, method string, password string) { +- udpServer := udp.Server{ +- MsgProcessor: xor, +- } +- udpDest, err := udpServer.Start() +- common.Must(err) +- defer udpServer.Close() +- +- serverPort := udp.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(&shadowsocks_2022.ServerConfig{ +- Method: method, +- Key: password, +- Network: []net.Network{net.Network_UDP}, +- }), +- }, +- }, +- Outbound: []*core.OutboundHandlerConfig{ +- { +- ProxySettings: serial.ToTypedMessage(&freedom.Config{}), +- }, +- }, +- } +- +- udpClientPort := udp.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(udpClientPort)}}, +- Listen: net.NewIPOrDomain(net.LocalHostIP), +- }), +- ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ +- Address: net.NewIPOrDomain(udpDest.Address), +- Port: uint32(udpDest.Port), +- Networks: []net.Network{net.Network_UDP}, +- }), +- }, +- }, +- Outbound: []*core.OutboundHandlerConfig{ +- { +- ProxySettings: serial.ToTypedMessage(&shadowsocks_2022.ClientConfig{ +- Address: net.NewIPOrDomain(net.LocalHostIP), +- Port: uint32(serverPort), +- Method: method, +- Key: password, +- }), +- }, +- }, +- } +- +- servers, err := InitializeServerConfigs(serverConfig, clientConfig) +- common.Must(err) +- defer CloseAllServers(servers) +- +- var errGroup errgroup.Group +- for i := 0; i < 10; i++ { +- errGroup.Go(testUDPConn(udpClientPort, 1024, time.Second*5)) +- } +- +- if err := errGroup.Wait(); err != nil { +- t.Error(err) +- } +-} -- 2.30.2