classical_strategy.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package provider
  2. import (
  3. "fmt"
  4. "strings"
  5. C "github.com/metacubex/mihomo/constant"
  6. P "github.com/metacubex/mihomo/constant/provider"
  7. "github.com/metacubex/mihomo/log"
  8. )
  9. type classicalStrategy struct {
  10. rules []C.Rule
  11. count int
  12. shouldResolveIP bool
  13. shouldFindProcess bool
  14. parse func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error)
  15. }
  16. func (c *classicalStrategy) Behavior() P.RuleBehavior {
  17. return P.Classical
  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. return false
  26. }
  27. func (c *classicalStrategy) Count() int {
  28. return c.count
  29. }
  30. func (c *classicalStrategy) ShouldResolveIP() bool {
  31. return c.shouldResolveIP
  32. }
  33. func (c *classicalStrategy) ShouldFindProcess() bool {
  34. return c.shouldFindProcess
  35. }
  36. func (c *classicalStrategy) Reset() {
  37. c.rules = nil
  38. c.count = 0
  39. c.shouldFindProcess = false
  40. c.shouldResolveIP = false
  41. }
  42. func (c *classicalStrategy) Insert(rule string) {
  43. ruleType, rule, params := ruleParse(rule)
  44. if ruleType == "PROCESS-NAME" {
  45. c.shouldFindProcess = true
  46. }
  47. r, err := c.parse(ruleType, rule, "", params)
  48. if err != nil {
  49. log.Warnln("parse rule error:[%s]", err.Error())
  50. } else {
  51. if r.ShouldResolveIP() {
  52. c.shouldResolveIP = true
  53. }
  54. if r.ShouldFindProcess() {
  55. c.shouldFindProcess = true
  56. }
  57. c.rules = append(c.rules, r)
  58. c.count++
  59. }
  60. }
  61. func (c *classicalStrategy) FinishInsert() {}
  62. func ruleParse(ruleRaw string) (string, string, []string) {
  63. item := strings.Split(ruleRaw, ",")
  64. if len(item) == 1 {
  65. return "", item[0], nil
  66. } else if len(item) == 2 {
  67. return item[0], item[1], nil
  68. } else if len(item) > 2 {
  69. if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" || item[0] == "PROCESS-NAME-REGEX" || item[0] == "PROCESS-PATH-REGEX" {
  70. return item[0], strings.Join(item[1:len(item)], ","), nil
  71. } else {
  72. return item[0], item[1], item[2:]
  73. }
  74. }
  75. return "", "", nil
  76. }
  77. func NewClassicalStrategy(parse func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (parsed C.Rule, parseErr error)) *classicalStrategy {
  78. return &classicalStrategy{rules: []C.Rule{}, parse: func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) {
  79. switch tp {
  80. case "MATCH":
  81. return nil, fmt.Errorf("unsupported rule type on rule-set")
  82. default:
  83. return parse(tp, payload, target, params, nil)
  84. }
  85. }}
  86. }