]> granicus.if.org Git - pdns/commitdiff
Stubresolver: Use only `resolver` setting if given
authorPieter Lexis <pieter.lexis@powerdns.com>
Mon, 6 Mar 2017 14:06:26 +0000 (15:06 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 21 Mar 2017 14:24:45 +0000 (15:24 +0100)
Use resolv.conf otherwise. Also, do not use 127.0.0.1:53 as fallback,
as this could be ourselves.

Closes #4655

docs/markdown/authoritative/howtos.md
docs/markdown/authoritative/settings.md
pdns/dnsproxy.cc
pdns/stubresolver.cc
pdns/stubresolver.hh

index 466ca7da78e5498c3791642ad3c837dc962e7d4b..e956e846b6fa895c8ceeac7d68ea52141bc5ca4b 100644 (file)
@@ -185,6 +185,8 @@ resolver=[::1]:5300
 expand-alias=yes
 ```
 
+**note**: If `resolver` is unset, ALIAS expension is disabled!
+
 and add the ALIAS record to your zone apex. e.g.:
 
 ```
index 5e1079d53490d2ab00fed92b7aff0fd2e853d5c2..86ba7b6057ba5c78ab665a14b9e2ce51c9e74489 100644 (file)
@@ -718,10 +718,11 @@ If set, recursive queries will be handed to the recursor specified here. See
 ["Recursion"](recursion.md).
 
 ## `resolver`
-* IP Address
+* IP Addresses with optional port, separated by commas
 * Added in: 4.1.0
 
-Use this resolver for ALIAS and the internal stub resolver.
+Use these resolver addresses for ALIAS and the internal stub resolver.
+If this is not set, `/etc/resolv.conf` is parsed for upstream resolvers.
 
 ## `retrieval-threads`
 * Integer
index 91c60a416b6be28da38afe3f4e8f1aa972ea1d32..5a7cfab05c8aa3b9740ccb4e39c0b1302ffc4d63 100644 (file)
@@ -42,7 +42,10 @@ DNSProxy::DNSProxy(const string &remote)
   d_resanswers=S.getPointer("recursing-answers");
   d_resquestions=S.getPointer("recursing-questions");
   d_udpanswers=S.getPointer("udp-answers");
-  ComboAddress remaddr(remote, 53);
+
+  vector<string> addresses;
+  stringtok(addresses, remote, " ,\t");
+  ComboAddress remaddr(addresses[0], 53);
   
   if((d_sock=socket(remaddr.sin4.sin_family, SOCK_DGRAM,0))<0)
     throw PDNSException(string("socket: ")+strerror(errno));
index 048e411762c979c3345a75bc91c3a064635fa57d..ab15434b2dbf4eca054ee692a1c680d28202273a 100644 (file)
 #include "statbag.hh"
 #include "stubresolver.hh"
 
-// s_stubresolvers contains the ComboAddresses that are used by
+// s_resolversForStub contains the ComboAddresses that are used by
 // stubDoResolve
-static vector<ComboAddress> s_stubresolvers;
+static vector<ComboAddress> s_resolversForStub;
 
-/** Parse /etc/resolv.conf and add the nameservers to the vector
- * s_stubresolvers.
+/*
+ * Returns false if no resolvers are configured, while emitting a warning about this
+ */
+bool resolversDefined()
+{
+  if (s_resolversForStub.empty()) {
+    L<<Logger::Warning<<"No upstream resolvers configured, stub resolving (including secpoll and ALIAS) impossible."<<endl;
+    return false;
+  }
+  return true;
+}
+
+/*
+ * Fill the s_resolversForStub vector with addresses for the upstream resolvers.
+ * First, parse the `resolver` configuration option for IP addresses to use.
+ * If that doesn't work, parse /etc/resolv.conf and add those nameservers to
+ * s_resolversForStub.
  */
 void stubParseResolveConf()
 {
-  ifstream ifs("/etc/resolv.conf");
-  if(!ifs)
-    return;
-
-  string line;
-  while(std::getline(ifs, line)) {
-    boost::trim_right_if(line, is_any_of(" \r\n\x1a"));
-    boost::trim_left(line); // leading spaces, let's be nice
-
-    string::size_type tpos = line.find_first_of(";#");
-    if(tpos != string::npos)
-      line.resize(tpos);
-
-    if(boost::starts_with(line, "nameserver ") || boost::starts_with(line, "nameserver\t")) {
-      vector<string> parts;
-      stringtok(parts, line, " \t,"); // be REALLY nice
-      for(vector<string>::const_iterator iter = parts.begin()+1; iter != parts.end(); ++iter) {
-        try {
-          s_stubresolvers.push_back(ComboAddress(*iter, 53));
-        }
-        catch(...)
-        {
+  if(::arg().mustDo("resolver")) {
+    vector<string> parts;
+    stringtok(parts, ::arg()["resolver"], " ,\t");
+    for (const auto& addr : parts)
+      s_resolversForStub.push_back(ComboAddress(addr, 53));
+  }
+
+  if (s_resolversForStub.empty()) {
+    ifstream ifs("/etc/resolv.conf");
+    if(!ifs)
+      return;
+
+    string line;
+    while(std::getline(ifs, line)) {
+      boost::trim_right_if(line, is_any_of(" \r\n\x1a"));
+      boost::trim_left(line); // leading spaces, let's be nice
+
+      string::size_type tpos = line.find_first_of(";#");
+      if(tpos != string::npos)
+        line.resize(tpos);
+
+      if(boost::starts_with(line, "nameserver ") || boost::starts_with(line, "nameserver\t")) {
+        vector<string> parts;
+        stringtok(parts, line, " \t,"); // be REALLY nice
+        for(vector<string>::const_iterator iter = parts.begin()+1; iter != parts.end(); ++iter) {
+          try {
+            s_resolversForStub.push_back(ComboAddress(*iter, 53));
+          }
+          catch(...)
+          {
+          }
         }
       }
     }
   }
-
-  if(::arg().mustDo("resolver"))
-    s_stubresolvers.push_back(ComboAddress(::arg()["resolver"], 53));
-
-  // Last resort, add 127.0.0.1
-  if(s_stubresolvers.empty()) {
-    s_stubresolvers.push_back(ComboAddress("127.0.0.1", 53));
-  }
+  // Emit a warning if there are no stubs.
+  resolversDefined();
 }
 
-// s_stubresolvers contains the ComboAddresses that are used to resolve the
+// s_resolversForStub contains the ComboAddresses that are used to resolve the
 int stubDoResolve(const DNSName& qname, uint16_t qtype, vector<DNSZoneRecord>& ret)
 {
+  if (!resolversDefined())
+    return RCode::ServFail;
+
   vector<uint8_t> packet;
 
   DNSPacketWriter pw(packet, qname, qtype);
   pw.getHeader()->id=dns_random(0xffff);
   pw.getHeader()->rd=1;
-  if (s_stubresolvers.empty()) {
-    L<<Logger::Warning<<"No recursors set, stub resolving (including secpoll and ALIAS) impossible."<<endl;
-    return RCode::ServFail;
-  }
 
   string msg ="Doing stub resolving, using resolvers: ";
-  for (const auto& server : s_stubresolvers) {
+  for (const auto& server : s_resolversForStub) {
     msg += server.toString() + ", ";
   }
   L<<Logger::Debug<<msg.substr(0, msg.length() - 2)<<endl;
 
-  for(const ComboAddress& dest :  s_stubresolvers) {
+  for(const ComboAddress& dest :  s_resolversForStub) {
     Socket sock(dest.sin4.sin_family, SOCK_DGRAM);
     sock.setNonBlocking();
     sock.connect(dest);
index fbf9aeae1a31a5b2a7d8f7344544efe8c993cb2a..bcbec421da07e5a572486257f7da5a9cdf8caa08 100644 (file)
@@ -24,4 +24,5 @@
 #include "dnsparser.hh"
 
 void stubParseResolveConf();
+bool resolversDefined();
 int stubDoResolve(const DNSName& qname, uint16_t qtype, vector<DNSZoneRecord>& ret);