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  }