Changeset 1168

Show
Ignore:
Timestamp:
03/22/08 19:27:44 (6 years ago)
Author:
ahu
Message:

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.

Location:
trunk/pdns/pdns
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dnsrecords.cc

    r1148 r1168  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2005 - 2007  PowerDNS.COM BV 
     3    Copyright (C) 2005 - 2008  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
  • trunk/pdns/pdns/docs/pdns.sgml

    r1163 r1168  
    74067406                <command>forward-zones= ds9a.nl=213.244.168.210, powerdns.com=127.0.0.1</command>. Available since 3.1. 
    74077407              </para> 
     7408              <para> 
     7409                Since version 3.1.5, multiple IP addresses can be specified. Additionally, port numbers other than 53 can be configured. 
     7410                Sample syntax: <command>forward-zones=ds9a.nl=213.244.168.210:5300;127.0.0.1, powerdns.com=127.0.0.1;9.8.7.6:530</command>, 
     7411                or on the command line: <command>--forward-zones="ds9a.nl=213.244.168.210:5300;127.0.0.1, powerdns.com=127.0.0.1;9.8.7.6:530"</command>, 
    74087412            </listitem> 
    74097413          </varlistentry> 
     
    74137417              <para> 
    74147418                Same as <command>forward-zones</command>, parsed from a file. Only 1 zone is allowed per line, specified as follows: 
    7415                 <command>ds9a.nl=213.244.168.210</command>. Available since 3.1.5. 
     7419                <command>ds9a.nl=213.244.168.210, 1.2.3.4:5300</command>. No comments are allowed. Available since 3.1.5.  
    74167420              </para> 
    74177421            </listitem> 
  • trunk/pdns/pdns/pdns_recursor.cc

    r1164 r1168  
    14231423void parseAuthAndForwards(); 
    14241424 
     1425void convertServersForAD(const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, bool verbose=true) 
     1426{ 
     1427  vector<string> servers; 
     1428  stringtok(servers, input, sepa); 
     1429  ad.d_servers.clear(); 
     1430  for(vector<string>::const_iterator iter = servers.begin(); iter != servers.end(); ++iter) { 
     1431    if(verbose && iter != servers.begin())  
     1432      L<<", "; 
     1433    pair<string,string> ipport=splitField(*iter, ':'); 
     1434    ComboAddress addr(ipport.first, ipport.second.empty() ? 53 : lexical_cast<uint16_t>(ipport.second)); 
     1435    if(verbose) 
     1436      L<<addr.toStringWithPort(); 
     1437    ad.d_servers.push_back(addr); 
     1438  } 
     1439  if(verbose) 
     1440    L<<endl; 
     1441} 
     1442 
    14251443string reloadAuthAndForwards() 
    14261444{ 
     
    15081526      } 
    15091527      else { 
    1510         L<<Logger::Error<<"Redirecting queries for zone '"<<headers.first<<"' to IP '"<<headers.second<<"'"<<endl; 
    1511         ad.d_server=headers.second; 
     1528        L<<Logger::Error<<"Redirecting queries for zone '"<<headers.first<<"' to: "; 
     1529        convertServersForAD(headers.second, ad, ";"); 
    15121530      } 
    15131531       
     
    15271545     
    15281546    char line[1024]; 
    1529     vector<string> parts; 
    15301547    int linenum=0; 
    15311548    uint64_t before = SyncRes::s_domainmap.size(); 
    15321549    while(linenum++, fgets(line, sizeof(line)-1, fp.get())) { 
    1533       parts.clear(); 
    1534       stringtok(parts,line,"=, "); 
    1535       if(parts.empty()) 
    1536         continue; 
    1537       if(parts.size()<2)  
     1550      string domain, instructions; 
     1551      tie(domain, instructions)=splitField(line, '='); 
     1552      trim(domain); 
     1553      trim(instructions); 
     1554 
     1555      if(domain.empty())  
    15381556        throw AhuException("Error parsing line "+lexical_cast<string>(linenum)+" of " +::arg()["forward-zones-file"]); 
    1539       trim(parts[0]); 
    1540       trim(parts[1]); 
    1541       parts[0]=toCanonic("", parts[0]); 
    1542       ad.d_server=parts[1]; 
    1543       //      cerr<<"Inserting '"<<domain<<"' to '"<<ad.d_server<<"'\n"; 
    1544       SyncRes::s_domainmap[parts[0]]=ad; 
    1545     } 
    1546     L<<Logger::Warning<<"Done parsing " << SyncRes::s_domainmap.size() - before<<" forwarding instructions from file '"<<::arg()["forward-zones-files"]<<"'"<<endl; 
     1557 
     1558      try { 
     1559        convertServersForAD(instructions, ad, ",; ", false); 
     1560      } 
     1561      catch(...) { 
     1562        throw AhuException("Conversion error parsing line "+lexical_cast<string>(linenum)+" of " +::arg()["forward-zones-file"]); 
     1563      } 
     1564 
     1565      SyncRes::s_domainmap[toCanonic("", domain)]=ad; 
     1566    } 
     1567    L<<Logger::Warning<<"Done parsing " << SyncRes::s_domainmap.size() - before<<" forwarding instructions from file '"<<::arg()["forward-zones-file"]<<"'"<<endl; 
    15471568  } 
    15481569 
  • trunk/pdns/pdns/syncres.cc

    r1160 r1168  
    204204      domainmap_t::const_iterator iter=getBestAuthZone(&authname); 
    205205      if(iter != s_domainmap.end()) { 
    206         string server=iter->second.d_server; 
    207         if(server.empty()) { 
     206        const vector<ComboAddress>& servers = iter->second.d_servers; 
     207        if(servers.empty()) { 
    208208          ret.clear(); 
    209209          doOOBResolve(qname, qtype, ret, depth, res); 
     
    211211        } 
    212212        else { 
    213           LOG<<prefix<<qname<<": forwarding query to hardcoded nameserver '"<<server<<"' for zone '"<<authname<<"'"<<endl; 
    214           ComboAddress remoteIP(server, 53); 
     213          const ComboAddress remoteIP = servers.front(); 
     214          LOG<<prefix<<qname<<": forwarding query to hardcoded nameserver '"<< remoteIP.toStringWithPort()<<"' for zone '"<<authname<<"'"<<endl; 
    215215 
    216216          res=asyncresolve(remoteIP, qname, qtype.getCode(), false, false, &d_now, &lwr);     
     
    373373{ 
    374374  string subdomain(qname); 
    375  
    376375  string authdomain(qname); 
    377376   
    378377  domainmap_t::const_iterator iter=getBestAuthZone(&authdomain); 
    379378  if(iter!=s_domainmap.end()) { 
    380     nsset.insert(iter->second.d_server); // this gets picked up in doResolveAt, if empty it means "we are auth", otherwise it denotes a forward 
     379    if( iter->second.d_servers.empty() ) 
     380      nsset.insert(string()); // this gets picked up in doResolveAt, if empty it means "we are auth", otherwise it denotes a forward 
     381    else { 
     382      for(vector<ComboAddress>::const_iterator server=iter->second.d_servers.begin(); server != iter->second.d_servers.end(); ++server) 
     383        nsset.insert(server->toStringWithPort()); 
     384    } 
     385 
    381386    return authdomain; 
    382387  } 
     
    626631        LOG<<prefix<<qname<<": Trying to resolve NS '"<<*tns<<"' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl; 
    627632        if(!isCanonical(*tns)) { 
    628           LOG<<prefix<<qname<<": Domain has hardcoded nameserver"<<endl; 
    629           remoteIPs.push_back(ComboAddress(*tns, 53)); 
     633          LOG<<prefix<<qname<<": Domain has hardcoded nameserver(s)"<<endl; 
     634 
     635          pair<string,string> ipport=splitField(*tns, ':'); 
     636          ComboAddress addr(ipport.first, ipport.second.empty() ? 53 : lexical_cast<uint16_t>(ipport.second)); 
     637 
     638          remoteIPs.push_back(addr); 
    630639        } 
    631640        else 
     
    649658 
    650659        for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) { 
    651           LOG<<prefix<<qname<<": Trying IP "<< remoteIP->toString() <<", asking '"<<qname<<"|"<<qtype.getName()<<"'"<<endl; 
     660          LOG<<prefix<<qname<<": Trying IP "<< remoteIP->toStringWithPort() <<", asking '"<<qname<<"|"<<qtype.getName()<<"'"<<endl; 
    652661          extern NetmaskGroup* g_dontQuery; 
    653662           
  • trunk/pdns/pdns/syncres.hh

    r1157 r1168  
    327327  struct AuthDomain 
    328328  { 
    329     string d_server; 
     329    vector<ComboAddress> d_servers; 
    330330    typedef multi_index_container < 
    331331      DNSResourceRecord,