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  }