chore: the resolve and findProcess behaviors of Logic and SubRules follow the order and needs of the internal rules
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run

This commit is contained in:
wwqgtxx 2025-06-10 20:11:50 +08:00
parent 01f8f2db2f
commit ae7967f662
29 changed files with 121 additions and 231 deletions

View File

@ -91,9 +91,7 @@ type RuleProvider interface {
Provider Provider
Behavior() RuleBehavior Behavior() RuleBehavior
Count() int Count() int
Match(*constant.Metadata) bool Match(metadata *constant.Metadata, helper constant.RuleMatchHelper) bool
ShouldResolveIP() bool
ShouldFindProcess() bool
Strategy() any Strategy() any
} }

View File

@ -111,14 +111,17 @@ func (rt RuleType) String() string {
type Rule interface { type Rule interface {
RuleType() RuleType RuleType() RuleType
Match(metadata *Metadata) (bool, string) Match(metadata *Metadata, helper RuleMatchHelper) (bool, string)
Adapter() string Adapter() string
Payload() string Payload() string
ShouldResolveIP() bool
ShouldFindProcess() bool
ProviderNames() []string ProviderNames() []string
} }
type RuleMatchHelper struct {
ResolveIP func()
FindProcess func()
}
type RuleGroup interface { type RuleGroup interface {
Rule Rule
GetRecodeSize() int GetRecodeSize() int

View File

@ -21,14 +21,6 @@ var (
type Base struct { type Base struct {
} }
func (b *Base) ShouldFindProcess() bool {
return false
}
func (b *Base) ShouldResolveIP() bool {
return false
}
func (b *Base) ProviderNames() []string { return nil } func (b *Base) ProviderNames() []string { return nil }
func ParseParams(params []string) (isSrc bool, noResolve bool) { func ParseParams(params []string) (isSrc bool, noResolve bool) {

View File

@ -17,7 +17,7 @@ func (d *Domain) RuleType() C.RuleType {
return C.Domain return C.Domain
} }
func (d *Domain) Match(metadata *C.Metadata) (bool, string) { func (d *Domain) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
return metadata.RuleHost() == d.domain, d.adapter return metadata.RuleHost() == d.domain, d.adapter
} }

View File

@ -17,7 +17,7 @@ func (dk *DomainKeyword) RuleType() C.RuleType {
return C.DomainKeyword return C.DomainKeyword
} }
func (dk *DomainKeyword) Match(metadata *C.Metadata) (bool, string) { func (dk *DomainKeyword) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
domain := metadata.RuleHost() domain := metadata.RuleHost()
return strings.Contains(domain, dk.keyword), dk.adapter return strings.Contains(domain, dk.keyword), dk.adapter
} }

View File

@ -16,7 +16,7 @@ func (dr *DomainRegex) RuleType() C.RuleType {
return C.DomainRegex return C.DomainRegex
} }
func (dr *DomainRegex) Match(metadata *C.Metadata) (bool, string) { func (dr *DomainRegex) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
domain := metadata.RuleHost() domain := metadata.RuleHost()
match, _ := dr.regex.MatchString(domain) match, _ := dr.regex.MatchString(domain)
return match, dr.adapter return match, dr.adapter

View File

@ -17,7 +17,7 @@ func (ds *DomainSuffix) RuleType() C.RuleType {
return C.DomainSuffix return C.DomainSuffix
} }
func (ds *DomainSuffix) Match(metadata *C.Metadata) (bool, string) { func (ds *DomainSuffix) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
domain := metadata.RuleHost() domain := metadata.RuleHost()
return strings.HasSuffix(domain, "."+ds.suffix) || domain == ds.suffix, ds.adapter return strings.HasSuffix(domain, "."+ds.suffix) || domain == ds.suffix, ds.adapter
} }

View File

@ -18,7 +18,7 @@ func (d *DSCP) RuleType() C.RuleType {
return C.DSCP return C.DSCP
} }
func (d *DSCP) Match(metadata *C.Metadata) (bool, string) { func (d *DSCP) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
return d.ranges.Check(metadata.DSCP), d.adapter return d.ranges.Check(metadata.DSCP), d.adapter
} }

View File

