Show
Ignore:
Timestamp:
10/10/05 21:42:06 (8 years ago)
Author:
ahu
Message:

the gist is: move pdns_recursor over to new {zone,packet}-{parser,generator} stuff
this means the pdns_recursor does not use DNSPacket anymore (yay)
Commit adds:

d_qtype storage to all DNSRecordContent classes
infrastructure to extract *only* the record for a packet, assuming it came with a qname
add reportAllTypes() if you want to be able to parse all types,

reportBasicTypes() for the pdns_recursor
reportOtherTypes() if you want the rest too

updates Makefile.am so everything compiles again
fix endian issues in packetwriter/parser

remove virtualness/inheritance from the pdns_recursor storage cache (teeny speedup)

Things might be a bit scary in the recursor now.

Files:
1 modified

Legend:

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

    r508 r514  
    4141#include <boost/tuple/tuple_comparison.hpp> 
    4242#include <boost/shared_array.hpp> 
    43  
     43#include <boost/lexical_cast.hpp> 
     44#include "dnsparser.hh" 
     45#include "dnswriter.hh" 
     46#include "dnsrecords.hh" 
    4447using namespace boost; 
    4548 
     
    5457 
    5558string s_programname="pdns_recursor"; 
     59 
     60struct DNSComboWriter { 
     61  DNSComboWriter(const char* data, uint16_t len) : d_mdp(data, len), d_tcp(false), d_socket(-1) 
     62  {} 
     63  MOADNSParser d_mdp; 
     64  void setRemote(struct sockaddr* sa, socklen_t len) 
     65  { 
     66    memcpy((void *)d_remote, (void *)sa, len); 
     67    d_socklen=len; 
     68  } 
     69 
     70  void setSocket(int sock) 
     71  { 
     72    d_socket=sock; 
     73  } 
     74  char d_remote[sizeof(sockaddr_in6)]; 
     75  socklen_t d_socklen; 
     76  bool d_tcp; 
     77  int d_socket; 
     78}; 
     79 
    5680 
    5781#if 0 
     
    206230    arr.qname=nsrr.content=templ; 
    207231    arr.content=ips[c-'a']; 
    208     set<DNSResourceRecord>aset; 
     232    set<DNSResourceRecord> aset; 
    209233    aset.insert(arr); 
    210     RC.replace(string(templ),QType(QType::A),aset); 
     234    RC.replace(string(templ), QType(QType::A), aset); 
    211235 
    212236    nsset.insert(nsrr); 
     
    219243  try { 
    220244    bool quiet=arg().mustDo("quiet"); 
    221     DNSPacket P=*(DNSPacket *)p; 
    222  
    223     delete (DNSPacket *)p; 
    224      
    225     vector<DNSResourceRecord>ret; 
    226     DNSPacket *R=P.replyPacket(); 
    227     R->setA(false); 
    228     R->setRA(true); 
     245    DNSComboWriter* dc=(DNSComboWriter *)p; 
     246 
     247    vector<DNSResourceRecord> ret; 
     248     
     249    vector<uint8_t> packet; 
     250    DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); 
     251 
     252    pw.getHeader()->aa=0; 
     253    pw.getHeader()->ra=1; 
     254    pw.getHeader()->id=dc->d_mdp.d_header.id; 
     255 
    229256    //    MT->setTitle("udp question for "+P.qdomain+"|"+P.qtype.getName()); 
    230257    SyncRes sr; 
    231258    if(!quiet) 
    232       L<<Logger::Error<<"["<<MT->getTid()<<"] " << (R->d_tcp ? "TCP " : "") << "question for '"<<P.qdomain<<"|"<<P.qtype.getName()<<"' from "<<P.getRemote()<<endl; 
     259      L<<Logger::Error<<"["<<MT->getTid()<<"] " << (dc->d_tcp ? "TCP " : "") << "question for '"<<dc->d_mdp.d_qname<<"|"<<dc->d_mdp.d_qtype<<"' from "<<"1.2.3.4"<<endl; 
    233260 
    234261    sr.setId(MT->getTid()); 
    235     if(!P.d.rd) 
     262    if(!dc->d_mdp.d_header.rd) 
    236263      sr.setCacheOnly(); 
    237264 
    238     int res=sr.beginResolve(P.qdomain, P.qtype, ret); 
     265    int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret); 
    239266    if(res<0) 
    240       R->setRcode(RCode::ServFail); 
     267      pw.getHeader()->rcode=RCode::ServFail; 
    241268    else { 
    242       R->setRcode(res); 
    243       for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) 
    244         R->addRecord(*i); 
     269      pw.getHeader()->rcode=res; 
     270      for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) { 
     271        pw.startRecord(i->qname, i->qtype.getCode()); 
     272        shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), 1, i->content));   
     273        drc->toPacket(pw); 
     274      } 
     275      pw.commit(); 
    245276    } 
    246277 
    247     const char *buffer=R->getData(); 
    248  
    249     if(!R->d_tcp) { 
     278    if(!dc->d_tcp) { 
     279      /* 
    250280      if(R->len > 512) { 
    251281        R->truncate(512); 
    252282      } 
    253  
    254       sendto(R->getSocket(),buffer,R->len,0,(struct sockaddr *)(R->remote),R->d_socklen); 
     283      */ 
     284 
     285      sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(dc->d_remote), dc->d_socklen); 
    255286    } 
    256287    else { 
    257288      char buf[2]; 
    258       buf[0]=R->len/256; 
    259       buf[1]=R->len%256; 
     289      buf[0]=packet.size()/256; 
     290      buf[1]=packet.size()%256; 
    260291 
    261292      struct iovec iov[2]; 
    262293 
    263       iov[0].iov_base=(void*)buf;    iov[0].iov_len=2; 
    264       iov[1].iov_base=(void*)buffer; iov[1].iov_len = R->len; 
    265  
    266       int ret=writev(R->getSocket(), iov, 2); 
     294      iov[0].iov_base=(void*)buf;              iov[0].iov_len=2; 
     295      iov[1].iov_base=(void*)&*packet.begin(); iov[1].iov_len = packet.size(); 
     296 
     297      int ret=writev(dc->d_socket, iov, 2); 
    267298 
    268299      if(ret <= 0 )  
    269         L<<Logger::Error<<"Error writing TCP answer to "<<P.getRemote()<<": "<< (ret ? strerror(errno) : "EOF") <<endl; 
    270       else if(ret != 2 + R->len) 
    271         L<<Logger::Error<<"Oops, partial answer sent to "<<P.getRemote()<<" - probably would have trouble receiving our answer anyhow (size="<<R->len<<")"<<endl; 
     300        L<<Logger::Error<<"Error writing TCP answer to "<<"1.2.3.4"<<": "<< (ret ? strerror(errno) : "EOF") <<endl; 
     301      else if((unsigned int)ret != 2 + packet.size()) 
     302        L<<Logger::Error<<"Oops, partial answer sent to "<<"1.2.3.4"<<" - probably would have trouble receiving our answer anyhow (size="<<packet.size()<<")"<<endl; 
    272303 
    273304      //      if(write(R->getSocket(),buf,2)!=2 || write(R->getSocket(),buffer,R->len)!=R->len) 
     
    277308    //    MT->setTitle("DONE! udp question for "+P.qdomain+"|"+P.qtype.getName()); 
    278309    if(!quiet) { 
    279       L<<Logger::Error<<"["<<MT->getTid()<<"] answer to "<<(P.d.rd?"":"non-rd ")<<"question '"<<P.qdomain<<"|"<<P.qtype.getName(); 
    280       L<<"': "<<ntohs(R->d.ancount)<<" answers, "<<ntohs(R->d.arcount)<<" additional, took "<<sr.d_outqueries<<" packets, "<< 
     310      L<<Logger::Error<<"["<<MT->getTid()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<<dc->d_mdp.d_qname<<"|"<<dc->d_mdp.d_qtype; 
     311      L<<"': "<<ntohs(pw.getHeader()->ancount)<<" answers, "<<ntohs(pw.getHeader()->arcount)<<" additional, took "<<sr.d_outqueries<<" packets, "<< 
    281312        sr.d_throttledqueries<<" throttled, "<<sr.d_timeouts<<" timeouts, "<<sr.d_tcpoutqueries<<" tcp connections, rcode="<<res<<endl; 
    282313    } 
    283314     
    284315    sr.d_outqueries ? RC.cacheMisses++ : RC.cacheHits++;  
    285  
    286     delete R; 
     316    delete dc; 
    287317  } 
    288318  catch(AhuException &ae) { 
     
    410440  close(1); 
    411441  close(2); 
    412  
    413442} 
    414443#endif 
     
    426455  SyncRes::setLog(true); 
    427456} 
    428  
    429  
    430457 
    431458void doStats(void) 
     
    459486  if(now -last_rootupdate>7200) { 
    460487    SyncRes sr; 
    461     vector<DNSResourceRecord>ret; 
     488    vector<DNSResourceRecord> ret; 
    462489 
    463490    sr.setNoCache(); 
     
    515542int main(int argc, char **argv)  
    516543{ 
     544  ARecordContent::report(); 
     545  //  AAAARecordContent::report(); // will be needed once we do ipv6 transport 
     546  NSRecordContent::report(); 
     547  CNAMERecordContent::report(); 
     548  MXRecordContent::report(); 
     549  SOARecordContent::report(); 
     550 
    517551  int ret = EXIT_SUCCESS; 
    518552#ifdef WIN32 
     
    636670      Utility::socklen_t addrlen=sizeof(fromaddr); 
    637671      int d_len; 
    638       DNSPacket P; 
    639672       
    640673      struct timeval tv; 
     
    699732        if(d_len<0)  
    700733          continue; 
    701          
    702         P.setRemote((struct sockaddr *)&fromaddr, addrlen); 
    703         if(P.parse(data,d_len)<0) { 
    704           L<<Logger::Error<<"Unparseable packet from remote server "<<P.getRemote()<<endl; 
    705         } 
    706         else {  
    707           if(P.d.qr) { 
     734 
     735        try { 
     736          DNSComboWriter dc(data, d_len); 
     737          dc.setRemote((struct sockaddr *)&fromaddr, addrlen); 
     738 
     739          if(dc.d_mdp.d_header.qr) { 
    708740            pident.remote=fromaddr; 
    709             pident.id=P.d.id; 
     741            pident.id=dc.d_mdp.d_header.id; 
    710742            string packet; 
    711             packet.assign(data,d_len); 
    712             MT->sendEvent(pident,&packet); 
     743            packet.assign(data, d_len); 
     744            MT->sendEvent(pident, &packet); 
    713745          } 
    714746          else  
    715             L<<Logger::Warning<<"Ignoring question on outgoing socket from "<<P.getRemote()<<endl; 
    716         } 
     747            L<<Logger::Warning<<"Ignoring question on outgoing socket from "<<"1.2.3.4"<<endl; 
     748        } 
     749        catch(MOADNSException& mde) { 
     750          L<<Logger::Error<<"Unparseable packet from remote server "<<"1.2.3.4"<<": "<<mde.what()<<endl; 
     751        } 
     752 
    717753      } 
    718754       
     
    722758          if(d_len<0)  
    723759            continue; 
    724           P.setRemote((struct sockaddr *)&fromaddr, addrlen); 
    725           if(P.parse(data,d_len)<0) { 
    726             L<<Logger::Error<<"Unparseable packet from remote client "<<P.getRemote()<<endl; 
    727           } 
    728           else {  
    729             if(P.d.qr) 
    730               L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 
    731             else { 
    732               ++qcounter; 
    733               P.setSocket(*i); 
    734               P.d_tcp=false; 
    735               MT->makeThread(startDoResolve,(void*)new DNSPacket(P), "udp"); 
    736             } 
     760 
     761          DNSComboWriter*dc = new DNSComboWriter(data, d_len); 
     762 
     763          dc->setRemote((struct sockaddr *)&fromaddr, addrlen); 
     764 
     765          if(dc->d_mdp.d_header.qr) 
     766            L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 
     767          else { 
     768            ++qcounter; 
     769            dc->setSocket(*i); 
     770            dc->d_tcp=false; 
     771            MT->makeThread(startDoResolve, (void*) dc, "udp"); 
    737772          } 
    738773        } 
     
    859894            if(i->bytesread==i->qlen) { 
    860895              i->state=TCPConnection::BYTE0; 
    861  
    862               if(P.parse(i->data,i->qlen)<0) { 
    863                 L<<Logger::Error<<"Unparseable packet from remote client "<<P.getRemote()<<endl; 
     896              DNSComboWriter* dc; 
     897              try { 
     898                dc=new DNSComboWriter(i->data, i->qlen); 
     899              } 
     900              catch(MOADNSException &mde) { 
     901                L<<Logger::Error<<"Unparseable packet from remote client "<<"1.2.3.4"<<endl; 
    864902                close(i->fd); 
    865903                tcpconnections.erase(i); 
    866904                break; 
    867905              } 
    868               else {  
    869                 P.setSocket(i->fd); 
    870                 P.d_tcp=true; 
    871                 P.setRemote((struct sockaddr *)&i->remote,sizeof(i->remote)); 
    872                 if(P.d.qr) 
    873                   L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 
    874                 else { 
    875                   ++qcounter; 
    876                   MT->makeThread(startDoResolve,(void*)new DNSPacket(P), "tcp"); 
    877                 } 
     906 
     907              dc->setSocket(i->fd); 
     908              dc->d_tcp=true; 
     909              dc->setRemote((struct sockaddr *)&i->remote,sizeof(i->remote)); 
     910              if(dc->d_mdp.d_header.qr) 
     911                L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 
     912              else { 
     913                ++qcounter; 
     914                MT->makeThread(startDoResolve, dc, "tcp"); 
    878915              } 
    879916            }