fieldrule.go 3.6 KB

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