diff --git a/infra/conf/shadowsocks.go b/infra/conf/shadowsocks.go index fbb2a79d..48b288d2 100644 --- a/infra/conf/shadowsocks.go +++ b/infra/conf/shadowsocks.go @@ -12,14 +12,6 @@ import ( func cipherFromString(c string) shadowsocks.CipherType { switch strings.ToLower(c) { - case "aes-256-cfb": - return shadowsocks.CipherType_AES_256_CFB - case "aes-128-cfb": - return shadowsocks.CipherType_AES_128_CFB - case "chacha20": - return shadowsocks.CipherType_CHACHA20 - case "chacha20-ietf": - return shadowsocks.CipherType_CHACHA20_IETF case "aes-128-gcm", "aead_aes_128_gcm": return shadowsocks.CipherType_AES_128_GCM case "aes-256-gcm", "aead_aes_256_gcm": diff --git a/infra/conf/shadowsocks_test.go b/infra/conf/shadowsocks_test.go index c3377a9a..a4ca6714 100644 --- a/infra/conf/shadowsocks_test.go +++ b/infra/conf/shadowsocks_test.go @@ -18,14 +18,14 @@ func TestShadowsocksServerConfigParsing(t *testing.T) { runMultiTestCase(t, []TestCase{ { Input: `{ - "method": "aes-128-gcm", + "method": "aes-256-GCM", "password": "xray-password" }`, Parser: loadJSON(creator), Output: &shadowsocks.ServerConfig{ Users: []*protocol.User{{ Account: serial.ToTypedMessage(&shadowsocks.Account{ - CipherType: shadowsocks.CipherType_AES_128_GCM, + CipherType: shadowsocks.CipherType_AES_256_GCM, Password: "xray-password", }), }}, diff --git a/proxy/shadowsocks/config.go b/proxy/shadowsocks/config.go index 607894b1..fa555de3 100644 --- a/proxy/shadowsocks/config.go +++ b/proxy/shadowsocks/config.go @@ -35,20 +35,12 @@ func (a *MemoryAccount) Equals(another protocol.Account) bool { func (a *MemoryAccount) GetCipherName() string { switch a.Cipher.(type) { - case *AesCfb: - keyBytes := a.Cipher.(*AesCfb).KeyBytes - return "AES_" + strconv.FormatInt(int64(keyBytes*8), 10) + "_CFB" - case *ChaCha20: - if a.Cipher.(*ChaCha20).IVBytes == 8 { - return "CHACHA20" - } - return "CHACHA20_IETF" case *AEADCipher: switch reflect.ValueOf(a.Cipher.(*AEADCipher).AEADAuthCreator).Pointer() { case reflect.ValueOf(createAesGcm).Pointer(): keyBytes := a.Cipher.(*AEADCipher).KeyBytes return "AES_" + strconv.FormatInt(int64(keyBytes*8), 10) + "_GCM" - case reflect.ValueOf(createChacha20Poly1305).Pointer(): + case reflect.ValueOf(createChaCha20Poly1305).Pointer(): return "CHACHA20_POLY1305" } case *NoneCipher: @@ -66,22 +58,14 @@ func createAesGcm(key []byte) cipher.AEAD { return gcm } -func createChacha20Poly1305(key []byte) cipher.AEAD { - chacha20, err := chacha20poly1305.New(key) +func createChaCha20Poly1305(key []byte) cipher.AEAD { + ChaChaPoly1305, err := chacha20poly1305.New(key) common.Must(err) - return chacha20 + return ChaChaPoly1305 } func (a *Account) getCipher() (Cipher, error) { switch a.CipherType { - case CipherType_AES_128_CFB: - return &AesCfb{KeyBytes: 16}, nil - case CipherType_AES_256_CFB: - return &AesCfb{KeyBytes: 32}, nil - case CipherType_CHACHA20: - return &ChaCha20{IVBytes: 8}, nil - case CipherType_CHACHA20_IETF: - return &ChaCha20{IVBytes: 12}, nil case CipherType_AES_128_GCM: return &AEADCipher{ KeyBytes: 16, @@ -98,7 +82,7 @@ func (a *Account) getCipher() (Cipher, error) { return &AEADCipher{ KeyBytes: 32, IVBytes: 32, - AEADAuthCreator: createChacha20Poly1305, + AEADAuthCreator: createChaCha20Poly1305, }, nil case CipherType_NONE: return NoneCipher{}, nil @@ -109,13 +93,13 @@ func (a *Account) getCipher() (Cipher, error) { // AsAccount implements protocol.AsAccount. func (a *Account) AsAccount() (protocol.Account, error) { - cipher, err := a.getCipher() + Cipher, err := a.getCipher() if err != nil { return nil, newError("failed to get cipher").Base(err) } return &MemoryAccount{ - Cipher: cipher, - Key: passwordToCipherKey([]byte(a.Password), cipher.KeySize()), + Cipher: Cipher, + Key: passwordToCipherKey([]byte(a.Password), Cipher.KeySize()), }, nil } @@ -130,53 +114,6 @@ type Cipher interface { DecodePacket(key []byte, b *buf.Buffer) error } -// AesCfb represents all AES-CFB ciphers. -type AesCfb struct { - KeyBytes int32 -} - -func (*AesCfb) IsAEAD() bool { - return false -} - -func (v *AesCfb) KeySize() int32 { - return v.KeyBytes -} - -func (v *AesCfb) IVSize() int32 { - return 16 -} - -func (v *AesCfb) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { - stream := crypto.NewAesEncryptionStream(key, iv) - return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil -} - -func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { - stream := crypto.NewAesDecryptionStream(key, iv) - return &buf.SingleReader{ - Reader: crypto.NewCryptionReader(stream, reader), - }, nil -} - -func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error { - iv := b.BytesTo(v.IVSize()) - stream := crypto.NewAesEncryptionStream(key, iv) - stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) - return nil -} - -func (v *AesCfb) DecodePacket(key []byte, b *buf.Buffer) error { - if b.Len() <= v.IVSize() { - return newError("insufficient data: ", b.Len()) - } - iv := b.BytesTo(v.IVSize()) - stream := crypto.NewAesDecryptionStream(key, iv) - stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) - b.Advance(v.IVSize()) - return nil -} - type AEADCipher struct { KeyBytes int32 IVBytes int32 @@ -245,56 +182,12 @@ func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error { return nil } -type ChaCha20 struct { - IVBytes int32 -} - -func (*ChaCha20) IsAEAD() bool { - return false -} - -func (v *ChaCha20) KeySize() int32 { - return 32 -} - -func (v *ChaCha20) IVSize() int32 { - return v.IVBytes -} - -func (v *ChaCha20) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) { - stream := crypto.NewChaCha20Stream(key, iv) - return &buf.SequentialWriter{Writer: crypto.NewCryptionWriter(stream, writer)}, nil -} - -func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { - stream := crypto.NewChaCha20Stream(key, iv) - return &buf.SingleReader{Reader: crypto.NewCryptionReader(stream, reader)}, nil -} - -func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error { - iv := b.BytesTo(v.IVSize()) - stream := crypto.NewChaCha20Stream(key, iv) - stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) - return nil -} - -func (v *ChaCha20) DecodePacket(key []byte, b *buf.Buffer) error { - if b.Len() <= v.IVSize() { - return newError("insufficient data: ", b.Len()) - } - iv := b.BytesTo(v.IVSize()) - stream := crypto.NewChaCha20Stream(key, iv) - stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize())) - b.Advance(v.IVSize()) - return nil -} - type NoneCipher struct{} func (NoneCipher) KeySize() int32 { return 0 } func (NoneCipher) IVSize() int32 { return 0 } func (NoneCipher) IsAEAD() bool { - return true // to avoid OTA + return false } func (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) { @@ -330,7 +223,7 @@ func passwordToCipherKey(password []byte, keySize int32) []byte { return key } -func hkdfSHA1(secret, salt, outkey []byte) { +func hkdfSHA1(secret, salt, outKey []byte) { r := hkdf.New(sha1.New, secret, salt, []byte("ss-subkey")) - common.Must2(io.ReadFull(r, outkey)) + common.Must2(io.ReadFull(r, outKey)) } diff --git a/proxy/shadowsocks/config.pb.go b/proxy/shadowsocks/config.pb.go index 6bac0d95..68b48891 100644 --- a/proxy/shadowsocks/config.pb.go +++ b/proxy/shadowsocks/config.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.14.0 +// protoc v3.15.8 // source: proxy/shadowsocks/config.proto package shadowsocks @@ -31,39 +31,27 @@ type CipherType int32 const ( CipherType_UNKNOWN CipherType = 0 - CipherType_AES_128_CFB CipherType = 1 - CipherType_AES_256_CFB CipherType = 2 - CipherType_CHACHA20 CipherType = 3 - CipherType_CHACHA20_IETF CipherType = 4 - CipherType_AES_128_GCM CipherType = 5 - CipherType_AES_256_GCM CipherType = 6 - CipherType_CHACHA20_POLY1305 CipherType = 7 - CipherType_NONE CipherType = 8 + CipherType_AES_128_GCM CipherType = 1 + CipherType_AES_256_GCM CipherType = 2 + CipherType_CHACHA20_POLY1305 CipherType = 3 + CipherType_NONE CipherType = 4 ) // Enum value maps for CipherType. var ( CipherType_name = map[int32]string{ 0: "UNKNOWN", - 1: "AES_128_CFB", - 2: "AES_256_CFB", - 3: "CHACHA20", - 4: "CHACHA20_IETF", - 5: "AES_128_GCM", - 6: "AES_256_GCM", - 7: "CHACHA20_POLY1305", - 8: "NONE", + 1: "AES_128_GCM", + 2: "AES_256_GCM", + 3: "CHACHA20_POLY1305", + 4: "NONE", } CipherType_value = map[string]int32{ "UNKNOWN": 0, - "AES_128_CFB": 1, - "AES_256_CFB": 2, - "CHACHA20": 3, - "CHACHA20_IETF": 4, - "AES_128_GCM": 5, - "AES_256_GCM": 6, - "CHACHA20_POLY1305": 7, - "NONE": 8, + "AES_128_GCM": 1, + "AES_256_GCM": 2, + "CHACHA20_POLY1305": 3, + "NONE": 4, } ) @@ -282,24 +270,19 @@ var file_proxy_shadowsocks_config_proto_rawDesc = []byte{ 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, 0x2a, 0x9f, 0x01, 0x0a, 0x0a, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, - 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x43, 0x46, 0x42, 0x10, 0x01, 0x12, 0x0f, - 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x43, 0x46, 0x42, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x10, 0x03, 0x12, 0x11, 0x0a, - 0x0d, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x49, 0x45, 0x54, 0x46, 0x10, 0x04, - 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x10, - 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, - 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, - 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x07, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, - 0x45, 0x10, 0x08, 0x42, 0x64, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, - 0x73, 0x50, 0x01, 0x5a, 0x2b, 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, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, - 0xaa, 0x02, 0x16, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x53, 0x68, - 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x72, 0x2a, 0x5c, 0x0a, 0x0a, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, + 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x01, 0x12, 0x0f, 0x0a, + 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, + 0x33, 0x30, 0x35, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x04, 0x42, + 0x64, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x01, 0x5a, + 0x2b, 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, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0xaa, 0x02, 0x16, 0x58, + 0x72, 0x61, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proxy/shadowsocks/config.proto b/proxy/shadowsocks/config.proto index 39ae11a3..137223f8 100644 --- a/proxy/shadowsocks/config.proto +++ b/proxy/shadowsocks/config.proto @@ -17,14 +17,10 @@ message Account { enum CipherType { UNKNOWN = 0; - AES_128_CFB = 1; - AES_256_CFB = 2; - CHACHA20 = 3; - CHACHA20_IETF = 4; - AES_128_GCM = 5; - AES_256_GCM = 6; - CHACHA20_POLY1305 = 7; - NONE = 8; + AES_128_GCM = 1; + AES_256_GCM = 2; + CHACHA20_POLY1305 = 3; + NONE = 4; } message ServerConfig { diff --git a/proxy/shadowsocks/protocol_test.go b/proxy/shadowsocks/protocol_test.go index 5663a5d9..9453fa74 100644 --- a/proxy/shadowsocks/protocol_test.go +++ b/proxy/shadowsocks/protocol_test.go @@ -18,6 +18,12 @@ func toAccount(a *Account) protocol.Account { return account } +func equalRequestHeader(x, y *protocol.RequestHeader) bool { + return cmp.Equal(x, y, cmp.Comparer(func(x, y protocol.RequestHeader) bool { + return x == y + })) +} + func TestUDPEncoding(t *testing.T) { request := &protocol.RequestHeader{ Version: Version, @@ -27,7 +33,7 @@ func TestUDPEncoding(t *testing.T) { User: &protocol.MemoryUser{ Email: "love@example.com", Account: toAccount(&Account{ - Password: "shadowsocks-password", + Password: "password", CipherType: CipherType_AES_128_GCM, }), }, @@ -47,8 +53,8 @@ func TestUDPEncoding(t *testing.T) { t.Error("data: ", r) } - if r := cmp.Diff(decodedRequest, request, cmp.Comparer(func(a1, a2 protocol.Account) bool { return a1.Equals(a2) })); r != "" { - t.Error("request: ", r) + if equalRequestHeader(decodedRequest, request) == false { + t.Error("different request") } } @@ -67,7 +73,7 @@ func TestTCPRequest(t *testing.T) { Email: "love@example.com", Account: toAccount(&Account{ Password: "tcp-password", - CipherType: CipherType_CHACHA20_POLY1305, + CipherType: CipherType_AES_128_GCM, }), }, }, @@ -99,7 +105,7 @@ func TestTCPRequest(t *testing.T) { Email: "love@example.com", Account: toAccount(&Account{ Password: "password", - CipherType: CipherType_AES_128_GCM, + CipherType: CipherType_CHACHA20_POLY1305, }), }, }, @@ -123,8 +129,8 @@ func TestTCPRequest(t *testing.T) { validator.Add(request.User) decodedRequest, reader, err := ReadTCPSession(validator, cache) common.Must(err) - if r := cmp.Diff(decodedRequest, request, cmp.Comparer(func(a1, a2 protocol.Account) bool { return a1.Equals(a2) })); r != "" { - t.Error("request: ", r) + if equalRequestHeader(decodedRequest, request) == false { + t.Error("different request") } decodedData, err := reader.ReadMultiBuffer() diff --git a/testing/scenarios/shadowsocks_test.go b/testing/scenarios/shadowsocks_test.go index 562343ac..ca93524d 100644 --- a/testing/scenarios/shadowsocks_test.go +++ b/testing/scenarios/shadowsocks_test.go @@ -1,17 +1,14 @@ package scenarios import ( - "crypto/rand" "testing" "time" - "github.com/google/go-cmp/cmp" "golang.org/x/sync/errgroup" "github.com/xtls/xray-core/app/log" "github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/errors" clog "github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" @@ -24,330 +21,7 @@ import ( "github.com/xtls/xray-core/testing/servers/udp" ) -func TestShadowsocksAES256TCP(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - defer tcpServer.Close() - - account := serial.ToTypedMessage(&shadowsocks.Account{ - Password: "shadowsocks-password", - CipherType: shadowsocks.CipherType_AES_256_CFB, - }) - - 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{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ - Users: []*protocol.User{{ - Account: account, - Level: 1, - }}, - 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{ - 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(&shadowsocks.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: account, - }, - }, - }, - }, - }), - }, - }, - } - - 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, 10240*1024, time.Second*20)) - } - if err := errg.Wait(); err != nil { - t.Fatal(err) - } -} - -func TestShadowsocksAES128UDP(t *testing.T) { - udpServer := udp.Server{ - MsgProcessor: xor, - } - dest, err := udpServer.Start() - common.Must(err) - defer udpServer.Close() - - account := serial.ToTypedMessage(&shadowsocks.Account{ - Password: "shadowsocks-password", - CipherType: shadowsocks.CipherType_AES_128_CFB, - }) - - 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{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ - Users: []*protocol.User{{ - Account: account, - Level: 1, - }}, - Network: []net.Network{net.Network_UDP}, - }), - }, - }, - 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{ - 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_UDP}, - }, - }), - }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: account, - }, - }, - }, - }, - }), - }, - }, - } - - servers, err := InitializeServerConfigs(serverConfig, clientConfig) - common.Must(err) - defer CloseAllServers(servers) - - var errg errgroup.Group - for i := 0; i < 10; i++ { - errg.Go(func() error { - conn, err := net.DialUDP("udp", nil, &net.UDPAddr{ - IP: []byte{127, 0, 0, 1}, - Port: int(clientPort), - }) - if err != nil { - return err - } - defer conn.Close() - - payload := make([]byte, 1024) - common.Must2(rand.Read(payload)) - - nBytes, err := conn.Write(payload) - if err != nil { - return err - } - if nBytes != len(payload) { - return errors.New("expect ", len(payload), " written, but actually ", nBytes) - } - - response := readFrom(conn, time.Second*5, 1024) - if r := cmp.Diff(response, xor(payload)); r != "" { - return errors.New(r) - } - return nil - }) - } - - if err := errg.Wait(); err != nil { - t.Fatal(err) - } -} - -func TestShadowsocksChacha20TCP(t *testing.T) { - tcpServer := tcp.Server{ - MsgProcessor: xor, - } - dest, err := tcpServer.Start() - common.Must(err) - - defer tcpServer.Close() - - account := serial.ToTypedMessage(&shadowsocks.Account{ - Password: "shadowsocks-password", - CipherType: shadowsocks.CipherType_CHACHA20_IETF, - }) - - 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{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{ - Users: []*protocol.User{{ - Account: account, - Level: 1, - }}, - 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{ - 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(&shadowsocks.ClientConfig{ - Server: []*protocol.ServerEndpoint{ - { - Address: net.NewIPOrDomain(net.LocalHostIP), - Port: uint32(serverPort), - User: []*protocol.User{ - { - Account: account, - }, - }, - }, - }, - }), - }, - }, - } - - 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, 10240*1024, time.Second*40)) - } - - if err := errg.Wait(); err != nil { - t.Error(err) - } -} - -func TestShadowsocksChacha20Poly1305TCP(t *testing.T) { +func TestShadowsocksChaCha20Poly1305TCP(t *testing.T) { tcpServer := tcp.Server{ MsgProcessor: xor, } @@ -395,9 +69,7 @@ func TestShadowsocksChacha20Poly1305TCP(t *testing.T) { ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ Address: net.NewIPOrDomain(dest.Address), Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, + Networks: []net.Network{net.Network_TCP}, }), }, }, @@ -424,11 +96,11 @@ func TestShadowsocksChacha20Poly1305TCP(t *testing.T) { common.Must(err) defer CloseAllServers(servers) - var errg errgroup.Group + var errGroup errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) + errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) } - if err := errg.Wait(); err != nil { + if err := errGroup.Wait(); err != nil { t.Error(err) } } @@ -493,9 +165,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) { ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ Address: net.NewIPOrDomain(dest.Address), Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, + Networks: []net.Network{net.Network_TCP}, }), }, }, @@ -522,12 +192,12 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) { common.Must(err) defer CloseAllServers(servers) - var errg errgroup.Group + var errGroup errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) + errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) } - if err := errg.Wait(); err != nil { + if err := errGroup.Wait(); err != nil { t.Error(err) } } @@ -592,9 +262,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) { ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ Address: net.NewIPOrDomain(dest.Address), Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_UDP}, - }, + Networks: []net.Network{net.Network_UDP}, }), }, }, @@ -621,11 +289,11 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) { common.Must(err) defer CloseAllServers(servers) - var errg errgroup.Group + var errGroup errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testUDPConn(clientPort, 1024, time.Second*5)) + errGroup.Go(testUDPConn(clientPort, 1024, time.Second*5)) } - if err := errg.Wait(); err != nil { + if err := errGroup.Wait(); err != nil { t.Error(err) } } @@ -690,9 +358,7 @@ func TestShadowsocksAES128GCMUDPMux(t *testing.T) { ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ Address: net.NewIPOrDomain(dest.Address), Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_UDP}, - }, + Networks: []net.Network{net.Network_UDP}, }), }, }, @@ -725,11 +391,11 @@ func TestShadowsocksAES128GCMUDPMux(t *testing.T) { common.Must(err) defer CloseAllServers(servers) - var errg errgroup.Group + var errGroup errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testUDPConn(clientPort, 1024, time.Second*5)) + errGroup.Go(testUDPConn(clientPort, 1024, time.Second*5)) } - if err := errg.Wait(); err != nil { + if err := errGroup.Wait(); err != nil { t.Error(err) } } @@ -783,9 +449,7 @@ func TestShadowsocksNone(t *testing.T) { ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ Address: net.NewIPOrDomain(dest.Address), Port: uint32(dest.Port), - NetworkList: &net.NetworkList{ - Network: []net.Network{net.Network_TCP}, - }, + Networks: []net.Network{net.Network_TCP}, }), }, }, @@ -813,12 +477,12 @@ func TestShadowsocksNone(t *testing.T) { defer CloseAllServers(servers) - var errg errgroup.Group + var errGroup errgroup.Group for i := 0; i < 10; i++ { - errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) + errGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20)) } - if err := errg.Wait(); err != nil { + if err := errGroup.Wait(); err != nil { t.Fatal(err) } }