fieldrule.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package json
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net"
  6. "regexp"
  7. "strings"
  8. v2net "github.com/v2ray/v2ray-core/common/net"
  9. v2netjson "github.com/v2ray/v2ray-core/common/net/json"
  10. )
  11. type StringList []string
  12. func NewStringList(str ...string) *StringList {
  13. list := StringList(str)
  14. return &list
  15. }
  16. func (this *StringList) UnmarshalJSON(data []byte) error {
  17. var strList []string
  18. err := json.Unmarshal(data, &strList)
  19. if err == nil {
  20. *this = make([]string, len(strList))
  21. copy(*this, strList)
  22. return nil
  23. }
  24. var str string
  25. err = json.Unmarshal(data, &str)
  26. if err == nil {
  27. *this = make([]string, 0, 1)
  28. *this = append(*this, str)
  29. return nil
  30. }
  31. return errors.New("Failed to unmarshal string list: " + string(data))
  32. }
  33. func (this *StringList) Len() int {
  34. return len([]string(*this))
  35. }
  36. type DomainMatcher interface {
  37. Match(domain string) bool
  38. }
  39. type PlainDomainMatcher struct {
  40. pattern string
  41. }
  42. func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
  43. return &PlainDomainMatcher{
  44. pattern: strings.ToLower(pattern),
  45. }
  46. }
  47. func (this *PlainDomainMatcher) Match(domain string) bool {
  48. return strings.Contains(strings.ToLower(domain), this.pattern)
  49. }
  50. type RegexpDomainMatcher struct {
  51. pattern *regexp.Regexp
  52. }
  53. func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
  54. r, err := regexp.Compile(pattern)
  55. if err != nil {
  56. return nil, err
  57. }
  58. return &RegexpDomainMatcher{
  59. pattern: r,
  60. }, nil
  61. }
  62. func (this *RegexpDomainMatcher) Match(domain string) bool {
  63. return this.pattern.MatchString(strings.ToLower(domain))
  64. }
  65. type FieldRule struct {
  66. Rule
  67. Domain []DomainMatcher
  68. IP []*net.IPNet
  69. Port v2net.PortRange
  70. Network v2net.NetworkList
  71. }
  72. func (this *FieldRule) Apply(dest v2net.Destination) bool {
  73. address := dest.Address()
  74. if len(this.Domain) > 0 {
  75. if !address.IsDomain() {
  76. return false
  77. }
  78. foundMatch := false
  79. for _, domain := range this.Domain {
  80. if domain.Match(address.Domain()) {
  81. foundMatch = true
  82. break
  83. }
  84. }
  85. if !foundMatch {
  86. return false
  87. }
  88. }
  89. if this.IP != nil && len(this.IP) > 0 {
  90. if !(address.IsIPv4() || address.IsIPv6()) {
  91. return false
  92. }
  93. foundMatch := false
  94. for _, ipnet := range this.IP {
  95. if ipnet.Contains(address.IP()) {
  96. foundMatch = true
  97. break
  98. }
  99. }
  100. if !foundMatch {
  101. return false
  102. }
  103. }
  104. if this.Port != nil {
  105. port := dest.Port()
  106. if port.Value() < this.Port.From().Value() || port.Value() > this.Port.To().Value() {
  107. return false
  108. }
  109. }
  110. if this.Network != nil {
  111. if !this.Network.HasNetwork(v2net.Network(dest.Network())) {
  112. return false
  113. }
  114. }
  115. return true
  116. }
  117. func (this *FieldRule) UnmarshalJSON(data []byte) error {
  118. type RawFieldRule struct {
  119. Rule
  120. Domain *StringList `json:"domain"`
  121. IP *StringList `json:"ip"`
  122. Port *v2netjson.PortRange `json:"port"`
  123. Network *v2netjson.NetworkList `json:"network"`
  124. }
  125. rawFieldRule := RawFieldRule{}
  126. err := json.Unmarshal(data, &rawFieldRule)
  127. if err != nil {
  128. return err
  129. }
  130. this.Type = rawFieldRule.Type
  131. this.OutboundTag = rawFieldRule.OutboundTag
  132. hasField := false
  133. if rawFieldRule.Domain != nil && rawFieldRule.Domain.Len() > 0 {
  134. this.Domain = make([]DomainMatcher, rawFieldRule.Domain.Len())
  135. for idx, rawDomain := range *(rawFieldRule.Domain) {
  136. var matcher DomainMatcher
  137. if strings.HasPrefix(rawDomain, "regexp:") {
  138. rawMatcher, err := NewRegexpDomainMatcher(rawDomain[7:])
  139. if err != nil {
  140. return err
  141. }
  142. matcher = rawMatcher
  143. } else {
  144. matcher = NewPlainDomainMatcher(rawDomain)
  145. }
  146. this.Domain[idx] = matcher
  147. }
  148. hasField = true
  149. }
  150. if rawFieldRule.IP != nil && rawFieldRule.IP.Len() > 0 {
  151. this.IP = make([]*net.IPNet, 0, rawFieldRule.IP.Len())
  152. for _, ipStr := range *(rawFieldRule.IP) {
  153. _, ipNet, err := net.ParseCIDR(ipStr)
  154. if err != nil {
  155. return errors.New("Invalid IP range in router rule: " + err.Error())
  156. }
  157. this.IP = append(this.IP, ipNet)
  158. }
  159. hasField = true
  160. }
  161. if rawFieldRule.Port != nil {
  162. this.Port = rawFieldRule.Port
  163. hasField = true
  164. }
  165. if rawFieldRule.Network != nil {
  166. this.Network = rawFieldRule.Network
  167. hasField = true
  168. }
  169. if !hasField {
  170. return errors.New("This rule has no effective fields.")
  171. }
  172. return nil
  173. }