mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-02 15:36:41 -05:00
Merge branch 'master' into v5
This commit is contained in:
commit
7fc30aca79
@ -258,12 +258,7 @@ func sniffer(ctx context.Context, cReader *cachedReader) (SniffResult, error) {
|
|||||||
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
|
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
|
||||||
var handler outbound.Handler
|
var handler outbound.Handler
|
||||||
|
|
||||||
skipRoutePick := false
|
if d.router != nil {
|
||||||
if content := session.ContentFromContext(ctx); content != nil {
|
|
||||||
skipRoutePick = content.SkipRoutePick
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.router != nil && !skipRoutePick {
|
|
||||||
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
|
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
|
||||||
tag := route.GetOutboundTag()
|
tag := route.GetOutboundTag()
|
||||||
if h := d.ohm.GetHandler(tag); h != nil {
|
if h := d.ohm.GetHandler(tag); h != nil {
|
||||||
|
@ -229,7 +229,7 @@ func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP n
|
|||||||
|
|
||||||
dnsCtx = session.ContextWithContent(dnsCtx, &session.Content{
|
dnsCtx = session.ContextWithContent(dnsCtx, &session.Content{
|
||||||
Protocol: "https",
|
Protocol: "https",
|
||||||
SkipRoutePick: true,
|
SkipDNSResolve: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
// forced to use mux for DOH
|
// forced to use mux for DOH
|
||||||
|
@ -175,7 +175,7 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
|
|||||||
|
|
||||||
dnsCtx = session.ContextWithContent(dnsCtx, &session.Content{
|
dnsCtx = session.ContextWithContent(dnsCtx, &session.Content{
|
||||||
Protocol: "quic",
|
Protocol: "quic",
|
||||||
SkipRoutePick: true,
|
SkipDNSResolve: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
|
@ -28,6 +28,13 @@ func (c routingContext) GetTargetPort() net.Port {
|
|||||||
return net.Port(c.RoutingContext.GetTargetPort())
|
return net.Port(c.RoutingContext.GetTargetPort())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSkipDNSResolve is a mock implementation here to match the interface,
|
||||||
|
// SkipDNSResolve is set from dns module, no use if coming from a protobuf object?
|
||||||
|
// TODO: please confirm @Vigilans
|
||||||
|
func (c routingContext) GetSkipDNSResolve() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context.
|
// AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context.
|
||||||
func AsRoutingContext(r *RoutingContext) routing.Context {
|
func AsRoutingContext(r *RoutingContext) routing.Context {
|
||||||
return routingContext{r}
|
return routingContext{r}
|
||||||
|
@ -80,7 +80,12 @@ func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {
|
func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {
|
||||||
if r.domainStrategy == Config_IpOnDemand {
|
// SkipDNSResolve is set from DNS module.
|
||||||
|
// the DOH remote server maybe a domain name,
|
||||||
|
// this prevents cycle resolving dead loop
|
||||||
|
skipDNSResolve := ctx.GetSkipDNSResolve()
|
||||||
|
|
||||||
|
if r.domainStrategy == Config_IpOnDemand && !skipDNSResolve {
|
||||||
ctx = routing_dns.ContextWithDNSClient(ctx, r.dns)
|
ctx = routing_dns.ContextWithDNSClient(ctx, r.dns)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.domainStrategy != Config_IpIfNonMatch || len(ctx.GetTargetDomain()) == 0 {
|
if r.domainStrategy != Config_IpIfNonMatch || len(ctx.GetTargetDomain()) == 0 || skipDNSResolve {
|
||||||
return nil, ctx, common.ErrNoClue
|
return nil, ctx, common.ErrNoClue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ type Content struct {
|
|||||||
|
|
||||||
Attributes map[string]string
|
Attributes map[string]string
|
||||||
|
|
||||||
SkipRoutePick bool
|
SkipDNSResolve bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sockopt is the settings for socket connection.
|
// Sockopt is the settings for socket connection.
|
||||||
|
@ -37,4 +37,7 @@ type Context interface {
|
|||||||
|
|
||||||
// GetAttributes returns extra attributes from the conneciont content.
|
// GetAttributes returns extra attributes from the conneciont content.
|
||||||
GetAttributes() map[string]string
|
GetAttributes() map[string]string
|
||||||
|
|
||||||
|
// GetSkipDNSResolve returns a flag switch for weather skip dns resolve during route pick.
|
||||||
|
GetSkipDNSResolve() bool
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,14 @@ func (ctx *Context) GetAttributes() map[string]string {
|
|||||||
return ctx.Content.Attributes
|
return ctx.Content.Attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSkipDNSResolve implements routing.Context.
|
||||||
|
func (ctx *Context) GetSkipDNSResolve() bool {
|
||||||
|
if ctx.Content == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return ctx.Content.SkipDNSResolve
|
||||||
|
}
|
||||||
|
|
||||||
// AsRoutingContext creates a context from context.context with session info.
|
// AsRoutingContext creates a context from context.context with session info.
|
||||||
func AsRoutingContext(ctx context.Context) routing.Context {
|
func AsRoutingContext(ctx context.Context) routing.Context {
|
||||||
return &Context{
|
return &Context{
|
||||||
|
@ -12,14 +12,6 @@ import (
|
|||||||
|
|
||||||
func cipherFromString(c string) shadowsocks.CipherType {
|
func cipherFromString(c string) shadowsocks.CipherType {
|
||||||
switch strings.ToLower(c) {
|
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":
|
case "aes-128-gcm", "aead_aes_128_gcm":
|
||||||
return shadowsocks.CipherType_AES_128_GCM
|
return shadowsocks.CipherType_AES_128_GCM
|
||||||
case "aes-256-gcm", "aead_aes_256_gcm":
|
case "aes-256-gcm", "aead_aes_256_gcm":
|
||||||
|
@ -18,14 +18,14 @@ func TestShadowsocksServerConfigParsing(t *testing.T) {
|
|||||||
runMultiTestCase(t, []TestCase{
|
runMultiTestCase(t, []TestCase{
|
||||||
{
|
{
|
||||||
Input: `{
|
Input: `{
|
||||||
"method": "aes-128-cfb",
|
"method": "aes-256-GCM",
|
||||||
"password": "v2ray-password"
|
"password": "v2ray-password"
|
||||||
}`,
|
}`,
|
||||||
Parser: loadJSON(creator),
|
Parser: loadJSON(creator),
|
||||||
Output: &shadowsocks.ServerConfig{
|
Output: &shadowsocks.ServerConfig{
|
||||||
User: &protocol.User{
|
User: &protocol.User{
|
||||||
Account: serial.ToTypedMessage(&shadowsocks.Account{
|
Account: serial.ToTypedMessage(&shadowsocks.Account{
|
||||||
CipherType: shadowsocks.CipherType_AES_128_CFB,
|
CipherType: shadowsocks.CipherType_AES_256_GCM,
|
||||||
Password: "v2ray-password",
|
Password: "v2ray-password",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -39,22 +39,14 @@ func createAesGcm(key []byte) cipher.AEAD {
|
|||||||
return gcm
|
return gcm
|
||||||
}
|
}
|
||||||
|
|
||||||
func createChacha20Poly1305(key []byte) cipher.AEAD {
|
func createChaCha20Poly1305(key []byte) cipher.AEAD {
|
||||||
chacha20, err := chacha20poly1305.New(key)
|
ChaChaPoly1305, err := chacha20poly1305.New(key)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
return chacha20
|
return ChaChaPoly1305
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Account) getCipher() (Cipher, error) {
|
func (a *Account) getCipher() (Cipher, error) {
|
||||||
switch a.CipherType {
|
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:
|
case CipherType_AES_128_GCM:
|
||||||
return &AEADCipher{
|
return &AEADCipher{
|
||||||
KeyBytes: 16,
|
KeyBytes: 16,
|
||||||
@ -71,7 +63,7 @@ func (a *Account) getCipher() (Cipher, error) {
|
|||||||
return &AEADCipher{
|
return &AEADCipher{
|
||||||
KeyBytes: 32,
|
KeyBytes: 32,
|
||||||
IVBytes: 32,
|
IVBytes: 32,
|
||||||
AEADAuthCreator: createChacha20Poly1305,
|
AEADAuthCreator: createChaCha20Poly1305,
|
||||||
}, nil
|
}, nil
|
||||||
case CipherType_NONE:
|
case CipherType_NONE:
|
||||||
return NoneCipher{}, nil
|
return NoneCipher{}, nil
|
||||||
@ -82,13 +74,13 @@ func (a *Account) getCipher() (Cipher, error) {
|
|||||||
|
|
||||||
// AsAccount implements protocol.AsAccount.
|
// AsAccount implements protocol.AsAccount.
|
||||||
func (a *Account) AsAccount() (protocol.Account, error) {
|
func (a *Account) AsAccount() (protocol.Account, error) {
|
||||||
cipher, err := a.getCipher()
|
Cipher, err := a.getCipher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to get cipher").Base(err)
|
return nil, newError("failed to get cipher").Base(err)
|
||||||
}
|
}
|
||||||
return &MemoryAccount{
|
return &MemoryAccount{
|
||||||
Cipher: cipher,
|
Cipher: Cipher,
|
||||||
Key: passwordToCipherKey([]byte(a.Password), cipher.KeySize()),
|
Key: passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,53 +95,6 @@ type Cipher interface {
|
|||||||
DecodePacket(key []byte, b *buf.Buffer) error
|
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 {
|
type AEADCipher struct {
|
||||||
KeyBytes int32
|
KeyBytes int32
|
||||||
IVBytes int32
|
IVBytes int32
|
||||||
@ -218,56 +163,12 @@ func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
|
|||||||
return nil
|
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{}
|
type NoneCipher struct{}
|
||||||
|
|
||||||
func (NoneCipher) KeySize() int32 { return 0 }
|
func (NoneCipher) KeySize() int32 { return 0 }
|
||||||
func (NoneCipher) IVSize() int32 { return 0 }
|
func (NoneCipher) IVSize() int32 { return 0 }
|
||||||
func (NoneCipher) IsAEAD() bool {
|
func (NoneCipher) IsAEAD() bool {
|
||||||
return true // to avoid OTA
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
|
func (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
|
||||||
@ -303,7 +204,7 @@ func passwordToCipherKey(password []byte, keySize int32) []byte {
|
|||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
func hkdfSHA1(secret, salt, outkey []byte) {
|
func hkdfSHA1(secret, salt, outKey []byte) {
|
||||||
r := hkdf.New(sha1.New, secret, salt, []byte("ss-subkey"))
|
r := hkdf.New(sha1.New, secret, salt, []byte("ss-subkey"))
|
||||||
common.Must2(io.ReadFull(r, outkey))
|
common.Must2(io.ReadFull(r, outKey))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.25.0
|
// protoc-gen-go v1.25.0
|
||||||
// protoc v3.13.0
|
// protoc v3.12.4
|
||||||
// source: proxy/shadowsocks/config.proto
|
// source: proxy/shadowsocks/config.proto
|
||||||
|
|
||||||
package shadowsocks
|
package shadowsocks
|
||||||
@ -31,39 +31,27 @@ type CipherType int32
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
CipherType_UNKNOWN CipherType = 0
|
CipherType_UNKNOWN CipherType = 0
|
||||||
CipherType_AES_128_CFB CipherType = 1
|
CipherType_AES_128_GCM CipherType = 1
|
||||||
CipherType_AES_256_CFB CipherType = 2
|
CipherType_AES_256_GCM CipherType = 2
|
||||||
CipherType_CHACHA20 CipherType = 3
|
CipherType_CHACHA20_POLY1305 CipherType = 3
|
||||||
CipherType_CHACHA20_IETF CipherType = 4
|
CipherType_NONE CipherType = 4
|
||||||
CipherType_AES_128_GCM CipherType = 5
|
|
||||||
CipherType_AES_256_GCM CipherType = 6
|
|
||||||
CipherType_CHACHA20_POLY1305 CipherType = 7
|
|
||||||
CipherType_NONE CipherType = 8
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Enum value maps for CipherType.
|
// Enum value maps for CipherType.
|
||||||
var (
|
var (
|
||||||
CipherType_name = map[int32]string{
|
CipherType_name = map[int32]string{
|
||||||
0: "UNKNOWN",
|
0: "UNKNOWN",
|
||||||
1: "AES_128_CFB",
|
1: "AES_128_GCM",
|
||||||
2: "AES_256_CFB",
|
2: "AES_256_GCM",
|
||||||
3: "CHACHA20",
|
3: "CHACHA20_POLY1305",
|
||||||
4: "CHACHA20_IETF",
|
4: "NONE",
|
||||||
5: "AES_128_GCM",
|
|
||||||
6: "AES_256_GCM",
|
|
||||||
7: "CHACHA20_POLY1305",
|
|
||||||
8: "NONE",
|
|
||||||
}
|
}
|
||||||
CipherType_value = map[string]int32{
|
CipherType_value = map[string]int32{
|
||||||
"UNKNOWN": 0,
|
"UNKNOWN": 0,
|
||||||
"AES_128_CFB": 1,
|
"AES_128_GCM": 1,
|
||||||
"AES_256_CFB": 2,
|
"AES_256_GCM": 2,
|
||||||
"CHACHA20": 3,
|
"CHACHA20_POLY1305": 3,
|
||||||
"CHACHA20_IETF": 4,
|
"NONE": 4,
|
||||||
"AES_128_GCM": 5,
|
|
||||||
"AES_256_GCM": 6,
|
|
||||||
"CHACHA20_POLY1305": 7,
|
|
||||||
"NONE": 8,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -299,24 +287,19 @@ var file_proxy_shadowsocks_config_proto_rawDesc = []byte{
|
|||||||
0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
|
0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
|
||||||
0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72,
|
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, 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,
|
0x76, 0x65, 0x72, 0x2a, 0x5c, 0x0a, 0x0a, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x54, 0x79, 0x70,
|
||||||
0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
|
0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0f,
|
||||||
0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x43, 0x46, 0x42, 0x10, 0x01,
|
0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x01, 0x12,
|
||||||
0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x43, 0x46, 0x42, 0x10,
|
0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x02,
|
||||||
0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x10, 0x03, 0x12,
|
0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c,
|
||||||
0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x49, 0x45, 0x54, 0x46,
|
0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10,
|
||||||
0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43,
|
0x04, 0x42, 0x65, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
||||||
0x4d, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47,
|
0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77,
|
||||||
0x43, 0x4d, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30,
|
0x73, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x01, 0x5a, 0x20, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
||||||
0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x07, 0x12, 0x08, 0x0a, 0x04, 0x4e,
|
0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x73, 0x68,
|
||||||
0x4f, 0x4e, 0x45, 0x10, 0x08, 0x42, 0x65, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72,
|
0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0xaa, 0x02, 0x1c, 0x56, 0x32, 0x52, 0x61,
|
||||||
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x73, 0x68,
|
0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x53, 0x68, 0x61,
|
||||||
0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x50, 0x01, 0x5a, 0x20, 0x76, 0x32, 0x72,
|
0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78,
|
|
||||||
0x79, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x73, 0xaa, 0x02, 0x1c,
|
|
||||||
0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 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 (
|
var (
|
||||||
|
@ -17,14 +17,10 @@ message Account {
|
|||||||
|
|
||||||
enum CipherType {
|
enum CipherType {
|
||||||
UNKNOWN = 0;
|
UNKNOWN = 0;
|
||||||
AES_128_CFB = 1;
|
AES_128_GCM = 1;
|
||||||
AES_256_CFB = 2;
|
AES_256_GCM = 2;
|
||||||
CHACHA20 = 3;
|
CHACHA20_POLY1305 = 3;
|
||||||
CHACHA20_IETF = 4;
|
NONE = 4;
|
||||||
AES_128_GCM = 5;
|
|
||||||
AES_256_GCM = 6;
|
|
||||||
CHACHA20_POLY1305 = 7;
|
|
||||||
NONE = 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message ServerConfig {
|
message ServerConfig {
|
||||||
|
@ -18,6 +18,12 @@ func toAccount(a *Account) protocol.Account {
|
|||||||
return 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) {
|
func TestUDPEncoding(t *testing.T) {
|
||||||
request := &protocol.RequestHeader{
|
request := &protocol.RequestHeader{
|
||||||
Version: Version,
|
Version: Version,
|
||||||
@ -25,10 +31,10 @@ func TestUDPEncoding(t *testing.T) {
|
|||||||
Address: net.LocalHostIP,
|
Address: net.LocalHostIP,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
User: &protocol.MemoryUser{
|
User: &protocol.MemoryUser{
|
||||||
Email: "love@v2ray.com",
|
Email: "love@v2fly.org",
|
||||||
Account: toAccount(&Account{
|
Account: toAccount(&Account{
|
||||||
Password: "shadowsocks-password",
|
Password: "password",
|
||||||
CipherType: CipherType_AES_128_CFB,
|
CipherType: CipherType_AES_128_GCM,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -45,8 +51,8 @@ func TestUDPEncoding(t *testing.T) {
|
|||||||
t.Error("data: ", r)
|
t.Error("data: ", r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if r := cmp.Diff(decodedRequest, request); r != "" {
|
if equalRequestHeader(decodedRequest, request) == false {
|
||||||
t.Error("request: ", r)
|
t.Error("different request")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,10 +68,10 @@ func TestTCPRequest(t *testing.T) {
|
|||||||
Address: net.LocalHostIP,
|
Address: net.LocalHostIP,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
User: &protocol.MemoryUser{
|
User: &protocol.MemoryUser{
|
||||||
Email: "love@v2ray.com",
|
Email: "love@v2fly.org",
|
||||||
Account: toAccount(&Account{
|
Account: toAccount(&Account{
|
||||||
Password: "tcp-password",
|
Password: "tcp-password",
|
||||||
CipherType: CipherType_CHACHA20,
|
CipherType: CipherType_AES_128_GCM,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -78,10 +84,10 @@ func TestTCPRequest(t *testing.T) {
|
|||||||
Address: net.LocalHostIPv6,
|
Address: net.LocalHostIPv6,
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
User: &protocol.MemoryUser{
|
User: &protocol.MemoryUser{
|
||||||
Email: "love@v2ray.com",
|
Email: "love@v2fly.org",
|
||||||
Account: toAccount(&Account{
|
Account: toAccount(&Account{
|
||||||
Password: "password",
|
Password: "password",
|
||||||
CipherType: CipherType_AES_256_CFB,
|
CipherType: CipherType_AES_256_GCM,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -91,13 +97,13 @@ func TestTCPRequest(t *testing.T) {
|
|||||||
request: &protocol.RequestHeader{
|
request: &protocol.RequestHeader{
|
||||||
Version: Version,
|
Version: Version,
|
||||||
Command: protocol.RequestCommandTCP,
|
Command: protocol.RequestCommandTCP,
|
||||||
Address: net.DomainAddress("v2ray.com"),
|
Address: net.DomainAddress("v2fly.org"),
|
||||||
Port: 1234,
|
Port: 1234,
|
||||||
User: &protocol.MemoryUser{
|
User: &protocol.MemoryUser{
|
||||||
Email: "love@v2ray.com",
|
Email: "love@v2fly.org",
|
||||||
Account: toAccount(&Account{
|
Account: toAccount(&Account{
|
||||||
Password: "password",
|
Password: "password",
|
||||||
CipherType: CipherType_CHACHA20_IETF,
|
CipherType: CipherType_CHACHA20_POLY1305,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -119,8 +125,8 @@ func TestTCPRequest(t *testing.T) {
|
|||||||
|
|
||||||
decodedRequest, reader, err := ReadTCPSession(request.User, cache)
|
decodedRequest, reader, err := ReadTCPSession(request.User, cache)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
if r := cmp.Diff(decodedRequest, request); r != "" {
|
if equalRequestHeader(decodedRequest, request) == false {
|
||||||
t.Error("request: ", r)
|
t.Error("different request")
|
||||||
}
|
}
|
||||||
|
|
||||||
decodedData, err := reader.ReadMultiBuffer()
|
decodedData, err := reader.ReadMultiBuffer()
|
||||||
@ -139,7 +145,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
user := &protocol.MemoryUser{
|
user := &protocol.MemoryUser{
|
||||||
Account: toAccount(&Account{
|
Account: toAccount(&Account{
|
||||||
Password: "test-password",
|
Password: "test-password",
|
||||||
CipherType: CipherType_CHACHA20_IETF,
|
CipherType: CipherType_CHACHA20_POLY1305,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
cache := buf.New()
|
cache := buf.New()
|
||||||
@ -149,7 +155,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
Writer: cache,
|
Writer: cache,
|
||||||
Request: &protocol.RequestHeader{
|
Request: &protocol.RequestHeader{
|
||||||
Version: Version,
|
Version: Version,
|
||||||
Address: net.DomainAddress("v2ray.com"),
|
Address: net.DomainAddress("v2fly.org"),
|
||||||
Port: 123,
|
Port: 123,
|
||||||
User: user,
|
User: user,
|
||||||
},
|
},
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,15 @@
|
|||||||
package scenarios
|
package scenarios
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/app/log"
|
"v2ray.com/core/app/log"
|
||||||
"v2ray.com/core/app/proxyman"
|
"v2ray.com/core/app/proxyman"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/errors"
|
|
||||||
clog "v2ray.com/core/common/log"
|
clog "v2ray.com/core/common/log"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
@ -24,330 +21,7 @@ import (
|
|||||||
"v2ray.com/core/testing/servers/udp"
|
"v2ray.com/core/testing/servers/udp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShadowsocksAES256TCP(t *testing.T) {
|
func TestShadowsocksChaCha20Poly1305TCP(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{
|
|
||||||
User: &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{
|
|
||||||
User: &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{
|
|
||||||
User: &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) {
|
|
||||||
tcpServer := tcp.Server{
|
tcpServer := tcp.Server{
|
||||||
MsgProcessor: xor,
|
MsgProcessor: xor,
|
||||||
}
|
}
|
||||||
@ -395,9 +69,7 @@ func TestShadowsocksChacha20Poly1305TCP(t *testing.T) {
|
|||||||
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
||||||
Address: net.NewIPOrDomain(dest.Address),
|
Address: net.NewIPOrDomain(dest.Address),
|
||||||
Port: uint32(dest.Port),
|
Port: uint32(dest.Port),
|
||||||
NetworkList: &net.NetworkList{
|
Networks: []net.Network{net.Network_TCP},
|
||||||
Network: []net.Network{net.Network_TCP},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -424,11 +96,11 @@ func TestShadowsocksChacha20Poly1305TCP(t *testing.T) {
|
|||||||
common.Must(err)
|
common.Must(err)
|
||||||
defer CloseAllServers(servers)
|
defer CloseAllServers(servers)
|
||||||
|
|
||||||
var errg errgroup.Group
|
var errGroup errgroup.Group
|
||||||
for i := 0; i < 10; i++ {
|
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)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,9 +165,7 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
|||||||
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
||||||
Address: net.NewIPOrDomain(dest.Address),
|
Address: net.NewIPOrDomain(dest.Address),
|
||||||
Port: uint32(dest.Port),
|
Port: uint32(dest.Port),
|
||||||
NetworkList: &net.NetworkList{
|
Networks: []net.Network{net.Network_TCP},
|
||||||
Network: []net.Network{net.Network_TCP},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -522,12 +192,12 @@ func TestShadowsocksAES256GCMTCP(t *testing.T) {
|
|||||||
common.Must(err)
|
common.Must(err)
|
||||||
defer CloseAllServers(servers)
|
defer CloseAllServers(servers)
|
||||||
|
|
||||||
var errg errgroup.Group
|
var errGroup errgroup.Group
|
||||||
for i := 0; i < 10; i++ {
|
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)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -592,9 +262,7 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
|||||||
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
||||||
Address: net.NewIPOrDomain(dest.Address),
|
Address: net.NewIPOrDomain(dest.Address),
|
||||||
Port: uint32(dest.Port),
|
Port: uint32(dest.Port),
|
||||||
NetworkList: &net.NetworkList{
|
Networks: []net.Network{net.Network_UDP},
|
||||||
Network: []net.Network{net.Network_UDP},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -621,11 +289,11 @@ func TestShadowsocksAES128GCMUDP(t *testing.T) {
|
|||||||
common.Must(err)
|
common.Must(err)
|
||||||
defer CloseAllServers(servers)
|
defer CloseAllServers(servers)
|
||||||
|
|
||||||
var errg errgroup.Group
|
var errGroup errgroup.Group
|
||||||
for i := 0; i < 10; i++ {
|
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)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,9 +358,7 @@ func TestShadowsocksAES128GCMUDPMux(t *testing.T) {
|
|||||||
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
||||||
Address: net.NewIPOrDomain(dest.Address),
|
Address: net.NewIPOrDomain(dest.Address),
|
||||||
Port: uint32(dest.Port),
|
Port: uint32(dest.Port),
|
||||||
NetworkList: &net.NetworkList{
|
Networks: []net.Network{net.Network_UDP},
|
||||||
Network: []net.Network{net.Network_UDP},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -725,11 +391,11 @@ func TestShadowsocksAES128GCMUDPMux(t *testing.T) {
|
|||||||
common.Must(err)
|
common.Must(err)
|
||||||
defer CloseAllServers(servers)
|
defer CloseAllServers(servers)
|
||||||
|
|
||||||
var errg errgroup.Group
|
var errGroup errgroup.Group
|
||||||
for i := 0; i < 10; i++ {
|
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)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -783,9 +449,7 @@ func TestShadowsocksNone(t *testing.T) {
|
|||||||
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
||||||
Address: net.NewIPOrDomain(dest.Address),
|
Address: net.NewIPOrDomain(dest.Address),
|
||||||
Port: uint32(dest.Port),
|
Port: uint32(dest.Port),
|
||||||
NetworkList: &net.NetworkList{
|
Networks: []net.Network{net.Network_TCP},
|
||||||
Network: []net.Network{net.Network_TCP},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -813,12 +477,12 @@ func TestShadowsocksNone(t *testing.T) {
|
|||||||
|
|
||||||
defer CloseAllServers(servers)
|
defer CloseAllServers(servers)
|
||||||
|
|
||||||
var errg errgroup.Group
|
var errGroup errgroup.Group
|
||||||
for i := 0; i < 10; i++ {
|
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)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user