Changeset 731

Show
Ignore:
Timestamp:
04/18/06 23:59:41 (7 years ago)
Author:
ahu
Message:

implement id.server, version.bind ("version-string" and "server-id" in config)
implement remote-ringbuffer, rec_control top-remotes to see who is querying you
implement max-negative-ttl
remove socklen

Location:
trunk/pdns/pdns
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dns.hh

    r681 r731  
    6161{ 
    6262public: 
    63   DNSResourceRecord() : priority(0), d_place(ANSWER) {}; 
     63  DNSResourceRecord() : qclass(1), priority(0), d_place(ANSWER) {}; 
    6464  ~DNSResourceRecord(){}; 
    6565 
     
    7070   
    7171  QType qtype; //!< qtype of this record, ie A, CNAME, MX etc 
     72  uint16_t qclass; //!< class of this record 
    7273  string qname; //!< the name of this record, for example: www.powerdns.com 
    7374  string content; //!< what this record points to. Example: 10.1.2.3 
  • trunk/pdns/pdns/dnsparser.cc

    r699 r731  
    5555    stringtok(parts, tmp); 
    5656    if(parts.size()!=3) 
    57       throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got "+lexical_cast<string>(parts.size())); 
     57      throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got "+lexical_cast<string>(parts.size())+": "+tmp ); 
    5858    const string& relevant=parts[2]; 
    5959    unsigned int total=atoi(parts[1].c_str()); 
  • trunk/pdns/pdns/dnsrecords.cc

    r680 r731  
    283283void reportBasicTypes() 
    284284{ 
    285     ARecordContent::report(); 
    286     AAAARecordContent::report(); 
    287     NSRecordContent::report(); 
    288     CNAMERecordContent::report(); 
    289     MXRecordContent::report(); 
    290     SOARecordContent::report(); 
    291     SRVRecordContent::report(); 
    292     PTRRecordContent::report(); 
     285  ARecordContent::report(); 
     286  AAAARecordContent::report(); 
     287  NSRecordContent::report(); 
     288  CNAMERecordContent::report(); 
     289  MXRecordContent::report(); 
     290  SOARecordContent::report(); 
     291  SRVRecordContent::report(); 
     292  PTRRecordContent::report(); 
     293  DNSRecordContent::regist(3, ns_t_txt, &TXTRecordContent::make, &TXTRecordContent::make, "TXT"); 
    293294} 
    294295 
    295296void reportOtherTypes() 
    296297{ 
    297    TXTRecordContent::report(); 
    298298   SPFRecordContent::report(); 
    299299   NAPTRRecordContent::report(); 
     
    307307   OPTRecordContent::report(); 
    308308   DNSRecordContent::regist(1,255, 0, 0, "ANY"); 
     309   TXTRecordContent::report(); 
    309310} 
    310311 
  • trunk/pdns/pdns/iputils.hh

    r728 r731  
    5050    else 
    5151      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, 16) < 0; 
     52  } 
     53 
     54  socklen_t getSocklen() 
     55  { 
     56    if(sin4.sin_family == AF_INET) 
     57      return sizeof(sin4); 
     58    else 
     59      return sizeof(sin6); 
    5260  } 
    5361 
  • trunk/pdns/pdns/pdns_recursor.cc

    r730 r731  
    8282  { 
    8383    d_remote=*sa; 
    84     d_socklen= d_remote.sin4.sin_family == AF_INET ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); 
    8584  } 
    8685 
     
    9796  struct timeval d_now; 
    9897  ComboAddress d_remote; 
    99   socklen_t d_socklen; 
    10098  bool d_tcp; 
    10199  int d_socket; 
     
    459457      sr.setCacheOnly(); 
    460458 
    461     int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret); 
     459    int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); 
    462460    if(res<0) { 
    463461      pw.getHeader()->rcode=RCode::ServFail; 
     
    482480        shuffle(ret); 
    483481        for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) { 
    484           pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, 1, (DNSPacketWriter::Place)i->d_place); 
    485            
    486           shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), 1, i->content)); 
     482          pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place); 
     483          shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content)); 
    487484           
    488485          drc->toPacket(pw); 
     
    500497  sendit:; 
    501498    if(!dc->d_tcp) { 
    502       sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(&dc->d_remote), dc->d_socklen); 
     499      sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(&dc->d_remote), dc->d_remote.getSocklen()); 
    503500    } 
    504501    else { 
     
    672669  int newsock=accept(fd, (struct sockaddr*)&addr, &addrlen); 
    673670  if(newsock>0) { 
     671    g_stats.addRemote(addr); 
    674672    if(g_allowFrom && !g_allowFrom->match(&addr)) { 
    675673      g_stats.unauthorizedTCP++; 
     
    698696} 
    699697 
    700  
    701698void handleNewUDPQuestion(int fd, boost::any& var) 
    702699{ 
    703   int d_len; 
     700  int len; 
    704701  char data[1500]; 
    705702  ComboAddress fromaddr; 
    706703  socklen_t addrlen=sizeof(fromaddr); 
    707704 
    708   while((d_len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 
     705  if((len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 
     706    g_stats.addRemote(fromaddr); 
    709707    if(g_allowFrom && !g_allowFrom->match(&fromaddr)) { 
    710708      g_stats.unauthorizedUDP++; 
    711       continue; 
     709      return; 
    712710    } 
    713711     
    714712    try { 
    715       DNSComboWriter* dc = new DNSComboWriter(data, d_len, g_now); 
     713      DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); 
    716714       
    717715      dc->setRemote(&fromaddr); 
     
    792790} 
    793791 
    794  
    795792void makeUDPServerSockets() 
    796793{ 
     
    927924 
    928925    sr.setNoCache(); 
    929     int res=sr.beginResolve(".", QType(QType::NS), ret); 
     926    int res=sr.beginResolve(".", QType(QType::NS), 1, ret); 
    930927    if(!res) { 
    931928      L<<Logger::Error<<"Refreshed . records"<<endl; 
     
    11761173    ::arg().set("hint-file", "If set, load root hints from this file")=""; 
    11771174    ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache")="0"; 
     1175    ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory")="3600"; 
     1176    ::arg().set("server-id", "Returned when queried for 'server.id' TXT, defaults to hostname")=""; 
     1177    ::arg().set("remotes-ringbuffer-entries", "maximum number of packets to store statistics for")="0"; 
     1178    ::arg().set("version-string", "maximum number of packets to store statistics for")="PowerDNS Recursor "VERSION" $Id$"; 
    11781179    ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse")="127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12"; 
    11791180    ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)")="0"; 
     
    12391240    } 
    12401241 
     1242    SyncRes::s_maxnegttl=::arg().asNum("max-negative-ttl"); 
     1243    SyncRes::s_serverID=::arg()["server-id"]; 
     1244    if(SyncRes::s_serverID.empty()) { 
     1245      char tmp[128]; 
     1246      gethostname(tmp, sizeof(tmp)-1); 
     1247      SyncRes::s_serverID=tmp; 
     1248    } 
     1249 
     1250    g_stats.remotes.resize(::arg().asNum("remotes-ringbuffer-entries")); 
     1251    memset(&*g_stats.remotes.begin(), 0, g_stats.remotes.size() * sizeof(RecursorStats::remotes_t::value_type)); 
    12411252    g_logCommonErrors=::arg().mustDo("log-common-errors"); 
    12421253 
  • trunk/pdns/pdns/rec_channel_rec.cc

    r721 r731  
    99#include <boost/optional.hpp> 
    1010#include <boost/tuple/tuple.hpp> 
     11#include <boost/format.hpp> 
    1112#include <sys/types.h> 
    1213#include <sys/stat.h> 
     
    182183} 
    183184 
     185string doTopRemotes() 
     186{ 
     187  typedef map<ComboAddress, int> counts_t; 
     188  counts_t counts; 
     189   
     190  unsigned int total=0; 
     191  for(RecursorStats::remotes_t::const_iterator i=g_stats.remotes.begin(); i != g_stats.remotes.end(); ++i) 
     192    if(i->sin4.sin_family) { 
     193      total++; 
     194      counts[*i]++; 
     195    } 
     196 
     197  typedef multimap<int, ComboAddress> rcounts_t; 
     198  rcounts_t rcounts; 
     199   
     200  for(counts_t::const_iterator i=counts.begin(); i != counts.end(); ++i) 
     201    rcounts.insert(make_pair(-i->second, i->first)); 
     202 
     203  ostringstream ret; 
     204  ret<<"Over last "<<total<<" queries:\n"; 
     205  format fmt("%.02f%%\t%s\n"); 
     206  if(total) 
     207    for(rcounts_t::const_iterator i=rcounts.begin(); i != rcounts.end(); ++i) 
     208      ret<< fmt % (-100.0*i->first/total) % i->second.toString(); 
     209 
     210  return ret.str(); 
     211} 
     212 
    184213string RecursorControlParser::getAnswer(const string& question, RecursorControlParser::func_t** command) 
    185214{ 
     
    210239  if(cmd=="wipe-cache")  
    211240    return doWipeCache(begin, end); 
     241 
     242  if(cmd=="top-remotes") 
     243    return doTopRemotes(); 
    212244   
    213245  return "Unknown command '"+cmd+"'\n"; 
  • trunk/pdns/pdns/syncres.cc

    r721 r731  
    4040SyncRes::negcache_t SyncRes::s_negcache;     
    4141SyncRes::nsspeeds_t SyncRes::s_nsSpeeds;     
    42  
     42unsigned int SyncRes::s_maxnegttl; 
    4343unsigned int SyncRes::s_queries; 
    4444unsigned int SyncRes::s_outgoingtimeouts; 
     
    4747unsigned int SyncRes::s_throttledqueries; 
    4848unsigned int SyncRes::s_nodelegated; 
     49string SyncRes::s_serverID; 
    4950bool SyncRes::s_log; 
    5051 
     
    5455 
    5556/** everything begins here - this is the entry point just after receiving a packet */ 
    56 int SyncRes::beginResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret) 
     57int SyncRes::beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret) 
    5758{ 
    5859  s_queries++; 
     
    6364    rr.qname=qname; 
    6465    rr.qtype=qtype; 
     66    rr.qclass=1; 
    6567    rr.ttl=86400; 
    6668    if(qtype.getCode()==QType::PTR) 
     
    6870    else 
    6971      rr.content="127.0.0.1"; 
     72    ret.push_back(rr); 
     73    return 0; 
     74  } 
     75 
     76  if(qclass==3 && qtype.getCode()==QType::TXT &&  
     77        (!strcasecmp(qname.c_str(), "version.bind.") || !strcasecmp(qname.c_str(), "id.server.") || !strcasecmp(qname.c_str(), "version.pdns.") )  
     78     ) { 
     79    ret.clear(); 
     80    DNSResourceRecord rr; 
     81    rr.qname=qname; 
     82    rr.qtype=qtype; 
     83    rr.qclass=qclass; 
     84    rr.ttl=86400; 
     85    if(!strcasecmp(qname.c_str(),"version.bind.")  || !strcasecmp(qname.c_str(),"version.pdns.")) 
     86      rr.content="\""+::arg()["version-string"]+"\""; 
     87    else 
     88      rr.content="\""+s_serverID+"\""; 
    7089    ret.push_back(rr); 
    7190    return 0; 
     
    546565 
    547566          ne.d_qname=i->qname; 
    548           ne.d_ttd=d_now.tv_sec + min(i->ttl, 3600U); // controversial 
     567          ne.d_ttd=d_now.tv_sec + min(i->ttl, s_maxnegttl); // controversial 
    549568          ne.d_name=qname; 
    550569          ne.d_qtype=QType(0); 
  • trunk/pdns/pdns/syncres.hh

    r721 r731  
    1919#include <boost/tuple/tuple_comparison.hpp> 
    2020#include "mtasker.hh" 
    21  
    22 /* external functions, opaque to us */ 
     21#include "iputils.hh" 
    2322 
    2423void primeHints(void); 
     
    215214  explicit SyncRes(const struct timeval& now) :  d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_now(now), 
    216215                                                d_cacheonly(false), d_nocache(false) { } 
    217   int beginResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret); 
     216  int beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret); 
    218217  void setId(int id) 
    219218  { 
     
    269268  static throttle_t s_throttle; 
    270269  struct timeval d_now; 
     270  static unsigned int s_maxnegttl; 
     271  static string s_serverID; 
    271272private: 
    272273  struct GetBestNSAnswer; 
     
    312313}; 
    313314class Socket; 
     315/* external functions, opaque to us */ 
    314316int asendtcp(const string& data, Socket* sock); 
    315317int arecvtcp(string& data, int len, Socket* sock); 
     
    373375  uint64_t spoofCount; 
    374376  uint64_t resourceLimits; 
     377  typedef vector<ComboAddress> remotes_t; 
     378  remotes_t remotes; 
     379  int d_remotepos; 
     380  void addRemote(const ComboAddress& remote) 
     381  { 
     382    if(!remotes.size()) 
     383      return; 
     384 
     385    remotes[(d_remotepos++) % remotes.size()]=remote; 
     386  } 
    375387}; 
    376388