vmess.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package conf
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "github.com/xtls/xray-core/common/errors"
  6. "github.com/xtls/xray-core/common/protocol"
  7. "github.com/xtls/xray-core/common/serial"
  8. "github.com/xtls/xray-core/common/uuid"
  9. "github.com/xtls/xray-core/proxy/vmess"
  10. "github.com/xtls/xray-core/proxy/vmess/inbound"
  11. "github.com/xtls/xray-core/proxy/vmess/outbound"
  12. "google.golang.org/protobuf/proto"
  13. )
  14. type VMessAccount struct {
  15. ID string `json:"id"`
  16. Security string `json:"security"`
  17. Experiments string `json:"experiments"`
  18. }
  19. // Build implements Buildable
  20. func (a *VMessAccount) Build() *vmess.Account {
  21. var st protocol.SecurityType
  22. switch strings.ToLower(a.Security) {
  23. case "aes-128-gcm":
  24. st = protocol.SecurityType_AES128_GCM
  25. case "chacha20-poly1305":
  26. st = protocol.SecurityType_CHACHA20_POLY1305
  27. case "auto":
  28. st = protocol.SecurityType_AUTO
  29. case "none":
  30. st = protocol.SecurityType_NONE
  31. case "zero":
  32. st = protocol.SecurityType_ZERO
  33. default:
  34. st = protocol.SecurityType_AUTO
  35. }
  36. return &vmess.Account{
  37. Id: a.ID,
  38. SecuritySettings: &protocol.SecurityConfig{
  39. Type: st,
  40. },
  41. TestsEnabled: a.Experiments,
  42. }
  43. }
  44. type VMessDefaultConfig struct {
  45. Level byte `json:"level"`
  46. }
  47. // Build implements Buildable
  48. func (c *VMessDefaultConfig) Build() *inbound.DefaultConfig {
  49. config := new(inbound.DefaultConfig)
  50. config.Level = uint32(c.Level)
  51. return config
  52. }
  53. type VMessInboundConfig struct {
  54. Users []json.RawMessage `json:"clients"`
  55. Defaults *VMessDefaultConfig `json:"default"`
  56. }
  57. // Build implements Buildable
  58. func (c *VMessInboundConfig) Build() (proto.Message, error) {
  59. config := &inbound.Config{}
  60. if c.Defaults != nil {
  61. config.Default = c.Defaults.Build()
  62. }
  63. config.User = make([]*protocol.User, len(c.Users))
  64. for idx, rawData := range c.Users {
  65. user := new(protocol.User)
  66. if err := json.Unmarshal(rawData, user); err != nil {
  67. return nil, errors.New("invalid VMess user").Base(err)
  68. }
  69. account := new(VMessAccount)
  70. if err := json.Unmarshal(rawData, account); err != nil {
  71. return nil, errors.New("invalid VMess user").Base(err)
  72. }
  73. u, err := uuid.ParseString(account.ID)
  74. if err != nil {
  75. return nil, err
  76. }
  77. account.ID = u.String()
  78. user.Account = serial.ToTypedMessage(account.Build())
  79. config.User[idx] = user
  80. }
  81. return config, nil
  82. }
  83. type VMessOutboundTarget struct {
  84. Address *Address `json:"address"`
  85. Port uint16 `json:"port"`
  86. Users []json.RawMessage `json:"users"`
  87. }
  88. type VMessOutboundConfig struct {
  89. Address *Address `json:"address"`
  90. Port uint16 `json:"port"`
  91. Level uint32 `json:"level"`
  92. Email string `json:"email"`
  93. ID string `json:"id"`
  94. Security string `json:"security"`
  95. Experiments string `json:"experiments"`
  96. Receivers []*VMessOutboundTarget `json:"vnext"`
  97. }
  98. // Build implements Buildable
  99. func (c *VMessOutboundConfig) Build() (proto.Message, error) {
  100. config := new(outbound.Config)
  101. if c.Address != nil {
  102. c.Receivers = []*VMessOutboundTarget{
  103. {
  104. Address: c.Address,
  105. Port: c.Port,
  106. Users: []json.RawMessage{{}},
  107. },
  108. }
  109. }
  110. if len(c.Receivers) != 1 {
  111. return nil, errors.New(`VMess settings: "vnext" should have one and only one member. Multiple endpoints in "vnext" should use multiple VMess outbounds and routing balancer instead`)
  112. }
  113. for _, rec := range c.Receivers {
  114. if len(rec.Users) != 1 {
  115. return nil, errors.New(`VMess vnext: "users" should have one and only one member. Multiple members in "users" should use multiple VMess outbounds and routing balancer instead`)
  116. }
  117. if rec.Address == nil {
  118. return nil, errors.New(`VMess vnext: "address" is not set`)
  119. }
  120. spec := &protocol.ServerEndpoint{
  121. Address: rec.Address.Build(),
  122. Port: uint32(rec.Port),
  123. }
  124. for _, rawUser := range rec.Users {
  125. user := new(protocol.User)
  126. if c.Address != nil {
  127. user.Level = c.Level
  128. user.Email = c.Email
  129. } else {
  130. if err := json.Unmarshal(rawUser, user); err != nil {
  131. return nil, errors.New("invalid VMess user").Base(err)
  132. }
  133. }
  134. account := new(VMessAccount)
  135. if c.Address != nil {
  136. account.ID = c.ID
  137. account.Security = c.Security
  138. account.Experiments = c.Experiments
  139. } else {
  140. if err := json.Unmarshal(rawUser, account); err != nil {
  141. return nil, errors.New("invalid VMess user").Base(err)
  142. }
  143. }
  144. u, err := uuid.ParseString(account.ID)
  145. if err != nil {
  146. return nil, err
  147. }
  148. account.ID = u.String()
  149. user.Account = serial.ToTypedMessage(account.Build())
  150. spec.User = user
  151. break
  152. }
  153. config.Receiver = spec
  154. break
  155. }
  156. return config, nil
  157. }