root/trunk/pdns/pdns/misc.hh @ 927

Revision 927, 8.8 KB (checked in by ahu, 6 years ago)

add #ifdeffed out tsc instructions, for high-precision time measurements. Prepare CIStringCompare for 'compatible key' use, where we can lookup char* in our multi_index of strings

  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1/*
2    PowerDNS Versatile Database Driven Nameserver
3    Copyright (C) 2002-2006  PowerDNS.COM BV
4
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
8   
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18*/
19#ifndef MISC_HH
20#define MISC_HH
21
22#if 0
23#define RDTSC(qp) \
24do { \
25  unsigned long lowPart, highPart;                                      \
26  __asm__ __volatile__("rdtsc" : "=a" (lowPart), "=d" (highPart)); \
27    qp = (((unsigned long long) highPart) << 32) | lowPart; \
28} while (0)
29
30#include <iostream>
31using std::cout;
32using std::endl;
33
34struct TSCTimer
35{
36  TSCTimer()
37  {
38    RDTSC(d_tsc1);
39  }
40  ~TSCTimer()
41  {
42    uint64_t tsc2;
43    RDTSC(tsc2);
44    cout<<"Timer: "<< (tsc2 - d_tsc1)/3000.0 << endl;
45  }
46  uint64_t d_tsc1;
47};
48#endif
49
50#include "utility.hh"
51#include "dns.hh"
52#ifndef WIN32
53# include <sys/time.h>
54# include <sys/types.h>
55# include <sys/socket.h>
56# include <time.h>
57# include <syslog.h>
58#else
59# define WINDOWS_LEAN_AND_MEAN
60# include <windows.h>
61# include "utility.hh"
62#endif // WIN32
63#include <deque>
64#include <stdexcept>
65#include <string>
66#include <ctype.h>
67#include <vector>
68#include <boost/optional.hpp>
69
70using namespace std;
71bool chopOff(string &domain);
72bool chopOffDotted(string &domain);
73
74bool endsOn(const string &domain, const string &suffix);
75bool dottedEndsOn(const string &domain, const string &suffix);
76string nowTime();
77const string unquotify(const string &item);
78string humanDuration(time_t passed);
79void chomp(string &line, const string &delim);
80bool stripDomainSuffix(string *qname, const string &domain);
81void stripLine(string &line);
82string getHostname();
83string urlEncode(const string &text);
84int waitForData(int fd, int seconds, int useconds=0);
85uint16_t getShort(const unsigned char *p);
86uint16_t getShort(const char *p);
87uint32_t getLong(const unsigned char *p);
88uint32_t getLong(const char *p);
89boost::optional<int> logFacilityToLOG(unsigned int facility);
90
91inline void putLong(unsigned char* p, uint32_t val)
92{
93  *p++=(val>>24)&0xff;
94  *p++=(val>>16)&0xff;
95  *p++=(val>>8)&0xff;
96  *p++=(val   )&0xff;
97
98}
99inline void putLong(char* p, uint32_t val)
100{
101  putLong((unsigned char *)p,val);
102}
103
104
105inline uint32_t getLong(unsigned char *p)
106{
107  return (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
108}
109
110
111struct ServiceTuple
112{
113  string host;
114  uint16_t port;
115};
116void parseService(const string &descr, ServiceTuple &st);
117
118template <typename Container>
119void
120stringtok (Container &container, string const &in,
121           const char * const delimiters = " \t\n")
122{
123  const string::size_type len = in.length();
124  string::size_type i = 0;
125 
126  while (i<len) {
127    // eat leading whitespace
128    i = in.find_first_not_of (delimiters, i);
129    if (i == string::npos)
130      return;   // nothing left but white space
131   
132    // find the end of the token
133    string::size_type j = in.find_first_of (delimiters, i);
134   
135    // push token
136    if (j == string::npos) {
137      container.push_back (in.substr(i));
138      return;
139    } else
140      container.push_back (in.substr(i, j-i));
141   
142    // set up for next loop
143    i = j + 1;
144  }
145}
146
147template <typename Container>
148void
149vstringtok (Container &container, string const &in,
150           const char * const delimiters = " \t\n")
151{
152  const string::size_type len = in.length();
153  string::size_type i = 0;
154 
155  while (i<len) {
156    // eat leading whitespace
157    i = in.find_first_not_of (delimiters, i);
158    if (i == string::npos)
159      return;   // nothing left but white space
160   
161    // find the end of the token
162    string::size_type j = in.find_first_of (delimiters, i);
163   
164    // push token
165    if (j == string::npos) {
166      container.push_back (make_pair(i, len));
167      return;
168    } else
169      container.push_back (make_pair(i, j));
170   
171    // set up for next loop
172    i = j + 1;
173  }
174}
175
176const string toLower(const string &upper);
177const string toLowerCanonic(const string &upper);
178bool IpToU32(const string &str, uint32_t *ip);
179string U32ToIP(uint32_t);
180string stringerror();
181string netstringerror();
182string itoa(int i);
183string uitoa(unsigned int i);
184
185void dropPrivs(int uid, int gid);
186int makeGidNumeric(const string &group);
187int makeUidNumeric(const string &user);
188void cleanSlashes(string &str);
189
190/** The DTime class can be used for timing statistics with microsecond resolution.
191On 32 bits systems this means that 2147 seconds is the longest time that can be measured. */
192class DTime 
193{
194public:
195  DTime(); //!< Does not set the timer for you! Saves lots of gettimeofday() calls
196  DTime(const DTime &dt);
197  time_t time();
198  inline void set();  //!< Reset the timer
199  inline int udiff(); //!< Return the number of microseconds since the timer was last set.
200  void setTimeval(const struct timeval& tv)
201  {
202    d_set=tv;
203  }
204  struct timeval getTimeval()
205  {
206    return d_set;
207  }
208private:
209  struct timeval d_set;
210};
211const string sockAddrToString(struct sockaddr_in *remote);
212int sendData(const char *buffer, int replen, int outsock);
213
214inline void DTime::set()
215{
216  Utility::gettimeofday(&d_set,0);
217}
218
219inline int DTime::udiff()
220{
221  struct timeval now;
222
223  Utility::gettimeofday(&now,0);
224  int ret=1000000*(now.tv_sec-d_set.tv_sec)+(now.tv_usec-d_set.tv_usec);
225  d_set=now;
226  return ret;
227}
228
229inline bool dns_isspace(char c)
230{
231  return c==' ' || c=='\t' || c=='\r' || c=='\n';
232}
233
234inline const char dns_tolower(char c)
235{
236  if(c>='A' && c<='Z')
237    c+='a'-'A';
238  return c;
239}
240
241inline const string toLower(const string &upper)
242{
243  string reply(upper);
244  char c;
245  for(unsigned int i = 0; i < reply.length(); i++) {
246    c = dns_tolower(reply[i]);
247    if( c != reply[i])
248      reply[i] = c;
249  }
250  return reply;
251}
252
253inline const string toLowerCanonic(const string &upper)
254{
255  string reply(upper);
256  if(!upper.empty()) {
257    unsigned int i, limit= ( unsigned int ) reply.length();
258    char c;
259    for(i = 0; i < limit ; i++) {
260      c = dns_tolower(reply[i]);
261      if(c != reply[i])
262        reply[i] = c;
263    }   
264    if(reply[i-1]=='.')
265      reply.resize(i-1);
266  }
267     
268  return reply;
269}
270
271
272
273// Make s uppercase:
274inline string toUpper( const string& s )
275{
276        string r(s);
277        for( unsigned int i = 0; i < s.length(); i++ ) {
278                r[i] = toupper( r[i] );
279        }
280        return r;
281}
282
283inline double getTime()
284{
285  struct timeval now;
286  Utility::gettimeofday(&now,0);
287 
288  return now.tv_sec+now.tv_usec/1000000.0;
289}
290
291
292inline void chomp( string& line, const string& delim )
293{
294        string::size_type pos;
295
296        if( ( pos = line.find_last_not_of( delim ) ) != string::npos )
297        {
298                line.resize( pos + 1 );
299        }
300}
301
302inline void unixDie(const string &why)
303{
304  throw runtime_error(why+": "+strerror(errno));
305}
306
307string makeHexDump(const string& str);
308void shuffle(vector<DNSResourceRecord>& rrs);
309
310void normalizeTV(struct timeval& tv);
311const struct timeval operator+(const struct timeval& lhs, const struct timeval& rhs);
312const struct timeval operator-(const struct timeval& lhs, const struct timeval& rhs);
313inline float makeFloat(const struct timeval& tv)
314{
315  return tv.tv_sec + tv.tv_usec/1000000.0f;
316}
317struct CIStringCompare: public binary_function<string, string, bool> 
318{
319  bool operator()(const string& a, const string& b) const
320  {
321    const unsigned char *p1 = (const unsigned char *) a.c_str();
322    const unsigned char *p2 = (const unsigned char *) b.c_str();
323    int result;
324   
325    if (p1 == p2)
326      return 0;
327   
328    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
329      if (*p1++ == '\0')
330        break;
331   
332    return result < 0;
333  }
334
335  bool operator()(const string& a, const char* b) const
336  {
337    const unsigned char *p1 = (const unsigned char *) a.c_str();
338    const unsigned char *p2 = (const unsigned char *) b;
339    int result;
340   
341    if (p1 == p2)
342      return 0;
343   
344    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
345      if (*p1++ == '\0')
346        break;
347   
348    return result < 0;
349  }
350
351  bool operator()(const char* a, const string& b) const
352  {
353    const unsigned char *p1 = (const unsigned char *) a;
354    const unsigned char *p2 = (const unsigned char *) b.c_str();
355    int result;
356   
357    if (p1 == p2)
358      return 0;
359   
360    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0)
361      if (*p1++ == '\0')
362        break;
363   
364    return result < 0;
365  }
366};
367
368pair<string, string> splitField(const string& inp, char sepa);
369
370inline bool isCanonical(const string& dom)
371{
372  if(dom.empty())
373    return false;
374  return dom[dom.size()-1]=='.';
375}
376
377inline string toCanonic(const string& zone, const string& domain)
378{
379  if(isCanonical(domain))
380    return domain;
381  string ret=domain;
382  ret.append(1,'.');
383  ret.append(zone);
384  return ret;
385}
386#endif
Note: See TracBrowser for help on using the browser.