github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/v4/shadowsocks.go (about)

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