123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- From f1d753f0693b3845ace8962bd9a34343f472631d Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= <[email protected]>
- 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)
- - }
- -}
|