Feature: add no-resolve for ip rules (#375)
This commit is contained in:
21
rules/base.go
Normal file
21
rules/base.go
Normal file
@ -0,0 +1,21 @@
|
||||
package rules
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
errPayload = errors.New("payload error")
|
||||
errParams = errors.New("params error")
|
||||
|
||||
noResolve = "no-resolve"
|
||||
)
|
||||
|
||||
func HasNoResolve(params []string) bool {
|
||||
for _, p := range params {
|
||||
if p == noResolve {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@ -15,7 +15,7 @@ func (d *Domain) RuleType() C.RuleType {
|
||||
return C.Domain
|
||||
}
|
||||
|
||||
func (d *Domain) IsMatch(metadata *C.Metadata) bool {
|
||||
func (d *Domain) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
@ -30,6 +30,10 @@ func (d *Domain) Payload() string {
|
||||
return d.domain
|
||||
}
|
||||
|
||||
func (d *Domain) NoResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewDomain(domain string, adapter string) *Domain {
|
||||
return &Domain{
|
||||
domain: strings.ToLower(domain),
|
||||
|
@ -15,7 +15,7 @@ func (dk *DomainKeyword) RuleType() C.RuleType {
|
||||
return C.DomainKeyword
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) IsMatch(metadata *C.Metadata) bool {
|
||||
func (dk *DomainKeyword) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
@ -31,6 +31,10 @@ func (dk *DomainKeyword) Payload() string {
|
||||
return dk.keyword
|
||||
}
|
||||
|
||||
func (dk *DomainKeyword) NoResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewDomainKeyword(keyword string, adapter string) *DomainKeyword {
|
||||
return &DomainKeyword{
|
||||
keyword: strings.ToLower(keyword),
|
||||
|
@ -15,7 +15,7 @@ func (ds *DomainSuffix) RuleType() C.RuleType {
|
||||
return C.DomainSuffix
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) IsMatch(metadata *C.Metadata) bool {
|
||||
func (ds *DomainSuffix) Match(metadata *C.Metadata) bool {
|
||||
if metadata.AddrType != C.AtypDomainName {
|
||||
return false
|
||||
}
|
||||
@ -31,6 +31,10 @@ func (ds *DomainSuffix) Payload() string {
|
||||
return ds.suffix
|
||||
}
|
||||
|
||||
func (ds *DomainSuffix) NoResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewDomainSuffix(suffix string, adapter string) *DomainSuffix {
|
||||
return &DomainSuffix{
|
||||
suffix: strings.ToLower(suffix),
|
||||
|
@ -12,7 +12,7 @@ func (f *Match) RuleType() C.RuleType {
|
||||
return C.MATCH
|
||||
}
|
||||
|
||||
func (f *Match) IsMatch(metadata *C.Metadata) bool {
|
||||
func (f *Match) Match(metadata *C.Metadata) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -24,6 +24,10 @@ func (f *Match) Payload() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (f *Match) NoResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewMatch(adapter string) *Match {
|
||||
return &Match{
|
||||
adapter: adapter,
|
||||
|
@ -15,19 +15,21 @@ var (
|
||||
)
|
||||
|
||||
type GEOIP struct {
|
||||
country string
|
||||
adapter string
|
||||
country string
|
||||
adapter string
|
||||
noResolveIP bool
|
||||
}
|
||||
|
||||
func (g *GEOIP) RuleType() C.RuleType {
|
||||
return C.GEOIP
|
||||
}
|
||||
|
||||
func (g *GEOIP) IsMatch(metadata *C.Metadata) bool {
|
||||
if metadata.DstIP == nil {
|
||||
func (g *GEOIP) Match(metadata *C.Metadata) bool {
|
||||
ip := metadata.DstIP
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
record, _ := mmdb.Country(metadata.DstIP)
|
||||
record, _ := mmdb.Country(ip)
|
||||
return record.Country.IsoCode == g.country
|
||||
}
|
||||
|
||||
@ -39,7 +41,11 @@ func (g *GEOIP) Payload() string {
|
||||
return g.country
|
||||
}
|
||||
|
||||
func NewGEOIP(country string, adapter string) *GEOIP {
|
||||
func (g *GEOIP) NoResolveIP() bool {
|
||||
return g.noResolveIP
|
||||
}
|
||||
|
||||
func NewGEOIP(country string, adapter string, noResolveIP bool) *GEOIP {
|
||||
once.Do(func() {
|
||||
var err error
|
||||
mmdb, err = geoip2.Open(C.Path.MMDB())
|
||||
@ -47,8 +53,12 @@ func NewGEOIP(country string, adapter string) *GEOIP {
|
||||
log.Fatalf("Can't load mmdb: %s", err.Error())
|
||||
}
|
||||
})
|
||||
return &GEOIP{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
|
||||
geoip := &GEOIP{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
noResolveIP: noResolveIP,
|
||||
}
|
||||
|
||||
return geoip
|
||||
}
|
||||
|
@ -6,10 +6,25 @@ import (
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type IPCIDROption func(*IPCIDR)
|
||||
|
||||
func WithIPCIDRSourceIP(b bool) IPCIDROption {
|
||||
return func(i *IPCIDR) {
|
||||
i.isSourceIP = b
|
||||
}
|
||||
}
|
||||
|
||||
func WithIPCIDRNoResolve(noResolve bool) IPCIDROption {
|
||||
return func(i *IPCIDR) {
|
||||
i.noResolveIP = !noResolve
|
||||
}
|
||||
}
|
||||
|
||||
type IPCIDR struct {
|
||||
ipnet *net.IPNet
|
||||
adapter string
|
||||
isSourceIP bool
|
||||
ipnet *net.IPNet
|
||||
adapter string
|
||||
isSourceIP bool
|
||||
noResolveIP bool
|
||||
}
|
||||
|
||||
func (i *IPCIDR) RuleType() C.RuleType {
|
||||
@ -19,7 +34,7 @@ func (i *IPCIDR) RuleType() C.RuleType {
|
||||
return C.IPCIDR
|
||||
}
|
||||
|
||||
func (i *IPCIDR) IsMatch(metadata *C.Metadata) bool {
|
||||
func (i *IPCIDR) Match(metadata *C.Metadata) bool {
|
||||
ip := metadata.DstIP
|
||||
if i.isSourceIP {
|
||||
ip = metadata.SrcIP
|
||||
@ -35,14 +50,24 @@ func (i *IPCIDR) Payload() string {
|
||||
return i.ipnet.String()
|
||||
}
|
||||
|
||||
func NewIPCIDR(s string, adapter string, isSourceIP bool) *IPCIDR {
|
||||
func (i *IPCIDR) NoResolveIP() bool {
|
||||
return i.noResolveIP
|
||||
}
|
||||
|
||||
func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) {
|
||||
_, ipnet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, errPayload
|
||||
}
|
||||
return &IPCIDR{
|
||||
ipnet: ipnet,
|
||||
adapter: adapter,
|
||||
isSourceIP: isSourceIP,
|
||||
|
||||
ipcidr := &IPCIDR{
|
||||
ipnet: ipnet,
|
||||
adapter: adapter,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(ipcidr)
|
||||
}
|
||||
|
||||
return ipcidr, nil
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func (p *Port) RuleType() C.RuleType {
|
||||
return C.DstPort
|
||||
}
|
||||
|
||||
func (p *Port) IsMatch(metadata *C.Metadata) bool {
|
||||
func (p *Port) Match(metadata *C.Metadata) bool {
|
||||
if p.isSource {
|
||||
return metadata.SrcPort == p.port
|
||||
}
|
||||
@ -34,14 +34,18 @@ func (p *Port) Payload() string {
|
||||
return p.port
|
||||
}
|
||||
|
||||
func NewPort(port string, adapter string, isSource bool) *Port {
|
||||
func (p *Port) NoResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewPort(port string, adapter string, isSource bool) (*Port, error) {
|
||||
_, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, errPayload
|
||||
}
|
||||
return &Port{
|
||||
adapter: adapter,
|
||||
port: port,
|
||||
isSource: isSource,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user