#include "dns.hh"
#include <stdexcept>
-void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type)
+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 std::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");
+
+ ret.append((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);
-}
-
-string questionExpand(const char* packet, uint16_t len, uint16_t& type)
-{
- char tmp[512];
- questionExpand(packet, len, tmp, sizeof(tmp), type);
- return tmp;
+ return ret;
}
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(boost::iequals(i->second, name))
return i->first.second;
throw runtime_error("Unknown DNS type '"+name+"'");
d_stuff = 0;
d_rollbackmarker=d_content.size();
- if(!strcasecmp(d_qname.c_str(), d_recordqname.c_str())) { // don't do the whole label compression thing if we *know* we can get away with "see question"
+ if(boost::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]);
}
{
DNSPacketWriter::lmap_t::iterator ret;
for(ret=lmap.begin(); ret != lmap.end(); ++ret)
- if(!strcasecmp(ret->first.c_str() ,label.c_str()))
+ if(boost::iequals(ret->first ,label))
break;
return ret;
}
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 - 2008 PowerDNS.COM BV
+ Copyright (C) 2002 - 2009 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
return 1; // this is "success", the error is set in lwr->d_rcode
}
- if(Utility::strcasecmp(domain.c_str(), mdp.d_qname.c_str())) {
+ if(!boost::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++;
return ::inet_pton(af, src, dst);
}
-// Compares two string, ignoring the case.
-int Utility::strcasecmp( const char *s1, const char *s2 )
-{
- return ::strcasecmp( s1, s2 );
-}
-
// Returns the current time.
int Utility::gettimeofday( struct timeval *tv, void *tz )
{
return ::inet_pton(af, src, dst);
}
-// Compares two string, ignoring the case.
-int Utility::strcasecmp( const char *s1, const char *s2 )
-{
- return ::strcasecmp( s1, s2 );
-}
// Returns the current time.
int Utility::gettimeofday( struct timeval *tv, void *tz )
continue;
}
- if(!Utility::strcasecmp(subdomain.c_str(),sd.qname.c_str())) // about to break out of our zone
+ if(boost::iequals(subdomain,sd.qname)) // about to break out of our zone
break;
B.lookup("NS", subdomain,p,zoneId); // start our search at the backend
void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var)
{
- // static HTimer s_timer("udp server response processing");
-
PacketID pid=any_cast<PacketID>(var);
int len;
char data[1500];
pident.type = 0;
}
else {
- 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(std::exception& e) {
+ L<<Logger::Warning<<"Error in packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr) << ": "<<e.what() << endl;
+ return;
+ }
}
string packet;
packet.assign(data, len);
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())) {
+ boost::iequals(pident.domain, mthread->key.domain)) {
mthread->key.nearMisses++;
}
string qname=questionExpand(d_packet.c_str(), d_packet.length(), qtype);
string rhsqname=questionExpand(rhs.d_packet.c_str(), rhs.d_packet.length(), rhsqtype);
+ // qtype is only known *after* questionExpand..
+
return tie(qtype, qname) < tie(rhsqtype, rhsqname);
}
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/sequenced_index.hpp>
+// #include <boost/thread/shared_mutex.hpp>
#include <boost/version.hpp>
-#if BOOST_VERSION >= 103300
-#include <boost/multi_index/hashed_index.hpp>
-#endif
#undef max
bool attemptToRefreshNSTTL(const QType& qt, const set<DNSResourceRecord>& content, const CacheEntry& stored);
pthread_rwlock_t d_rwlock;
-
+ // boost::shared_mutex d_smutex;
};
string DNSRR2String(const DNSResourceRecord& rr);
DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd);
NSRecordContent nrc2("ns2.powerdns.com");
nrc2.toPacket(pw);
*/
+
string ping("hallo!");
- DNSPacketWriter::optvect_t opts;
+/* DNSPacketWriter::optvect_t opts;
opts.push_back(make_pair(5, ping));
pw.addOpt(5200, 0, 0x8000, opts);
pw.commit();
+*/
Socket sock(InterNetwork, Datagram);
ComboAddress dest(argv[1] + (*argv[1]=='@'), atoi(argv[2]));
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 && iequals(qname, "1.0.0.127.in-addr.arpa.")) ||
+ (qtype.getCode()==QType::A && qname.length()==10 && iequals(qname, "localhost."))) {
ret.clear();
DNSResourceRecord rr;
rr.qname=qname;
}
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.") )
+ (iequals(qname, "version.bind.") || iequals(qname, "id.server.") || iequals(qname, "version.pdns.") )
) {
ret.clear();
DNSResourceRecord rr;
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(iequals(qname,"version.bind.") || iequals(qname,"version.pdns."))
rr.content="\""+::arg()["version-string"]+"\"";
else
rr.content="\""+s_serverID+"\"";
{
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(boost::ilexicographical_compare(a.first, b.first))
return true;
- if(cmp > 0)
+ if(boost::ilexicographical_compare(b.first, a.first))
return false;
-
+
return a.second < b.second;
}
};
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 && boost::iequals(i->qname, qname) &&
(
i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
)
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(boost::ilexicographical_compare(domain, b.domain))
return true;
- if(cmp > 0)
+ if(boost::ilexicographical_compare(b.domain, domain))
return false;
return tie(fd, id) < tie(b.fd, b.id);
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 boost::ilexicographical_compare(a.domain, b.domain);
}
};
extern MemRecursorCache RC;
::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 )
//! 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 );
}
-// 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 )
{
// cout<<"Next part: '"<<nextpart<<"'"<<endl;
- if(!Utility::strcasecmp(nextpart.c_str(), "IN")) {
+ if(boost::iequals(nextpart, "IN")) {
// cout<<"Ignoring 'IN'\n";
continue;
}