2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002-2012 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <boost/algorithm/string.hpp>
25 #include <boost/multi_index_container.hpp>
26 #include <boost/multi_index/ordered_index.hpp>
27 #include <boost/tuple/tuple_comparison.hpp>
28 #include <boost/multi_index/key_extractors.hpp>
29 #include <boost/multi_index/sequenced_index.hpp>
30 using namespace ::boost::multi_index;
46 cout<<"Timer: "<< (tsc2 - d_tsc1)/3000.0 << endl;
55 #include <sys/types.h>
56 #include <sys/socket.h>
65 #include "namespaces.hh"
66 bool chopOff(string &domain);
67 bool chopOffDotted(string &domain);
69 bool endsOn(const string &domain, const string &suffix);
70 bool dottedEndsOn(const string &domain, const string &suffix);
72 const string unquotify(const string &item);
73 string humanDuration(time_t passed);
74 bool stripDomainSuffix(string *qname, const string &domain);
75 void stripLine(string &line);
77 string urlEncode(const string &text);
78 int waitForData(int fd, int seconds, int useconds=0);
79 int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int* fd);
80 int waitForRWData(int fd, bool waitForRead, int seconds, int useconds);
81 uint16_t getShort(const unsigned char *p);
82 uint16_t getShort(const char *p);
83 uint32_t getLong(const unsigned char *p);
84 uint32_t getLong(const char *p);
85 int logFacilityToLOG(unsigned int facility);
92 void parseService(const string &descr, ServiceTuple &st);
94 template <typename Container>
96 stringtok (Container &container, string const &in,
97 const char * const delimiters = " \t\n")
99 const string::size_type len = in.length();
100 string::size_type i = 0;
103 // eat leading whitespace
104 i = in.find_first_not_of (delimiters, i);
105 if (i == string::npos)
106 return; // nothing left but white space
108 // find the end of the token
109 string::size_type j = in.find_first_of (delimiters, i);
112 if (j == string::npos) {
113 container.push_back (in.substr(i));
116 container.push_back (in.substr(i, j-i));
118 // set up for next loop
123 template<typename T> bool rfc1982LessThan(T a, T b)
125 return ((signed)(a - b)) < 0;
128 // fills container with ranges, so {posbegin,posend}
129 template <typename Container>
131 vstringtok (Container &container, string const &in,
132 const char * const delimiters = " \t\n")
134 const string::size_type len = in.length();
135 string::size_type i = 0;
138 // eat leading whitespace
139 i = in.find_first_not_of (delimiters, i);
140 if (i == string::npos)
141 return; // nothing left but white space
143 // find the end of the token
144 string::size_type j = in.find_first_of (delimiters, i);
147 if (j == string::npos) {
148 container.push_back (make_pair(i, len));
151 container.push_back (make_pair(i, j));
153 // set up for next loop
158 int writen2(int fd, const void *buf, size_t count);
159 inline int writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); }
160 int readn2(int fd, void* buffer, unsigned int len);
162 const string toLower(const string &upper);
163 const string toLowerCanonic(const string &upper);
164 bool IpToU32(const string &str, uint32_t *ip);
165 string U32ToIP(uint32_t);
166 string stringerror();
167 string netstringerror();
169 string uitoa(unsigned int i);
171 void dropPrivs(int uid, int gid);
172 int makeGidNumeric(const string &group);
173 int makeUidNumeric(const string &user);
174 void cleanSlashes(string &str);
176 /** The DTime class can be used for timing statistics with microsecond resolution.
177 On 32 bits systems this means that 2147 seconds is the longest time that can be measured. */
181 DTime(); //!< Does not set the timer for you! Saves lots of gettimeofday() calls
182 DTime(const DTime &dt);
184 inline void set(); //!< Reset the timer
185 inline int udiff(); //!< Return the number of microseconds since the timer was last set.
186 inline int udiffNoReset(); //!< Return the number of microseconds since the timer was last set.
187 void setTimeval(const struct timeval& tv)
191 struct timeval getTimeval()
196 struct timeval d_set;
199 inline void DTime::set()
201 Utility::gettimeofday(&d_set,0);
204 inline int DTime::udiff()
206 int res=udiffNoReset();
207 Utility::gettimeofday(&d_set,0);
211 inline int DTime::udiffNoReset()
215 Utility::gettimeofday(&now,0);
216 int ret=1000000*(now.tv_sec-d_set.tv_sec)+(now.tv_usec-d_set.tv_usec);
221 inline bool dns_isspace(char c)
223 return c==' ' || c=='\t' || c=='\r' || c=='\n';
226 inline char dns_tolower(char c)
233 inline const string toLower(const string &upper)
237 for(unsigned int i = 0; i < reply.length(); i++) {
238 c = dns_tolower(upper[i]);
245 inline const string toLowerCanonic(const string &upper)
249 unsigned int i, limit= ( unsigned int ) reply.length();
251 for(i = 0; i < limit ; i++) {
252 c = dns_tolower(upper[i]);
266 inline string toUpper( const string& s )
269 for( unsigned int i = 0; i < s.length(); i++ ) {
270 r[i] = toupper( r[i] );
275 inline double getTime()
278 Utility::gettimeofday(&now,0);
280 return now.tv_sec+now.tv_usec/1000000.0;
283 inline void unixDie(const string &why)
285 throw runtime_error(why+": "+strerror(errno));
288 string makeHexDump(const string& str);
289 void shuffle(vector<DNSResourceRecord>& rrs);
290 void orderAndShuffle(vector<DNSResourceRecord>& rrs);
292 void normalizeTV(struct timeval& tv);
293 const struct timeval operator+(const struct timeval& lhs, const struct timeval& rhs);
294 const struct timeval operator-(const struct timeval& lhs, const struct timeval& rhs);
295 inline float makeFloat(const struct timeval& tv)
297 return tv.tv_sec + tv.tv_usec/1000000.0f;
300 inline bool operator<(const struct timeval& lhs, const struct timeval& rhs)
302 return make_pair(lhs.tv_sec, lhs.tv_usec) < make_pair(rhs.tv_sec, rhs.tv_usec);
305 inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) __attribute__((pure));
306 inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)
308 const unsigned char *aPtr = (const unsigned char*)a.c_str(), *bPtr = (const unsigned char*)b.c_str();
310 while(*aPtr && *bPtr) {
311 if ((*aPtr != *bPtr) && (dns_tolower(*aPtr) - dns_tolower(*bPtr)))
312 return (dns_tolower(*aPtr) - dns_tolower(*bPtr)) < 0;
316 if(!*aPtr && !*bPtr) // strings are equal (in length)
318 return !*aPtr; // true if first string was shorter
321 inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure));
322 inline bool pdns_iequals(const std::string& a, const std::string& b)
324 if (a.length() != b.length())
327 const char *aPtr = a.c_str(), *bPtr = b.c_str();
329 if((*aPtr != *bPtr) && (dns_tolower(*aPtr) != dns_tolower(*bPtr)))
337 // lifted from boost, with thanks
342 explicit AtomicCounter( unsigned int v = 0) : value_( v ) {}
344 unsigned int operator++()
346 return atomic_exchange_and_add( &value_, +1 ) + 1;
349 unsigned int operator++(int)
351 return atomic_exchange_and_add( &value_, +1 );
354 unsigned int operator--()
356 return atomic_exchange_and_add( &value_, -1 ) - 1;
359 operator unsigned int() const
361 return atomic_exchange_and_add( &value_, 0);
364 AtomicCounter(AtomicCounter const &rhs) : value_(rhs)
369 mutable unsigned int value_;
371 // the below is necessary because __sync_fetch_and_add is not universally available on i386.. I 3> RHEL5.
372 #if defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
373 static int atomic_exchange_and_add( unsigned int * pw, int dv )
385 "+m"( *pw ), "=r"( r ): // outputs (%0, %1)
386 "1"( dv ): // inputs (%2 == %1)
387 "memory", "cc" // clobbers
393 static int atomic_exchange_and_add( unsigned int * pw, int dv )
395 return __sync_fetch_and_add(pw, dv);
401 struct CIStringCompare: public std::binary_function<string, string, bool>
403 bool operator()(const string& a, const string& b) const
405 return pdns_ilexicographical_compare(a, b);
409 struct CIStringComparePOSIX
411 bool operator() (const std::string& lhs, const std::string& rhs)
413 std::string::const_iterator a,b;
414 const std::locale &loc = std::locale("POSIX");
415 a=lhs.begin();b=rhs.begin();
416 while(a!=lhs.end()) {
417 if (b==rhs.end() || std::tolower(*b,loc)<std::tolower(*a,loc)) return false;
418 else if (std::tolower(*a,loc)<std::tolower(*b,loc)) return true;
421 return (b!=rhs.end());
425 struct CIStringPairCompare: public std::binary_function<pair<string, uint16_t>, pair<string,uint16_t>, bool>
427 bool operator()(const pair<string, uint16_t>& a, const pair<string, uint16_t>& b) const
429 if(pdns_ilexicographical_compare(a.first, b.first))
431 if(pdns_ilexicographical_compare(b.first, a.first))
433 return a.second < b.second;
438 pair<string, string> splitField(const string& inp, char sepa);
440 inline bool isCanonical(const string& dom)
444 return dom[dom.size()-1]=='.';
447 inline string toCanonic(const string& zone, const string& domain)
449 if(domain.length()==1 && domain[0]=='@')
452 if(isCanonical(domain))
456 if(!zone.empty() && zone[0]!='.')
461 inline void setSocketReusable(int fd)
464 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, static_cast<unsigned>(sizeof tmp));
467 string stripDot(const string& dom);
468 void seedRandom(const string& source);
469 string makeRelative(const std::string& fqdn, const std::string& zone);
470 string labelReverse(const std::string& qname);
471 std::string dotConcat(const std::string& a, const std::string &b);
472 int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret);
473 int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret);
474 int makeUNsockaddr(const std::string& path, struct sockaddr_un* ret);
475 bool stringfgets(FILE* fp, std::string& line);
477 template<typename Index>
478 std::pair<typename Index::iterator,bool>
479 replacing_insert(Index& i,const typename Index::value_type& x)
481 std::pair<typename Index::iterator,bool> res=i.insert(x);
482 if(!res.second)res.second=i.replace(res.first,x);
486 /** very small regex wrapper */
490 /** constructor that accepts the expression to regex */
491 Regex(const string &expr);
497 /** call this to find out if 'line' matches your expression */
498 bool match(const string &line)
500 return regexec(&d_preg,line.c_str(),0,0,0)==0;