Changeset 931
- Timestamp:
- 12/16/06 16:04:10 (2 years ago)
- Files:
-
- trunk/pdns/pdns/misc.hh (modified) (1 diff)
- trunk/pdns/pdns/pdns_recursor.cc (modified) (14 diffs)
- trunk/pdns/pdns/recursor_cache.cc (modified) (1 diff)
- trunk/pdns/pdns/recursor_cache.hh (modified) (2 diffs)
- trunk/pdns/pdns/syncres.hh (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/pdns/pdns/misc.hh
r927 r931 20 20 #define MISC_HH 21 21 22 #if 022 #if 1 23 23 #define RDTSC(qp) \ 24 24 do { \ trunk/pdns/pdns/pdns_recursor.cc
r923 r931 283 283 --d_numsocks; 284 284 } 285 } g_udpclientsocks;285 } g_udpclientsocks; 286 286 287 287 … … 395 395 setBuffer(fd, SO_SNDBUF, size); 396 396 } 397 397 398 398 399 static void writePid(void) … … 486 487 { 487 488 DNSComboWriter* dc=(DNSComboWriter *)p; 489 488 490 try { 489 491 uint16_t maxudpsize=512; … … 494 496 495 497 vector<DNSResourceRecord> ret; 496 497 498 vector<uint8_t> packet; 498 DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); 499 500 DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); 499 501 500 502 pw.getHeader()->aa=0; … … 514 516 515 517 int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); 518 516 519 if(res<0) { 517 520 pw.getHeader()->rcode=RCode::ServFail; … … 535 538 if(ret.size()) { 536 539 shuffle(ret); 537 for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) { 538 pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place);539 shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content));540 541 for(vector<DNSResourceRecord>::const_iterator i=ret.begin(); i!=ret.end(); ++i) { 542 pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place); 540 543 541 drc->toPacket(pw); 542 544 if(i->qtype.getCode() == QType::A) { // blast out A record w/o doing whole dnswriter thing 545 uint32_t ip=0; 546 IpToU32(i->content, &ip); 547 pw.xfr32BitInt(htonl(ip)); 548 } else { 549 shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content)); 550 drc->toPacket(pw); 551 } 543 552 if(!dc->d_tcp && pw.size() > maxudpsize) { 544 553 pw.rollback(); … … 548 557 } 549 558 } 559 550 560 pw.commit(); 551 561 } … … 594 604 } 595 605 } 596 606 597 607 if(!g_quiet) { 598 608 L<<Logger::Error<<"["<<MT->getTid()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<<dc->d_mdp.d_qname<<"|"<<DNSRecordContent::NumberToType(dc->d_mdp.d_qtype); … … 600 610 sr.d_throttledqueries<<" throttled, "<<sr.d_timeouts<<" timeouts, "<<sr.d_tcpoutqueries<<" tcp connections, rcode="<<res<<endl; 601 611 } 602 612 603 613 sr.d_outqueries ? RC.cacheMisses++ : RC.cacheHits++; 604 614 float spent=makeFloat(sr.d_now-dc->d_now); … … 617 627 if(newLat < 1000000) // outliers of several minutes exist.. 618 628 g_stats.avgLatencyUsec=(uint64_t)((1-0.0001)*g_stats.avgLatencyUsec + 0.0001*newLat); 629 619 630 delete dc; 620 631 } … … 765 776 } 766 777 778 void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type) 779 { 780 type=0; 781 const unsigned char* end=(const unsigned char*)packet+len; 782 unsigned char* lbegin=(unsigned char*)packet+12; 783 unsigned char* pos=lbegin; 784 unsigned char labellen; 785 786 // 3www4ds9a2nl0 787 char *dst=qname; 788 char* lend=dst + maxlen; 789 790 if(!*pos) 791 *dst++='.'; 792 793 while((labellen=*pos++) && pos < end) { // "scan and copy" 794 if(dst >= lend) 795 throw runtime_error("Label length exceeded destination length"); 796 for(;labellen;--labellen) 797 *dst++ = *pos++; 798 *dst++='.'; 799 } 800 *dst=0; 801 802 if(pos + labellen + 2 <= end) // is this correct XXX FIXME? 803 type=(*pos)*256 + *(pos+1); 804 805 806 // cerr<<"Returning: '"<< string(tmp+1, pos) <<"'\n"; 807 } 808 809 string questionExpand(const char* packet, uint16_t len, uint16_t& type) 810 { 811 char tmp[512]; 812 questionExpand(packet, len, tmp, sizeof(tmp), type); 813 return tmp; 814 } 815 767 816 void handleNewUDPQuestion(int fd, boost::any& var) 768 817 { … … 771 820 ComboAddress fromaddr; 772 821 socklen_t addrlen=sizeof(fromaddr); 822 uint64_t tsc1, tsc2; 773 823 774 824 if((len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 825 RDTSC(tsc1); 775 826 g_stats.addRemote(fromaddr); 827 776 828 if(g_allowFrom && !g_allowFrom->match(&fromaddr)) { 777 829 if(!g_quiet) … … 782 834 } 783 835 try { 784 DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); 785 dc->setRemote(&fromaddr); 836 dnsheader* dh=(dnsheader*)data; 786 837 787 if(d c->d_mdp.d_header.qr) {838 if(dh->qr) { 788 839 if(g_logCommonErrors) 789 L<<Logger::Error<<"Ignoring answer from "<<dc->getRemote()<<" on server socket!"<<endl; 790 delete dc; 840 L<<Logger::Error<<"Ignoring answer from "<<fromaddr.toString()<<" on server socket!"<<endl; 791 841 } 792 842 else { 793 843 ++g_stats.qcounter; 844 uint16_t type; 845 char qname[256]; 846 questionExpand(data, len, qname, sizeof(qname), type); 847 848 // must all be same length answers right now! 849 if((type==QType::A || type==QType::AAAA) && dh->arcount==0 && dh->ancount==0 && dh->nscount ==0 && ntohs(dh->qdcount)==1 ) { 850 char *record[10]; 851 uint16_t rlen[10]; 852 uint32_t ttd[10]; 853 int count; 854 if((count=RC.getDirect(g_now.tv_sec, qname, QType(type), ttd, record, rlen))) { 855 if(len + count*(sizeof(dnsrecordheader) + 2 + rlen[0]) > 512) 856 goto slow; 857 858 random_shuffle(record, &record[count]); 859 dh->qr=1; 860 dh->ra=1; 861 dh->ancount=ntohs(count); 862 for(int n=0; n < count ; ++n) { 863 memcpy(data+len, "\xc0\x0c", 2); // answer label pointer 864 len+=2; 865 struct dnsrecordheader drh; 866 drh.d_type=htons(type); 867 drh.d_class=htons(1); 868 drh.d_ttl=htonl(ttd[n] - g_now.tv_sec); 869 drh.d_clen=htons(rlen[n]); 870 memcpy(data+len, &drh, sizeof(drh)); 871 len+=sizeof(drh); 872 memcpy(data+len, record[n], rlen[n]); 873 len+=rlen[n]; 874 } 875 RDTSC(tsc2); 876 g_stats.shunted++; 877 sendto(fd, data, len, 0, (struct sockaddr *)(&fromaddr), fromaddr.getSocklen()); 878 cerr<<"shunted: " << (tsc2-tsc1) / 3000.0 << endl; 879 return; 880 } 881 } 882 slow: 883 DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); 794 884 dc->setSocket(fd); 885 dc->setRemote(&fromaddr); 886 795 887 dc->d_tcp=false; 888 796 889 MT->makeThread(startDoResolve, (void*) dc); // deletes dc 797 890 } … … 1028 1121 } 1029 1122 ; 1030 1031 string questionExpand(const char* packet, uint16_t len, uint16_t& type)1032 {1033 type=0;1034 const unsigned char* end=(const unsigned char*)packet+len;1035 const unsigned char* pos=(const unsigned char*)packet+12;1036 unsigned char labellen;1037 string ret;1038 ret.reserve(len-12);1039 while((labellen=*pos++)) {1040 if(pos+labellen > end)1041 break;1042 ret.append((const char*)pos, labellen);1043 ret.append(1,'.');1044 pos+=labellen;1045 }1046 if(ret.empty())1047 ret=".";1048 1049 if(pos + labellen + 2 <= end) // is this correct XXX FIXME?1050 type=(*pos)*256 + *(pos+1);1051 1052 return ret;1053 }1054 1123 1055 1124 trunk/pdns/pdns/recursor_cache.cc
r901 r931 143 143 } 144 144 145 int MemRecursorCache::getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]) 146 { 147 if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname)) { 148 cerr<<"had cache cache miss for '"<<qname<<"'"<<endl; 149 d_cachedqname=qname; 150 d_cachecache=d_cache.equal_range(tie(qname)); 151 d_cachecachevalid=true; 152 } 153 else 154 ; 155 // cerr<<"had cache cache hit!"<<endl; 156 157 if(d_cachecache.first == d_cachecache.second) 158 return false; 159 160 pair<cache_t::iterator, cache_t::iterator> range = d_cachecache; 161 162 unsigned int n=0; 163 for(;range.first != range.second; ++range.first) { 164 if(range.first->d_qtype == QType::CNAME) // if we see a cname, we need the whole shebang (for now) 165 return false; 166 if(range.first->d_qtype != qt.getCode()) 167 continue; 168 if(range.first->getTTD() < (unsigned int) now) 169 return false; 170 171 if(range.first->d_records.empty() || range.first->d_records.size() > 9 ) 172 return false; 173 174 size_t limit=range.first->d_records.size(); 175 n=0; 176 for(; n < limit; ++n) { 177 data[n]=(char*)range.first->d_records[n].d_string.c_str(); 178 len[n]=range.first->d_records[n].d_string.length(); 179 ttd[n]=range.first->d_records[n].d_ttd; 180 } 181 if(n<10) { 182 data[n]=0; 183 typedef cache_t::nth_index<1>::type sequence_t; 184 sequence_t& sidx=d_cache.get<1>(); 185 sequence_t::iterator si=d_cache.project<1>(range.first); 186 sidx.relocate(sidx.end(), si); // move it in the LRU list 187 // can't yet return, need to figure out if there isn't a CNAME that messes things up 188 } 189 else 190 return false; 191 } 192 return n; 193 194 } 145 195 146 196 int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res) trunk/pdns/pdns/recursor_cache.hh
r896 r931 33 33 unsigned int bytes(); 34 34 int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res); 35 36 int getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]); 35 37 void replace(time_t, const string &qname, const QType& qt, const set<DNSResourceRecord>& content, bool auth); 36 38 void doPrune(void); … … 96 98 return earliest; 97 99 } 98 99 100 }; 100 101 trunk/pdns/pdns/syncres.hh
r901 r931 478 478 uint64_t chainResends; 479 479 uint64_t nsSetInvalidations; 480 uint64_t shunted; 480 481 481 482 typedef vector<ComboAddress> remotes_t;