feat: nameserver policy support multiple server

This commit is contained in:
Skyxim 2023-02-03 21:40:05 +08:00
parent 99662b616f
commit e1e1984d3e
3 changed files with 30 additions and 12 deletions

View file

@ -8,6 +8,7 @@ import (
"net/netip" "net/netip"
"net/url" "net/url"
"os" "os"
"reflect"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
@ -97,7 +98,7 @@ type DNS struct {
DefaultNameserver []dns.NameServer `yaml:"default-nameserver"` DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
FakeIPRange *fakeip.Pool FakeIPRange *fakeip.Pool
Hosts *trie.DomainTrie[netip.Addr] Hosts *trie.DomainTrie[netip.Addr]
NameServerPolicy map[string]dns.NameServer NameServerPolicy map[string][]dns.NameServer
ProxyServerNameserver []dns.NameServer ProxyServerNameserver []dns.NameServer
} }
@ -181,7 +182,7 @@ type RawDNS struct {
FakeIPRange string `yaml:"fake-ip-range"` FakeIPRange string `yaml:"fake-ip-range"`
FakeIPFilter []string `yaml:"fake-ip-filter"` FakeIPFilter []string `yaml:"fake-ip-filter"`
DefaultNameserver []string `yaml:"default-nameserver"` DefaultNameserver []string `yaml:"default-nameserver"`
NameServerPolicy map[string]string `yaml:"nameserver-policy"` NameServerPolicy map[string]any `yaml:"nameserver-policy"`
ProxyServerNameserver []string `yaml:"proxy-server-nameserver"` ProxyServerNameserver []string `yaml:"proxy-server-nameserver"`
} }
@ -952,18 +953,35 @@ func parsePureDNSServer(server string) string {
} }
} }
} }
func parseNameServerPolicy(nsPolicy map[string]string, preferH3 bool) (map[string]dns.NameServer, error) { func parseNameServerPolicy(nsPolicy map[string]any, preferH3 bool) (map[string][]dns.NameServer, error) {
policy := map[string]dns.NameServer{} policy := map[string][]dns.NameServer{}
for domain, server := range nsPolicy { for domain, server := range nsPolicy {
nameservers, err := parseNameServer([]string{server}, preferH3) var (
nameservers []dns.NameServer
err error
)
switch reflect.TypeOf(server).Kind() {
case reflect.Slice, reflect.Array:
origin := reflect.ValueOf(server)
servers := make([]string, 0)
for i := 0; i < origin.Len(); i++ {
servers = append(servers, fmt.Sprintf("%v", origin.Index(i)))
}
nameservers, err = parseNameServer(servers, preferH3)
case reflect.String:
nameservers, err = parseNameServer([]string{fmt.Sprintf("%v", server)}, preferH3)
default:
return nil, errors.New("server format error, must be string or array")
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, valid := trie.ValidAndSplitDomain(domain); !valid { if _, valid := trie.ValidAndSplitDomain(domain); !valid {
return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain) return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
} }
policy[domain] = nameservers[0] policy[domain] = nameservers
} }
return policy, nil return policy, nil

View file

@ -109,7 +109,7 @@ func NewEnhancer(cfg Config) *ResolverEnhancer {
if cfg.EnhancedMode != C.DNSNormal { if cfg.EnhancedMode != C.DNSNormal {
fakePool = cfg.Pool fakePool = cfg.Pool
mapping = cache.New[netip.Addr, string](cache.WithSize[netip.Addr, string](4096), cache.WithStale[netip.Addr, string](true)) mapping = cache.New(cache.WithSize[netip.Addr, string](4096), cache.WithStale[netip.Addr, string](true))
} }
return &ResolverEnhancer{ return &ResolverEnhancer{

View file

@ -423,19 +423,19 @@ type Config struct {
FallbackFilter FallbackFilter FallbackFilter FallbackFilter
Pool *fakeip.Pool Pool *fakeip.Pool
Hosts *trie.DomainTrie[netip.Addr] Hosts *trie.DomainTrie[netip.Addr]
Policy map[string]NameServer Policy map[string][]NameServer
} }
func NewResolver(config Config) *Resolver { func NewResolver(config Config) *Resolver {
defaultResolver := &Resolver{ defaultResolver := &Resolver{
main: transform(config.Default, nil), main: transform(config.Default, nil),
lruCache: cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)), lruCache: cache.New(cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
} }
r := &Resolver{ r := &Resolver{
ipv6: config.IPv6, ipv6: config.IPv6,
main: transform(config.Main, defaultResolver), main: transform(config.Main, defaultResolver),
lruCache: cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)), lruCache: cache.New(cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true)),
hosts: config.Hosts, hosts: config.Hosts,
} }
@ -464,11 +464,11 @@ func NewResolver(config Config) *Resolver {
} }
r.geositePolicy = append(r.geositePolicy, geositePolicyRecord{ r.geositePolicy = append(r.geositePolicy, geositePolicyRecord{
matcher: matcher, matcher: matcher,
policy: NewPolicy(transform([]NameServer{nameserver}, defaultResolver)), policy: NewPolicy(transform(nameserver, defaultResolver)),
inversedMatching: inverse, inversedMatching: inverse,
}) })
} else { } else {
_ = r.policy.Insert(domain, NewPolicy(transform([]NameServer{nameserver}, defaultResolver))) _ = r.policy.Insert(domain, NewPolicy(transform(nameserver, defaultResolver)))
} }
} }
r.policy.Optimize() r.policy.Optimize()