Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
pdns-recursor
pdns-recursor-3.1.7.2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pdns-recursor-3.1.7.2.patch of Package pdns-recursor
--- pdns-recursor-3.1.7/dnsparser.cc +++ pdns-recursor-3.1.7/dnsparser.cc @@ -75,20 +75,38 @@ vector<uint8_t> d_record; }; -static const string EncodeDNSLabel(const string& input) +static const string EncodeDNSLabel(const string& input) { - typedef vector<string> parts_t; - parts_t parts; - stringtok(parts,input,"."); - string ret; - for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { - ret.append(1,(char)i->length()); - ret.append(*i); - } - ret.append(1,(char)0); - return ret; + if(input.length() == 1 && input[0]=='.') // otherwise we encode .. (long story) + return string (1, 0); + + labelparts_t parts; + bool unescapedSomething = labeltokUnescape(parts, input); + string ret; + + if(!unescapedSomething) { + for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { + ret.append(1, i->second - i->first); + ret.append(input.c_str() + i->first, i->second - i->first); + } + + } else { + for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { + string part(input.c_str() + i->first, i->second - i->first); + boost::replace_all(part, "\\\\", "\\"); + boost::replace_all(part, "\\.", "."); + + ret.append(1, part.length()); + ret.append(part); + } + } + ret.append(1, 0); + // cerr<<"Asked to encode '"<<input<<"', returning: '"<<makeHexDump(ret)<<endl; + // cerr<<"parts length: "<<parts.size()<<endl; + return ret; } + shared_ptr<DNSRecordContent> DNSRecordContent::unserialize(const string& qname, uint16_t qtype, const string& serialized) { dnsheader dnsheader; @@ -437,7 +455,7 @@ // XXX FIXME THIS MIGHT BE VERY SLOW! ret.reserve(ret.size() + labellen + 2); for(string::size_type n = 0 ; n < labellen; ++n, frompos++) { - if(content.at(frompos)=='.') + if(content.at(frompos)=='.' || content.at(frompos)=='\\') ret.append(1, '\\'); ret.append(1, content[frompos]); } --- pdns-recursor-3.1.7/dnsparser.hh +++ pdns-recursor-3.1.7/dnsparser.hh @@ -194,7 +194,7 @@ static uint16_t TypeToNumber(const string& name) { for(namemap_t::const_iterator i=getNamemap().begin(); i!=getNamemap().end();++i) - if(!Utility::strcasecmp(i->second.c_str(), name.c_str())) + if(pdns_iequals(i->second,name)) return i->first.second; throw runtime_error("Unknown DNS type '"+name+"'"); --- pdns-recursor-3.1.7/dnswriter.cc +++ pdns-recursor-3.1.7/dnswriter.cc @@ -67,7 +67,7 @@ d_stuff = 0; d_rollbackmarker=d_content.size(); - if(iequals(d_qname,d_recordqname)) { // don't do the whole label compression thing if we *know* we can get away with "see question" + if(pdns_iequals(d_qname,d_recordqname)) { // don't do the whole label compression thing if we *know* we can get away with "see question" static char marker[2]={0xc0, 0x0c}; d_content.insert(d_content.end(), &marker[0], &marker[2]); } @@ -153,14 +153,12 @@ { DNSPacketWriter::lmap_t::iterator ret; for(ret=lmap.begin(); ret != lmap.end(); ++ret) - if(iequals(ret->first,label)) + if(pdns_iequals(ret->first,label)) break; return ret; } -typedef vector<pair<string::size_type, string::size_type> > parts_t; - -bool labeltokUnescape(parts_t& parts, const string& label) +bool labeltokUnescape(labelparts_t& parts, const string& label) { string::size_type epos = label.size(), lpos(0), pos; bool unescapedSomething = false; @@ -188,7 +186,7 @@ // this is the absolute hottest function in the pdns recursor void DNSPacketWriter::xfrLabel(const string& label, bool compress) { - parts_t parts; + labelparts_t parts; if(label.size()==1 && label[0]=='.') { // otherwise we encode '..' d_record.push_back(0); @@ -200,7 +198,7 @@ // d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example unsigned int pos=d_content.size() + d_record.size() + d_stuff; string chopped; - for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { + for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { chopped.assign(label.c_str() + i->first); lmap_t::iterator li=d_labelmap.end(); // see if we've written out this domain before @@ -218,6 +216,10 @@ if(unescaped) { string part(label.c_str() + i -> first, i->second - i->first); replace_all(part, "\\.", "."); + replace_all(part, "\\\\", "\\"); + if(part.size() > 255) + throw MOADNSException("Attempting to express a label of invalid size in xfrLabel"); + d_record.push_back(part.size()); unsigned int len=d_record.size(); d_record.resize(len + part.size()); --- pdns-recursor-3.1.7/dnswriter.hh +++ pdns-recursor-3.1.7/dnswriter.hh @@ -107,4 +107,8 @@ uint16_t d_rollbackmarker; // start of last complete packet, for rollback Place d_recordplace; }; + +typedef vector<pair<std::string::size_type, std::string::size_type> > labelparts_t; + +bool labeltokUnescape(labelparts_t& parts, const std::string& label); #endif --- pdns-recursor-3.1.7/lwres.cc +++ pdns-recursor-3.1.7/lwres.cc @@ -155,7 +155,7 @@ lwr->d_tcbit=mdp.d_header.tc; lwr->d_rcode=mdp.d_header.rcode; - if(Utility::strcasecmp(domain.c_str(), mdp.d_qname.c_str())) { + if(!pdns_iequals(domain,mdp.d_qname)) { if(domain.find((char)0)==string::npos) {// embedded nulls are too noisy L<<Logger::Notice<<"Packet purporting to come from remote server "<<ip.toString()<<" contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl; g_stats.unexpectedCount++; --- pdns-recursor-3.1.7/misc.hh +++ pdns-recursor-3.1.7/misc.hh @@ -318,54 +318,45 @@ { return tv.tv_sec + tv.tv_usec/1000000.0f; } -struct CIStringCompare: public binary_function<string, string, bool> + +inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) __attribute__((pure)); +inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) { - bool operator()(const string& a, const string& b) const - { - const unsigned char *p1 = (const unsigned char *) a.c_str(); - const unsigned char *p2 = (const unsigned char *) b.c_str(); - int result; - - if (p1 == p2) - return 0; - - while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0) - if (*p1++ == '\0') - break; - - return result < 0; + string::size_type aLen = a.length(), bLen = b.length(), n; + const char *aPtr = a.c_str(), *bPtr = b.c_str(); + int result; + + for(n = 0 ; n < aLen && n < bLen ; ++n) { + if((result = dns_tolower(*aPtr++) - dns_tolower(*bPtr++))) { + return result < 0; + } } + if(n == aLen && n == bLen) // strings are equal (in length) + return 0; + if(n == aLen) // first string was shorter + return true; + return false; +} - bool operator()(const string& a, const char* b) const - { - const unsigned char *p1 = (const unsigned char *) a.c_str(); - const unsigned char *p2 = (const unsigned char *) b; - int result; - - if (p1 == p2) - return 0; - - while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0) - if (*p1++ == '\0') - break; - - return result < 0; +inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure)); + +inline bool pdns_iequals(const std::string& a, const std::string& b) +{ + string::size_type aLen = a.length(), bLen = b.length(), n; + const char *aPtr = a.c_str(), *bPtr = b.c_str(); + + for(n = 0 ; n < aLen && n < bLen ; ++n) { + if(dns_tolower(*aPtr++) != dns_tolower(*bPtr++)) + return false; } + return aLen == bLen; // strings are equal (in length) +} - bool operator()(const char* a, const string& b) const +struct CIStringCompare: public binary_function<string, string, bool> +{ + bool operator()(const string& a, const string& b) const { - const unsigned char *p1 = (const unsigned char *) a; - const unsigned char *p2 = (const unsigned char *) b.c_str(); - int result; - - if (p1 == p2) - return 0; - - while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0) - if (*p1++ == '\0') - break; - - return result < 0; + return pdns_ilexicographical_compare(a, b); } }; --- pdns-recursor-3.1.7/pdns_recursor.cc +++ pdns-recursor-3.1.7/pdns_recursor.cc @@ -806,43 +806,54 @@ } } -void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type) + +static void appendEscapedLabel(string& ret, const char* begin, unsigned char labellen) +{ + unsigned char n = 0; + for(n = 0 ; n < labellen; ++n) + if(begin[n] == '.' || begin[n] == '\\') + break; + + if( n == labellen) { + ret.append(begin, labellen); + return; + } + string label(begin, labellen); + boost::replace_all(label, "\\", "\\\\"); + boost::replace_all(label, ".", "\\."); + ret.append(label); +} + +string questionExpand(const char* packet, uint16_t len, uint16_t& type) { type=0; - const unsigned char* end=(const unsigned char*)packet+len; - unsigned char* lbegin=(unsigned char*)packet+12; - unsigned char* pos=lbegin; + string ret; + if(len < 12) + throw runtime_error("Error parsing question in incoming packet: packet too short"); + + const unsigned char* end = (const unsigned char*)packet+len; + const unsigned char* pos = (const unsigned char*)packet+12; unsigned char labellen; - - // 3www4ds9a2nl0 - char *dst=qname; - char* lend=dst + maxlen; if(!*pos) - *dst++='.'; - + ret.assign(1, '.'); + while((labellen=*pos++) && pos < end) { // "scan and copy" - if(dst >= lend) - throw runtime_error("Label length exceeded destination length"); - for(;labellen;--labellen) - *dst++ = *pos++; - *dst++='.'; + if(pos + labellen > end) + throw runtime_error("Error parsing question in incoming packet: label extends beyond packet"); + + appendEscapedLabel(ret, (const char*) pos, labellen); + + ret.append(1, '.'); + pos += labellen; } - *dst=0; - if(pos + labellen + 2 <= end) // is this correct XXX FIXME? + if(pos + labellen + 2 <= end) type=(*pos)*256 + *(pos+1); - - - // cerr<<"Returning: '"<< string(tmp+1, pos) <<"'\n"; + // cerr << "returning: '"<<ret<<"'"<<endl; + return ret; } -string questionExpand(const char* packet, uint16_t len, uint16_t& type) -{ - char tmp[512]; - questionExpand(packet, len, tmp, sizeof(tmp), type); - return tmp; -} void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) { @@ -874,59 +885,6 @@ } else { ++g_stats.qcounter; -#if 0 - uint16_t type; - char qname[256]; - try { - questionExpand(data, len, qname, sizeof(qname), type); - } - catch(exception &e) - { - throw MOADNSException(e.what()); - } - - // must all be same length answers right now! - if((type==QType::A || type==QType::AAAA) && dh->arcount==0 && dh->ancount==0 && dh->nscount ==0 && ntohs(dh->qdcount)==1 ) { - char *record[10]; - uint16_t rlen[10]; - uint32_t ttd[10]; - int count; - if((count=RC.getDirect(g_now.tv_sec, qname, QType(type), ttd, record, rlen))) { - if(len + count*(sizeof(dnsrecordheader) + 2 + rlen[0]) > 512) - goto slow; - - random_shuffle(record, &record[count]); - dh->qr=1; - dh->ra=1; - dh->ancount=ntohs(count); - for(int n=0; n < count ; ++n) { - memcpy(data+len, "\xc0\x0c", 2); // answer label pointer - len+=2; - struct dnsrecordheader drh; - drh.d_type=htons(type); - drh.d_class=htons(1); - drh.d_ttl=htonl(ttd[n] - g_now.tv_sec); - drh.d_clen=htons(rlen[n]); - memcpy(data+len, &drh, sizeof(drh)); - len+=sizeof(drh); - memcpy(data+len, record[n], rlen[n]); - len+=rlen[n]; - } - RDTSC(tsc2); - g_stats.shunted++; - sendto(fd, data, len, 0, (struct sockaddr *)(&fromaddr), fromaddr.getSocklen()); -// cerr<<"shunted: " << (tsc2-tsc1) / 3000.0 << endl; - return; - } - } - else { - if(type!=QType::A && type!=QType::AAAA) - g_stats.noShuntWrongType++; - else - g_stats.noShuntWrongQuestion++; - } - slow: -#endif DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); dc->setSocket(fd); dc->setRemote(&fromaddr); @@ -1304,7 +1262,13 @@ pident.remote=fromaddr; pident.id=dh.id; pident.fd=fd; - pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read + try { + pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read + } + catch(...) { + return; + } + string packet; packet.assign(data, len); @@ -1322,7 +1286,7 @@ for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) { if(pident.fd==mthread->key.fd && mthread->key.remote==pident.remote && mthread->key.type == pident.type && - !Utility::strcasecmp(pident.domain.c_str(), mthread->key.domain.c_str())) { + pdns_iequals(pident.domain,mthread->key.domain)) { mthread->key.nearMisses++; } } --- pdns-recursor-3.1.7/rec_channel_rec.cc +++ pdns-recursor-3.1.7/rec_channel_rec.cc @@ -294,6 +294,7 @@ return "bye\n"; } + if(cmd=="dump-cache") return doDumpCache(begin, end); --- pdns-recursor-3.1.7/recursor_cache.cc +++ pdns-recursor-3.1.7/recursor_cache.cc @@ -121,74 +121,13 @@ return ret; } -int MemRecursorCache::getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]) -{ - if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname)) { -// cerr<<"had cache cache miss for '"<<qname<<"'"<<endl; - d_cachedqname=qname; - d_cachecache=d_cache.equal_range(tie(qname)); - d_cachecachevalid=true; - } - else - ; - // cerr<<"had cache cache hit!"<<endl; - - if(d_cachecache.first == d_cachecache.second) { - g_stats.noShuntNoMatch++; - return false; - } - - pair<cache_t::iterator, cache_t::iterator> range = d_cachecache; - - unsigned int n=0; - for(;range.first != range.second; ++range.first) { - if(range.first->d_qtype == QType::CNAME) { // if we see a cname, we need the whole shebang (for now) - g_stats.noShuntCNAME++; - return false; - } - if(range.first->d_qtype != qt.getCode()) - continue; - if(range.first->getTTD() < (unsigned int) now) { - g_stats.noShuntExpired++; - return false; - } - - if(range.first->d_records.empty() || range.first->d_records.size() > 9 ) { - g_stats.noShuntSize++; - return false; - } - - size_t limit=range.first->d_records.size(); - n=0; - for(; n < limit; ++n) { - data[n]=(char*)range.first->d_records[n].d_string.c_str(); - len[n]=range.first->d_records[n].d_string.length(); - ttd[n]=range.first->d_records[n].d_ttd; - } - if(n<10) { - data[n]=0; - typedef cache_t::nth_index<1>::type sequence_t; - sequence_t& sidx=d_cache.get<1>(); - sequence_t::iterator si=d_cache.project<1>(range.first); - sidx.relocate(sidx.end(), si); // move it in the LRU list - // can't yet return, need to figure out if there isn't a CNAME that messes things up - } - else - return false; - } - if(!n) - g_stats.noShuntNoMatch++; - return n; - -} - int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res) { unsigned int ttd=0; // cerr<<"looking up "<< qname+"|"+qt.getName()<<"\n"; - if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname.c_str())) { + if(!d_cachecachevalid || !pdns_iequals(d_cachedqname,qname)) { // cerr<<"had cache cache miss"<<endl; d_cachedqname=qname; d_cachecache=d_cache.equal_range(tie(qname)); --- pdns-recursor-3.1.7/syncres.cc +++ pdns-recursor-3.1.7/syncres.cc @@ -62,8 +62,8 @@ int SyncRes::beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret) { s_queries++; - if( (qtype.getCode()==QType::PTR && !Utility::strcasecmp(qname.c_str(), "1.0.0.127.in-addr.arpa.")) || - (qtype.getCode()==QType::A && qname.length()==10 && !Utility::strcasecmp(qname.c_str(), "localhost."))) { + if( (qtype.getCode()==QType::PTR && pdns_iequals(qname, "1.0.0.127.in-addr.arpa.")) || + (qtype.getCode()==QType::A && qname.length()==10 && pdns_iequals(qname, "localhost."))) { ret.clear(); DNSResourceRecord rr; rr.qname=qname; @@ -79,7 +79,7 @@ } if(qclass==3 && qtype.getCode()==QType::TXT && - (!Utility::strcasecmp(qname.c_str(), "version.bind.") || !Utility::strcasecmp(qname.c_str(), "id.server.") || !Utility::strcasecmp(qname.c_str(), "version.pdns.") ) + (pdns_iequals(qname, "version.bind.") || pdns_iequals(qname, "id.server.") || pdns_iequals(qname, "version.pdns.") ) ) { ret.clear(); DNSResourceRecord rr; @@ -87,7 +87,7 @@ rr.qtype=qtype; rr.qclass=qclass; rr.ttl=86400; - if(!Utility::strcasecmp(qname.c_str(),"version.bind.") || !Utility::strcasecmp(qname.c_str(),"version.pdns.")) + if(pdns_iequals(qname, "version.bind.") || pdns_iequals(qname, "version.pdns.")) rr.content="\""+::arg()["version-string"]+"\""; else rr.content="\""+s_serverID+"\""; @@ -571,10 +571,9 @@ { bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const { - int cmp=Utility::strcasecmp(a.first.c_str(), b.first.c_str()); - if(cmp < 0) + if(pdns_ilexicographical_compare(a.first, b.first)) return true; - if(cmp > 0) + if(pdns_ilexicographical_compare(b.first, a.first)) return false; return a.second < b.second; @@ -829,7 +828,7 @@ newtarget=i->content; } // for ANY answers we *must* have an authoritive answer - else if(i->d_place==DNSResourceRecord::ANSWER && !Utility::strcasecmp(i->qname.c_str(),qname.c_str()) && + else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname,qname) && ( i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) ) ) --- pdns-recursor-3.1.7/syncres.hh +++ pdns-recursor-3.1.7/syncres.hh @@ -434,12 +434,11 @@ if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type)) return false; - int cmp=Utility::strcasecmp(domain.c_str(), b.domain.c_str()); - if(cmp < 0) + if(pdns_ilexicographical_compare(domain,b.domain)) return true; - if(cmp > 0) - return false; + if(pdns_ilexicographical_compare(b.domain,domain)) + return false; return tie(fd, id) < tie(b.fd, b.id); } }; @@ -455,8 +454,7 @@ if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type)) return false; - int cmp=Utility::strcasecmp(a.domain.c_str(), b.domain.c_str()); - return cmp < 0; + return pdns_ilexicographical_compare(a.domain,b.domain); } }; extern MemRecursorCache RC; --- pdns-recursor-3.1.7/unix_utility.cc +++ pdns-recursor-3.1.7/unix_utility.cc @@ -174,13 +174,6 @@ ::srandom(seed); } -// Compares two string, ignoring the case. -int Utility::strcasecmp( const char *s1, const char *s2 ) -{ - return ::strcasecmp( s1, s2 ); -} - - // Writes a vector. int Utility::writev(int socket, const iovec *vector, size_t count ) { --- pdns-recursor-3.1.7/utility.hh +++ pdns-recursor-3.1.7/utility.hh @@ -187,9 +187,6 @@ //! Sets the random seed. static void srandom( unsigned int seed ); - //! Compares two strings and ignores case. - static int strcasecmp( const char *s1, const char *s2 ); - //! Drops the program's privileges. static void dropPrivs( int uid, int gid ); --- pdns-recursor-3.1.7/win32_utility.cc +++ pdns-recursor-3.1.7/win32_utility.cc @@ -379,14 +379,6 @@ srand( seed ); } - -// Compares two string, ignoring the case. -int Utility::strcasecmp( const char *s1, const char *s2 ) -{ - return strcmp( s1, s2 ); -} - - // Sleeps for a number of microseconds. void Utility::usleep( unsigned long usec ) { --- pdns-recursor-3.1.7/zoneparser-tng.cc +++ pdns-recursor-3.1.7/zoneparser-tng.cc @@ -303,7 +303,7 @@ // cout<<"Next part: '"<<nextpart<<"'"<<endl; - if(!Utility::strcasecmp(nextpart.c_str(), "IN")) { + if(pdns_iequals(nextpart, "IN")) { // cout<<"Ignoring 'IN'\n"; continue; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor