github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/conf/shadowsocks.go (about)

     1  package conf
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/golang/protobuf/proto"
     7  
     8  	"v2ray.com/core/common/protocol"
     9  	"v2ray.com/core/common/serial"
    10  	"v2ray.com/core/proxy/shadowsocks"
    11  )
    12  
    13  func cipherFromString(c string) shadowsocks.CipherType {
    14  	switch strings.ToLower(c) {
    15  	case "aes-256-cfb":
    16  		return shadowsocks.CipherType_AES_256_CFB
    17  	case "aes-128-cfb":
    18  		return shadowsocks.CipherType_AES_128_CFB
    19  	case "chacha20":
    20  		return shadowsocks.CipherType_CHACHA20
    21  	case "chacha20-ietf":
    22  		return shadowsocks.CipherType_CHACHA20_IETF
    23  	case "aes-128-gcm", "aead_aes_128_gcm":
    24  		return shadowsocks.CipherType_AES_128_GCM
    25  	case "aes-256-gcm", "aead_aes_256_gcm":
    26  		return shadowsocks.CipherType_AES_256_GCM
    27  	case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305":
    28  		return shadowsocks.CipherType_CHACHA20_POLY1305
    29  	case "none", "plain":
    30  		return shadowsocks.CipherType_NONE
    31  	default:
    32  		return shadowsocks.CipherType_UNKNOWN
    33  	}
    34  }
    35  
    36  type ShadowsocksServerConfig struct {
    37  	Cipher      string       `json:"method"`
    38  	Password    string       `json:"password"`
    39  	UDP         bool         `json:"udp"`
    40  	Level       byte         `json:"level"`
    41  	Email       string       `json:"email"`
    42  	NetworkList *NetworkList `json:"network"`
    43  }
    44  
    45  func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
    46  	config := new(shadowsocks.ServerConfig)
    47  	config.UdpEnabled = v.UDP
    48  	config.Network = v.NetworkList.Build()
    49  
    50  	if v.Password == "" {
    51  		return nil, newError("Shadowsocks password is not specified.")
    52  	}
    53  	account := &shadowsocks.Account{
    54  		Password: v.Password,
    55  	}
    56  	account.CipherType = cipherFromString(v.Cipher)
    57  	if account.CipherType == shadowsocks.CipherType_UNKNOWN {
    58  		return nil, newError("unknown cipher method: ", v.Cipher)
    59  	}
    60  
    61  	config.User = &protocol.User{
    62  		Email:   v.Email,
    63  		Level:   uint32(v.Level),
    64  		Account: serial.ToTypedMessage(account),
    65  	}
    66  
    67  	return config, nil
    68  }
    69  
    70  type ShadowsocksServerTarget struct {
    71  	Address  *Address `json:"address"`
    72  	Port     uint16   `json:"port"`
    73  	Cipher   string   `json:"method"`
    74  	Password string   `json:"password"`
    75  	Email    string   `json:"email"`
    76  	Ota      bool     `json:"ota"`
    77  	Level    byte     `json:"level"`
    78  }
    79  
    80  type ShadowsocksClientConfig struct {
    81  	Servers []*ShadowsocksServerTarget `json:"servers"`
    82  }
    83  
    84  func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
    85  	config := new(shadowsocks.ClientConfig)
    86  
    87  	if len(v.Servers) == 0 {
    88  		return nil, newError("0 Shadowsocks server configured.")
    89  	}
    90  
    91  	serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers))
    92  	for idx, server := range v.Servers {
    93  		if server.Address == nil {
    94  			return nil, newError("Shadowsocks server address is not set.")
    95  		}
    96  		if server.Port == 0 {
    97  			return nil, newError("Invalid Shadowsocks port.")
    98  		}
    99  		if server.Password == "" {
   100  			return nil, newError("Shadowsocks password is not specified.")
   101  		}
   102  		account := &shadowsocks.Account{
   103  			Password: server.Password,
   104  		}
   105  		account.CipherType = cipherFromString(server.Cipher)
   106  		if account.CipherType == shadowsocks.CipherType_UNKNOWN {
   107  			return nil, newError("unknown cipher method: ", server.Cipher)
   108  		}
   109  
   110  		ss := &protocol.ServerEndpoint{
   111  			Address: server.Address.Build(),
   112  			Port:    uint32(server.Port),
   113  			User: []*protocol.User{
   114  				{
   115  					Level:   uint32(server.Level),
   116  					Email:   server.Email,
   117  					Account: serial.ToTypedMessage(account),
   118  				},
   119  			},
   120  		}
   121  
   122  		serverSpecs[idx] = ss
   123  	}
   124  
   125  	config.Server = serverSpecs
   126  
   127  	return config, nil
   128  }