Changeset 1232
- Timestamp:
- 07/13/08 22:21:54 (4 months ago)
- Files:
-
- trunk/pdns/pdns/common_startup.cc (modified) (3 diffs)
- trunk/pdns/pdns/dnspacket.cc (modified) (9 diffs)
- trunk/pdns/pdns/dnspacket.hh (modified) (2 diffs)
- trunk/pdns/pdns/dnsparser.cc (modified) (3 diffs)
- trunk/pdns/pdns/dnsparser.hh (modified) (1 diff)
- trunk/pdns/pdns/dnsrecords.cc (modified) (2 diffs)
- trunk/pdns/pdns/dnsrecords.hh (modified) (2 diffs)
- trunk/pdns/pdns/dnswriter.cc (modified) (3 diffs)
- trunk/pdns/pdns/dnswriter.hh (modified) (1 diff)
- trunk/pdns/pdns/packethandler.cc (modified) (2 diffs)
- trunk/pdns/pdns/pdns_recursor.cc (modified) (2 diffs)
- trunk/pdns/pdns/receiver.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/pdns/pdns/common_startup.cc
r1217 r1232 105 105 ::arg().set("query-cache-ttl","Seconds to store packets in the PacketCache")="20"; 106 106 ::arg().set("soa-minimum-ttl","Default SOA mininum ttl")="3600"; 107 107 ::arg().set("server-id", "Returned when queried for 'server.id' TXT or NSID, defaults to hostname")=""; 108 108 ::arg().set("soa-refresh-default","Default SOA refresh")="10800"; 109 109 ::arg().set("soa-retry-default","Default SOA retry")="3600"; … … 123 123 ::arg().set("max-cache-entries", "Maximum number of cache entries")="1000000"; 124 124 } 125 126 127 125 128 126 void declareStats(void) … … 242 240 S.ringAccount("remotes",P->getRemote()); 243 241 244 if((P->d.opcode != Opcode::Notify) && P C.get(P,&cached)) { // short circuit - does the PacketCache recognize this question?242 if((P->d.opcode != Opcode::Notify) && P->couldBeCached() && PC.get(P,&cached)) { // short circuit - does the PacketCache recognize this question? 245 243 cached.setRemote(&P->remote); // inlined 246 244 cached.setSocket(P->getSocket()); // inlined trunk/pdns/pdns/dnspacket.cc
r1138 r1232 39 39 #include "dnswriter.hh" 40 40 #include "dnsparser.hh" 41 #include "dnsrecords.hh" 41 42 42 43 DNSPacket::DNSPacket() … … 45 46 d_compress=true; 46 47 d_tcp=false; 48 d_wantsnsid=false; 47 49 } 48 50 … … 89 91 qdomain=orig.qdomain; 90 92 d_maxreplylen = orig.d_maxreplylen; 93 d_ednsping = orig.d_ednsping; 94 d_wantsnsid = orig.d_wantsnsid; 91 95 rrs=orig.rrs; 92 96 … … 264 268 } 265 269 270 bool DNSPacket::couldBeCached() 271 { 272 return d_ednsping.empty() && !d_wantsnsid; 273 } 274 266 275 /** Must be called before attempting to access getData(). This function stuffs all resource 267 276 * records found in rrs into the data buffer. It also frees resource records queued for us. … … 305 314 pw.getHeader()->rd=d.rd; 306 315 307 if(!rrs.empty()) { 316 DNSPacketWriter::optvect_t opts; 317 if(d_wantsnsid) { 318 opts.push_back(make_pair(3, ::arg()["server-id"])); 319 } 320 321 if(!d_ednsping.empty()) { 322 opts.push_back(make_pair(4, d_ednsping)); 323 } 324 325 if(!rrs.empty() || !opts.empty()) { 308 326 try { 309 327 for(pos=rrs.begin(); pos < rrs.end(); ++pos) { … … 321 339 drc->toPacket(pw); 322 340 } 341 if(!opts.empty()) 342 pw.addOpt(2800, 0, 0, opts); 343 323 344 pw.commit(); 324 345 } … … 384 405 r->qtype = qtype; 385 406 r->d_maxreplylen = d_maxreplylen; 407 r->d_ednsping = d_ednsping; 408 r->d_wantsnsid = d_wantsnsid; 386 409 return r; 387 410 } … … 403 426 { 404 427 stringbuffer.assign(mesg,length); 405 428 406 429 len=length; 407 430 if(length < 12) { … … 410 433 return -1; 411 434 } 435 412 436 MOADNSParser mdp(stringbuffer); 413 MOADNSParser::EDNSOpts edo; 414 if(mdp.getEDNSOpts(&edo)) { 437 EDNSOpts edo; 438 439 // ANY OPTION WHICH *MIGHT* BE SET DOWN BELOW SHOULD BE CLEARED FIRST! 440 441 d_wantsnsid=false; 442 d_ednsping.clear(); 443 444 if(getEDNSOpts(mdp, &edo)) { 415 445 d_maxreplylen=edo.d_packetsize; 416 } 417 else 446 447 for(vector<pair<uint16_t, string> >::const_iterator iter = edo.d_options.begin(); 448 iter != edo.d_options.end(); 449 ++iter) { 450 if(iter->first == 3) {// 'EDNS NSID' 451 d_wantsnsid=1; 452 } 453 else if(iter->first == 4) {// 'EDNS PING' 454 d_ednsping = iter->second; 455 } 456 else 457 ; // cerr<<"Have an option #"<<iter->first<<endl; 458 } 459 } 460 else { 418 461 d_maxreplylen=512; 462 } 419 463 420 464 memcpy((void *)&d,(const void *)stringbuffer.c_str(),12); trunk/pdns/pdns/dnspacket.hh
r1123 r1232 140 140 void commitD(); //!< copies 'd' into the stringbuffer 141 141 int getMaxReplyLen(); //!< retrieve the maximum length of the packet we should send in response 142 143 bool couldBeCached(); //!< returns 0 if this query should bypass the packet cache 144 142 145 //////// DATA ! 143 146 … … 163 166 string stringbuffer; // this is where everything lives 4 164 167 int d_maxreplylen; 168 string d_ednsping; 169 bool d_wantsnsid; 165 170 vector<DNSResourceRecord> rrs; // 4 166 171 }; trunk/pdns/pdns/dnsparser.cc
r1166 r1232 133 133 PacketReader& pr) 134 134 { 135 typemap_t::const_iterator i=getTypemap().find(make_pair(dr.d_class, dr.d_type)); 135 uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT 136 137 typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass, dr.d_type)); 136 138 if(i==getTypemap().end() || !i->second) { 137 139 return new UnknownRecordContent(dr, pr); … … 258 260 } 259 261 260 bool MOADNSParser::getEDNSOpts(EDNSOpts* eo)261 {262 if(d_header.arcount && !d_answers.empty() && d_answers.back().first.d_type == QType::OPT) {263 eo->d_packetsize=d_answers.back().first.d_class;264 265 EDNS0Record stuff;266 uint32_t ttl=ntohl(d_answers.back().first.d_ttl);267 memcpy(&stuff, &ttl, sizeof(stuff));268 269 eo->d_extRCode=stuff.extRCode;270 eo->d_version=stuff.version;271 eo->d_Z=stuff.Z;272 273 return true;274 }275 else276 return false;277 }278 262 279 263 void PacketReader::getDnsrecordheader(struct dnsrecordheader &ah) … … 448 432 void PacketReader::xfrBlob(string& blob) 449 433 { 450 blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1); 434 if(d_recordlen) 435 blob.assign(&d_content.at(d_pos), &d_content.at(d_startrecordpos + d_recordlen - 1 ) + 1); 436 else 437 blob.clear(); 451 438 452 439 d_pos = d_startrecordpos + d_recordlen; trunk/pdns/pdns/dnsparser.hh
r1100 r1232 299 299 } 300 300 301 struct EDNSOpts 302 { 303 uint16_t d_packetsize; 304 uint8_t d_extRCode, d_version; 305 uint16_t d_Z; 306 }; 307 308 //! Convenience function that fills out EDNS0 options, and returns true if there are any 309 bool getEDNSOpts(EDNSOpts* eo); 310 301 311 302 private: 312 303 void getDnsrecordheader(struct dnsrecordheader &ah); trunk/pdns/pdns/dnsrecords.cc
r1168 r1232 188 188 189 189 190 boilerplate_conv(OPT, ns_t_opt, 191 conv.xfrText(d_data)190 boilerplate_conv(OPT, ns_t_opt, 191 conv.xfrBlob(d_data) 192 192 ); 193 193 194 void OPTRecordContent::getData(vector<pair<uint16_t, string> >& options) 195 { 196 string::size_type pos=0; 197 uint16_t code, len; 198 while(d_data.size() >= 4 + pos) { 199 code = 0xff * d_data[pos] + d_data[pos+1]; 200 len = 0xff * d_data[pos+2] + d_data[pos+3]; 201 pos+=4; 202 203 if(pos + len > d_data.size()) 204 break; 205 206 string field(d_data.c_str() + pos, len); 207 pos+=len; 208 209 options.push_back(make_pair(code, field)); 210 } 211 } 194 212 195 213 boilerplate_conv(TSIG, ns_t_tsig, … … 321 339 ) 322 340 341 342 bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo) 343 { 344 if(mdp.d_header.arcount && !mdp.d_answers.empty() && 345 mdp.d_answers.back().first.d_type == QType::OPT) { 346 eo->d_packetsize=mdp.d_answers.back().first.d_class; 347 348 EDNS0Record stuff; 349 uint32_t ttl=ntohl(mdp.d_answers.back().first.d_ttl); 350 memcpy(&stuff, &ttl, sizeof(stuff)); 351 352 eo->d_extRCode=stuff.extRCode; 353 eo->d_version=stuff.version; 354 eo->d_Z=stuff.Z; 355 356 OPTRecordContent* orc = 357 dynamic_cast<OPTRecordContent*>(mdp.d_answers.back().first.d_content.get()); 358 359 orc->getData(eo->d_options); 360 361 return true; 362 } 363 else 364 return false; 365 } 366 367 323 368 void reportBasicTypes() 324 369 { trunk/pdns/pdns/dnsrecords.hh
r1144 r1232 198 198 public: 199 199 includeboilerplate(OPT) 200 200 void getData(vector<pair<uint16_t, string> > &opts); 201 201 private: 202 202 string d_data; … … 423 423 } \ 424 424 425 struct EDNSOpts 426 { 427 uint16_t d_packetsize; 428 uint8_t d_extRCode, d_version; 429 uint16_t d_Z; 430 vector<pair<uint16_t, string> > d_options; 431 }; 432 //! Convenience function that fills out EDNS0 options, and returns true if there are any 433 434 class MOADNSParser; 435 bool getEDNSOpts(const MOADNSParser& mdp, EDNSOpts* eo); 436 425 437 void reportBasicTypes(); 426 438 void reportOtherTypes(); trunk/pdns/pdns/dnswriter.cc
r1156 r1232 82 82 } 83 83 84 void DNSPacketWriter::addOpt(int udpsize, int extRCode, int Z )84 void DNSPacketWriter::addOpt(int udpsize, int extRCode, int Z, const vector<pair<uint16_t,string> >& options) 85 85 { 86 86 uint32_t ttl=0; … … 91 91 stuff.version=0; 92 92 stuff.Z=htons(Z); 93 93 94 94 memcpy(&ttl, &stuff, sizeof(stuff)); 95 95 … … 97 97 98 98 startRecord("", ns_t_opt, ttl, udpsize, ADDITIONAL); 99 for(optvect_t::const_iterator iter = options.begin(); iter != options.end(); ++iter) { 100 xfr16BitInt(iter->first); 101 xfr16BitInt(iter->second.length()); 102 xfrBlob(iter->second); 103 } 99 104 } 100 105 trunk/pdns/pdns/dnswriter.hh
r1100 r1232 54 54 55 55 /** Shorthand way to add an Opt-record, for example for EDNS0 purposes */ 56 void addOpt(int udpsize, int extRCode, int Z); 56 typedef vector<pair<uint16_t,std::string> > optvect_t; 57 void addOpt(int udpsize, int extRCode, int Z, const optvect_t& options=optvect_t()); 57 58 58 59 /** needs to be called after the last record is added, but can be called again and again later on. Is called internally by startRecord too. trunk/pdns/pdns/packethandler.cc
r1216 r1232 797 797 } 798 798 799 if(!noCache) 800 noCache = !p->couldBeCached(); 801 799 802 string::size_type pos; 800 803 … … 925 928 926 929 r->wrapup(); // needed for inserting in cache 927 if(!noCache) 930 if(!noCache) { 928 931 PC.insert(p,r); // in the packet cache 932 } 929 933 } 930 934 catch(DBException &e) { trunk/pdns/pdns/pdns_recursor.cc
r1200 r1232 512 512 try { 513 513 uint16_t maxudpsize=512; 514 MOADNSParser::EDNSOpts edo;515 if( dc->d_mdp.getEDNSOpts(&edo)) {514 EDNSOpts edo; 515 if(getEDNSOpts(dc->d_mdp, &edo)) { 516 516 maxudpsize=edo.d_packetsize; 517 517 } … … 1996 1996 ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache")="0"; 1997 1997 ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory")="3600"; 1998 ::arg().set("server-id", "Returned when queried for 'server.id' TXT , defaults to hostname")="";1998 ::arg().set("server-id", "Returned when queried for 'server.id' TXT or NSID, defaults to hostname")=""; 1999 1999 ::arg().set("remotes-ringbuffer-entries", "maximum number of packets to store statistics for")="0"; 2000 2000 ::arg().set("version-string", "string reported on version.pdns or version.bind")="PowerDNS Recursor "VERSION" $Id$"; trunk/pdns/pdns/receiver.cc
r1216 r1232 464 464 exit(99); 465 465 } 466 467 468 466 469 467 if(::arg().mustDo("help")) { … … 499 497 if(!isGuarded(argv)) 500 498 daemonize(); 499 } 500 501 if(::arg()["server-id"].empty()) { 502 char tmp[128]; 503 gethostname(tmp, sizeof(tmp)-1); 504 ::arg().set("server-id")=tmp; 501 505 } 502 506