]> granicus.if.org Git - pdns/commitdiff
implement --forward-zones-recurse and special '+domain=1.2.3.4' syntax for forward...
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 6 Dec 2009 17:20:10 +0000 (17:20 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 6 Dec 2009 17:20:10 +0000 (17:20 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1451 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/pdns_recursor.cc
pdns/syncres.cc
pdns/syncres.hh

index 614ca73dfefa0bd17e59e2278be1d3853bdbb1d8..101894229035630ef5e8f56fcc6c433c7a184266 100644 (file)
@@ -1544,9 +1544,10 @@ void parseAuthAndForwards()
 
   typedef vector<string> parts_t;
   parts_t parts;  
-  for(int n=0; n < 2 ; ++n ) {
+  const char *option_names[3]={"auth-zones", "forward-zones", "forward-zones-recurse"};
+  for(int n=0; n < 3 ; ++n ) {
     parts.clear();
-    stringtok(parts, ::arg()[n ? "forward-zones" : "auth-zones"], ",\t\n\r");
+    stringtok(parts, ::arg()[option_names[n]], ",\t\n\r");
     for(parts_t::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) {
       SyncRes::AuthDomain ad;
       pair<string,string> headers=splitField(*iter, '=');
@@ -1554,28 +1555,37 @@ void parseAuthAndForwards()
       trim(headers.second);
       headers.first=toCanonic("", headers.first);
       if(n==0) {
-       L<<Logger::Error<<"Parsing authoritative data for zone '"<<headers.first<<"' from file '"<<headers.second<<"'"<<endl;
-       ZoneParserTNG zpt(headers.second, headers.first);
-       DNSResourceRecord rr;
-       while(zpt.get(rr)) {
-         try {
-           string tmp=DNSRR2String(rr);
-           rr=String2DNSRR(rr.qname, rr.qtype, tmp, rr.ttl);
-         }
-         catch(std::exception &e) {
-           throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
-         }
-         catch(...) {
-           throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
-         }
-
-         ad.d_records.insert(rr);
-
-       }
+        L<<Logger::Error<<"Parsing authoritative data for zone '"<<headers.first<<"' from file '"<<headers.second<<"'"<<endl;
+        ZoneParserTNG zpt(headers.second, headers.first);
+        DNSResourceRecord rr;
+        while(zpt.get(rr)) {
+          try {
+            string tmp=DNSRR2String(rr);
+            rr=String2DNSRR(rr.qname, rr.qtype, tmp, rr.ttl);
+          }
+          catch(std::exception &e) {
+            throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
+          }
+          catch(...) {
+            throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
+          }
+
+          ad.d_records.insert(rr);
+        }
       }
       else {
-       L<<Logger::Error<<"Redirecting queries for zone '"<<headers.first<<"' to: ";
-       convertServersForAD(headers.second, ad, ";");
+        L<<Logger::Error<<"Redirecting queries for zone '"<<headers.first<<"' ";
+        if(n == 2) {
+          L<<"with recursion ";
+          ad.d_rdForward = 1;
+        }
+        else ad.d_rdForward = 0;
+        L<<"to: ";
+        
+        convertServersForAD(headers.second, ad, ";");
+        if(n == 2) {
+          ad.d_rdForward = 1;
+        }
       }
       
       SyncRes::s_domainmap[headers.first]=ad;
@@ -1600,7 +1610,12 @@ void parseAuthAndForwards()
       tie(domain, instructions)=splitField(line, '=');
       trim(domain);
       trim(instructions);
-
+      if(boost::starts_with(domain,"+")) {
+        domain=domain.c_str()+1;
+        ad.d_rdForward = true;
+      }
+      else
+        ad.d_rdForward = false;
       if(domain.empty()) 
        throw AhuException("Error parsing line "+lexical_cast<string>(linenum)+" of " +::arg()["forward-zones-file"]);
 
@@ -2113,6 +2128,7 @@ int main(int argc, char **argv)
     ::arg().set("single-socket", "If set, only use a single socket for outgoing queries")="off";
     ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ")="";
     ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs")="";
+    ::arg().set("forward-zones-recurse", "Zones for which we forward queries, comma separated domain=ip pairs")="";
     ::arg().set("forward-zones-file", "File with domain=ip pairs for forwarding")="";
     ::arg().set("export-etc-hosts", "If we should serve up contents from /etc/hosts")="off";
     ::arg().set("etc-hosts-file", "Path to 'hosts' file")="/etc/hosts";
index ecdc88dedf69f04295d298ab531e477e6e55bca0..096e71a01b73fe9557955de0ba2e9253186cad37 100644 (file)
@@ -554,7 +554,7 @@ string SyncRes::getBestNSNamesFromCache(const string &qname, set<string, CIStrin
       nsset.insert(string()); // this gets picked up in doResolveAt, if empty it means "we are auth", otherwise it denotes a forward
     else {
       for(vector<ComboAddress>::const_iterator server=iter->second.d_servers.begin(); server != iter->second.d_servers.end(); ++server)
-       nsset.insert(server->toStringWithPort());
+       nsset.insert((iter->second.d_rdForward ? "+" : "-") + server->toStringWithPort()); // add a '+' if the rd bit should be set
     }
 
     return authdomain;
@@ -827,11 +827,15 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
        if(!isCanonical(*tns)) {
          LOG<<prefix<<qname<<": Domain has hardcoded nameserver(s)"<<endl;
 
-         ComboAddress addr=parseIPAndPort(*tns, 53);
+         string txtAddr = *tns;
+         if(!tns->empty()) {
+           sendRDQuery = txtAddr[0] == '+';
+           txtAddr=txtAddr.c_str()+1;
+         }
+         ComboAddress addr=parseIPAndPort(txtAddr, 53);
          
          remoteIPs.push_back(addr);
          pierceDontQuery=true;
-         //      sendRDQuery=true;
        }
        else {
          remoteIPs=getAs(*tns, depth+1, beenthere);
index 1f9af4cf8567c90750eab8454331fd34aa8a4628..fa2f54b475c591b60b07e9f42736a9f65ea143cd 100644 (file)
@@ -362,6 +362,7 @@ public:
   struct AuthDomain
   {
     vector<ComboAddress> d_servers;
+    bool d_rdForward;
     typedef multi_index_container <
       DNSResourceRecord,
       indexed_by <