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