@ -13,7 +13,7 @@ func (f *Match) RuleType() C.RuleType {
return C.MATCH return C.MATCH
} }
func (f *Match) Match(metadata *C.Metadata) (bool, string) { func (f *Match) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
return true, f.adapter return true, f.adapter
} }

View File

@ -33,7 +33,11 @@ func (g *GEOIP) RuleType() C.RuleType {
return C.GEOIP return C.GEOIP
} }
func (g *GEOIP) Match(metadata *C.Metadata) (bool, string) { func (g *GEOIP) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if !g.noResolveIP && !g.isSourceIP && helper.ResolveIP != nil {
helper.ResolveIP()
}
ip := metadata.DstIP ip := metadata.DstIP
if g.isSourceIP { if g.isSourceIP {
ip = metadata.SrcIP ip = metadata.SrcIP
@ -161,10 +165,6 @@ func (g *GEOIP) Payload() string {
return g.country return g.country
} }
func (g *GEOIP) ShouldResolveIP() bool {
return !g.noResolveIP
}
func (g *GEOIP) GetCountry() string { func (g *GEOIP) GetCountry() string {
return g.country return g.country
} }

View File

@ -22,7 +22,7 @@ func (gs *GEOSITE) RuleType() C.RuleType {
return C.GEOSITE return C.GEOSITE
} }
func (gs *GEOSITE) Match(metadata *C.Metadata) (bool, string) { func (gs *GEOSITE) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
return gs.MatchDomain(metadata.RuleHost()), gs.adapter return gs.MatchDomain(metadata.RuleHost()), gs.adapter
} }

View File

