1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-18 10:26:01 -05:00
v2fly/infra/conf/shadowsocks.go
Kirill Motkov 0401a91ef4 Some code improvements
* Rewrite empty string checks more idiomatically.
* Change strings.ToLower comparisons to strings.EqualFold.
* Rewrite switch statement with only one case as if.
2019-06-28 17:53:44 +03:00

140 lines
3.6 KiB
Go

package conf
import (
"strings"
"github.com/golang/protobuf/proto"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy/shadowsocks"
)
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":
return shadowsocks.CipherType_AES_256_GCM
case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305":
return shadowsocks.CipherType_CHACHA20_POLY1305
default:
return shadowsocks.CipherType_UNKNOWN
}
}
type ShadowsocksServerConfig struct {
Cipher string `json:"method"`
Password string `json:"password"`
UDP bool `json:"udp"`
Level byte `json:"level"`
Email string `json:"email"`
OTA *bool `json:"ota"`
NetworkList *NetworkList `json:"network"`
}
func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
config := new(shadowsocks.ServerConfig)
config.UdpEnabled = v.UDP
config.Network = v.NetworkList.Build()
if v.Password == "" {
return nil, newError("Shadowsocks password is not specified.")
}
account := &shadowsocks.Account{
Password: v.Password,
Ota: shadowsocks.Account_Auto,
}
if v.OTA != nil {
if *v.OTA {
account.Ota = shadowsocks.Account_Enabled
} else {
account.Ota = shadowsocks.Account_Disabled
}
}
account.CipherType = cipherFromString(v.Cipher)
if account.CipherType == shadowsocks.CipherType_UNKNOWN {
return nil, newError("unknown cipher method: ", v.Cipher)
}
config.User = &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"`
Ota bool `json:"ota"`
Level byte `json:"level"`
}
type ShadowsocksClientConfig struct {
Servers []*ShadowsocksServerTarget `json:"servers"`
}
func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
config := new(shadowsocks.ClientConfig)
if len(v.Servers) == 0 {
return nil, newError("0 Shadowsocks server configured.")
}
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,
Ota: shadowsocks.Account_Enabled,
}
if !server.Ota {
account.Ota = shadowsocks.Account_Disabled
}
account.CipherType = cipherFromString(server.Cipher)
if account.CipherType == shadowsocks.CipherType_UNKNOWN {
return nil, newError("unknown cipher method: ", server.Cipher)
}
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
}