shadowsocks.go 3.3 KB

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