@ -13,7 +13,7 @@ type InName struct {
payload string payload string
} }
func (u *InName) Match(metadata *C.Metadata) (bool, string) { func (u *InName) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
for _, name := range u.names { for _, name := range u.names {
if metadata.InName == name { if metadata.InName == name {
return true, u.adapter return true, u.adapter

View File

@ -13,7 +13,7 @@ type InType struct {
payload string payload string
} }
func (u *InType) Match(metadata *C.Metadata) (bool, string) { func (u *InType) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
for _, tp := range u.types { for _, tp := range u.types {
if metadata.Type == tp { if metadata.Type == tp {
return true, u.adapter return true, u.adapter

View File

@ -13,7 +13,7 @@ type InUser struct {
payload string payload string
} }
func (u *InUser) Match(metadata *C.Metadata) (bool, string) { func (u *InUser) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
for _, user := range u.users { for _, user := range u.users {
if metadata.InUser == user { if metadata.InUser == user {
return true, u.adapter return true, u.adapter

View File

@ -15,7 +15,11 @@ type ASN struct {
isSourceIP bool isSourceIP bool
} }
func (a *ASN) Match(metadata *C.Metadata) (bool, string) { func (a *ASN) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if !a.noResolveIP && !a.isSourceIP && helper.ResolveIP != nil {
helper.ResolveIP()
}
ip := metadata.DstIP ip := metadata.DstIP
if a.isSourceIP { if a.isSourceIP {
ip = metadata.SrcIP ip = metadata.SrcIP
@ -49,10 +53,6 @@ func (a *ASN) Payload() string {
return a.asn return a.asn
} }
func (a *ASN) ShouldResolveIP() bool {
return !a.noResolveIP
}
func (a *ASN) GetASN() string { func (a *ASN) GetASN() string {
return a.asn return a.asn
} }

View File

@ -35,7 +35,11 @@ func (i *IPCIDR) RuleType() C.RuleType {
return C.IPCIDR return C.IPCIDR
} }
func (i *IPCIDR) Match(metadata *C.Metadata) (bool, string) { func (i *IPCIDR) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if !i.noResolveIP && !i.isSourceIP && helper.ResolveIP != nil {
helper.ResolveIP()
}
ip := metadata.DstIP ip := metadata.DstIP
if i.isSourceIP { if i.isSourceIP {
ip = metadata.SrcIP ip = metadata.SrcIP
@ -51,10 +55,6 @@ func (i *IPCIDR) Payload() string {
return i.ipnet.String() return i.ipnet.String()
} }
func (i *IPCIDR) ShouldResolveIP() bool {
return !i.noResolveIP
}
func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) { func NewIPCIDR(s string, adapter string, opts ...IPCIDROption) (*IPCIDR, error) {
ipnet, err := netip.ParsePrefix(s) ipnet, err := netip.ParsePrefix(s)
if err != nil { if err != nil {

View File

@ -22,7 +22,11 @@ func (is *IPSuffix) RuleType() C.RuleType {
return C.IPSuffix return C.IPSuffix
} }
func (is *IPSuffix) Match(metadata *C.Metadata) (bool, string) { func (is *IPSuffix) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if !is.noResolveIP && !is.isSourceIP && helper.ResolveIP != nil {
helper.ResolveIP()
}
ip := metadata.DstIP ip := metadata.DstIP
if is.isSourceIP { if is.isSourceIP {
ip = metadata.SrcIP ip = metadata.SrcIP
@ -57,10 +61,6 @@ func (is *IPSuffix) Payload() string {
return is.payload return is.payload
} }
func (is *IPSuffix) ShouldResolveIP() bool {
return !is.noResolveIP
}
func NewIPSuffix(payload, adapter string, isSrc, noResolveIP bool) (*IPSuffix, error) { func NewIPSuffix(payload, adapter string, isSrc, noResolveIP bool) (*IPSuffix, error) {
ipnet, err := netip.ParsePrefix(payload) ipnet, err := netip.ParsePrefix(payload)
if err != nil { if err != nil {

View File

@ -34,7 +34,7 @@ func (n *NetworkType) RuleType() C.RuleType {
return C.Network return C.Network
} }
func (n *NetworkType) Match(metadata *C.Metadata) (bool, string) { func (n *NetworkType) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
return n.network == metadata.NetWork, n.adapter return n.network == metadata.NetWork, n.adapter
} }

View File

@ -19,7 +19,7 @@ func (p *Port) RuleType() C.RuleType {
return p.ruleType return p.ruleType
} }
func (p *Port) Match(metadata *C.Metadata) (bool, string) { func (p *Port) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
targetPort := metadata.DstPort targetPort := metadata.DstPort
switch p.ruleType { switch p.ruleType {
case C.InPort: case C.InPort:

View File

@ -30,7 +30,10 @@ func (ps *Process) RuleType() C.RuleType {
return C.ProcessPath return C.ProcessPath
} }
func (ps *Process) Match(metadata *C.Metadata) (bool, string) { func (ps *Process) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if helper.FindProcess != nil {
helper.FindProcess()
}
if ps.nameOnly { if ps.nameOnly {
if ps.regexp != nil { if ps.regexp != nil {
match, _ := ps.regexp.MatchString(metadata.Process) match, _ := ps.regexp.MatchString(metadata.Process)
@ -54,10 +57,6 @@ func (ps *Process) Payload() string {
return ps.process return ps.process
} }
func (ps *Process) ShouldFindProcess() bool {
return true
}
func NewProcess(process string, adapter string, nameOnly bool, regex bool) (*Process, error) { func NewProcess(process string, adapter string, nameOnly bool, regex bool) (*Process, error) {
var r *regexp2.Regexp var r *regexp2.Regexp
var err error var err error

View File

@ -41,7 +41,10 @@ func (u *Uid) RuleType() C.RuleType {
return C.Uid return C.Uid
} }
func (u *Uid) Match(metadata *C.Metadata) (bool, string) { func (u *Uid) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if helper.FindProcess != nil {
helper.FindProcess()
}
if metadata.Uid != 0 { if metadata.Uid != 0 {
if u.uids.Check(metadata.Uid) { if u.uids.Check(metadata.Uid) {
return true, u.adapter return true, u.adapter
@ -58,7 +61,3 @@ func (u *Uid) Adapter() string {
func (u *Uid) Payload() string { func (u *Uid) Payload() string {
return u.oUid return u.oUid
} }
func (u *Uid) ShouldFindProcess() bool {
return true
}

View File

@ -195,11 +195,11 @@ func (logic *Logic) RuleType() C.RuleType {
return logic.ruleType return logic.ruleType
} }
func matchSubRules(metadata *C.Metadata, name string, subRules map[string][]C.Rule) (bool, string) { func matchSubRules(metadata *C.Metadata, name string, subRules map[string][]C.Rule, helper C.RuleMatchHelper) (bool, string) {
for _, rule := range subRules[name] { for _, rule := range subRules[name] {
if m, a := rule.Match(metadata); m { if m, a := rule.Match(metadata, helper); m {
if rule.RuleType() == C.SubRules { if rule.RuleType() == C.SubRules {
return matchSubRules(metadata, rule.Adapter(), subRules) return matchSubRules(metadata, rule.Adapter(), subRules, helper)
} else { } else {
return m, a return m, a
} }
@ -208,28 +208,28 @@ func matchSubRules(metadata *C.Metadata, name string, subRules map[string][]C.Ru
return false, "" return false, ""
} }
func (logic *Logic) Match(metadata *C.Metadata) (bool, string) { func (logic *Logic) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
switch logic.ruleType { switch logic.ruleType {
case C.SubRules: case C.SubRules:
if m, _ := logic.rules[0].Match(metadata); m { if m, _ := logic.rules[0].Match(metadata, helper); m {
return matchSubRules(metadata, logic.adapter, logic.subRules) return matchSubRules(metadata, logic.adapter, logic.subRules, helper)
} }
return false, "" return false, ""
case C.NOT: case C.NOT:
if m, _ := logic.rules[0].Match(metadata); !m { if m, _ := logic.rules[0].Match(metadata, helper); !m {
return true, logic.adapter return true, logic.adapter
} }
return false, "" return false, ""
case C.OR: case C.OR:
for _, rule := range logic.rules { for _, rule := range logic.rules {
if m, _ := rule.Match(metadata); m { if m, _ := rule.Match(metadata, helper); m {
return true, logic.adapter return true, logic.adapter
} }
} }
return false, "" return false, ""
case C.AND: case C.AND:
for _, rule := range logic.rules { for _, rule := range logic.rules {
if m, _ := rule.Match(metadata); !m { if m, _ := rule.Match(metadata, helper); !m {
return false, logic.adapter return false, logic.adapter
} }
} }
@ -266,38 +266,6 @@ func (logic *Logic) Payload() string {
return logic.payload return logic.payload
} }
func (logic *Logic) ShouldResolveIP() bool {
if logic.ruleType == C.SubRules {
for _, rule := range logic.subRules[logic.adapter] {
if rule.ShouldResolveIP() {
return true
}
}
}
for _, rule := range logic.rules {
if rule.ShouldResolveIP() {
return true
}
}
return false
}
func (logic *Logic) ShouldFindProcess() bool {
if logic.ruleType == C.SubRules {
for _, rule := range logic.subRules[logic.adapter] {
if rule.ShouldFindProcess() {
return true
}
}
}
for _, rule := range logic.rules {
if rule.ShouldFindProcess() {
return true
}
}
return false
}
func (logic *Logic) ProviderNames() (names []string) { func (logic *Logic) ProviderNames() (names []string) {
for _, rule := range logic.rules { for _, rule := range logic.rules {
names = append(names, rule.ProviderNames()...) names = append(names, rule.ProviderNames()...)

View File

@ -16,12 +16,11 @@ func TestAND(t *testing.T) {
and, err := NewAND("((DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule) and, err := NewAND("((DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
assert.Equal(t, "DIRECT", and.Adapter()) assert.Equal(t, "DIRECT", and.Adapter())
assert.Equal(t, false, and.ShouldResolveIP())
m, _ := and.Match(&C.Metadata{ m, _ := and.Match(&C.Metadata{
Host: "baidu.com", Host: "baidu.com",
NetWork: C.TCP, NetWork: C.TCP,
DstPort: 20000, DstPort: 20000,
}) }, C.RuleMatchHelper{})
assert.Equal(t, true, m) assert.Equal(t, true, m)
and, err = NewAND("(DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule) and, err = NewAND("(DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule)
@ -36,7 +35,7 @@ func TestNOT(t *testing.T) {
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
m, _ := not.Match(&C.Metadata{ m, _ := not.Match(&C.Metadata{
DstPort: 6100, DstPort: 6100,
}) }, C.RuleMatchHelper{})
assert.Equal(t, false, m) assert.Equal(t, false, m)
_, err = NewNOT("((DST-PORT,5600-6666),(DOMAIN,baidu.com))", "DIRECT", ParseRule) _, err = NewNOT("((DST-PORT,5600-6666),(DOMAIN,baidu.com))", "DIRECT", ParseRule)
@ -51,7 +50,6 @@ func TestOR(t *testing.T) {
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
m, _ := or.Match(&C.Metadata{ m, _ := or.Match(&C.Metadata{
NetWork: C.TCP, NetWork: C.TCP,
}) }, C.RuleMatchHelper{})
assert.Equal(t, true, m) assert.Equal(t, true, m)
assert.Equal(t, false, or.ShouldResolveIP())
} }

View File

@ -10,20 +10,18 @@ import (
) )
type classicalStrategy struct { type classicalStrategy struct {
rules []C.Rule rules []C.Rule
count int count int
shouldResolveIP bool parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)
shouldFindProcess bool
parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)
} }
func (c *classicalStrategy) Behavior() P.RuleBehavior { func (c *classicalStrategy) Behavior() P.RuleBehavior {
return P.Classical return P.Classical
} }
func (c *classicalStrategy) Match(metadata *C.Metadata) bool { func (c *classicalStrategy) Match(metadata *C.Metadata, helper C.RuleMatchHelper) bool {
for _, rule := range c.rules { for _, rule := range c.rules {
if m, _ := rule.Match(metadata); m { if m, _ := rule.Match(metadata, helper); m {
return true return true
} }
} }
@ -35,39 +33,17 @@ func (c *classicalStrategy) Count() int {
return c.count return c.count
} }
func (c *classicalStrategy) ShouldResolveIP() bool {
return c.shouldResolveIP
}
func (c *classicalStrategy) ShouldFindProcess() bool {
return c.shouldFindProcess
}
func (c *classicalStrategy) Reset() { func (c *classicalStrategy) Reset() {
c.rules = nil c.rules = nil
c.count = 0 c.count = 0
c.shouldFindProcess = false
c.shouldResolveIP = false
} }
func (c *classicalStrategy) Insert(rule string) { func (c *classicalStrategy) Insert(rule string) {
ruleType, rule, params := ruleParse(rule) ruleType, rule, params := ruleParse(rule)
if ruleType == "PROCESS-NAME" {
c.shouldFindProcess = true
}
r, err := c.parse(ruleType, rule, "", params) r, err := c.parse(ruleType, rule, "", params)
if err != nil { if err != nil {
log.Warnln("parse classical rule error: %s", err.Error()) log.Warnln("parse classical rule error: %s", err.Error())
} else { } else {
if r.ShouldResolveIP() {
c.shouldResolveIP = true
}
if r.ShouldFindProcess() {
c.shouldFindProcess = true
}
c.rules = append(c.rules, r) c.rules = append(c.rules, r)
c.count++ c.count++
} }

View File

@ -23,11 +23,7 @@ func (d *domainStrategy) Behavior() P.RuleBehavior {
return P.Domain return P.Domain
} }
func (d *domainStrategy) ShouldFindProcess() bool { func (d *domainStrategy) Match(metadata *C.Metadata, helper C.RuleMatchHelper) bool {
return false
}
func (d *domainStrategy) Match(metadata *C.Metadata) bool {
return d.domainSet != nil && d.domainSet.Has(metadata.RuleHost()) return d.domainSet != nil && d.domainSet.Has(metadata.RuleHost())
} }
@ -35,10 +31,6 @@ func (d *domainStrategy) Count() int {
return d.count return d.count
} }
func (d *domainStrategy) ShouldResolveIP() bool {
return false
}
func (d *domainStrategy) Reset() { func (d *domainStrategy) Reset() {
d.domainTrie = trie.New[struct{}]() d.domainTrie = trie.New[struct{}]()
d.domainSet = nil d.domainSet = nil

View File

@ -14,21 +14,19 @@ import (
) )
type ipcidrStrategy struct { type ipcidrStrategy struct {
count int count int
shouldResolveIP bool cidrSet *cidr.IpCidrSet
cidrSet *cidr.IpCidrSet //trie *trie.IpCidrTrie
//trie *trie.IpCidrTrie
} }
func (i *ipcidrStrategy) Behavior() P.RuleBehavior { func (i *ipcidrStrategy) Behavior() P.RuleBehavior {
return P.IPCIDR return P.IPCIDR
} }
func (i *ipcidrStrategy) ShouldFindProcess() bool { func (i *ipcidrStrategy) Match(metadata *C.Metadata, helper C.RuleMatchHelper) bool {
return false if helper.ResolveIP != nil {
} helper.ResolveIP()
}
func (i *ipcidrStrategy) Match(metadata *C.Metadata) bool {
// return i.trie != nil && i.trie.IsContain(metadata.DstIP.AsSlice()) // return i.trie != nil && i.trie.IsContain(metadata.DstIP.AsSlice())
return i.cidrSet != nil && i.cidrSet.IsContain(metadata.DstIP) return i.cidrSet != nil && i.cidrSet.IsContain(metadata.DstIP)
} }
@ -37,15 +35,10 @@ func (i *ipcidrStrategy) Count() int {
return i.count return i.count
} }
func (i *ipcidrStrategy) ShouldResolveIP() bool {
return i.shouldResolveIP
}
func (i *ipcidrStrategy) Reset() { func (i *ipcidrStrategy) Reset() {
// i.trie = trie.NewIpCidrTrie() // i.trie = trie.NewIpCidrTrie()
i.cidrSet = cidr.NewIpCidrSet() i.cidrSet = cidr.NewIpCidrSet()
i.count = 0 i.count = 0
i.shouldResolveIP = false
} }
func (i *ipcidrStrategy) Insert(rule string) { func (i *ipcidrStrategy) Insert(rule string) {
@ -54,7 +47,6 @@ func (i *ipcidrStrategy) Insert(rule string) {
if err != nil { if err != nil {
log.Warnln("invalid Ipcidr:[%s]", rule) log.Warnln("invalid Ipcidr:[%s]", rule)
} else { } else {
i.shouldResolveIP = true
i.count++ i.count++
} }
} }
@ -70,9 +62,6 @@ func (i *ipcidrStrategy) FromMrs(r io.Reader, count int) error {
} }
i.count = count i.count = count
i.cidrSet = cidrSet i.cidrSet = cidrSet
if i.count > 0 {
i.shouldResolveIP = true
}
return nil return nil
} }

View File

@ -46,10 +46,8 @@ type providerForApi struct {
type ruleStrategy interface { type ruleStrategy interface {
Behavior() P.RuleBehavior Behavior() P.RuleBehavior
Match(metadata *C.Metadata) bool Match(metadata *C.Metadata, helper C.RuleMatchHelper) bool
Count() int Count() int
ShouldResolveIP() bool
ShouldFindProcess() bool
Reset() Reset()
Insert(rule string) Insert(rule string)
FinishInsert() FinishInsert()
@ -79,16 +77,8 @@ func (bp *baseProvider) Count() int {
return bp.strategy.Count() return bp.strategy.Count()
} }
func (bp *baseProvider) Match(metadata *C.Metadata) bool { func (bp *baseProvider) Match(metadata *C.Metadata, helper C.RuleMatchHelper) bool {
return bp.strategy != nil && bp.strategy.Match(metadata) return bp.strategy != nil && bp.strategy.Match(metadata, helper)
}
func (bp *baseProvider) ShouldResolveIP() bool {
return bp.strategy.ShouldResolveIP()
}
func (bp *baseProvider) ShouldFindProcess() bool {
return bp.strategy.ShouldFindProcess()
} }
func (bp *baseProvider) Strategy() any { func (bp *baseProvider) Strategy() any {

View File

@ -10,47 +10,40 @@ import (
type RuleSet struct { type RuleSet struct {
*common.Base *common.Base
ruleProviderName string ruleProviderName string
adapter string adapter string
isSrc bool isSrc bool
noResolveIP bool noResolveIP bool
shouldFindProcess bool
}
func (rs *RuleSet) ShouldFindProcess() bool {
if rs.shouldFindProcess {
return true
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldFindProcess()
}
return false
} }
func (rs *RuleSet) RuleType() C.RuleType { func (rs *RuleSet) RuleType() C.RuleType {
return C.RuleSet return C.RuleSet
} }
func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) { func (rs *RuleSet) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
if provider, ok := rs.getProvider(); ok { if provider, ok := rs.getProvider(); ok {
if rs.isSrc { if rs.isSrc {
metadata.SwapSrcDst() metadata.SwapSrcDst()
defer metadata.SwapSrcDst() defer metadata.SwapSrcDst()
helper.ResolveIP = nil // src mode should not resolve ip
} else if rs.noResolveIP {
helper.ResolveIP = nil
} }
return provider.Match(metadata), rs.adapter return provider.Match(metadata, helper), rs.adapter
} }
return false, "" return false, ""
} }
// MatchDomain implements C.DomainMatcher // MatchDomain implements C.DomainMatcher
func (rs *RuleSet) MatchDomain(domain string) bool { func (rs *RuleSet) MatchDomain(domain string) bool {
ok, _ := rs.Match(&C.Metadata{Host: domain}) ok, _ := rs.Match(&C.Metadata{Host: domain}, C.RuleMatchHelper{})
return ok return ok
} }
// MatchIp implements C.IpMatcher // MatchIp implements C.IpMatcher
func (rs *RuleSet) MatchIp(ip netip.Addr) bool { func (rs *RuleSet) MatchIp(ip netip.Addr) bool {
ok, _ := rs.Match(&C.Metadata{DstIP: ip}) ok, _ := rs.Match(&C.Metadata{DstIP: ip}, C.RuleMatchHelper{})
return ok return ok
} }
@ -62,16 +55,6 @@ func (rs *RuleSet) Payload() string {
return rs.ruleProviderName return rs.ruleProviderName
} }
func (rs *RuleSet) ShouldResolveIP() bool {
if rs.noResolveIP {
return false
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldResolveIP()
}
return false
}
func (rs *RuleSet) ProviderNames() []string { func (rs *RuleSet) ProviderNames() []string {
return []string{rs.ruleProviderName} return []string{rs.ruleProviderName}
} }

View File

@ -590,10 +590,6 @@ func logMetadata(metadata *C.Metadata, rule C.Rule, remoteConn C.Connection) {
} }
} }
func shouldResolveIP(rule C.Rule, metadata *C.Metadata) bool {
return rule.ShouldResolveIP() && metadata.Host != "" && !metadata.DstIP.IsValid()
}
func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
configMux.RLock() configMux.RLock()
defer configMux.RUnlock() defer configMux.RUnlock()
@ -607,9 +603,9 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
resolved = true resolved = true
} }
for _, rule := range getRules(metadata) { helper := C.RuleMatchHelper{
if !resolved && shouldResolveIP(rule, metadata) { ResolveIP: func() {
func() { if !resolved && metadata.Host != "" && !metadata.Resolved() {
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout) ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout)
defer cancel() defer cancel()
ip, err := resolver.ResolveIP(ctx, metadata.Host) ip, err := resolver.ResolveIP(ctx, metadata.Host)
@ -620,37 +616,44 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
metadata.DstIP = ip metadata.DstIP = ip
} }
resolved = true resolved = true
}() }
} },
FindProcess: func() {
if attemptProcessLookup && !findProcessMode.Off() {
attemptProcessLookup = false
if !features.CMFA {
// normal check for process
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort))
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = filepath.Base(path)
metadata.ProcessPath = path
metadata.Uid = uid
if attemptProcessLookup && !findProcessMode.Off() && (findProcessMode.Always() || rule.ShouldFindProcess()) { if pkg, err := P.FindPackageName(metadata); err == nil { // for android (not CMFA) package names
attemptProcessLookup = false metadata.Process = pkg
if !features.CMFA { }
// normal check for process }
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort))
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else { } else {
metadata.Process = filepath.Base(path) // check package names
metadata.ProcessPath = path pkg, err := P.FindPackageName(metadata)
metadata.Uid = uid if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
if pkg, err := P.FindPackageName(metadata); err == nil { // for android (not CMFA) package names } else {
metadata.Process = pkg metadata.Process = pkg
} }
} }
} else {
// check package names
pkg, err := P.FindPackageName(metadata)
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = pkg
}
} }
} },
}
if matched, ada := rule.Match(metadata); matched { if findProcessMode.Always() {
helper.FindProcess()
}
for _, rule := range getRules(metadata) {
if matched, ada := rule.Match(metadata, helper); matched {
adapter, ok := proxies[ada] adapter, ok := proxies[ada]
if !ok { if !ok {
continue continue