condition.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package rules
  2. import (
  3. "net"
  4. "regexp"
  5. "strings"
  6. v2net "github.com/v2ray/v2ray-core/common/net"
  7. )
  8. type Condition interface {
  9. Apply(dest v2net.Destination) bool
  10. }
  11. type ConditionChan []Condition
  12. func NewConditionChan() *ConditionChan {
  13. var condChan ConditionChan = make([]Condition, 0, 8)
  14. return &condChan
  15. }
  16. func (this *ConditionChan) Add(cond Condition) *ConditionChan {
  17. *this = append(*this, cond)
  18. return this
  19. }
  20. func (this *ConditionChan) Apply(dest v2net.Destination) bool {
  21. for _, cond := range *this {
  22. if !cond.Apply(dest) {
  23. return false
  24. }
  25. }
  26. return true
  27. }
  28. func (this *ConditionChan) Len() int {
  29. return len(*this)
  30. }
  31. type AnyCondition []Condition
  32. func NewAnyCondition() *AnyCondition {
  33. var anyCond AnyCondition = make([]Condition, 0, 8)
  34. return &anyCond
  35. }
  36. func (this *AnyCondition) Add(cond Condition) *AnyCondition {
  37. *this = append(*this, cond)
  38. return this
  39. }
  40. func (this *AnyCondition) Apply(dest v2net.Destination) bool {
  41. for _, cond := range *this {
  42. if cond.Apply(dest) {
  43. return true
  44. }
  45. }
  46. return false
  47. }
  48. func (this *AnyCondition) Len() int {
  49. return len(*this)
  50. }
  51. type PlainDomainMatcher struct {
  52. pattern string
  53. }
  54. func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
  55. return &PlainDomainMatcher{
  56. pattern: pattern,
  57. }
  58. }
  59. func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
  60. if !dest.Address().Family().IsDomain() {
  61. return false
  62. }
  63. domain := dest.Address().Domain()
  64. return strings.Contains(domain, this.pattern)
  65. }
  66. type RegexpDomainMatcher struct {
  67. pattern *regexp.Regexp
  68. }
  69. func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
  70. r, err := regexp.Compile(pattern)
  71. if err != nil {
  72. return nil, err
  73. }
  74. return &RegexpDomainMatcher{
  75. pattern: r,
  76. }, nil
  77. }
  78. func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
  79. if !dest.Address().Family().IsDomain() {
  80. return false
  81. }
  82. domain := dest.Address().Domain()
  83. return this.pattern.MatchString(strings.ToLower(domain))
  84. }
  85. type CIDRMatcher struct {
  86. cidr *net.IPNet
  87. }
  88. func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
  89. _, cidr, err := net.ParseCIDR(ipnet)
  90. if err != nil {
  91. return nil, err
  92. }
  93. return &CIDRMatcher{
  94. cidr: cidr,
  95. }, nil
  96. }
  97. func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
  98. if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
  99. return false
  100. }
  101. return this.cidr.Contains(dest.Address().IP())
  102. }
  103. type IPv4Matcher struct {
  104. ipv4net *v2net.IPNet
  105. }
  106. func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
  107. return &IPv4Matcher{
  108. ipv4net: ipnet,
  109. }
  110. }
  111. func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
  112. if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) {
  113. return false
  114. }
  115. return this.ipv4net.Contains(dest.Address().IP())
  116. }
  117. type PortMatcher struct {
  118. port v2net.PortRange
  119. }
  120. func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
  121. return &PortMatcher{
  122. port: portRange,
  123. }
  124. }
  125. func (this *PortMatcher) Apply(dest v2net.Destination) bool {
  126. return this.port.Contains(dest.Port())
  127. }
  128. type NetworkMatcher struct {
  129. network *v2net.NetworkList
  130. }
  131. func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
  132. return &NetworkMatcher{
  133. network: network,
  134. }
  135. }
  136. func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
  137. return this.network.HasNetwork(dest.Network())
  138. }