Feature: add support for dns search domains (#2597)

This commit is contained in:
Jeff An 2023-03-17 00:53:06 -07:00 committed by GitHub
parent ff2f2b667b
commit 3b1d319820
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 9 deletions

View File

@ -69,6 +69,7 @@ type DNS struct {
FakeIPRange *fakeip.Pool
Hosts *trie.DomainTrie
NameServerPolicy map[string]dns.NameServer
SearchDomains []string
}
// FallbackFilter config
@ -117,6 +118,7 @@ type RawDNS struct {
FakeIPFilter []string `yaml:"fake-ip-filter"`
DefaultNameserver []string `yaml:"default-nameserver"`
NameServerPolicy map[string]string `yaml:"nameserver-policy"`
SearchDomains []string `yaml:"search-domains"`
}
type RawFallbackFilter struct {
@ -702,6 +704,18 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie) (*DNS, error) {
dnsCfg.Hosts = hosts
}
if len(cfg.SearchDomains) != 0 {
for _, domain := range cfg.SearchDomains {
if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") {
return nil, errors.New("search domains should not start or end with '.'")
}
if strings.Contains(domain, ":") {
return nil, errors.New("search domains are for ipv4 only and should not contain ports")
}
}
dnsCfg.SearchDomains = cfg.SearchDomains
}
return dnsCfg, nil
}

View File

@ -39,6 +39,7 @@ type Resolver struct {
group singleflight.Group
lruCache *cache.LruCache
policy *trie.DomainTrie
searchDomains []string
}
// LookupIP request with TypeA and TypeAAAA, priority return TypeA
@ -285,17 +286,34 @@ func (r *Resolver) lookupIP(ctx context.Context, host string, dnsType uint16) ([
query := &D.Msg{}
query.SetQuestion(D.Fqdn(host), dnsType)
msg, err := r.Exchange(query)
msg, err := r.ExchangeContext(ctx, query)
if err != nil {
return nil, err
}
ips := msgToIP(msg)
if len(ips) == 0 {
if len(ips) != 0 {
return ips, nil
} else if len(r.searchDomains) == 0 {
return nil, resolver.ErrIPNotFound
}
// query provided search domains serially
for _, domain := range r.searchDomains {
q := &D.Msg{}
q.SetQuestion(D.Fqdn(fmt.Sprintf("%s.%s", host, domain)), dnsType)
msg, err := r.ExchangeContext(ctx, q)
if err != nil {
return nil, err
}
ips := msgToIP(msg)
if len(ips) != 0 {
return ips, nil
}
}
return nil, resolver.ErrIPNotFound
}
func (r *Resolver) msgToDomain(msg *D.Msg) string {
if len(msg.Question) > 0 {
@ -336,6 +354,7 @@ type Config struct {
Pool *fakeip.Pool
Hosts *trie.DomainTrie
Policy map[string]NameServer
SearchDomains []string
}
func NewResolver(config Config) *Resolver {
@ -349,6 +368,7 @@ func NewResolver(config Config) *Resolver {
main: transform(config.Main, defaultResolver),
lruCache: cache.New(cache.WithSize(4096), cache.WithStale(true)),
hosts: config.Hosts,
searchDomains: config.SearchDomains,
}
if len(config.Fallback) != 0 {

View File

@ -131,6 +131,7 @@ func updateDNS(c *config.DNS) {
},
Default: c.DefaultNameserver,
Policy: c.NameServerPolicy,
SearchDomains: c.SearchDomains,
}
r := dns.NewResolver(cfg)