router.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package conf
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "strconv"
  6. "strings"
  7. "v2ray.com/core/app/router"
  8. "v2ray.com/core/common/log"
  9. v2net "v2ray.com/core/common/net"
  10. "v2ray.com/core/tools/geoip"
  11. "github.com/golang/protobuf/proto"
  12. )
  13. type RouterRulesConfig struct {
  14. RuleList []json.RawMessage `json:"rules"`
  15. DomainStrategy string `json:"domainStrategy"`
  16. }
  17. type RouterConfig struct {
  18. Settings *RouterRulesConfig `json:"settings"`
  19. }
  20. func (this *RouterConfig) Build() (*router.Config, error) {
  21. if this.Settings == nil {
  22. return nil, errors.New("Router settings is not specified.")
  23. }
  24. config := new(router.Config)
  25. settings := this.Settings
  26. config.DomainStrategy = router.Config_AsIs
  27. config.Rule = make([]*router.RoutingRule, len(settings.RuleList))
  28. domainStrategy := strings.ToLower(settings.DomainStrategy)
  29. if domainStrategy == "alwaysip" {
  30. config.DomainStrategy = router.Config_UseIp
  31. } else if domainStrategy == "ipifnonmatch" {
  32. config.DomainStrategy = router.Config_IpIfNonMatch
  33. }
  34. for idx, rawRule := range settings.RuleList {
  35. rule := ParseRule(rawRule)
  36. config.Rule[idx] = rule
  37. }
  38. return config, nil
  39. }
  40. type RouterRule struct {
  41. Type string `json:"type"`
  42. OutboundTag string `json:"outboundTag"`
  43. }
  44. func parseIP(s string) *router.IP {
  45. var addr, mask string
  46. i := strings.Index(s, "/")
  47. if i < 0 {
  48. addr = s
  49. } else {
  50. addr = s[:i]
  51. mask = s[i+1:]
  52. }
  53. ip := v2net.ParseAddress(addr)
  54. switch ip.Family() {
  55. case v2net.AddressFamilyIPv4:
  56. bits := uint32(32)
  57. if len(mask) > 0 {
  58. bits64, err := strconv.ParseUint(mask, 10, 32)
  59. if err != nil {
  60. return nil
  61. }
  62. bits = uint32(bits64)
  63. }
  64. if bits > 32 {
  65. log.Warning("Router: invalid network mask: ", bits)
  66. return nil
  67. }
  68. return &router.IP{
  69. Ip: []byte(ip.IP()),
  70. UnmatchingBits: 32 - bits,
  71. }
  72. case v2net.AddressFamilyIPv6:
  73. bits := uint32(128)
  74. if len(mask) > 0 {
  75. bits64, err := strconv.ParseUint(mask, 10, 32)
  76. if err != nil {
  77. return nil
  78. }
  79. bits = uint32(bits64)
  80. }
  81. if bits > 128 {
  82. log.Warning("Router: invalid network mask: ", bits)
  83. return nil
  84. }
  85. return &router.IP{
  86. Ip: []byte(ip.IP()),
  87. UnmatchingBits: 128 - bits,
  88. }
  89. default:
  90. log.Warning("Router: unsupported address: ", s)
  91. return nil
  92. }
  93. }
  94. func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
  95. type RawFieldRule struct {
  96. RouterRule
  97. Domain *StringList `json:"domain"`
  98. IP *StringList `json:"ip"`
  99. Port *PortRange `json:"port"`
  100. Network *NetworkList `json:"network"`
  101. }
  102. rawFieldRule := new(RawFieldRule)
  103. err := json.Unmarshal(msg, rawFieldRule)
  104. if err != nil {
  105. return nil, err
  106. }
  107. rule := new(router.RoutingRule)
  108. rule.Tag = rawFieldRule.OutboundTag
  109. if rawFieldRule.Domain != nil {
  110. for _, domain := range *rawFieldRule.Domain {
  111. domainRule := new(router.Domain)
  112. if strings.HasPrefix(domain, "regexp:") {
  113. domainRule.Type = router.Domain_Regex
  114. domainRule.Value = domain[7:]
  115. } else {
  116. domainRule.Type = router.Domain_Plain
  117. domainRule.Value = domain
  118. }
  119. rule.Domain = append(rule.Domain, domainRule)
  120. }
  121. }
  122. if rawFieldRule.IP != nil {
  123. for _, ip := range *rawFieldRule.IP {
  124. ipRule := parseIP(ip)
  125. if ipRule != nil {
  126. rule.Ip = append(rule.Ip, ipRule)
  127. }
  128. }
  129. }
  130. if rawFieldRule.Port != nil {
  131. rule.PortRange = rawFieldRule.Port.Build()
  132. }
  133. if rawFieldRule.Network != nil {
  134. rule.NetworkList = rawFieldRule.Network.Build()
  135. }
  136. return rule, nil
  137. }
  138. func ParseRule(msg json.RawMessage) *router.RoutingRule {
  139. rawRule := new(RouterRule)
  140. err := json.Unmarshal(msg, rawRule)
  141. if err != nil {
  142. log.Error("Router: Invalid router rule: ", err)
  143. return nil
  144. }
  145. if rawRule.Type == "field" {
  146. fieldrule, err := parseFieldRule(msg)
  147. if err != nil {
  148. log.Error("Invalid field rule: ", err)
  149. return nil
  150. }
  151. return fieldrule
  152. }
  153. if rawRule.Type == "chinaip" {
  154. chinaiprule, err := parseChinaIPRule(msg)
  155. if err != nil {
  156. log.Error("Router: Invalid chinaip rule: ", err)
  157. return nil
  158. }
  159. return chinaiprule
  160. }
  161. if rawRule.Type == "chinasites" {
  162. chinasitesrule, err := parseChinaSitesRule(msg)
  163. if err != nil {
  164. log.Error("Invalid chinasites rule: ", err)
  165. return nil
  166. }
  167. return chinasitesrule
  168. }
  169. log.Error("Unknown router rule type: ", rawRule.Type)
  170. return nil
  171. }
  172. func parseChinaIPRule(data []byte) (*router.RoutingRule, error) {
  173. rawRule := new(RouterRule)
  174. err := json.Unmarshal(data, rawRule)
  175. if err != nil {
  176. log.Error("Router: Invalid router rule: ", err)
  177. return nil, err
  178. }
  179. var chinaIPs geoip.CountryIPRange
  180. if err := proto.Unmarshal(geoip.ChinaIPs, &chinaIPs); err != nil {
  181. return nil, err
  182. }
  183. return &router.RoutingRule{
  184. Tag: rawRule.OutboundTag,
  185. Ip: chinaIPs.Ips,
  186. }, nil
  187. }
  188. func parseChinaSitesRule(data []byte) (*router.RoutingRule, error) {
  189. rawRule := new(RouterRule)
  190. err := json.Unmarshal(data, rawRule)
  191. if err != nil {
  192. log.Error("Router: Invalid router rule: ", err)
  193. return nil, err
  194. }
  195. return &router.RoutingRule{
  196. Tag: rawRule.OutboundTag,
  197. Domain: chinaSitesDomains,
  198. }, nil
  199. }