+++ /dev/null
-From f1d753f0693b3845ace8962bd9a34343f472631d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= <i@sekai.icu>
-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)
-- }
--}