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