Feature: add no-resolve for ip rules (#375)

This commit is contained in:
Fndroid
2019-10-28 00:02:23 +08:00
committed by Dreamacro
parent 207371aeae
commit 82a8c03953
12 changed files with 137 additions and 50 deletions

21
rules/base.go Normal file
View 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
}

View File

@ -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),

View File

@ -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),

View File

@ -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),

View File

@ -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,

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}