]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
2 | * This file is part of PowerDNS or dnsdist. |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
ea76bac0 | 22 | #pragma once |
61b26744 | 23 | #include <inttypes.h> |
8b3cfcd3 | 24 | #include <cstring> |
f9822705 | 25 | #include <cstdio> |
3ee84c3f | 26 | #include <regex.h> |
58044407 | 27 | #include <limits.h> |
88bf3279 | 28 | #include <type_traits> |
ec6480f3 | 29 | #include <boost/algorithm/string.hpp> |
f0db590d BH |
30 | #include <boost/multi_index_container.hpp> |
31 | #include <boost/multi_index/ordered_index.hpp> | |
32 | #include <boost/tuple/tuple_comparison.hpp> | |
33 | #include <boost/multi_index/key_extractors.hpp> | |
34 | #include <boost/multi_index/sequenced_index.hpp> | |
d190894c | 35 | |
f0db590d | 36 | using namespace ::boost::multi_index; |
12c86877 | 37 | |
e67e250f | 38 | #include "dns.hh" |
ac0995bb | 39 | #include <atomic> |
76473b92 KM |
40 | #include <sys/time.h> |
41 | #include <sys/types.h> | |
42 | #include <sys/socket.h> | |
43 | #include <time.h> | |
44 | #include <syslog.h> | |
3de83124 | 45 | #include <deque> |
a640a9d4 | 46 | #include <stdexcept> |
12c86877 BH |
47 | #include <string> |
48 | #include <ctype.h> | |
e67e250f BH |
49 | #include <vector> |
50 | ||
10f4eea8 | 51 | #include "namespaces.hh" |
d72aaada KM |
52 | #include "dnsname.hh" |
53 | ||
bcb5b94e | 54 | typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_SHA512, TSIG_GSS } TSIGHashEnum; |
da15912b | 55 | |
cc3afe25 | 56 | string nowTime(); |
1d329048 | 57 | const string unquotify(const string &item); |
12c86877 | 58 | string humanDuration(time_t passed); |
f2c11a48 | 59 | bool stripDomainSuffix(string *qname, const string &domain); |
12c86877 BH |
60 | void stripLine(string &line); |
61 | string getHostname(); | |
62 | string urlEncode(const string &text); | |
a7d50153 | 63 | int waitForData(int fd, int seconds, int useconds=0); |
f4ff5929 | 64 | int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int* fd); |
d529011f | 65 | int waitForMultiData(const set<int>& fds, const int seconds, const int useconds, int* fd); |
51959320 | 66 | int waitForRWData(int fd, bool waitForRead, int seconds, int useconds, bool* error=nullptr, bool* disconnected=nullptr); |
092f210a BH |
67 | uint16_t getShort(const unsigned char *p); |
68 | uint16_t getShort(const char *p); | |
69 | uint32_t getLong(const unsigned char *p); | |
70 | uint32_t getLong(const char *p); | |
21a3792f KM |
71 | bool getTSIGHashEnum(const DNSName& algoName, TSIGHashEnum& algoEnum); |
72 | DNSName getTSIGAlgoName(TSIGHashEnum& algoEnum); | |
58044407 | 73 | |
f8499e52 | 74 | int logFacilityToLOG(unsigned int facility); |
bbce5bf0 | 75 | |
12c86877 BH |
76 | struct ServiceTuple |
77 | { | |
78 | string host; | |
092f210a | 79 | uint16_t port; |
12c86877 BH |
80 | }; |
81 | void parseService(const string &descr, ServiceTuple &st); | |
82 | ||
83 | template <typename Container> | |
84 | void | |
85 | stringtok (Container &container, string const &in, | |
86 | const char * const delimiters = " \t\n") | |
87 | { | |
88 | const string::size_type len = in.length(); | |
89 | string::size_type i = 0; | |
3ddb9247 | 90 | |
12c86877 BH |
91 | while (i<len) { |
92 | // eat leading whitespace | |
93 | i = in.find_first_not_of (delimiters, i); | |
94 | if (i == string::npos) | |
95 | return; // nothing left but white space | |
3ddb9247 | 96 | |
12c86877 BH |
97 | // find the end of the token |
98 | string::size_type j = in.find_first_of (delimiters, i); | |
3ddb9247 | 99 | |
12c86877 BH |
100 | // push token |
101 | if (j == string::npos) { | |
102 | container.push_back (in.substr(i)); | |
103 | return; | |
104 | } else | |
105 | container.push_back (in.substr(i, j-i)); | |
3ddb9247 | 106 | |
12c86877 BH |
107 | // set up for next loop |
108 | i = j + 1; | |
109 | } | |
110 | } | |
8c3149f2 | 111 | |
f7a69a4c RA |
112 | template<typename T> bool rfc1982LessThan(T a, T b) |
113 | { | |
d24c4eec | 114 | static_assert(std::is_unsigned<T>::value, "rfc1982LessThan only works for unsigned types"); |
9a363102 OM |
115 | typedef typename std::make_signed<T>::type signed_t; |
116 | return static_cast<signed_t>(a - b) < 0; | |
f7a69a4c RA |
117 | } |
118 | ||
0ab3fdc6 | 119 | // fills container with ranges, so {posbegin,posend} |
8c3149f2 BH |
120 | template <typename Container> |
121 | void | |
122 | vstringtok (Container &container, string const &in, | |
123 | const char * const delimiters = " \t\n") | |
124 | { | |
125 | const string::size_type len = in.length(); | |
126 | string::size_type i = 0; | |
3ddb9247 | 127 | |
8c3149f2 BH |
128 | while (i<len) { |
129 | // eat leading whitespace | |
130 | i = in.find_first_not_of (delimiters, i); | |
131 | if (i == string::npos) | |
132 | return; // nothing left but white space | |
3ddb9247 | 133 | |
8c3149f2 BH |
134 | // find the end of the token |
135 | string::size_type j = in.find_first_of (delimiters, i); | |
3ddb9247 | 136 | |
8c3149f2 BH |
137 | // push token |
138 | if (j == string::npos) { | |
139 | container.push_back (make_pair(i, len)); | |
140 | return; | |
141 | } else | |
142 | container.push_back (make_pair(i, j)); | |
3ddb9247 | 143 | |
8c3149f2 BH |
144 | // set up for next loop |
145 | i = j + 1; | |
146 | } | |
147 | } | |
148 | ||
a683e8bd RG |
149 | size_t writen2(int fd, const void *buf, size_t count); |
150 | inline size_t writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); } | |
151 | size_t readn2(int fd, void* buffer, size_t len); | |
9396d955 | 152 | size_t readn2WithTimeout(int fd, void* buffer, size_t len, int idleTimeout, int totalTimeout=0); |
a683e8bd | 153 | size_t writen2WithTimeout(int fd, const void * buffer, size_t len, int timeout); |
040712e0 | 154 | |
c3d9d009 | 155 | const string toLower(const string &upper); |
b0d4fb45 | 156 | const string toLowerCanonic(const string &upper); |
092f210a | 157 | bool IpToU32(const string &str, uint32_t *ip); |
5730f30c | 158 | string U32ToIP(uint32_t); |
a2a81d42 | 159 | string stringerror(int); |
12c86877 BH |
160 | string stringerror(); |
161 | string itoa(int i); | |
22c9c86a | 162 | string uitoa(unsigned int i); |
d88babea | 163 | string bitFlip(const string &str); |
12c86877 BH |
164 | |
165 | void dropPrivs(int uid, int gid); | |
12c86877 BH |
166 | void cleanSlashes(string &str); |
167 | ||
c6d04bdc | 168 | #if defined(_POSIX_THREAD_CPUTIME) && defined(CLOCK_THREAD_CPUTIME_ID) |
df13e61d | 169 | /** CPUTime measurements */ |
170 | class CPUTime | |
171 | { | |
172 | public: | |
173 | void start() | |
174 | { | |
175 | clock_gettime(CLOCK_THREAD_CPUTIME_ID, &d_start); | |
176 | } | |
177 | uint64_t ndiff() | |
178 | { | |
179 | struct timespec now; | |
180 | clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now); | |
181 | return 1000000000ULL*(now.tv_sec - d_start.tv_sec) + (now.tv_nsec - d_start.tv_nsec); | |
182 | } | |
183 | private: | |
184 | struct timespec d_start; | |
185 | }; | |
3ddb9247 | 186 | #endif |
df13e61d | 187 | |
3ddb9247 | 188 | /** The DTime class can be used for timing statistics with microsecond resolution. |
12c86877 | 189 | On 32 bits systems this means that 2147 seconds is the longest time that can be measured. */ |
3ddb9247 | 190 | class DTime |
12c86877 BH |
191 | { |
192 | public: | |
eefd15f9 | 193 | DTime(); //!< Does not set the timer for you! Saves lots of gettimeofday() calls |
f238ce64 OM |
194 | DTime(const DTime &dt) = default; |
195 | DTime & operator=(const DTime &dt) = default; | |
12c86877 BH |
196 | time_t time(); |
197 | inline void set(); //!< Reset the timer | |
198 | inline int udiff(); //!< Return the number of microseconds since the timer was last set. | |
62c3a7b8 | 199 | inline int udiffNoReset(); //!< Return the number of microseconds since the timer was last set. |
88358c9b BH |
200 | void setTimeval(const struct timeval& tv) |
201 | { | |
202 | d_set=tv; | |
203 | } | |
204 | struct timeval getTimeval() | |
205 | { | |
206 | return d_set; | |
207 | } | |
12c86877 BH |
208 | private: |
209 | struct timeval d_set; | |
210 | }; | |
85db02c5 | 211 | |
12c86877 BH |
212 | inline void DTime::set() |
213 | { | |
15ad1a99 | 214 | gettimeofday(&d_set,0); |
12c86877 BH |
215 | } |
216 | ||
217 | inline int DTime::udiff() | |
62c3a7b8 BH |
218 | { |
219 | int res=udiffNoReset(); | |
15ad1a99 | 220 | gettimeofday(&d_set,0); |
62c3a7b8 BH |
221 | return res; |
222 | } | |
223 | ||
224 | inline int DTime::udiffNoReset() | |
12c86877 BH |
225 | { |
226 | struct timeval now; | |
12c86877 | 227 | |
15ad1a99 | 228 | gettimeofday(&now,0); |
fe213470 | 229 | int ret=1000000*(now.tv_sec-d_set.tv_sec)+(now.tv_usec-d_set.tv_usec); |
fe213470 | 230 | return ret; |
12c86877 BH |
231 | } |
232 | ||
c3d9d009 | 233 | inline const string toLower(const string &upper) |
12c86877 BH |
234 | { |
235 | string reply(upper); | |
2b3eefc3 | 236 | const size_t length = reply.length(); |
c536ca8d | 237 | char c; |
2b3eefc3 | 238 | for(unsigned int i = 0; i < length; ++i) { |
e3cacd48 BH |
239 | c = dns_tolower(upper[i]); |
240 | if( c != upper[i]) | |
c536ca8d BH |
241 | reply[i] = c; |
242 | } | |
12c86877 BH |
243 | return reply; |
244 | } | |
245 | ||
b0d4fb45 BH |
246 | inline const string toLowerCanonic(const string &upper) |
247 | { | |
248 | string reply(upper); | |
249 | if(!upper.empty()) { | |
705f31ae | 250 | unsigned int i, limit= ( unsigned int ) reply.length(); |
1352c9b6 | 251 | unsigned char c; |
c536ca8d | 252 | for(i = 0; i < limit ; i++) { |
e3cacd48 BH |
253 | c = dns_tolower(upper[i]); |
254 | if(c != upper[i]) | |
4957a608 | 255 | reply[i] = c; |
3ddb9247 | 256 | } |
e3cacd48 | 257 | if(upper[i-1]=='.') |
b0d4fb45 BH |
258 | reply.resize(i-1); |
259 | } | |
3ddb9247 | 260 | |
b0d4fb45 BH |
261 | return reply; |
262 | } | |
263 | ||
264 | ||
12c86877 | 265 | |
52936200 BH |
266 | // Make s uppercase: |
267 | inline string toUpper( const string& s ) | |
268 | { | |
4957a608 BH |
269 | string r(s); |
270 | for( unsigned int i = 0; i < s.length(); i++ ) { | |
315f45a0 | 271 | r[i] = dns_toupper(r[i]); |
4957a608 BH |
272 | } |
273 | return r; | |
52936200 BH |
274 | } |
275 | ||
a6d7640a BH |
276 | inline double getTime() |
277 | { | |
278 | struct timeval now; | |
15ad1a99 | 279 | gettimeofday(&now,0); |
3ddb9247 | 280 | |
a6d7640a BH |
281 | return now.tv_sec+now.tv_usec/1000000.0; |
282 | } | |
283 | ||
a640a9d4 BH |
284 | inline void unixDie(const string &why) |
285 | { | |
a2a81d42 | 286 | throw runtime_error(why+": "+stringerror()); |
a640a9d4 BH |
287 | } |
288 | ||
2db9c30e | 289 | string makeHexDump(const string& str); |
88358c9b BH |
290 | |
291 | void normalizeTV(struct timeval& tv); | |
292 | const struct timeval operator+(const struct timeval& lhs, const struct timeval& rhs); | |
293 | const struct timeval operator-(const struct timeval& lhs, const struct timeval& rhs); | |
294 | inline float makeFloat(const struct timeval& tv) | |
295 | { | |
705f31ae | 296 | return tv.tv_sec + tv.tv_usec/1000000.0f; |
88358c9b | 297 | } |
5b0ddd18 | 298 | |
3ddb9247 | 299 | inline bool operator<(const struct timeval& lhs, const struct timeval& rhs) |
5b0ddd18 BH |
300 | { |
301 | return make_pair(lhs.tv_sec, lhs.tv_usec) < make_pair(rhs.tv_sec, rhs.tv_usec); | |
302 | } | |
303 | ||
80a216c9 | 304 | inline bool operator<(const struct timespec& lhs, const struct timespec& rhs) |
305 | { | |
306 | return tie(lhs.tv_sec, lhs.tv_nsec) < tie(rhs.tv_sec, rhs.tv_nsec); | |
307 | } | |
308 | ||
309 | ||
ec6480f3 | 310 | inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) __attribute__((pure)); |
8fb5b29a | 311 | inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b) |
7738a23f | 312 | { |
97a24230 | 313 | const unsigned char *aPtr = (const unsigned char*)a.c_str(), *bPtr = (const unsigned char*)b.c_str(); |
7fd7a590 | 314 | const unsigned char *aEptr = aPtr + a.length(), *bEptr = bPtr + b.length(); |
315 | while(aPtr != aEptr && bPtr != bEptr) { | |
8fb5b29a KM |
316 | if ((*aPtr != *bPtr) && (dns_tolower(*aPtr) - dns_tolower(*bPtr))) |
317 | return (dns_tolower(*aPtr) - dns_tolower(*bPtr)) < 0; | |
318 | aPtr++; | |
319 | bPtr++; | |
7738a23f | 320 | } |
7fd7a590 | 321 | if(aPtr == aEptr && bPtr == bEptr) // strings are equal (in length) |
8fb5b29a | 322 | return false; |
7fd7a590 | 323 | return aPtr == aEptr; // true if first string was shorter |
ec6480f3 | 324 | } |
eff65ff8 | 325 | |
ec6480f3 | 326 | inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure)); |
8fb5b29a | 327 | inline bool pdns_iequals(const std::string& a, const std::string& b) |
ec6480f3 | 328 | { |
8fb5b29a KM |
329 | if (a.length() != b.length()) |
330 | return false; | |
331 | ||
ec6480f3 | 332 | const char *aPtr = a.c_str(), *bPtr = b.c_str(); |
b10795de | 333 | const char *aEptr = aPtr + a.length(); |
334 | while(aPtr != aEptr) { | |
8fb5b29a KM |
335 | if((*aPtr != *bPtr) && (dns_tolower(*aPtr) != dns_tolower(*bPtr))) |
336 | return false; | |
337 | aPtr++; | |
338 | bPtr++; | |
eff65ff8 | 339 | } |
8fb5b29a | 340 | return true; |
ec6480f3 BH |
341 | } |
342 | ||
57cb86d8 CH |
343 | inline bool pdns_iequals_ch(const char a, const char b) __attribute__((pure)); |
344 | inline bool pdns_iequals_ch(const char a, const char b) | |
345 | { | |
346 | if ((a != b) && (dns_tolower(a) != dns_tolower(b))) | |
347 | return false; | |
348 | ||
349 | return true; | |
350 | } | |
351 | ||
1566533a | 352 | |
00c6f2b9 RG |
353 | typedef unsigned long AtomicCounterInner; |
354 | typedef std::atomic<AtomicCounterInner> AtomicCounter ; | |
1bc9e6bd | 355 | |
ac0995bb | 356 | // FIXME400 this should probably go? |
3ddb9247 | 357 | struct CIStringCompare: public std::binary_function<string, string, bool> |
ec6480f3 BH |
358 | { |
359 | bool operator()(const string& a, const string& b) const | |
eff65ff8 | 360 | { |
ec6480f3 | 361 | return pdns_ilexicographical_compare(a, b); |
eff65ff8 | 362 | } |
7738a23f | 363 | }; |
eff65ff8 | 364 | |
2aa1b703 AT |
365 | struct CIStringComparePOSIX |
366 | { | |
367 | bool operator() (const std::string& lhs, const std::string& rhs) | |
368 | { | |
369 | std::string::const_iterator a,b; | |
370 | const std::locale &loc = std::locale("POSIX"); | |
371 | a=lhs.begin();b=rhs.begin(); | |
372 | while(a!=lhs.end()) { | |
373 | if (b==rhs.end() || std::tolower(*b,loc)<std::tolower(*a,loc)) return false; | |
374 | else if (std::tolower(*a,loc)<std::tolower(*b,loc)) return true; | |
4b5da564 | 375 | ++a;++b; |
2aa1b703 AT |
376 | } |
377 | return (b!=rhs.end()); | |
378 | } | |
379 | }; | |
380 | ||
3ddb9247 | 381 | struct CIStringPairCompare: public std::binary_function<pair<string, uint16_t>, pair<string,uint16_t>, bool> |
21f0f88b BH |
382 | { |
383 | bool operator()(const pair<string, uint16_t>& a, const pair<string, uint16_t>& b) const | |
384 | { | |
385 | if(pdns_ilexicographical_compare(a.first, b.first)) | |
386 | return true; | |
387 | if(pdns_ilexicographical_compare(b.first, a.first)) | |
388 | return false; | |
389 | return a.second < b.second; | |
390 | } | |
391 | }; | |
392 | ||
57cb86d8 CH |
393 | inline size_t pdns_ci_find(const string& haystack, const string& needle) |
394 | { | |
395 | string::const_iterator it = std::search(haystack.begin(), haystack.end(), | |
396 | needle.begin(), needle.end(), pdns_iequals_ch); | |
397 | if (it == haystack.end()) { | |
398 | // not found | |
399 | return string::npos; | |
400 | } else { | |
401 | return it - haystack.begin(); | |
402 | } | |
403 | } | |
21f0f88b | 404 | |
50c79a76 | 405 | pair<string, string> splitField(const string& inp, char sepa); |
26cd1b3f | 406 | |
e720f311 | 407 | inline bool isCanonical(const string& qname) |
26cd1b3f | 408 | { |
e720f311 | 409 | if(qname.empty()) |
26cd1b3f | 410 | return false; |
e720f311 | 411 | return qname[qname.size()-1]=='.'; |
26cd1b3f BH |
412 | } |
413 | ||
e720f311 | 414 | inline DNSName toCanonic(const DNSName& zone, const string& qname) |
675fa24c | 415 | { |
e720f311 | 416 | if(qname.size()==1 && qname[0]=='@') |
8171ab83 | 417 | return zone; |
e720f311 | 418 | if(isCanonical(qname)) |
8171ab83 | 419 | return DNSName(qname); |
e720f311 | 420 | return DNSName(qname) += zone; |
26cd1b3f | 421 | } |
da042e6e BH |
422 | |
423 | string stripDot(const string& dom); | |
561434a6 | 424 | |
f71bc087 | 425 | int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret); |
76cb4593 CH |
426 | int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret); |
427 | int makeUNsockaddr(const std::string& path, struct sockaddr_un* ret); | |
834942f1 | 428 | bool stringfgets(FILE* fp, std::string& line); |
f0db590d BH |
429 | |
430 | template<typename Index> | |
431 | std::pair<typename Index::iterator,bool> | |
432 | replacing_insert(Index& i,const typename Index::value_type& x) | |
433 | { | |
434 | std::pair<typename Index::iterator,bool> res=i.insert(x); | |
435 | if(!res.second)res.second=i.replace(res.first,x); | |
436 | return res; | |
437 | } | |
438 | ||
3ee84c3f BH |
439 | /** very small regex wrapper */ |
440 | class Regex | |
441 | { | |
442 | public: | |
443 | /** constructor that accepts the expression to regex */ | |
444 | Regex(const string &expr); | |
3ddb9247 | 445 | |
3ee84c3f BH |
446 | ~Regex() |
447 | { | |
448 | regfree(&d_preg); | |
449 | } | |
450 | /** call this to find out if 'line' matches your expression */ | |
6eecd4c2 | 451 | bool match(const string &line) const |
3ee84c3f BH |
452 | { |
453 | return regexec(&d_preg,line.c_str(),0,0,0)==0; | |
454 | } | |
6eecd4c2 | 455 | bool match(const DNSName& name) const |
60ee1829 AT |
456 | { |
457 | return match(name.toStringNoDot()); | |
458 | } | |
459 | ||
3ee84c3f BH |
460 | private: |
461 | regex_t d_preg; | |
462 | }; | |
463 | ||
ac84f00c AT |
464 | class SimpleMatch |
465 | { | |
466 | public: | |
8a70e507 | 467 | SimpleMatch(const string &mask, bool caseFold = false): d_mask(mask), d_fold(caseFold) |
ac84f00c | 468 | { |
ac84f00c AT |
469 | } |
470 | ||
471 | bool match(string::const_iterator mi, string::const_iterator mend, string::const_iterator vi, string::const_iterator vend) | |
472 | { | |
4b5da564 | 473 | for(;;++mi) { |
ac84f00c AT |
474 | if (mi == mend) { |
475 | return vi == vend; | |
476 | } else if (*mi == '?') { | |
477 | if (vi == vend) return false; | |
4b5da564 | 478 | ++vi; |
ac84f00c | 479 | } else if (*mi == '*') { |
4b5da564 | 480 | while(*mi == '*') ++mi; |
ac84f00c AT |
481 | if (mi == d_mask.end()) return true; |
482 | while(vi != vend) { | |
483 | if (match(mi,mend,vi,vend)) return true; | |
4b5da564 | 484 | ++vi; |
ac84f00c AT |
485 | } |
486 | return false; | |
487 | } else { | |
488 | if ((mi == mend && vi != vend)|| | |
489 | (mi != mend && vi == vend)) return false; | |
490 | if (d_fold) { | |
491 | if (dns_tolower(*mi) != dns_tolower(*vi)) return false; | |
492 | } else { | |
493 | if (*mi != *vi) return false; | |
494 | } | |
4b5da564 | 495 | ++vi; |
ac84f00c AT |
496 | } |
497 | } | |
498 | } | |
499 | ||
500 | bool match(const string& value) { | |
501 | return match(d_mask.begin(), d_mask.end(), value.begin(), value.end()); | |
502 | } | |
503 | ||
504 | bool match(const DNSName& name) { | |
505 | return match(name.toStringNoDot()); | |
506 | } | |
507 | ||
508 | private: | |
509 | string d_mask; | |
510 | bool d_fold; | |
511 | }; | |
512 | ||
65d8e171 | 513 | union ComboAddress; |
7bec330a | 514 | |
00692909 | 515 | // An aligned type to hold cmsgbufs. See https://man.openbsd.org/CMSG_DATA |
7bec330a OM |
516 | typedef union { struct cmsghdr hdr; char buf[256]; } cmsgbuf_aligned; |
517 | ||
fbe2a2e0 | 518 | /* itfIndex is an interface index, as returned by if_nametoindex(). 0 means default. */ |
7bec330a | 519 | void addCMsgSrcAddr(struct msghdr* msgh, cmsgbuf_aligned* cbuf, const ComboAddress* source, int itfIndex); |
3a8a4d68 | 520 | |
521 | unsigned int getFilenumLimit(bool hardOrSoft=0); | |
522 | void setFilenumLimit(unsigned int lim); | |
4e9a20e6 | 523 | bool readFileIfThere(const char* fname, std::string* line); |
5c57a75a | 524 | uint32_t burtle(const unsigned char* k, uint32_t length, uint32_t init); |
915b0c39 | 525 | bool setSocketTimestamps(int fd); |
15ad1a99 | 526 | |
527 | //! Sets the socket into blocking mode. | |
528 | bool setBlocking( int sock ); | |
529 | ||
530 | //! Sets the socket into non-blocking mode. | |
531 | bool setNonBlocking( int sock ); | |
883a30a7 | 532 | bool setTCPNoDelay(int sock); |
bf676f2f | 533 | bool setReuseAddr(int sock); |
18861f97 | 534 | bool isNonBlocking(int sock); |
29bb743c | 535 | bool setReceiveSocketErrors(int sock, int af); |
3897b9e1 | 536 | int closesocket(int fd); |
537 | bool setCloseOnExec(int sock); | |
74ad42dc | 538 | |
ee271fc4 RG |
539 | size_t getPipeBufferSize(int fd); |
540 | bool setPipeBufferSize(int fd, size_t size); | |
541 | ||
542 | uint64_t udpErrorStats(const std::string& str); | |
a1a787dc | 543 | uint64_t getRealMemoryUsage(const std::string&); |
330dcb5c | 544 | uint64_t getSpecialMemoryUsage(const std::string&); |
a9b6db56 | 545 | uint64_t getOpenFileDescriptors(const std::string&); |
4f99f3d3 RG |
546 | uint64_t getCPUTimeUser(const std::string&); |
547 | uint64_t getCPUTimeSystem(const std::string&); | |
591d1bd3 RG |
548 | uint64_t getCPUIOWait(const std::string&); |
549 | uint64_t getCPUSteal(const std::string&); | |
6907f014 | 550 | std::string getMACAddress(const ComboAddress& ca); |
74ad42dc | 551 | template<typename T, typename... Args> |
552 | std::unique_ptr<T> make_unique(Args&&... args) | |
553 | { | |
554 | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | |
555 | } | |
1c150f27 | 556 | |
557 | ||
558 | template<typename T> | |
559 | const T& defTer(const T& a, const T& b) | |
560 | { | |
561 | return a ? a : b; | |
562 | } | |
3555371a AT |
563 | |
564 | template<typename P, typename T> | |
565 | T valueOrEmpty(const P val) { | |
566 | if (!val) return T{}; | |
567 | return T(val); | |
568 | } | |
f5f96ff1 | 569 | |
88bf3279 | 570 | |
f5f96ff1 | 571 | // I'm not very OCD, but I appreciate loglines like "processing 1 delta", "processing 2 deltas" :-) |
88bf3279 | 572 | template <typename Integer> |
573 | const char* addS(Integer siz, typename std::enable_if<std::is_integral<Integer>::value>::type*P=0) | |
f5f96ff1 | 574 | { |
f5f96ff1 | 575 | if(!siz || siz > 1) |
576 | return "s"; | |
577 | else return ""; | |
578 | } | |
88bf3279 | 579 | |
580 | template<typename C> | |
581 | const char* addS(const C& c, typename std::enable_if<std::is_class<C>::value>::type*P=0) | |
582 | { | |
583 | return addS(c.size()); | |
584 | } | |
585 | ||
2ac8ae89 | 586 | template<typename C> |
587 | const typename C::value_type::second_type* rplookup(const C& c, const typename C::value_type::first_type& key) | |
588 | { | |
589 | auto fnd = c.find(key); | |
590 | if(fnd == c.end()) | |
591 | return 0; | |
592 | return &fnd->second; | |
593 | } | |
594 | ||
3fcaeeac | 595 | double DiffTime(const struct timespec& first, const struct timespec& second); |
596 | double DiffTime(const struct timeval& first, const struct timeval& second); | |
ffb07158 | 597 | uid_t strToUID(const string &str); |
598 | gid_t strToGID(const string &str); | |
a5c4e4a6 AT |
599 | |
600 | unsigned int pdns_stou(const std::string& str, size_t * idx = 0, int base = 10); | |
60a1c204 | 601 | |
8fd25133 RG |
602 | bool isSettingThreadCPUAffinitySupported(); |
603 | int mapThreadToCPUList(pthread_t tid, const std::set<int>& cpus); | |
5d4e1ef8 RG |
604 | |
605 | std::vector<ComboAddress> getResolvers(const std::string& resolvConfPath); | |
ef3ee606 RG |
606 | |
607 | DNSName reverseNameFromIP(const ComboAddress& ip); |