rule_set_local.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package route
  2. import (
  3. "context"
  4. "os"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-box/common/srs"
  7. C "github.com/sagernet/sing-box/constant"
  8. "github.com/sagernet/sing-box/option"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. "github.com/sagernet/sing/common/json"
  11. )
  12. var _ adapter.RuleSet = (*LocalRuleSet)(nil)
  13. type LocalRuleSet struct {
  14. rules []adapter.HeadlessRule
  15. metadata adapter.RuleSetMetadata
  16. }
  17. func NewLocalRuleSet(router adapter.Router, options option.RuleSet) (*LocalRuleSet, error) {
  18. var plainRuleSet option.PlainRuleSet
  19. switch options.Format {
  20. case C.RuleSetFormatSource, "":
  21. content, err := os.ReadFile(options.LocalOptions.Path)
  22. if err != nil {
  23. return nil, err
  24. }
  25. compat, err := json.UnmarshalExtended[option.PlainRuleSetCompat](content)
  26. if err != nil {
  27. return nil, err
  28. }
  29. plainRuleSet = compat.Upgrade()
  30. case C.RuleSetFormatBinary:
  31. setFile, err := os.Open(options.LocalOptions.Path)
  32. if err != nil {
  33. return nil, err
  34. }
  35. plainRuleSet, err = srs.Read(setFile, false)
  36. if err != nil {
  37. return nil, err
  38. }
  39. default:
  40. return nil, E.New("unknown rule set format: ", options.Format)
  41. }
  42. rules := make([]adapter.HeadlessRule, len(plainRuleSet.Rules))
  43. var err error
  44. for i, ruleOptions := range plainRuleSet.Rules {
  45. rules[i], err = NewHeadlessRule(router, ruleOptions)
  46. if err != nil {
  47. return nil, E.Cause(err, "parse rule_set.rules.[", i, "]")
  48. }
  49. }
  50. var metadata adapter.RuleSetMetadata
  51. metadata.ContainsProcessRule = hasHeadlessRule(plainRuleSet.Rules, isProcessHeadlessRule)
  52. metadata.ContainsWIFIRule = hasHeadlessRule(plainRuleSet.Rules, isWIFIHeadlessRule)
  53. return &LocalRuleSet{rules, metadata}, nil
  54. }
  55. func (s *LocalRuleSet) Match(metadata *adapter.InboundContext) bool {
  56. for _, rule := range s.rules {
  57. if rule.Match(metadata) {
  58. return true
  59. }
  60. }
  61. return false
  62. }
  63. func (s *LocalRuleSet) StartContext(ctx context.Context, startContext adapter.RuleSetStartContext) error {
  64. return nil
  65. }
  66. func (s *LocalRuleSet) PostStart() error {
  67. return nil
  68. }
  69. func (s *LocalRuleSet) Metadata() adapter.RuleSetMetadata {
  70. return s.metadata
  71. }
  72. func (s *LocalRuleSet) Close() error {
  73. return nil
  74. }