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