router.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package conf
  2. import (
  3. "context"
  4. "encoding/json"
  5. "strings"
  6. "github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
  7. "github.com/v2fly/v2ray-core/v4/infra/conf/geodata"
  8. rule2 "github.com/v2fly/v2ray-core/v4/infra/conf/rule"
  9. "github.com/v2fly/v2ray-core/v4/app/router"
  10. )
  11. type RouterRulesConfig struct {
  12. RuleList []json.RawMessage `json:"rules"`
  13. DomainStrategy string `json:"domainStrategy"`
  14. }
  15. // StrategyConfig represents a strategy config
  16. type StrategyConfig struct {
  17. Type string `json:"type"`
  18. Settings *json.RawMessage `json:"settings"`
  19. }
  20. type BalancingRule struct {
  21. Tag string `json:"tag"`
  22. Selectors cfgcommon.StringList `json:"selector"`
  23. Strategy StrategyConfig `json:"strategy"`
  24. }
  25. func (r *BalancingRule) Build() (*router.BalancingRule, error) {
  26. if r.Tag == "" {
  27. return nil, newError("empty balancer tag")
  28. }
  29. if len(r.Selectors) == 0 {
  30. return nil, newError("empty selector list")
  31. }
  32. var strategy string
  33. switch strings.ToLower(r.Strategy.Type) {
  34. case strategyRandom, "":
  35. strategy = strategyRandom
  36. case strategyLeastPing:
  37. strategy = "leastPing"
  38. default:
  39. return nil, newError("unknown balancing strategy: " + r.Strategy.Type)
  40. }
  41. return &router.BalancingRule{
  42. Tag: r.Tag,
  43. OutboundSelector: []string(r.Selectors),
  44. Strategy: strategy,
  45. }, nil
  46. }
  47. type RouterConfig struct {
  48. Settings *RouterRulesConfig `json:"settings"` // Deprecated
  49. RuleList []json.RawMessage `json:"rules"`
  50. DomainStrategy *string `json:"domainStrategy"`
  51. Balancers []*BalancingRule `json:"balancers"`
  52. DomainMatcher string `json:"domainMatcher"`
  53. GeoLoader string `json:"geoLoader"`
  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. if c.GeoLoader == "" {
  78. c.GeoLoader = "standard"
  79. }
  80. if loader, err := geodata.GetGeoDataLoader(c.GeoLoader); 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. }