rule_geosite.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package route
  2. import (
  3. "strings"
  4. "github.com/sagernet/sing-box/adapter"
  5. "github.com/sagernet/sing-box/log"
  6. E "github.com/sagernet/sing/common/exceptions"
  7. )
  8. var _ RuleItem = (*GeositeItem)(nil)
  9. type GeositeItem struct {
  10. router adapter.Router
  11. logger log.ContextLogger
  12. codes []string
  13. matchers []adapter.Rule
  14. }
  15. func NewGeositeItem(router adapter.Router, logger log.ContextLogger, codes []string) *GeositeItem {
  16. return &GeositeItem{
  17. router: router,
  18. logger: logger,
  19. codes: codes,
  20. }
  21. }
  22. func (r *GeositeItem) Update() error {
  23. matchers := make([]adapter.Rule, 0, len(r.codes))
  24. for _, code := range r.codes {
  25. matcher, err := r.router.LoadGeosite(code)
  26. if err != nil {
  27. return E.Cause(err, "read geosite")
  28. }
  29. matchers = append(matchers, matcher)
  30. }
  31. r.matchers = matchers
  32. return nil
  33. }
  34. func (r *GeositeItem) Match(metadata *adapter.InboundContext) bool {
  35. for _, matcher := range r.matchers {
  36. if matcher.Match(metadata) {
  37. return true
  38. }
  39. }
  40. return false
  41. }
  42. func (r *GeositeItem) String() string {
  43. description := "geosite="
  44. cLen := len(r.codes)
  45. if cLen == 1 {
  46. description += r.codes[0]
  47. } else if cLen > 3 {
  48. description += "[" + strings.Join(r.codes[:3], " ") + "...]"
  49. } else {
  50. description += "[" + strings.Join(r.codes, " ") + "]"
  51. }
  52. return description
  53. }