| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 | package rulesimport (	"net"	"regexp"	v2net "github.com/v2ray/v2ray-core/common/net"	"github.com/v2ray/v2ray-core/common/serial")type Condition interface {	Apply(dest v2net.Destination) bool}type ConditionChan []Conditionfunc NewConditionChan() *ConditionChan {	var condChan ConditionChan = make([]Condition, 0, 8)	return &condChan}func (this *ConditionChan) Add(cond Condition) *ConditionChan {	*this = append(*this, cond)	return this}func (this *ConditionChan) Apply(dest v2net.Destination) bool {	for _, cond := range *this {		if !cond.Apply(dest) {			return false		}	}	return true}func (this *ConditionChan) Len() int {	return len(*this)}type PlainDomainMatcher struct {	pattern serial.StringLiteral}func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher {	return &PlainDomainMatcher{		pattern: serial.StringLiteral(pattern),	}}func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {	if !dest.Address().IsDomain() {		return false	}	domain := serial.StringLiteral(dest.Address().Domain())	return domain.Contains(this.pattern)}type RegexpDomainMatcher struct {	pattern *regexp.Regexp}func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) {	r, err := regexp.Compile(pattern)	if err != nil {		return nil, err	}	return &RegexpDomainMatcher{		pattern: r,	}, nil}func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {	if !dest.Address().IsDomain() {		return false	}	domain := serial.StringLiteral(dest.Address().Domain())	return this.pattern.MatchString(domain.ToLower().String())}type CIDRMatcher struct {	cidr *net.IPNet}func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) {	_, cidr, err := net.ParseCIDR(ipnet)	if err != nil {		return nil, err	}	return &CIDRMatcher{		cidr: cidr,	}, nil}func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {	if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() {		return false	}	return this.cidr.Contains(dest.Address().IP())}type IPv4Matcher struct {	ipv4net *v2net.IPNet}func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher {	return &IPv4Matcher{		ipv4net: ipnet,	}}func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {	if !dest.Address().IsIPv4() {		return false	}	return this.ipv4net.Contains(dest.Address().IP())}type PortMatcher struct {	port v2net.PortRange}func NewPortMatcher(portRange v2net.PortRange) *PortMatcher {	return &PortMatcher{		port: portRange,	}}func (this *PortMatcher) Apply(dest v2net.Destination) bool {	return this.port.Contains(dest.Port())}type NetworkMatcher struct {	network *v2net.NetworkList}func NewNetworkMatcher(network *v2net.NetworkList) *NetworkMatcher {	return &NetworkMatcher{		network: network,	}}func (this *NetworkMatcher) Apply(dest v2net.Destination) bool {	return this.network.HasNetwork(v2net.Network(dest.Network()))}
 |