github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/infra/conf/vmess.go (about) 1 package conf 2 3 import ( 4 "encoding/json" 5 "strings" 6 7 "github.com/xtls/xray-core/common/protocol" 8 "github.com/xtls/xray-core/common/serial" 9 "github.com/xtls/xray-core/common/uuid" 10 "github.com/xtls/xray-core/proxy/vmess" 11 "github.com/xtls/xray-core/proxy/vmess/inbound" 12 "github.com/xtls/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 if err != nil { 108 return nil, err 109 } 110 account.ID = u.String() 111 112 user.Account = serial.ToTypedMessage(account.Build()) 113 config.User[idx] = user 114 } 115 116 return config, nil 117 } 118 119 type VMessOutboundTarget struct { 120 Address *Address `json:"address"` 121 Port uint16 `json:"port"` 122 Users []json.RawMessage `json:"users"` 123 } 124 125 type VMessOutboundConfig struct { 126 Receivers []*VMessOutboundTarget `json:"vnext"` 127 } 128 129 // Build implements Buildable 130 func (c *VMessOutboundConfig) Build() (proto.Message, error) { 131 config := new(outbound.Config) 132 133 if len(c.Receivers) == 0 { 134 return nil, newError("0 VMess receiver configured") 135 } 136 serverSpecs := make([]*protocol.ServerEndpoint, len(c.Receivers)) 137 for idx, rec := range c.Receivers { 138 if len(rec.Users) == 0 { 139 return nil, newError("0 user configured for VMess outbound") 140 } 141 if rec.Address == nil { 142 return nil, newError("address is not set in VMess outbound config") 143 } 144 spec := &protocol.ServerEndpoint{ 145 Address: rec.Address.Build(), 146 Port: uint32(rec.Port), 147 } 148 for _, rawUser := range rec.Users { 149 user := new(protocol.User) 150 if err := json.Unmarshal(rawUser, user); err != nil { 151 return nil, newError("invalid VMess user").Base(err) 152 } 153 account := new(VMessAccount) 154 if err := json.Unmarshal(rawUser, account); err != nil { 155 return nil, newError("invalid VMess user").Base(err) 156 } 157 158 u, err := uuid.ParseString(account.ID) 159 if err != nil { 160 return nil, err 161 } 162 account.ID = u.String() 163 164 user.Account = serial.ToTypedMessage(account.Build()) 165 spec.User = append(spec.User, user) 166 } 167 serverSpecs[idx] = spec 168 } 169 config.Receiver = serverSpecs 170 return config, nil 171 }