github.com/yaling888/clash@v1.53.0/dns/filters.go (about) 1 package dns 2 3 import ( 4 "net/netip" 5 "strings" 6 7 "github.com/yaling888/clash/component/geodata/router" 8 "github.com/yaling888/clash/component/mmdb" 9 "github.com/yaling888/clash/component/trie" 10 ) 11 12 type fallbackIPFilter interface { 13 Match(netip.Addr) bool 14 } 15 16 type geoipFilter struct { 17 code string 18 } 19 20 func (gf *geoipFilter) Match(ip netip.Addr) bool { 21 record, _ := mmdb.Instance().Country(ip.AsSlice()) 22 return !strings.EqualFold(record.Country.IsoCode, gf.code) && !ip.IsPrivate() 23 } 24 25 type ipnetFilter struct { 26 ipnet *netip.Prefix 27 } 28 29 func (inf *ipnetFilter) Match(ip netip.Addr) bool { 30 return inf.ipnet.Contains(ip) 31 } 32 33 type fallbackDomainFilter interface { 34 Match(domain string) bool 35 } 36 37 type domainFilter struct { 38 tree *trie.DomainTrie[bool] 39 } 40 41 func NewDomainFilter(domains []string) *domainFilter { 42 df := domainFilter{tree: trie.New[bool]()} 43 for _, domain := range domains { 44 _ = df.tree.Insert(domain, true) 45 } 46 return &df 47 } 48 49 func (df *domainFilter) Match(domain string) bool { 50 return df.tree.Search(domain) != nil 51 } 52 53 type geoSiteFilter struct { 54 matchers []*router.DomainMatcher 55 } 56 57 func (gsf *geoSiteFilter) Match(domain string) bool { 58 for _, matcher := range gsf.matchers { 59 if matcher.ApplyDomain(domain) { 60 return true 61 } 62 } 63 return false 64 }