fix: adjust sub_rule to logic package, and fix not rule failed

This commit is contained in:
Skyxim
2022-09-11 16:19:42 +08:00
parent ef2f8317c7
commit 4597ed49cf
4 changed files with 13 additions and 16 deletions

View File

@@ -2,16 +2,14 @@ package logic
import (
"fmt"
"github.com/Dreamacro/clash/constant"
C "github.com/Dreamacro/clash/constant"
RC "github.com/Dreamacro/clash/rules/common"
RP "github.com/Dreamacro/clash/rules/provider"
"github.com/Dreamacro/clash/rules/sub_rule"
"github.com/stretchr/testify/assert"
"testing"
)
func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed constant.Rule, parseErr error) {
func ParseRule(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error) {
switch tp {
case "DOMAIN":
parsed = RC.NewDomain(payload, target)
@@ -49,7 +47,7 @@ func ParseRule(tp, payload, target string, params []string, subRules *map[string
case "IN-TYPE":
parsed, parseErr = RC.NewInType(payload, target)
case "SUB-RULE":
parsed, parseErr = sub_rule.NewSubRule(payload, target, subRules, ParseRule)
parsed, parseErr = NewSubRule(payload, target, subRules, ParseRule)
case "AND":
parsed, parseErr = NewAND(payload, target, ParseRule)
case "OR":
@@ -74,10 +72,10 @@ func TestAND(t *testing.T) {
assert.Equal(t, nil, err)
assert.Equal(t, "DIRECT", and.adapter)
assert.Equal(t, false, and.ShouldResolveIP())
m, _ := and.Match(&constant.Metadata{
m, _ := and.Match(&C.Metadata{
Host: "baidu.com",
AddrType: constant.AtypDomainName,
NetWork: constant.TCP,
AddrType: C.AtypDomainName,
NetWork: C.TCP,
DstPort: "20000",
})
assert.Equal(t, true, m)
@@ -92,7 +90,7 @@ func TestAND(t *testing.T) {
func TestNOT(t *testing.T) {
not, err := NewNOT("((DST-PORT,6000-6500))", "REJECT", ParseRule)
assert.Equal(t, nil, err)
m, _ := not.Match(&constant.Metadata{
m, _ := not.Match(&C.Metadata{
DstPort: "6100",
})
assert.Equal(t, false, m)
@@ -107,8 +105,8 @@ func TestNOT(t *testing.T) {
func TestOR(t *testing.T) {
or, err := NewOR("((DOMAIN,baidu.com),(NETWORK,TCP),(DST-PORT,10001-65535))", "DIRECT", ParseRule)
assert.Equal(t, nil, err)
m, _ := or.Match(&constant.Metadata{
NetWork: constant.TCP,
m, _ := or.Match(&C.Metadata{
NetWork: C.TCP,
})
assert.Equal(t, true, m)
assert.Equal(t, false, or.ShouldResolveIP())

View File

@@ -43,7 +43,7 @@ func (not *NOT) Match(metadata *C.Metadata) (bool, string) {
return true, not.adapter
}
if m, _ := not.rule.Match(metadata); m {
if m, _ := not.rule.Match(metadata); !m {
return true, not.adapter
}

91
rules/logic/sub_rules.go Normal file
View File

@@ -0,0 +1,91 @@
package logic
import (
"fmt"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/rules/common"
)
type SubRule struct {
*common.Base
payload string
payloadRule C.Rule
subName string
subRules *map[string][]C.Rule
shouldFindProcess *bool
shouldResolveIP *bool
}
func NewSubRule(payload, subName string, sub *map[string][]C.Rule,
parse func(tp, payload, target string, params []string, subRules *map[string][]C.Rule) (parsed C.Rule, parseErr error)) (*SubRule, error) {
payloadRule, err := ParseRuleByPayload(fmt.Sprintf("(%s)", payload), parse)
if err != nil {
return nil, err
}
if len(payloadRule) != 1 {
return nil, fmt.Errorf("Sub-Rule rule must contain one rule")
}
return &SubRule{
Base: &common.Base{},
payload: payload,
payloadRule: payloadRule[0],
subName: subName,
subRules: sub,
}, nil
}
func (r *SubRule) RuleType() C.RuleType {
return C.SubRules
}
func (r *SubRule) Match(metadata *C.Metadata) (bool, string) {
return match(metadata, r.subName, r.subRules)
}
func match(metadata *C.Metadata, name string, subRules *map[string][]C.Rule) (bool, string) {
for _, rule := range (*subRules)[name] {
if m, a := rule.Match(metadata); m {
if rule.RuleType() == C.SubRules {
match(metadata, rule.Adapter(), subRules)
} else {
return m, a
}
}
}
return false, ""
}
func (r *SubRule) ShouldResolveIP() bool {
if r.shouldResolveIP == nil {
s := false
for _, rule := range (*r.subRules)[r.subName] {
s = s || rule.ShouldResolveIP()
}
r.shouldResolveIP = &s
}
return *r.shouldResolveIP
}
func (r *SubRule) ShouldFindProcess() bool {
if r.shouldFindProcess == nil {
s := false
for _, rule := range (*r.subRules)[r.subName] {
s = s || rule.ShouldFindProcess()
}
r.shouldFindProcess = &s
}
return *r.shouldFindProcess
}
func (r *SubRule) Adapter() string {
return r.subName
}
func (r *SubRule) Payload() string {
return r.payload
}