From db9a7021ac961169a1890cc5c3f7487f97d47684 Mon Sep 17 00:00:00 2001 From: Santhosh Manohar Date: Fri, 9 Sep 2016 21:45:03 -0700 Subject: [PATCH] Drop queries in root doamin when ndots is set Signed-off-by: Santhosh Manohar --- libnetwork/resolver.go | 15 +++++++++++++++ libnetwork/sandbox.go | 1 + libnetwork/sandbox_dns_unix.go | 30 ++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/libnetwork/resolver.go b/libnetwork/resolver.go index b9eb4f3ff2..fcb1a00a02 100644 --- a/libnetwork/resolver.go +++ b/libnetwork/resolver.go @@ -325,6 +325,21 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { return } + // If the user sets ndots > 0 explicitly and the query is + // in the root domain don't forward it out. We will return + // failure and let the client retry with the search domain + // attached + if resp == nil { + switch query.Question[0].Qtype { + case dns.TypeA: + fallthrough + case dns.TypeAAAA: + if r.sb.ndotsSet && !strings.Contains(strings.TrimSuffix(name, "."), ".") { + resp = createRespMsg(query) + } + } + } + proto := w.LocalAddr().Network() maxSize := 0 if proto == "tcp" { diff --git a/libnetwork/sandbox.go b/libnetwork/sandbox.go index 775b92ab31..e077eb628b 100644 --- a/libnetwork/sandbox.go +++ b/libnetwork/sandbox.go @@ -86,6 +86,7 @@ type sandbox struct { isStub bool inDelete bool ingress bool + ndotsSet bool sync.Mutex } diff --git a/libnetwork/sandbox_dns_unix.go b/libnetwork/sandbox_dns_unix.go index 0c649a9b9e..cd9e66224f 100644 --- a/libnetwork/sandbox_dns_unix.go +++ b/libnetwork/sandbox_dns_unix.go @@ -8,6 +8,8 @@ import ( "os" "path" "path/filepath" + "strconv" + "strings" log "github.com/Sirupsen/logrus" "github.com/docker/libnetwork/etchosts" @@ -313,8 +315,32 @@ func (sb *sandbox) rebuildDNS() error { // external v6 DNS servers has to be listed in resolv.conf dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, types.IPv6)...) - // Resolver returns the options in the format resolv.conf expects - dnsOptionsList = append(dnsOptionsList, sb.resolver.ResolverOptions()...) + // If the user config and embedded DNS server both have ndots option set, + // remember the user's config so that unqualified names not in the docker + // domain can be dropped. + resOptions := sb.resolver.ResolverOptions() + +dnsOpt: + for _, resOpt := range resOptions { + if strings.Contains(resOpt, "ndots") { + for _, option := range dnsOptionsList { + if strings.Contains(option, "ndots") { + parts := strings.Split(option, ":") + if len(parts) != 2 { + return fmt.Errorf("invalid ndots option %v", option) + } + if num, err := strconv.Atoi(parts[1]); err != nil { + return fmt.Errorf("invalid number for ndots option %v", option) + } else if num > 0 { + sb.ndotsSet = true + break dnsOpt + } + } + } + } + } + + dnsOptionsList = append(dnsOptionsList, resOptions...) _, err = resolvconf.Build(sb.config.resolvConfPath, dnsList, dnsSearchList, dnsOptionsList) return err