config_json.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // +build json
  2. package rules
  3. import (
  4. "encoding/json"
  5. "errors"
  6. "strings"
  7. router "github.com/v2ray/v2ray-core/app/router"
  8. "github.com/v2ray/v2ray-core/common/log"
  9. v2net "github.com/v2ray/v2ray-core/common/net"
  10. "github.com/v2ray/v2ray-core/common/serial"
  11. )
  12. type JsonRule struct {
  13. Type string `json:"type"`
  14. OutboundTag string `json:"outboundTag"`
  15. }
  16. func parseFieldRule(msg json.RawMessage) (*Rule, error) {
  17. type RawFieldRule struct {
  18. JsonRule
  19. Domain *serial.StringLiteralList `json:"domain"`
  20. IP *serial.StringLiteralList `json:"ip"`
  21. Port *v2net.PortRange `json:"port"`
  22. Network *v2net.NetworkList `json:"network"`
  23. }
  24. rawFieldRule := new(RawFieldRule)
  25. err := json.Unmarshal(msg, rawFieldRule)
  26. if err != nil {
  27. return nil, err
  28. }
  29. conds := NewConditionChan()
  30. if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
  31. anyCond := NewAnyCondition()
  32. for _, rawDomain := range *(rawFieldRule.Domain) {
  33. var matcher Condition
  34. if strings.HasPrefix(rawDomain.String(), "regexp:") {
  35. rawMatcher, err := NewRegexpDomainMatcher(rawDomain.String()[7:])
  36. if err != nil {
  37. return nil, err
  38. }
  39. matcher = rawMatcher
  40. } else {
  41. matcher = NewPlainDomainMatcher(rawDomain.String())
  42. }
  43. anyCond.Add(matcher)
  44. }
  45. conds.Add(anyCond)
  46. }
  47. if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 {
  48. anyCond := NewAnyCondition()
  49. for _, ipStr := range *(rawFieldRule.IP) {
  50. cidrMatcher, err := NewCIDRMatcher(ipStr.String())
  51. if err != nil {
  52. log.Error("Router: Invalid IP range in router rule: ", err)
  53. return nil, err
  54. }
  55. anyCond.Add(cidrMatcher)
  56. }
  57. conds.Add(anyCond)
  58. }
  59. if rawFieldRule.Port != nil {
  60. conds.Add(NewPortMatcher(*rawFieldRule.Port))
  61. }
  62. if rawFieldRule.Network != nil {
  63. conds.Add(NewNetworkMatcher(rawFieldRule.Network))
  64. }
  65. if conds.Len() == 0 {
  66. return nil, errors.New("Router: This rule has no effective fields.")
  67. }
  68. return &Rule{
  69. Tag: rawFieldRule.OutboundTag,
  70. Condition: conds,
  71. }, nil
  72. }
  73. func ParseRule(msg json.RawMessage) *Rule {
  74. rawRule := new(JsonRule)
  75. err := json.Unmarshal(msg, rawRule)
  76. if err != nil {
  77. log.Error("Router: Invalid router rule: ", err)
  78. return nil
  79. }
  80. if rawRule.Type == "field" {
  81. fieldrule, err := parseFieldRule(msg)
  82. if err != nil {
  83. log.Error("Invalid field rule: ", err)
  84. return nil
  85. }
  86. return fieldrule
  87. }
  88. if rawRule.Type == "chinaip" {
  89. chinaiprule, err := parseChinaIPRule(msg)
  90. if err != nil {
  91. log.Error("Router: Invalid chinaip rule: ", err)
  92. return nil
  93. }
  94. return chinaiprule
  95. }
  96. if rawRule.Type == "chinasites" {
  97. chinasitesrule, err := parseChinaSitesRule(msg)
  98. if err != nil {
  99. log.Error("Invalid chinasites rule: ", err)
  100. return nil
  101. }
  102. return chinasitesrule
  103. }
  104. log.Error("Unknown router rule type: ", rawRule.Type)
  105. return nil
  106. }
  107. func init() {
  108. router.RegisterRouterConfig("rules", func(data []byte) (interface{}, error) {
  109. type JsonConfig struct {
  110. RuleList []json.RawMessage `json:"rules"`
  111. DomainStrategy string `json:"domainStrategy"`
  112. }
  113. jsonConfig := new(JsonConfig)
  114. if err := json.Unmarshal(data, jsonConfig); err != nil {
  115. return nil, err
  116. }
  117. config := &RouterRuleConfig{
  118. Rules: make([]*Rule, len(jsonConfig.RuleList)),
  119. DomainStrategy: DomainAsIs,
  120. }
  121. domainStrategy := serial.StringLiteral(jsonConfig.DomainStrategy).ToLower()
  122. if domainStrategy.String() == "alwaysip" {
  123. config.DomainStrategy = AlwaysUseIP
  124. } else if domainStrategy.String() == "ipifnonmatch" {
  125. config.DomainStrategy = UseIPIfNonMatch
  126. }
  127. for idx, rawRule := range jsonConfig.RuleList {
  128. rule := ParseRule(rawRule)
  129. config.Rules[idx] = rule
  130. }
  131. return config, nil
  132. })
  133. }