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