From: Bert Hubert Date: Sat, 22 Mar 2008 18:27:44 +0000 (+0000) Subject: implement multiple forwarders per domain, both from file and from X-Git-Tag: rec-3.1.7.1~73 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e5ae2b29a3af9343e2190fab5571cc4fef4afc4;p=pdns implement multiple forwarders per domain, both from file and from configuration file, based on patch by Aaron Thompson, with work from Augie Schwer. Closes ticket 81. Plus, add support for forwarding to ports != 53, closing ticket 122. git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1168 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index 44238d917..08a0b95ec 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -1,6 +1,6 @@ /* PowerDNS Versatile Database Driven Nameserver - Copyright (C) 2005 - 2007 PowerDNS.COM BV + Copyright (C) 2005 - 2008 PowerDNS.COM BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as diff --git a/pdns/docs/pdns.sgml b/pdns/docs/pdns.sgml index 840b30ccc..d271a7a75 100644 --- a/pdns/docs/pdns.sgml +++ b/pdns/docs/pdns.sgml @@ -7405,6 +7405,10 @@ local0.err /var/log/pdns.err Comma separated list of 'zonename=IP' pairs. Queries for zones listed here will be forwarded to the IP address listed. forward-zones= ds9a.nl=213.244.168.210, powerdns.com=127.0.0.1. Available since 3.1. + + Since version 3.1.5, multiple IP addresses can be specified. Additionally, port numbers other than 53 can be configured. + Sample syntax: forward-zones=ds9a.nl=213.244.168.210:5300;127.0.0.1, powerdns.com=127.0.0.1;9.8.7.6:530, + or on the command line: --forward-zones="ds9a.nl=213.244.168.210:5300;127.0.0.1, powerdns.com=127.0.0.1;9.8.7.6:530", @@ -7412,7 +7416,7 @@ local0.err /var/log/pdns.err Same as forward-zones, parsed from a file. Only 1 zone is allowed per line, specified as follows: - ds9a.nl=213.244.168.210. Available since 3.1.5. + ds9a.nl=213.244.168.210, 1.2.3.4:5300. No comments are allowed. Available since 3.1.5. diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 6b4dea499..106b8a435 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1422,6 +1422,24 @@ static void makeIPToNamesZone(const vector& parts) void parseAuthAndForwards(); +void convertServersForAD(const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, bool verbose=true) +{ + vector servers; + stringtok(servers, input, sepa); + ad.d_servers.clear(); + for(vector::const_iterator iter = servers.begin(); iter != servers.end(); ++iter) { + if(verbose && iter != servers.begin()) + L<<", "; + pair ipport=splitField(*iter, ':'); + ComboAddress addr(ipport.first, ipport.second.empty() ? 53 : lexical_cast(ipport.second)); + if(verbose) + L< fp=shared_ptr(rfp, fclose); char line[1024]; - vector parts; int linenum=0; uint64_t before = SyncRes::s_domainmap.size(); while(linenum++, fgets(line, sizeof(line)-1, fp.get())) { - parts.clear(); - stringtok(parts,line,"=, "); - if(parts.empty()) - continue; - if(parts.size()<2) + string domain, instructions; + tie(domain, instructions)=splitField(line, '='); + trim(domain); + trim(instructions); + + if(domain.empty()) throw AhuException("Error parsing line "+lexical_cast(linenum)+" of " +::arg()["forward-zones-file"]); - trim(parts[0]); - trim(parts[1]); - parts[0]=toCanonic("", parts[0]); - ad.d_server=parts[1]; - // cerr<<"Inserting '"<(linenum)+" of " +::arg()["forward-zones-file"]); + } + + SyncRes::s_domainmap[toCanonic("", domain)]=ad; + } + L<second.d_server; - if(server.empty()) { + const vector& servers = iter->second.d_servers; + if(servers.empty()) { ret.clear(); doOOBResolve(qname, qtype, ret, depth, res); return res; } else { - LOG<& nsset, bool* flawedNSSet, int depth, set&beenthere) { string subdomain(qname); - string authdomain(qname); domainmap_t::const_iterator iter=getBestAuthZone(&authdomain); if(iter!=s_domainmap.end()) { - nsset.insert(iter->second.d_server); // this gets picked up in doResolveAt, if empty it means "we are auth", otherwise it denotes a forward + if( iter->second.d_servers.empty() ) + nsset.insert(string()); // this gets picked up in doResolveAt, if empty it means "we are auth", otherwise it denotes a forward + else { + for(vector::const_iterator server=iter->second.d_servers.begin(); server != iter->second.d_servers.end(); ++server) + nsset.insert(server->toStringWithPort()); + } + return authdomain; } @@ -625,8 +630,12 @@ int SyncRes::doResolveAt(set nameservers, string auth, else { LOG< ipport=splitField(*tns, ':'); + ComboAddress addr(ipport.first, ipport.second.empty() ? 53 : lexical_cast(ipport.second)); + + remoteIPs.push_back(addr); } else remoteIPs=getAs(*tns, depth+1, beenthere); @@ -648,7 +657,7 @@ int SyncRes::doResolveAt(set nameservers, string auth, } for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) { - LOG<toString() <<", asking '"<toStringWithPort() <<", asking '"< d_servers; typedef multi_index_container < DNSResourceRecord, indexed_by <