rule_domain.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package route
  2. import (
  3. "strings"
  4. "github.com/sagernet/sing-box/adapter"
  5. "github.com/sagernet/sing-box/common/domain"
  6. "github.com/sagernet/sing/common"
  7. )
  8. var _ RuleItem = (*DomainItem)(nil)
  9. type DomainItem struct {
  10. description string
  11. matcher *domain.Matcher
  12. }
  13. func NewDomainItem(domains []string, domainSuffixes []string) *DomainItem {
  14. domains = common.Uniq(domains)
  15. domainSuffixes = common.Uniq(domainSuffixes)
  16. var description string
  17. if dLen := len(domains); dLen > 0 {
  18. if dLen == 1 {
  19. description = "domain=" + domains[0]
  20. } else if dLen > 3 {
  21. description = "domain=[" + strings.Join(domains[:3], " ") + "...]"
  22. } else {
  23. description = "domain=[" + strings.Join(domains, " ") + "]"
  24. }
  25. }
  26. if dsLen := len(domainSuffixes); dsLen > 0 {
  27. if len(description) > 0 {
  28. description += " "
  29. }
  30. if dsLen == 1 {
  31. description += "domainSuffix=" + domainSuffixes[0]
  32. } else if dsLen > 3 {
  33. description += "domainSuffix=[" + strings.Join(domainSuffixes[:3], " ") + "...]"
  34. } else {
  35. description += "domainSuffix=[" + strings.Join(domainSuffixes, " ") + "]"
  36. }
  37. }
  38. return &DomainItem{
  39. description,
  40. domain.NewMatcher(domains, domainSuffixes),
  41. }
  42. }
  43. func (r *DomainItem) Match(metadata *adapter.InboundContext) bool {
  44. var domainHost string
  45. if metadata.Domain != "" {
  46. domainHost = metadata.Domain
  47. } else {
  48. domainHost = metadata.Destination.Fqdn
  49. }
  50. if domainHost == "" {
  51. return false
  52. }
  53. return r.matcher.Match(domainHost)
  54. }
  55. func (r *DomainItem) String() string {
  56. return r.description
  57. }