diff --git a/config/config.go b/config/config.go index c4834d58..68863271 100644 --- a/config/config.go +++ b/config/config.go @@ -166,6 +166,7 @@ type DNS struct { FakeIPTTL int NameServerPolicy []dns.Policy ProxyServerNameserver []dns.NameServer + ProxyServerPolicy []dns.Policy DirectNameServer []dns.NameServer DirectFollowPolicy bool } @@ -236,6 +237,7 @@ type RawDNS struct { CacheMaxSize int `yaml:"cache-max-size" json:"cache-max-size"` NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"` ProxyServerNameserver []string `yaml:"proxy-server-nameserver" json:"proxy-server-nameserver"` + ProxyServerNameserverPolicy *orderedmap.OrderedMap[string, any] `yaml:"proxy-server-nameserver-policy" json:"proxy-server-nameserver-policy"` DirectNameServer []string `yaml:"direct-nameserver" json:"direct-nameserver"` DirectNameServerFollowPolicy bool `yaml:"direct-nameserver-follow-policy" json:"direct-nameserver-follow-policy"` } @@ -1403,6 +1405,10 @@ func parseDNS(rawCfg *RawConfig, ruleProviders map[string]P.RuleProvider) (*DNS, return nil, err } + if dnsCfg.ProxyServerPolicy, err = parseNameServerPolicy(cfg.ProxyServerNameserverPolicy, ruleProviders, false, cfg.PreferH3); err != nil { + return nil, err + } + if dnsCfg.DirectNameServer, err = parseNameServer(cfg.DirectNameServer, false, cfg.PreferH3); err != nil { return nil, err } diff --git a/dns/resolver.go b/dns/resolver.go index fd51507d..9184fbfb 100644 --- a/dns/resolver.go +++ b/dns/resolver.go @@ -451,6 +451,7 @@ type Config struct { FallbackIPFilter []C.IpMatcher FallbackDomainFilter []C.DomainMatcher Policy []Policy + ProxyServerPolicy []Policy CacheAlgorithm string CacheMaxSize int } @@ -519,55 +520,20 @@ func NewResolver(config Config) (rs Resolvers) { return } - r := &Resolver{ - ipv6: config.IPv6, - main: cacheTransform(config.Main), - cache: config.newCache(), - ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, - } - r.defaultResolver = defaultResolver - rs.Resolver = r - - if len(config.ProxyServer) != 0 { - rs.ProxyResolver = &Resolver{ - ipv6: config.IPv6, - main: cacheTransform(config.ProxyServer), - cache: config.newCache(), - ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, - } - } - - if len(config.DirectServer) != 0 { - rs.DirectResolver = &Resolver{ - ipv6: config.IPv6, - main: cacheTransform(config.DirectServer), - cache: config.newCache(), - ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, - } - } - - if len(config.Fallback) != 0 { - r.fallback = cacheTransform(config.Fallback) - r.fallbackIPFilters = config.FallbackIPFilter - r.fallbackDomainFilters = config.FallbackDomainFilter - } - - if len(config.Policy) != 0 { - r.policy = make([]dnsPolicy, 0) - + makePolicy := func(policies []Policy) (dnsPolicies []dnsPolicy) { var triePolicy *trie.DomainTrie[[]dnsClient] insertPolicy := func(policy dnsPolicy) { if triePolicy != nil { triePolicy.Optimize() - r.policy = append(r.policy, domainTriePolicy{triePolicy}) + dnsPolicies = append(dnsPolicies, domainTriePolicy{triePolicy}) triePolicy = nil } if policy != nil { - r.policy = append(r.policy, policy) + dnsPolicies = append(dnsPolicies, policy) } } - for _, policy := range config.Policy { + for _, policy := range policies { if policy.Matcher != nil { insertPolicy(domainMatcherPolicy{matcher: policy.Matcher, dnsClients: cacheTransform(policy.NameServers)}) } else { @@ -578,12 +544,47 @@ func NewResolver(config Config) (rs Resolvers) { } } insertPolicy(nil) + return + } - if rs.DirectResolver != nil && config.DirectFollowPolicy { + r := &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.Main), + cache: config.newCache(), + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + policy: makePolicy(config.Policy), + } + r.defaultResolver = defaultResolver + rs.Resolver = r + + if len(config.ProxyServer) != 0 { + rs.ProxyResolver = &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.ProxyServer), + cache: config.newCache(), + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + policy: makePolicy(config.ProxyServerPolicy), + } + } + + if len(config.DirectServer) != 0 { + rs.DirectResolver = &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.DirectServer), + cache: config.newCache(), + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + } + if config.DirectFollowPolicy { rs.DirectResolver.policy = r.policy } } + if len(config.Fallback) != 0 { + r.fallback = cacheTransform(config.Fallback) + r.fallbackIPFilters = config.FallbackIPFilter + r.fallbackDomainFilters = config.FallbackDomainFilter + } + return } diff --git a/docs/config.yaml b/docs/config.yaml index a70a48b8..190d1690 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -318,8 +318,10 @@ dns: # 专用于节点域名解析的 DNS 服务器,非必要配置项,如果不填则遵循nameserver-policy、nameserver和fallback的配置 # proxy-server-nameserver: - # - https://dns.google/dns-query - # - tls://one.one.one.one + # - https://doh.pub/dns-query + # - tls://223.5.5.5:853 + # proxy-server-nameserver-policy: # 格式同nameserver-policy,仅用于节点域名解析 + # 'www.yournode.com': '114.114.114.114' # 专用于direct出口域名解析的 DNS 服务器,非必要配置项,如果不填则遵循nameserver-policy、nameserver和fallback的配置 # direct-nameserver: diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 3091f838..5db0744a 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -258,6 +258,7 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { Default: c.DefaultNameserver, Policy: c.NameServerPolicy, ProxyServer: c.ProxyServerNameserver, + ProxyServerPolicy: c.ProxyServerPolicy, DirectServer: c.DirectNameServer, DirectFollowPolicy: c.DirectFollowPolicy, CacheAlgorithm: c.CacheAlgorithm,