github.com/kelleygo/clashcore@v1.0.2/rules/provider/classical_strategy.go (about) 1 package provider 2 3 import ( 4 "fmt" 5 "strings" 6 7 C "github.com/kelleygo/clashcore/constant" 8 "github.com/kelleygo/clashcore/log" 9 ) 10 11 type classicalStrategy struct { 12 rules []C.Rule 13 count int 14 shouldResolveIP bool 15 shouldFindProcess bool 16 parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) 17 } 18 19 func (c *classicalStrategy) Match(metadata *C.Metadata) bool { 20 for _, rule := range c.rules { 21 if m, _ := rule.Match(metadata); m { 22 return true 23 } 24 } 25 26 return false 27 } 28 29 func (c *classicalStrategy) Count() int { 30 return c.count 31 } 32 33 func (c *classicalStrategy) ShouldResolveIP() bool { 34 return c.shouldResolveIP 35 } 36 37 func (c *classicalStrategy) ShouldFindProcess() bool { 38 return c.shouldFindProcess 39 } 40 41 func (c *classicalStrategy) Reset() { 42 c.rules = nil 43 c.count = 0 44 c.shouldFindProcess = false 45 c.shouldResolveIP = false 46 } 47 48 func (c *classicalStrategy) Insert(rule string) { 49 ruleType, rule, params := ruleParse(rule) 50 51 if ruleType == "PROCESS-NAME" { 52 c.shouldFindProcess = true 53 } 54 55 r, err := c.parse(ruleType, rule, "", params) 56 if err != nil { 57 log.Warnln("parse rule error:[%s]", err.Error()) 58 } else { 59 if r.ShouldResolveIP() { 60 c.shouldResolveIP = true 61 } 62 if r.ShouldFindProcess() { 63 c.shouldFindProcess = true 64 } 65 66 c.rules = append(c.rules, r) 67 c.count++ 68 } 69 } 70 71 func (c *classicalStrategy) FinishInsert() {} 72 73 func ruleParse(ruleRaw string) (string, string, []string) { 74 item := strings.Split(ruleRaw, ",") 75 if len(item) == 1 { 76 return "", item[0], nil 77 } else if len(item) == 2 { 78 return item[0], item[1], nil 79 } else if len(item) > 2 { 80 if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" { 81 return item[0], strings.Join(item[1:len(item)], ","), nil 82 } else { 83 return item[0], item[1], item[2:] 84 } 85 } 86 87 return "", "", nil 88 } 89 90 func NewClassicalStrategy(parse func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (parsed C.Rule, parseErr error)) *classicalStrategy { 91 return &classicalStrategy{rules: []C.Rule{}, parse: func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { 92 switch tp { 93 case "MATCH": 94 return nil, fmt.Errorf("unsupported rule type on rule-set") 95 default: 96 return parse(tp, payload, target, params, nil) 97 } 98 }} 99 }