condition.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package rules
  2. import (
  3. "net"
  4. "regexp"
  5. v2net "github.com/v2ray/v2ray-core/common/net"
  6. "github.com/v2ray/v2ray-core/common/serial"
  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 PlainDomainMatcher struct {
  32. pattern serial.StringLiteral
  33. }
  34. func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {
  35. return &PlainDomainMatcher{
  36. pattern: serial.StringLiteral(pattern),
  37. }
  38. }
  39. func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
  40. if !dest.Address().IsDomain() {
  41. return false
  42. }
  43. domain := serial.StringLiteral(dest.Address().Domain())
  44. return domain.Contains(this.pattern)
  45. }
  46. type RegexpDomainMatcher struct {
  47. pattern *regexp.Regexp
  48. }
  49. func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {
  50. r, err := regexp.Compile(pattern)
  51. if err != nil {
  52. return nil, err
  53. }
  54. return &RegexpDomainMatcher{
  55. pattern: r,
  56. }, nil
  57. }
  58. func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
  59. if !dest.Address().IsDomain() {
  60. return false
  61. }
  62. domain := serial.StringLiteral(dest.Address().Domain())
  63. return this.pattern.MatchString(domain.ToLower().String())
  64. }
  65. type CIDRMatcher struct {
  66. cidr *net.IPNet
  67. }
  68. func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {
  69. _, cidr, err := net.ParseCIDR(ipnet)
  70. if err != nil {
  71. return nil, err
  72. }
  73. return &CIDRMatcher{
  74. cidr: cidr,
  75. }, nil
  76. }
  77. func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
  78. if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() {
  79. return false
  80. }
  81. return this.cidr.Contains(dest.Address().IP())
  82. }
  83. type IPv4Matcher struct {
  84. ipv4net *v2net.IPNet
  85. }
  86. func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {
  87. return &IPv4Matcher{
  88. ipv4net: ipnet,
  89. }
  90. }
  91. func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
  92. if !dest.Address().IsIPv4() {
  93. return false
  94. }
  95. return this.ipv4net.Contains(dest.Address().IP())
  96. }
  97. type PortMatcher struct {
  98. port v2net.PortRange
  99. }
  100. func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {
  101. return &PortMatcher{
  102. port: portRange,
  103. }
  104. }
  105. func (this *PortMatcher) Apply(dest v2net.Destination) bool {
  106. return this.port.Contains(dest.Port())
  107. }
  108. type NetworkMatcher struct {
  109. network *v2net.NetworkList
  110. }
  111. func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {
  112. return &NetworkMatcher{
  113. network: network,
  114. }
  115. }
  116. func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {
  117. return this.network.HasNetwork(v2net.Network(dest.Network()))
  118. }