chore: cleanup dns policy match code
Some checks are pending
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run

This commit is contained in:
wwqgtxx 2024-08-15 20:04:24 +08:00
parent 4c10d42fbf
commit 92ec5f2236
9 changed files with 241 additions and 420 deletions

View File

@ -20,9 +20,9 @@ import (
N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/auth"
"github.com/metacubex/mihomo/component/cidr"
"github.com/metacubex/mihomo/component/fakeip"
"github.com/metacubex/mihomo/component/geodata"
"github.com/metacubex/mihomo/component/geodata/router"
P "github.com/metacubex/mihomo/component/process"
"github.com/metacubex/mihomo/component/resolver"
SNIFF "github.com/metacubex/mihomo/component/sniffer"
@ -114,33 +114,25 @@ type NTP struct {
// DNS config
type DNS struct {
Enable bool `yaml:"enable"`
PreferH3 bool `yaml:"prefer-h3"`
IPv6 bool `yaml:"ipv6"`
IPv6Timeout uint `yaml:"ipv6-timeout"`
UseSystemHosts bool `yaml:"use-system-hosts"`
NameServer []dns.NameServer `yaml:"nameserver"`
Fallback []dns.NameServer `yaml:"fallback"`
FallbackFilter FallbackFilter `yaml:"fallback-filter"`
Listen string `yaml:"listen"`
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
CacheAlgorithm string `yaml:"cache-algorithm"`
Enable bool
PreferH3 bool
IPv6 bool
IPv6Timeout uint
UseSystemHosts bool
NameServer []dns.NameServer
Fallback []dns.NameServer
FallbackIPFilter []C.Rule
FallbackDomainFilter []C.Rule
Listen string
EnhancedMode C.DNSMode
DefaultNameserver []dns.NameServer
CacheAlgorithm string
FakeIPRange *fakeip.Pool
Hosts *trie.DomainTrie[resolver.HostValue]
NameServerPolicy *orderedmap.OrderedMap[string, []dns.NameServer]
NameServerPolicy []dns.Policy
ProxyServerNameserver []dns.NameServer
}
// FallbackFilter config
type FallbackFilter struct {
GeoIP bool `yaml:"geoip"`
GeoIPCode string `yaml:"geoip-code"`
IPCIDR []netip.Prefix `yaml:"ipcidr"`
Domain []string `yaml:"domain"`
GeoSite []router.DomainMatcher `yaml:"geosite"`
}
// Profile config
type Profile struct {
StoreSelected bool `yaml:"store-selected"`
@ -1205,49 +1197,13 @@ func parsePureDNSServer(server string) string {
}
}
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) (*orderedmap.OrderedMap[string, []dns.NameServer], error) {
policy := orderedmap.New[string, []dns.NameServer]()
updatedPolicy := orderedmap.New[string, any]()
func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) {
var policy []dns.Policy
re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)
for pair := nsPolicy.Oldest(); pair != nil; pair = pair.Next() {
k, v := pair.Key, pair.Value
if strings.Contains(strings.ToLower(k), ",") {
if strings.Contains(k, "geosite:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, subkey := range subkeys {
newKey := "geosite:" + subkey
updatedPolicy.Store(newKey, v)
}
} else if strings.Contains(strings.ToLower(k), "rule-set:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, subkey := range subkeys {
newKey := "rule-set:" + subkey
updatedPolicy.Store(newKey, v)
}
} else if re.MatchString(k) {
subkeys := strings.Split(k, ",")
for _, subkey := range subkeys {
updatedPolicy.Store(subkey, v)
}
}
} else {
if strings.Contains(strings.ToLower(k), "geosite:") {
updatedPolicy.Store("geosite:"+k[8:], v)
} else if strings.Contains(strings.ToLower(k), "rule-set:") {
updatedPolicy.Store("rule-set:"+k[9:], v)
}
updatedPolicy.Store(k, v)
}
}
for pair := updatedPolicy.Oldest(); pair != nil; pair = pair.Next() {
domain, server := pair.Key, pair.Value
servers, err := utils.ToStringSlice(server)
servers, err := utils.ToStringSlice(v)
if err != nil {
return nil, err
}
@ -1255,75 +1211,65 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro
if err != nil {
return nil, err
}
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
if strings.Contains(strings.ToLower(k), ",") {
if strings.Contains(k, "geosite:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, subkey := range subkeys {
newKey := "geosite:" + subkey
policy = append(policy, dns.Policy{Domain: newKey, NameServers: nameservers})
}
} else if strings.Contains(strings.ToLower(k), "rule-set:") {
subkeys := strings.Split(k, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, subkey := range subkeys {
newKey := "rule-set:" + subkey
policy = append(policy, dns.Policy{Domain: newKey, NameServers: nameservers})
}
} else if re.MatchString(k) {
subkeys := strings.Split(k, ",")
for _, subkey := range subkeys {
policy = append(policy, dns.Policy{Domain: subkey, NameServers: nameservers})
}
}
} else {
if strings.Contains(strings.ToLower(k), "geosite:") {
policy = append(policy, dns.Policy{Domain: "geosite:" + k[8:], NameServers: nameservers})
} else if strings.Contains(strings.ToLower(k), "rule-set:") {
policy = append(policy, dns.Policy{Domain: "rule-set:" + k[9:], NameServers: nameservers})
} else {
policy = append(policy, dns.Policy{Domain: k, NameServers: nameservers})
}
}
}
for idx, p := range policy {
domain, nameservers := p.Domain, p.NameServers
if strings.HasPrefix(domain, "rule-set:") {
domainSetName := domain[9:]
if provider, ok := ruleProviders[domainSetName]; !ok {
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
} else {
switch provider.Behavior() {
case providerTypes.IPCIDR:
return nil, fmt.Errorf("rule provider type error, except domain,actual %s", provider.Behavior())
case providerTypes.Classical:
log.Warnln("%s provider is %s, only matching it contain domain rule", provider.Name(), provider.Behavior())
}
}
}
policy.Store(domain, nameservers)
}
return policy, nil
}
func parseFallbackIPCIDR(ips []string) ([]netip.Prefix, error) {
var ipNets []netip.Prefix
for idx, ip := range ips {
ipnet, err := netip.ParsePrefix(ip)
if err != nil {
return nil, fmt.Errorf("DNS FallbackIP[%d] format error: %s", idx, err.Error())
}
ipNets = append(ipNets, ipnet)
}
return ipNets, nil
}
func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]router.DomainMatcher, error) {
var sites []router.DomainMatcher
if len(countries) > 0 {
if err := geodata.InitGeoSite(); err != nil {
return nil, fmt.Errorf("can't initial GeoSite: %s", err)
}
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
}
for _, country := range countries {
found := false
for _, rule := range rules {
if rule.RuleType() == C.GEOSITE {
if strings.EqualFold(country, rule.Payload()) {
found = true
sites = append(sites, rule.(C.RuleGeoSite).GetDomainMatcher())
log.Infoln("Start initial GeoSite dns fallback filter from rule `%s`", country)
}
}
}
if !found {
matcher, recordsCount, err := geodata.LoadGeoSiteMatcher(country)
rule, err := parseDomainRuleSet(domainSetName, ruleProviders)
if err != nil {
return nil, err
}
sites = append(sites, matcher)
log.Infoln("Start initial GeoSite dns fallback filter `%s`, records: %d", country, recordsCount)
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
} else if strings.HasPrefix(domain, "geosite:") {
country := domain[8:]
rule, err := parseGEOSITE(country, rules)
if err != nil {
return nil, err
}
policy[idx] = dns.Policy{Rule: rule, NameServers: nameservers}
} else {
if _, valid := trie.ValidAndSplitDomain(domain); !valid {
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
}
}
}
return sites, nil
return policy, nil
}
func paresNTP(rawCfg *RawConfig) *NTP {
@ -1357,10 +1303,6 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
IPv6: cfg.IPv6,
UseSystemHosts: cfg.UseSystemHosts,
EnhancedMode: cfg.EnhancedMode,
FallbackFilter: FallbackFilter{
IPCIDR: []netip.Prefix{},
GeoSite: []router.DomainMatcher{},
},
}
var err error
if dnsCfg.NameServer, err = parseNameServer(cfg.NameServer, cfg.RespectRules, cfg.PreferH3); err != nil {
@ -1371,7 +1313,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
return nil, err
}
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, rules, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
return nil, err
}
@ -1438,18 +1380,51 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rul
dnsCfg.FakeIPRange = pool
}
var rule C.Rule
if len(cfg.Fallback) != 0 {
dnsCfg.FallbackFilter.GeoIP = cfg.FallbackFilter.GeoIP
dnsCfg.FallbackFilter.GeoIPCode = cfg.FallbackFilter.GeoIPCode
if fallbackip, err := parseFallbackIPCIDR(cfg.FallbackFilter.IPCIDR); err == nil {
dnsCfg.FallbackFilter.IPCIDR = fallbackip
if cfg.FallbackFilter.GeoIP {
rule, err = RC.NewGEOIP(cfg.FallbackFilter.GeoIPCode, "", false, true)
if err != nil {
return nil, fmt.Errorf("load GeoIP dns fallback filter error, %w", err)
}
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
}
dnsCfg.FallbackFilter.Domain = cfg.FallbackFilter.Domain
fallbackGeoSite, err := parseFallbackGeoSite(cfg.FallbackFilter.GeoSite, rules)
if err != nil {
return nil, fmt.Errorf("load GeoSite dns fallback filter error, %w", err)
if len(cfg.FallbackFilter.IPCIDR) > 0 {
cidrSet := cidr.NewIpCidrSet()
for idx, ipcidr := range cfg.FallbackFilter.IPCIDR {
err = cidrSet.AddIpCidrForString(ipcidr)
if err != nil {
return nil, fmt.Errorf("DNS FallbackIP[%d] format error: %w", idx, err)
}
}
err = cidrSet.Merge()
if err != nil {
return nil, err
}
rule = RP.NewIpCidrSet(cidrSet, "")
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
}
if len(cfg.FallbackFilter.Domain) > 0 {
domainTrie := trie.New[struct{}]()
for idx, domain := range cfg.FallbackFilter.Domain {
err = domainTrie.Insert(domain, struct{}{})
if err != nil {
return nil, fmt.Errorf("DNS FallbackDomain[%d] format error: %w", idx, err)
}
}
rule = RP.NewDomainSet(domainTrie.NewDomainSet(), "")
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
}
if len(cfg.FallbackFilter.GeoSite) > 0 {
log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
for idx, geoSite := range cfg.FallbackFilter.GeoSite {
rule, err = parseGEOSITE(geoSite, rules)
if err != nil {
return nil, fmt.Errorf("DNS FallbackGeosite[%d] format error: %w", idx, err)
}
dnsCfg.FallbackIPFilter = append(dnsCfg.FallbackIPFilter, rule)
}
}
dnsCfg.FallbackFilter.GeoSite = fallbackGeoSite
}
if cfg.UseHosts {
@ -1636,44 +1611,21 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], rules
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, country := range subkeys {
found := false
for _, rule = range rules {
if rule.RuleType() == C.GEOSITE {
if strings.EqualFold(country, rule.Payload()) {
found = true
domainRules = append(domainRules, rule)
}
}
}
if !found {
rule, err = RC.NewGEOSITE(country, "")
if err != nil {
return nil, err
}
domainRules = append(domainRules, rule)
rule, err = parseGEOSITE(country, rules)
if err != nil {
return nil, err
}
domainRules = append(domainRules, rule)
}
} else if strings.Contains(domainLower, "rule-set:") {
subkeys := strings.Split(domain, ":")
subkeys = subkeys[1:]
subkeys = strings.Split(subkeys[0], ",")
for _, domainSetName := range subkeys {
if rp, ok := ruleProviders[domainSetName]; !ok {
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
} else {
switch rp.Behavior() {
case providerTypes.IPCIDR:
return nil, fmt.Errorf("rule provider type error, except domain,actual %s", rp.Behavior())
case providerTypes.Classical:
log.Warnln("%s provider is %s, only matching it contain domain rule", rp.Name(), rp.Behavior())
default:
}
}
rule, err = RP.NewRuleSet(domainSetName, "", true)
rule, err = parseDomainRuleSet(domainSetName, ruleProviders)
if err != nil {
return nil, err
}
domainRules = append(domainRules, rule)
}
} else {
@ -1692,3 +1644,29 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], rules
}
return
}
func parseDomainRuleSet(domainSetName string, ruleProviders map[string]providerTypes.RuleProvider) (C.Rule, error) {
if rp, ok := ruleProviders[domainSetName]; !ok {
return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
} else {
switch rp.Behavior() {
case providerTypes.IPCIDR:
return nil, fmt.Errorf("rule provider type error, except domain,actual %s", rp.Behavior())
case providerTypes.Classical:
log.Warnln("%s provider is %s, only matching it contain domain rule", rp.Name(), rp.Behavior())
default:
}
}
return RP.NewRuleSet(domainSetName, "", true)
}
func parseGEOSITE(country string, rules []C.Rule) (C.Rule, error) {
for _, rule := range rules {
if rule.RuleType() == C.GEOSITE {
if strings.EqualFold(country, rule.Payload()) {
return rule, nil
}
}
}
return RC.NewGEOSITE(country, "")
}

