router.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package conf
  2. import (
  3. "context"
  4. "encoding/json"
  5. "strings"
  6. "github.com/v2fly/v2ray-core/v4/common/platform"
  7. "github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
  8. "github.com/v2fly/v2ray-core/v4/infra/conf/geodata"
  9. rule2 "github.com/v2fly/v2ray-core/v4/infra/conf/rule"
  10. "github.com/v2fly/v2ray-core/v4/app/router"
  11. )
  12. type RouterRulesConfig struct {
  13. RuleList []json.RawMessage `json:"rules"`
  14. DomainStrategy string `json:"domainStrategy"`
  15. }
  16. // StrategyConfig represents a strategy config
  17. type StrategyConfig struct {
  18. Type string `json:"type"`
  19. Settings *json.RawMessage `json:"settings"`
  20. }
  21. type BalancingRule struct {
  22. Tag string `json:"tag"`
  23. Selectors cfgcommon.StringList `json:"selector"`
  24. Strategy StrategyConfig `json:"strategy"`
  25. }
  26. func (r *BalancingRule) Build() (*router.BalancingRule, error) {
  27. if r.Tag == "" {
  28. return nil, newError("empty balancer tag")
  29. }
  30. if len(r.Selectors) == 0 {
  31. return nil, newError("empty selector list")
  32. }
  33. var strategy string
  34. switch strings.ToLower(r.Strategy.Type) {
  35. case strategyRandom, "":
  36. strategy = strategyRandom
  37. case strategyLeastPing:
  38. strategy = "leastPing"
  39. default:
  40. return nil, newError("unknown balancing strategy: " + r.Strategy.Type)
  41. }
  42. return &router.BalancingRule{
  43. Tag: r.Tag,
  44. OutboundSelector: []string(r.Selectors),
  45. Strategy: strategy,
  46. }, nil
  47. }
  48. type RouterConfig struct {
  49. Settings *RouterRulesConfig `json:"settings"` // Deprecated
  50. RuleList []json.RawMessage `json:"rules"`
  51. DomainStrategy *string `json:"domainStrategy"`
  52. Balancers []*BalancingRule `json:"balancers"`
  53. DomainMatcher string `json:"domainMatcher"`
  54. }
  55. func (c *RouterConfig) getDomainStrategy() router.Config_DomainStrategy {
  56. ds := ""
  57. if c.DomainStrategy != nil {
  58. ds = *c.DomainStrategy
  59. } else if c.Settings != nil {
  60. ds = c.Settings.DomainStrategy
  61. }
  62. switch strings.ToLower(ds) {
  63. case "alwaysip", "always_ip", "always-ip":
  64. return router.Config_UseIp
  65. case "ipifnonmatch", "ip_if_non_match", "ip-if-non-match":
  66. return router.Config_IpIfNonMatch
  67. case "ipondemand", "ip_on_demand", "ip-on-demand":
  68. return router.Config_IpOnDemand
  69. default:
  70. return router.Config_AsIs
  71. }
  72. }
  73. func (c *RouterConfig) Build() (*router.Config, error) {
  74. config := new(router.Config)
  75. config.DomainStrategy = c.getDomainStrategy()
  76. cfgctx := cfgcommon.NewConfigureLoadingContext(context.Background())
  77. geoloadername := platform.NewEnvFlag("v2ray.conf.geoloader").GetValue(func() string {
  78. return "standard"
  79. })
  80. if loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {
  81. cfgcommon.SetGeoDataLoader(cfgctx, loader)
  82. } else {
  83. return nil, newError("unable to create geo data loader ").Base(err)
  84. }
  85. var rawRuleList []json.RawMessage
  86. if c != nil {
  87. rawRuleList = c.RuleList
  88. if c.Settings != nil {
  89. c.RuleList = append(c.RuleList, c.Settings.RuleList...)
  90. rawRuleList = c.RuleList
  91. }
  92. }
  93. for _, rawRule := range rawRuleList {
  94. rule, err := rule2.ParseRule(cfgctx, rawRule)
  95. if err != nil {
  96. return nil, err
  97. }
  98. if rule.DomainMatcher == "" {
  99. rule.DomainMatcher = c.DomainMatcher
  100. }
  101. config.Rule = append(config.Rule, rule)
  102. }
  103. for _, rawBalancer := range c.Balancers {
  104. balancer, err := rawBalancer.Build()
  105. if err != nil {
  106. return nil, err
  107. }
  108. config.BalancingRule = append(config.BalancingRule, balancer)
  109. }
  110. return config, nil
  111. }