github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/conf/v2ray.go (about) 1 package conf 2 3 import ( 4 "encoding/json" 5 "log" 6 "os" 7 "strings" 8 9 "v2ray.com/core" 10 "v2ray.com/core/app/dispatcher" 11 "v2ray.com/core/app/proxyman" 12 "v2ray.com/core/app/stats" 13 "v2ray.com/core/common/serial" 14 "v2ray.com/core/transport/internet/xtls" 15 ) 16 17 var ( 18 inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ 19 "dokodemo-door": func() interface{} { return new(DokodemoConfig) }, 20 "http": func() interface{} { return new(HttpServerConfig) }, 21 "shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) }, 22 "socks": func() interface{} { return new(SocksServerConfig) }, 23 "vless": func() interface{} { return new(VLessInboundConfig) }, 24 "vmess": func() interface{} { return new(VMessInboundConfig) }, 25 "trojan": func() interface{} { return new(TrojanServerConfig) }, 26 "mtproto": func() interface{} { return new(MTProtoServerConfig) }, 27 }, "protocol", "settings") 28 29 outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ 30 "blackhole": func() interface{} { return new(BlackholeConfig) }, 31 "freedom": func() interface{} { return new(FreedomConfig) }, 32 "http": func() interface{} { return new(HttpClientConfig) }, 33 "shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) }, 34 "socks": func() interface{} { return new(SocksClientConfig) }, 35 "vless": func() interface{} { return new(VLessOutboundConfig) }, 36 "vmess": func() interface{} { return new(VMessOutboundConfig) }, 37 "trojan": func() interface{} { return new(TrojanClientConfig) }, 38 "mtproto": func() interface{} { return new(MTProtoClientConfig) }, 39 "dns": func() interface{} { return new(DnsOutboundConfig) }, 40 }, "protocol", "settings") 41 42 ctllog = log.New(os.Stderr, "v2ctl> ", 0) 43 ) 44 45 func toProtocolList(s []string) ([]proxyman.KnownProtocols, error) { 46 kp := make([]proxyman.KnownProtocols, 0, 8) 47 for _, p := range s { 48 switch strings.ToLower(p) { 49 case "http": 50 kp = append(kp, proxyman.KnownProtocols_HTTP) 51 case "https", "tls", "ssl": 52 kp = append(kp, proxyman.KnownProtocols_TLS) 53 default: 54 return nil, newError("Unknown protocol: ", p) 55 } 56 } 57 return kp, nil 58 } 59 60 type SniffingConfig struct { 61 Enabled bool `json:"enabled"` 62 DestOverride *StringList `json:"destOverride"` 63 } 64 65 // Build implements Buildable. 66 func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) { 67 var p []string 68 if c.DestOverride != nil { 69 for _, domainOverride := range *c.DestOverride { 70 switch strings.ToLower(domainOverride) { 71 case "http": 72 p = append(p, "http") 73 case "tls", "https", "ssl": 74 p = append(p, "tls") 75 default: 76 return nil, newError("unknown protocol: ", domainOverride) 77 } 78 } 79 } 80 81 return &proxyman.SniffingConfig{ 82 Enabled: c.Enabled, 83 DestinationOverride: p, 84 }, nil 85 } 86 87 type MuxConfig struct { 88 Enabled bool `json:"enabled"` 89 Concurrency int16 `json:"concurrency"` 90 } 91 92 // Build creates MultiplexingConfig, Concurrency < 0 completely disables mux. 93 func (m *MuxConfig) Build() *proxyman.MultiplexingConfig { 94 if m.Concurrency < 0 { 95 return nil 96 } 97 98 var con uint32 = 8 99 if m.Concurrency > 0 { 100 con = uint32(m.Concurrency) 101 } 102 103 return &proxyman.MultiplexingConfig{ 104 Enabled: m.Enabled, 105 Concurrency: con, 106 } 107 } 108 109 type InboundDetourAllocationConfig struct { 110 Strategy string `json:"strategy"` 111 Concurrency *uint32 `json:"concurrency"` 112 RefreshMin *uint32 `json:"refresh"` 113 } 114 115 // Build implements Buildable. 116 func (c *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, error) { 117 config := new(proxyman.AllocationStrategy) 118 switch strings.ToLower(c.Strategy) { 119 case "always": 120 config.Type = proxyman.AllocationStrategy_Always 121 case "random": 122 config.Type = proxyman.AllocationStrategy_Random 123 case "external": 124 config.Type = proxyman.AllocationStrategy_External 125 default: 126 return nil, newError("unknown allocation strategy: ", c.Strategy) 127 } 128 if c.Concurrency != nil { 129 config.Concurrency = &proxyman.AllocationStrategy_AllocationStrategyConcurrency{ 130 Value: *c.Concurrency, 131 } 132 } 133 134 if c.RefreshMin != nil { 135 config.Refresh = &proxyman.AllocationStrategy_AllocationStrategyRefresh{ 136 Value: *c.RefreshMin, 137 } 138 } 139 140 return config, nil 141 } 142 143 type InboundDetourConfig struct { 144 Protocol string `json:"protocol"` 145 PortRange *PortRange `json:"port"` 146 ListenOn *Address `json:"listen"` 147 Settings *json.RawMessage `json:"settings"` 148 Tag string `json:"tag"` 149 Allocation *InboundDetourAllocationConfig `json:"allocate"` 150 StreamSetting *StreamConfig `json:"streamSettings"` 151 DomainOverride *StringList `json:"domainOverride"` 152 SniffingConfig *SniffingConfig `json:"sniffing"` 153 } 154 155 // Build implements Buildable. 156 func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) { 157 receiverSettings := &proxyman.ReceiverConfig{} 158 159 if c.PortRange == nil { 160 return nil, newError("port range not specified in InboundDetour.") 161 } 162 receiverSettings.PortRange = c.PortRange.Build() 163 164 if c.ListenOn != nil { 165 if c.ListenOn.Family().IsDomain() { 166 return nil, newError("unable to listen on domain address: ", c.ListenOn.Domain()) 167 } 168 receiverSettings.Listen = c.ListenOn.Build() 169 } 170 if c.Allocation != nil { 171 concurrency := -1 172 if c.Allocation.Concurrency != nil && c.Allocation.Strategy == "random" { 173 concurrency = int(*c.Allocation.Concurrency) 174 } 175 portRange := int(c.PortRange.To - c.PortRange.From + 1) 176 if concurrency >= 0 && concurrency >= portRange { 177 return nil, newError("not enough ports. concurrency = ", concurrency, " ports: ", c.PortRange.From, " - ", c.PortRange.To) 178 } 179 180 as, err := c.Allocation.Build() 181 if err != nil { 182 return nil, err 183 } 184 receiverSettings.AllocationStrategy = as 185 } 186 if c.StreamSetting != nil { 187 ss, err := c.StreamSetting.Build() 188 if err != nil { 189 return nil, err 190 } 191 if ss.SecurityType == serial.GetMessageType(&xtls.Config{}) && !strings.EqualFold(c.Protocol, "vless") { 192 return nil, newError("XTLS only supports VLESS for now.") 193 } 194 receiverSettings.StreamSettings = ss 195 } 196 if c.SniffingConfig != nil { 197 s, err := c.SniffingConfig.Build() 198 if err != nil { 199 return nil, newError("failed to build sniffing config").Base(err) 200 } 201 receiverSettings.SniffingSettings = s 202 } 203 if c.DomainOverride != nil { 204 kp, err := toProtocolList(*c.DomainOverride) 205 if err != nil { 206 return nil, newError("failed to parse inbound detour config").Base(err) 207 } 208 receiverSettings.DomainOverride = kp 209 } 210 211 settings := []byte("{}") 212 if c.Settings != nil { 213 settings = ([]byte)(*c.Settings) 214 } 215 rawConfig, err := inboundConfigLoader.LoadWithID(settings, c.Protocol) 216 if err != nil { 217 return nil, newError("failed to load inbound detour config.").Base(err) 218 } 219 if dokodemoConfig, ok := rawConfig.(*DokodemoConfig); ok { 220 receiverSettings.ReceiveOriginalDestination = dokodemoConfig.Redirect 221 } 222 ts, err := rawConfig.(Buildable).Build() 223 if err != nil { 224 return nil, err 225 } 226 227 return &core.InboundHandlerConfig{ 228 Tag: c.Tag, 229 ReceiverSettings: serial.ToTypedMessage(receiverSettings), 230 ProxySettings: serial.ToTypedMessage(ts), 231 }, nil 232 } 233 234 type OutboundDetourConfig struct { 235 Protocol string `json:"protocol"` 236 SendThrough *Address `json:"sendThrough"` 237 Tag string `json:"tag"` 238 Settings *json.RawMessage `json:"settings"` 239 StreamSetting *StreamConfig `json:"streamSettings"` 240 ProxySettings *ProxyConfig `json:"proxySettings"` 241 MuxSettings *MuxConfig `json:"mux"` 242 } 243 244 // Build implements Buildable. 245 func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) { 246 senderSettings := &proxyman.SenderConfig{} 247 248 if c.SendThrough != nil { 249 address := c.SendThrough 250 if address.Family().IsDomain() { 251 return nil, newError("unable to send through: " + address.String()) 252 } 253 senderSettings.Via = address.Build() 254 } 255 256 if c.StreamSetting != nil { 257 ss, err := c.StreamSetting.Build() 258 if err != nil { 259 return nil, err 260 } 261 if ss.SecurityType == serial.GetMessageType(&xtls.Config{}) && !strings.EqualFold(c.Protocol, "vless") { 262 return nil, newError("XTLS only supports VLESS for now.") 263 } 264 senderSettings.StreamSettings = ss 265 } 266 267 if c.ProxySettings != nil { 268 ps, err := c.ProxySettings.Build() 269 if err != nil { 270 return nil, newError("invalid outbound detour proxy settings.").Base(err) 271 } 272 senderSettings.ProxySettings = ps 273 } 274 275 if c.MuxSettings != nil { 276 ms := c.MuxSettings.Build() 277 if ms != nil && ms.Enabled { 278 if ss := senderSettings.StreamSettings; ss != nil { 279 if ss.SecurityType == serial.GetMessageType(&xtls.Config{}) { 280 return nil, newError("XTLS doesn't support Mux for now.") 281 } 282 } 283 } 284 senderSettings.MultiplexSettings = ms 285 } 286 287 settings := []byte("{}") 288 if c.Settings != nil { 289 settings = ([]byte)(*c.Settings) 290 } 291 rawConfig, err := outboundConfigLoader.LoadWithID(settings, c.Protocol) 292 if err != nil { 293 return nil, newError("failed to parse to outbound detour config.").Base(err) 294 } 295 ts, err := rawConfig.(Buildable).Build() 296 if err != nil { 297 return nil, err 298 } 299 300 return &core.OutboundHandlerConfig{ 301 SenderSettings: serial.ToTypedMessage(senderSettings), 302 Tag: c.Tag, 303 ProxySettings: serial.ToTypedMessage(ts), 304 }, nil 305 } 306 307 type StatsConfig struct{} 308 309 // Build implements Buildable. 310 func (c *StatsConfig) Build() (*stats.Config, error) { 311 return &stats.Config{}, nil 312 } 313 314 type Config struct { 315 Port uint16 `json:"port"` // Port of this Point server. Deprecated. 316 LogConfig *LogConfig `json:"log"` 317 RouterConfig *RouterConfig `json:"routing"` 318 DNSConfig *DnsConfig `json:"dns"` 319 InboundConfigs []InboundDetourConfig `json:"inbounds"` 320 OutboundConfigs []OutboundDetourConfig `json:"outbounds"` 321 InboundConfig *InboundDetourConfig `json:"inbound"` // Deprecated. 322 OutboundConfig *OutboundDetourConfig `json:"outbound"` // Deprecated. 323 InboundDetours []InboundDetourConfig `json:"inboundDetour"` // Deprecated. 324 OutboundDetours []OutboundDetourConfig `json:"outboundDetour"` // Deprecated. 325 Transport *TransportConfig `json:"transport"` 326 Policy *PolicyConfig `json:"policy"` 327 Api *ApiConfig `json:"api"` 328 Stats *StatsConfig `json:"stats"` 329 Reverse *ReverseConfig `json:"reverse"` 330 } 331 332 func (c *Config) findInboundTag(tag string) int { 333 found := -1 334 for idx, ib := range c.InboundConfigs { 335 if ib.Tag == tag { 336 found = idx 337 break 338 } 339 } 340 return found 341 } 342 343 func (c *Config) findOutboundTag(tag string) int { 344 found := -1 345 for idx, ob := range c.OutboundConfigs { 346 if ob.Tag == tag { 347 found = idx 348 break 349 } 350 } 351 return found 352 } 353 354 // Override method accepts another Config overrides the current attribute 355 func (c *Config) Override(o *Config, fn string) { 356 357 // only process the non-deprecated members 358 359 if o.LogConfig != nil { 360 c.LogConfig = o.LogConfig 361 } 362 if o.RouterConfig != nil { 363 c.RouterConfig = o.RouterConfig 364 } 365 if o.DNSConfig != nil { 366 c.DNSConfig = o.DNSConfig 367 } 368 if o.Transport != nil { 369 c.Transport = o.Transport 370 } 371 if o.Policy != nil { 372 c.Policy = o.Policy 373 } 374 if o.Api != nil { 375 c.Api = o.Api 376 } 377 if o.Stats != nil { 378 c.Stats = o.Stats 379 } 380 if o.Reverse != nil { 381 c.Reverse = o.Reverse 382 } 383 384 // deprecated attrs... keep them for now 385 if o.InboundConfig != nil { 386 c.InboundConfig = o.InboundConfig 387 } 388 if o.OutboundConfig != nil { 389 c.OutboundConfig = o.OutboundConfig 390 } 391 if o.InboundDetours != nil { 392 c.InboundDetours = o.InboundDetours 393 } 394 if o.OutboundDetours != nil { 395 c.OutboundDetours = o.OutboundDetours 396 } 397 // deprecated attrs 398 399 // update the Inbound in slice if the only one in overide config has same tag 400 if len(o.InboundConfigs) > 0 { 401 if len(c.InboundConfigs) > 0 && len(o.InboundConfigs) == 1 { 402 if idx := c.findInboundTag(o.InboundConfigs[0].Tag); idx > -1 { 403 c.InboundConfigs[idx] = o.InboundConfigs[0] 404 ctllog.Println("[", fn, "] updated inbound with tag: ", o.InboundConfigs[0].Tag) 405 } else { 406 c.InboundConfigs = append(c.InboundConfigs, o.InboundConfigs[0]) 407 ctllog.Println("[", fn, "] appended inbound with tag: ", o.InboundConfigs[0].Tag) 408 } 409 } else { 410 c.InboundConfigs = o.InboundConfigs 411 } 412 } 413 414 // update the Outbound in slice if the only one in overide config has same tag 415 if len(o.OutboundConfigs) > 0 { 416 if len(c.OutboundConfigs) > 0 && len(o.OutboundConfigs) == 1 { 417 if idx := c.findOutboundTag(o.OutboundConfigs[0].Tag); idx > -1 { 418 c.OutboundConfigs[idx] = o.OutboundConfigs[0] 419 ctllog.Println("[", fn, "] updated outbound with tag: ", o.OutboundConfigs[0].Tag) 420 } else { 421 if strings.Contains(strings.ToLower(fn), "tail") { 422 c.OutboundConfigs = append(c.OutboundConfigs, o.OutboundConfigs[0]) 423 ctllog.Println("[", fn, "] appended outbound with tag: ", o.OutboundConfigs[0].Tag) 424 } else { 425 c.OutboundConfigs = append(o.OutboundConfigs, c.OutboundConfigs...) 426 ctllog.Println("[", fn, "] prepended outbound with tag: ", o.OutboundConfigs[0].Tag) 427 } 428 } 429 } else { 430 c.OutboundConfigs = o.OutboundConfigs 431 } 432 } 433 } 434 435 func applyTransportConfig(s *StreamConfig, t *TransportConfig) { 436 if s.TCPSettings == nil { 437 s.TCPSettings = t.TCPConfig 438 } 439 if s.KCPSettings == nil { 440 s.KCPSettings = t.KCPConfig 441 } 442 if s.WSSettings == nil { 443 s.WSSettings = t.WSConfig 444 } 445 if s.HTTPSettings == nil { 446 s.HTTPSettings = t.HTTPConfig 447 } 448 if s.DSSettings == nil { 449 s.DSSettings = t.DSConfig 450 } 451 } 452 453 // Build implements Buildable. 454 func (c *Config) Build() (*core.Config, error) { 455 config := &core.Config{ 456 App: []*serial.TypedMessage{ 457 serial.ToTypedMessage(&dispatcher.Config{}), 458 serial.ToTypedMessage(&proxyman.InboundConfig{}), 459 serial.ToTypedMessage(&proxyman.OutboundConfig{}), 460 }, 461 } 462 463 if c.Api != nil { 464 apiConf, err := c.Api.Build() 465 if err != nil { 466 return nil, err 467 } 468 config.App = append(config.App, serial.ToTypedMessage(apiConf)) 469 } 470 471 if c.Stats != nil { 472 statsConf, err := c.Stats.Build() 473 if err != nil { 474 return nil, err 475 } 476 config.App = append(config.App, serial.ToTypedMessage(statsConf)) 477 } 478 479 var logConfMsg *serial.TypedMessage 480 if c.LogConfig != nil { 481 logConfMsg = serial.ToTypedMessage(c.LogConfig.Build()) 482 } else { 483 logConfMsg = serial.ToTypedMessage(DefaultLogConfig()) 484 } 485 // let logger module be the first App to start, 486 // so that other modules could print log during initiating 487 config.App = append([]*serial.TypedMessage{logConfMsg}, config.App...) 488 489 if c.RouterConfig != nil { 490 routerConfig, err := c.RouterConfig.Build() 491 if err != nil { 492 return nil, err 493 } 494 config.App = append(config.App, serial.ToTypedMessage(routerConfig)) 495 } 496 497 if c.DNSConfig != nil { 498 dnsApp, err := c.DNSConfig.Build() 499 if err != nil { 500 return nil, newError("failed to parse DNS config").Base(err) 501 } 502 config.App = append(config.App, serial.ToTypedMessage(dnsApp)) 503 } 504 505 if c.Policy != nil { 506 pc, err := c.Policy.Build() 507 if err != nil { 508 return nil, err 509 } 510 config.App = append(config.App, serial.ToTypedMessage(pc)) 511 } 512 513 if c.Reverse != nil { 514 r, err := c.Reverse.Build() 515 if err != nil { 516 return nil, err 517 } 518 config.App = append(config.App, serial.ToTypedMessage(r)) 519 } 520 521 var inbounds []InboundDetourConfig 522 523 if c.InboundConfig != nil { 524 inbounds = append(inbounds, *c.InboundConfig) 525 } 526 527 if len(c.InboundDetours) > 0 { 528 inbounds = append(inbounds, c.InboundDetours...) 529 } 530 531 if len(c.InboundConfigs) > 0 { 532 inbounds = append(inbounds, c.InboundConfigs...) 533 } 534 535 // Backward compatibility. 536 if len(inbounds) > 0 && inbounds[0].PortRange == nil && c.Port > 0 { 537 inbounds[0].PortRange = &PortRange{ 538 From: uint32(c.Port), 539 To: uint32(c.Port), 540 } 541 } 542 543 for _, rawInboundConfig := range inbounds { 544 if c.Transport != nil { 545 if rawInboundConfig.StreamSetting == nil { 546 rawInboundConfig.StreamSetting = &StreamConfig{} 547 } 548 applyTransportConfig(rawInboundConfig.StreamSetting, c.Transport) 549 } 550 ic, err := rawInboundConfig.Build() 551 if err != nil { 552 return nil, err 553 } 554 config.Inbound = append(config.Inbound, ic) 555 } 556 557 var outbounds []OutboundDetourConfig 558 559 if c.OutboundConfig != nil { 560 outbounds = append(outbounds, *c.OutboundConfig) 561 } 562 563 if len(c.OutboundDetours) > 0 { 564 outbounds = append(outbounds, c.OutboundDetours...) 565 } 566 567 if len(c.OutboundConfigs) > 0 { 568 outbounds = append(outbounds, c.OutboundConfigs...) 569 } 570 571 for _, rawOutboundConfig := range outbounds { 572 if c.Transport != nil { 573 if rawOutboundConfig.StreamSetting == nil { 574 rawOutboundConfig.StreamSetting = &StreamConfig{} 575 } 576 applyTransportConfig(rawOutboundConfig.StreamSetting, c.Transport) 577 } 578 oc, err := rawOutboundConfig.Build() 579 if err != nil { 580 return nil, err 581 } 582 config.Outbound = append(config.Outbound, oc) 583 } 584 585 return config, nil 586 }