fieldrule.go 4.1 KB

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