View File

@ -28,6 +28,7 @@ const (
ProcessPathRegex
RuleSet
DomainSet
IpCidrSet
Network
Uid
SubRules
@ -93,6 +94,8 @@ func (rt RuleType) String() string {
return "RuleSet"
case DomainSet:
return "DomainSet"
case IpCidrSet:
return "IpCidrSet"
case Network:
return "Network"
case DSCP:
@ -121,3 +124,8 @@ type Rule interface {
ShouldFindProcess() bool
ProviderNames() []string
}
type RuleGroup interface {
Rule
GetRecodeSize() int
}

View File

@ -1,17 +0,0 @@
package constant
import (
"github.com/metacubex/mihomo/component/geodata/router"
)
type RuleGeoSite interface {
GetDomainMatcher() router.DomainMatcher
}
type RuleGeoIP interface {
GetIPMatcher() *router.GeoIPMatcher
}
type RuleGroup interface {
GetRecodeSize() int
}

View File

@ -1,102 +0,0 @@
package dns
import (
"net/netip"
"strings"
"github.com/metacubex/mihomo/component/geodata"
"github.com/metacubex/mihomo/component/geodata/router"
"github.com/metacubex/mihomo/component/mmdb"
"github.com/metacubex/mihomo/component/trie"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
)
type fallbackIPFilter interface {
Match(netip.Addr) bool
}
type geoipFilter struct {
code string
}
var geoIPMatcher *router.GeoIPMatcher
func (gf *geoipFilter) Match(ip netip.Addr) bool {
if !C.GeodataMode {
codes := mmdb.IPInstance().LookupCode(ip.AsSlice())
for _, code := range codes {
if !strings.EqualFold(code, gf.code) && !ip.IsPrivate() {
return true
}
}
return false
}
if geoIPMatcher == nil {
var err error
geoIPMatcher, _, err = geodata.LoadGeoIPMatcher("CN")
if err != nil {
log.Errorln("[GeoIPFilter] LoadGeoIPMatcher error: %s", err.Error())
return false
}
}
return !geoIPMatcher.Match(ip)
}
type ipnetFilter struct {
ipnet netip.Prefix
}
func (inf *ipnetFilter) Match(ip netip.Addr) bool {
return inf.ipnet.Contains(ip)
}
type fallbackDomainFilter interface {
Match(domain string) bool
}
type domainFilter struct {
tree *trie.DomainTrie[struct{}]
}
func NewDomainFilter(domains []string) *domainFilter {
df := domainFilter{tree: trie.New[struct{}]()}
for _, domain := range domains {
_ = df.tree.Insert(domain, struct{}{})
}
df.tree.Optimize()
return &df
}
func (df *domainFilter) Match(domain string) bool {
return df.tree.Search(domain) != nil
}
type geoSiteFilter struct {
matchers []router.DomainMatcher
}
func NewGeoSite(group string) (fallbackDomainFilter, error) {
if err := geodata.InitGeoSite(); err != nil {
log.Errorln("can't initial GeoSite: %s", err)
return nil, err
}
matcher, _, err := geodata.LoadGeoSiteMatcher(group)
if err != nil {
return nil, err
}
filter := &geoSiteFilter{
matchers: []router.DomainMatcher{matcher},
}
return filter, nil
}
func (gsf *geoSiteFilter) Match(domain string) bool {
for _, matcher := range gsf.matchers {
if matcher.ApplyDomain(domain) {
return true
}
}
return false
}

View File

@ -3,7 +3,6 @@ package dns
import (
"github.com/metacubex/mihomo/component/trie"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/provider"
)
type dnsPolicy interface {
@ -22,32 +21,14 @@ func (p domainTriePolicy) Match(domain string) []dnsClient {
return nil
}
type geositePolicy struct {
matcher fallbackDomainFilter
inverse bool
type domainRulePolicy struct {
rule C.Rule
dnsClients []dnsClient
}
func (p geositePolicy) Match(domain string) []dnsClient {
matched := p.matcher.Match(domain)
if matched != p.inverse {
func (p domainRulePolicy) Match(domain string) []dnsClient {
if ok, _ := p.rule.Match(&C.Metadata{Host: domain}); ok {
return p.dnsClients
}
return nil
}
type domainSetPolicy struct {
tunnel provider.Tunnel
name string
dnsClients []dnsClient
}
func (p domainSetPolicy) Match(domain string) []dnsClient {
if ruleProvider, ok := p.tunnel.RuleProviders()[p.name]; ok {
metadata := &C.Metadata{Host: domain}
if ok := ruleProvider.Match(metadata); ok {
return p.dnsClients
}
}
return nil
}

View File

@ -4,13 +4,11 @@ import (
"context"
"errors"
"net/netip"
"strings"
"time"
"github.com/metacubex/mihomo/common/arc"
"github.com/metacubex/mihomo/common/lru"
"github.com/metacubex/mihomo/component/fakeip"
"github.com/metacubex/mihomo/component/geodata/router"
"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/component/trie"
C "github.com/metacubex/mihomo/constant"
@ -19,7 +17,6 @@ import (
D "github.com/miekg/dns"
"github.com/samber/lo"
orderedmap "github.com/wk8/go-ordered-map/v2"
"golang.org/x/exp/maps"
"golang.org/x/sync/singleflight"
)
@ -45,8 +42,8 @@ type Resolver struct {
hosts *trie.DomainTrie[resolver.HostValue]
main []dnsClient
fallback []dnsClient
fallbackDomainFilters []fallbackDomainFilter
fallbackIPFilters []fallbackIPFilter
fallbackDomainFilters []C.Rule
fallbackIPFilters []C.Rule
group singleflight.Group
cache dnsCache
policy []dnsPolicy
@ -122,7 +119,7 @@ func (r *Resolver) LookupIPv6(ctx context.Context, host string) ([]netip.Addr, e
func (r *Resolver) shouldIPFallback(ip netip.Addr) bool {
for _, filter := range r.fallbackIPFilters {
if filter.Match(ip) {
if ok, _ := filter.Match(&C.Metadata{DstIP: ip}); ok {
return true
}
}
@ -277,7 +274,7 @@ func (r *Resolver) shouldOnlyQueryFallback(m *D.Msg) bool {
}
for _, df := range r.fallbackDomainFilters {
if df.Match(domain) {
if ok, _ := df.Match(&C.Metadata{Host: domain}); ok {
return true
}
}
@ -398,27 +395,26 @@ func (ns NameServer) Equal(ns2 NameServer) bool {
return false
}
type FallbackFilter struct {
GeoIP bool
GeoIPCode string
IPCIDR []netip.Prefix
Domain []string
GeoSite []router.DomainMatcher
type Policy struct {
Domain string
Rule C.Rule
NameServers []NameServer
}
type Config struct {
Main, Fallback []NameServer
Default []NameServer
ProxyServer []NameServer
IPv6 bool
IPv6Timeout uint
EnhancedMode C.DNSMode
FallbackFilter FallbackFilter
Pool *fakeip.Pool
Hosts *trie.DomainTrie[resolver.HostValue]
Policy *orderedmap.OrderedMap[string, []NameServer]
Tunnel provider.Tunnel
CacheAlgorithm string
Main, Fallback []NameServer
Default []NameServer
ProxyServer []NameServer
IPv6 bool
IPv6Timeout uint
EnhancedMode C.DNSMode
FallbackIPFilter []C.Rule
FallbackDomainFilter []C.Rule
Pool *fakeip.Pool
Hosts *trie.DomainTrie[resolver.HostValue]
Policy []Policy
Tunnel provider.Tunnel
CacheAlgorithm string
}
func NewResolver(config Config) *Resolver {
@ -482,7 +478,7 @@ func NewResolver(config Config) *Resolver {
r.proxyServer = cacheTransform(config.ProxyServer)
}
if config.Policy.Len() != 0 {
if len(config.Policy) != 0 {
r.policy = make([]dnsPolicy, 0)
var triePolicy *trie.DomainTrie[[]dnsClient]
@ -497,75 +493,20 @@ func NewResolver(config Config) *Resolver {
}
}
for pair := config.Policy.Oldest(); pair != nil; pair = pair.Next() {
domain, nameserver := pair.Key, pair.Value
if temp := strings.Split(domain, ":"); len(temp) == 2 {
prefix := temp[0]
key := temp[1]
switch prefix {
case "rule-set":
if _, ok := config.Tunnel.RuleProviders()[key]; ok {
log.Debugln("Adding rule-set policy: %s ", key)
insertPolicy(domainSetPolicy{
tunnel: config.Tunnel,
name: key,
dnsClients: cacheTransform(nameserver),
})
continue
} else {
log.Warnln("Can't found ruleset policy: %s", key)
}
case "geosite":
inverse := false
if strings.HasPrefix(key, "!") {
inverse = true
key = key[1:]
}
log.Debugln("Adding geosite policy: %s inversed %t", key, inverse)
matcher, err := NewGeoSite(key)
if err != nil {
log.Warnln("adding geosite policy %s error: %s", key, err)
continue
}
insertPolicy(geositePolicy{
matcher: matcher,
inverse: inverse,
dnsClients: cacheTransform(nameserver),
})
continue // skip triePolicy new
for _, policy := range config.Policy {
if policy.Rule != nil {
insertPolicy(domainRulePolicy{rule: policy.Rule, dnsClients: cacheTransform(policy.NameServers)})
} else {
if triePolicy == nil {
triePolicy = trie.New[[]dnsClient]()
}
_ = triePolicy.Insert(policy.Domain, cacheTransform(policy.NameServers))
}
if triePolicy == nil {
triePolicy = trie.New[[]dnsClient]()
}
_ = triePolicy.Insert(domain, cacheTransform(nameserver))
}
insertPolicy(nil)
}
fallbackIPFilters := []fallbackIPFilter{}
if config.FallbackFilter.GeoIP {
fallbackIPFilters = append(fallbackIPFilters, &geoipFilter{
code: config.FallbackFilter.GeoIPCode,
})
}
for _, ipnet := range config.FallbackFilter.IPCIDR {
fallbackIPFilters = append(fallbackIPFilters, &ipnetFilter{ipnet: ipnet})
}
r.fallbackIPFilters = fallbackIPFilters
fallbackDomainFilters := []fallbackDomainFilter{}
if len(config.FallbackFilter.Domain) != 0 {
fallbackDomainFilters = append(fallbackDomainFilters, NewDomainFilter(config.FallbackFilter.Domain))
}
if len(config.FallbackFilter.GeoSite) != 0 {
fallbackDomainFilters = append(fallbackDomainFilters, &geoSiteFilter{
matchers: config.FallbackFilter.GeoSite,
})
}
r.fallbackDomainFilters = fallbackDomainFilters
r.fallbackIPFilters = config.FallbackIPFilter
r.fallbackDomainFilters = config.FallbackDomainFilter
return r
}

View File

@ -222,25 +222,20 @@ func updateDNS(c *config.DNS, generalIPv6 bool) {
return
}
cfg := dns.Config{
Main: c.NameServer,
Fallback: c.Fallback,
IPv6: c.IPv6 && generalIPv6,
IPv6Timeout: c.IPv6Timeout,
EnhancedMode: c.EnhancedMode,
Pool: c.FakeIPRange,
Hosts: c.Hosts,
FallbackFilter: dns.FallbackFilter{
GeoIP: c.FallbackFilter.GeoIP,
GeoIPCode: c.FallbackFilter.GeoIPCode,
IPCIDR: c.FallbackFilter.IPCIDR,
Domain: c.FallbackFilter.Domain,
GeoSite: c.FallbackFilter.GeoSite,
},
Default: c.DefaultNameserver,
Policy: c.NameServerPolicy,
ProxyServer: c.ProxyServerNameserver,
Tunnel: tunnel.Tunnel,
CacheAlgorithm: c.CacheAlgorithm,
Main: c.NameServer,
Fallback: c.Fallback,
IPv6: c.IPv6 && generalIPv6,
IPv6Timeout: c.IPv6Timeout,
EnhancedMode: c.EnhancedMode,
Pool: c.FakeIPRange,
Hosts: c.Hosts,
FallbackIPFilter: c.FallbackIPFilter,
FallbackDomainFilter: c.FallbackDomainFilter,
Default: c.DefaultNameserver,
Policy: c.NameServerPolicy,
ProxyServer: c.ProxyServerNameserver,
Tunnel: tunnel.Tunnel,
CacheAlgorithm: c.CacheAlgorithm,
}
r := dns.NewResolver(cfg)

View File

@ -19,10 +19,7 @@ func (d *DomainSet) RuleType() C.RuleType {
}
func (d *DomainSet) Match(metadata *C.Metadata) (bool, string) {
if d.domainSet == nil {
return false, ""
}
return d.domainSet.Has(metadata.RuleHost()), d.adapter
return d.domainStrategy.Match(metadata), d.adapter
}
func (d *DomainSet) Adapter() string {

View File

@ -0,0 +1,40 @@
package provider
import (
"github.com/metacubex/mihomo/component/cidr"
C "github.com/metacubex/mihomo/constant"
)
type IpCidrSet struct {
*ipcidrStrategy
adapter string
}
func (d *IpCidrSet) ProviderNames() []string {
return nil
}
func (d *IpCidrSet) RuleType() C.RuleType {
return C.IpCidrSet
}
func (d *IpCidrSet) Match(metadata *C.Metadata) (bool, string) {
return d.ipcidrStrategy.Match(metadata), d.adapter
}
func (d *IpCidrSet) Adapter() string {
return d.adapter
}
func (d *IpCidrSet) Payload() string {
return ""
}
func NewIpCidrSet(cidrSet *cidr.IpCidrSet, adapter string) *IpCidrSet {
return &IpCidrSet{
ipcidrStrategy: &ipcidrStrategy{cidrSet: cidrSet},
adapter: adapter,
}
}
var _ C.Rule = (*IpCidrSet)(nil)