]>
Commit | Line | Data |
---|---|---|
00a19ff7 BH |
1 | #ifndef PDNS_SYNCRES_HH |
2 | #define PDNS_SYNCRES_HH | |
3 | #include <string> | |
4 | #include "dns.hh" | |
5 | #include "qtype.hh" | |
6 | #include <vector> | |
7 | #include <set> | |
8 | #include <map> | |
eefd15f9 BH |
9 | #include <cmath> |
10 | #include <iostream> | |
11 | #include <utility> | |
c836dc19 | 12 | #include "misc.hh" |
00a19ff7 | 13 | #include "lwres.hh" |
d6d5dea7 | 14 | #include <boost/utility.hpp> |
1d5b3ce6 | 15 | #include "sstuff.hh" |
9fdf67d5 | 16 | #include "recursor_cache.hh" |
16beeaa4 | 17 | #include "recpacketcache.hh" |
1d5b3ce6 | 18 | #include <boost/tuple/tuple.hpp> |
71dea98d | 19 | #include <boost/optional.hpp> |
1d5b3ce6 BH |
20 | #include <boost/tuple/tuple_comparison.hpp> |
21 | #include "mtasker.hh" | |
a9af3782 | 22 | #include "iputils.hh" |
eefd15f9 | 23 | |
bdf40704 | 24 | void primeHints(void); |
00a19ff7 | 25 | |
38e22b5a BH |
26 | struct NegCacheEntry |
27 | { | |
f4df5e89 | 28 | string d_name; |
be718669 | 29 | QType d_qtype; |
33988bfb | 30 | string d_qname; |
33988bfb | 31 | uint32_t d_ttd; |
38e22b5a | 32 | }; |
00a19ff7 | 33 | |
49f076e8 | 34 | |
bb4bdbaf | 35 | template<class Thing> class Throttle : public boost::noncopyable |
49f076e8 BH |
36 | { |
37 | public: | |
38 | Throttle() | |
39 | { | |
40 | d_limit=3; | |
41 | d_ttl=60; | |
42 | d_last_clean=time(0); | |
43 | } | |
87da00e7 | 44 | bool shouldThrottle(time_t now, const Thing& t) |
49f076e8 | 45 | { |
cd7bf56b | 46 | if(now > d_last_clean + 300 ) { |
bb4bdbaf | 47 | |
49f076e8 | 48 | d_last_clean=now; |
594c2ee7 | 49 | for(typename cont_t::iterator i=d_cont.begin();i!=d_cont.end();) { |
4957a608 BH |
50 | if( i->second.ttd < now) { |
51 | d_cont.erase(i++); | |
52 | } | |
53 | else | |
54 | ++i; | |
594c2ee7 | 55 | } |
49f076e8 BH |
56 | } |
57 | ||
49f076e8 BH |
58 | typename cont_t::iterator i=d_cont.find(t); |
59 | if(i==d_cont.end()) | |
60 | return false; | |
014c60c3 | 61 | if(now > i->second.ttd || i->second.count-- < 0) { |
49f076e8 | 62 | d_cont.erase(i); |
49f076e8 | 63 | } |
014c60c3 BH |
64 | |
65 | return true; // still listed, still blocked | |
49f076e8 | 66 | } |
87da00e7 | 67 | void throttle(time_t now, const Thing& t, unsigned int ttl=0, unsigned int tries=0) |
49f076e8 BH |
68 | { |
69 | typename cont_t::iterator i=d_cont.find(t); | |
87da00e7 | 70 | entry e={ now+(ttl ? ttl : d_ttl), tries ? tries : d_limit}; |
49f076e8 | 71 | |
c214232f | 72 | if(i==d_cont.end()) { |
49f076e8 | 73 | d_cont[t]=e; |
c214232f BH |
74 | } |
75 | else if(i->second.ttd > e.ttd || (i->second.count) < e.count) | |
76 | d_cont[t]=e; | |
8a5602d4 BH |
77 | } |
78 | ||
79 | unsigned int size() | |
80 | { | |
705f31ae | 81 | return (unsigned int)d_cont.size(); |
49f076e8 BH |
82 | } |
83 | private: | |
84 | int d_limit; | |
85 | int d_ttl; | |
86 | time_t d_last_clean; | |
87 | struct entry | |
88 | { | |
89 | time_t ttd; | |
90 | int count; | |
91 | }; | |
92 | typedef map<Thing,entry> cont_t; | |
93 | cont_t d_cont; | |
94 | }; | |
95 | ||
96 | ||
eefd15f9 | 97 | /** Class that implements a decaying EWMA. |
36c5ee42 | 98 | This class keeps an exponentially weighted moving average which, additionally, decays over time. |
eefd15f9 BH |
99 | The decaying is only done on get. |
100 | */ | |
101 | class DecayingEwma | |
102 | { | |
103 | public: | |
71dea98d BH |
104 | DecayingEwma() : d_val(0.0) |
105 | { | |
106 | d_needinit=true; | |
118dcc93 | 107 | d_last.tv_sec = d_last.tv_usec = 0; |
71dea98d | 108 | d_lastget=d_last; |
36c5ee42 | 109 | } |
d6d5dea7 | 110 | |
71dea98d | 111 | DecayingEwma(const DecayingEwma& orig) : d_last(orig.d_last), d_lastget(orig.d_lastget), d_val(orig.d_val), d_needinit(orig.d_needinit) |
eefd15f9 | 112 | { |
71dea98d | 113 | } |
d6d5dea7 | 114 | |
71dea98d BH |
115 | struct timeval getOrMakeTime(struct timeval* tv) |
116 | { | |
117 | if(tv) | |
118 | return *tv; | |
119 | else { | |
120 | struct timeval ret; | |
f2b6ccd6 | 121 | Utility::gettimeofday(&ret, 0); |
71dea98d BH |
122 | return ret; |
123 | } | |
d6d5dea7 BH |
124 | } |
125 | ||
5a26bb53 | 126 | void submit(int val, struct timeval* tv) |
d6d5dea7 | 127 | { |
71dea98d BH |
128 | struct timeval now=getOrMakeTime(tv); |
129 | ||
130 | if(d_needinit) { | |
131 | d_last=now; | |
132 | d_needinit=false; | |
133 | } | |
134 | ||
135 | float diff= makeFloat(d_last - now); | |
d6d5dea7 | 136 | |
36c5ee42 | 137 | d_last=now; |
71dea98d | 138 | double factor=exp(diff)/2.0; // might be '0.5', or 0.0001 |
705f31ae | 139 | d_val=(float)((1-factor)*val+ (float)factor*d_val); |
eefd15f9 | 140 | } |
d6d5dea7 | 141 | |
5a26bb53 | 142 | double get(struct timeval* tv) |
71dea98d BH |
143 | { |
144 | struct timeval now=getOrMakeTime(tv); | |
145 | float diff=makeFloat(d_lastget-now); | |
36c5ee42 | 146 | d_lastget=now; |
705f31ae | 147 | float factor=exp(diff/60.0f); // is 1.0 or less |
eefd15f9 BH |
148 | return d_val*=factor; |
149 | } | |
150 | ||
996c89cc | 151 | bool stale(time_t limit) const |
9fdf67d5 | 152 | { |
71dea98d | 153 | return limit > d_lastget.tv_sec; |
9fdf67d5 BH |
154 | } |
155 | ||
eefd15f9 | 156 | private: |
71dea98d BH |
157 | struct timeval d_last; // stores time |
158 | struct timeval d_lastget; // stores time | |
159 | float d_val; | |
160 | bool d_needinit; | |
161 | }; | |
162 | ||
163 | ||
bb4bdbaf | 164 | class SyncRes : public boost::noncopyable |
00a19ff7 BH |
165 | { |
166 | public: | |
c571588b | 167 | explicit SyncRes(const struct timeval& now) : d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0), |
4957a608 BH |
168 | d_now(now), |
169 | d_cacheonly(false), d_nocache(false), d_doEDNS0(false) | |
bb4bdbaf | 170 | { |
49a699c4 BH |
171 | if(!t_sstorage) { |
172 | t_sstorage = new StaticStorage(); | |
173 | } | |
bb4bdbaf BH |
174 | } |
175 | ||
a9af3782 | 176 | int beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret); |
c836dc19 BH |
177 | void setId(int id) |
178 | { | |
9fdf67d5 BH |
179 | if(s_log) |
180 | d_prefix="["+itoa(id)+"] "; | |
c836dc19 BH |
181 | } |
182 | static void setLog(bool log) | |
183 | { | |
184 | s_log=log; | |
185 | } | |
186 | void setCacheOnly(bool state=true) | |
187 | { | |
188 | d_cacheonly=state; | |
189 | } | |
190 | void setNoCache(bool state=true) | |
191 | { | |
192 | d_nocache=state; | |
193 | } | |
2188dcc3 BH |
194 | |
195 | void setDoEDNS0(bool state=true) | |
196 | { | |
197 | d_doEDNS0=state; | |
198 | } | |
199 | ||
ff1872cf BH |
200 | |
201 | ||
c1d73d94 | 202 | int asyncresolveWrapper(const ComboAddress& ip, const string& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res); |
ff1872cf BH |
203 | |
204 | static void doEDNSDumpAndClose(int fd); | |
c0ea6e55 | 205 | |
c836dc19 | 206 | static unsigned int s_queries; |
7becf07f | 207 | static unsigned int s_outgoingtimeouts; |
3de83124 | 208 | static unsigned int s_throttledqueries; |
c836dc19 | 209 | static unsigned int s_outqueries; |
5c633640 | 210 | static unsigned int s_tcpoutqueries; |
525b8a7c | 211 | static unsigned int s_nodelegated; |
c571588b | 212 | static unsigned int s_unreachables; |
996c89cc | 213 | static bool s_doIPv6; |
c836dc19 | 214 | unsigned int d_outqueries; |
5c633640 | 215 | unsigned int d_tcpoutqueries; |
3de83124 | 216 | unsigned int d_throttledqueries; |
d77df2e1 | 217 | unsigned int d_timeouts; |
c571588b BH |
218 | unsigned int d_unreachables; |
219 | ||
33988bfb BH |
220 | // typedef map<string,NegCacheEntry> negcache_t; |
221 | ||
222 | typedef multi_index_container < | |
223 | NegCacheEntry, | |
224 | indexed_by < | |
225 | ordered_unique< | |
f4df5e89 BH |
226 | composite_key< |
227 | NegCacheEntry, | |
228 | member<NegCacheEntry, string, &NegCacheEntry::d_name>, | |
229 | member<NegCacheEntry, QType, &NegCacheEntry::d_qtype> | |
7738a23f BH |
230 | >, |
231 | composite_key_compare<CIStringCompare, std::less<QType> > | |
33988bfb BH |
232 | >, |
233 | ordered_non_unique< | |
234 | member<NegCacheEntry, uint32_t, &NegCacheEntry::d_ttd> | |
235 | > | |
236 | > | |
49a699c4 BH |
237 | > negcache_t; |
238 | ||
996c89cc BH |
239 | //! This represents a number of decaying Ewmas, used to store performance per namerserver-name. |
240 | /** Modelled to work mostly like the underlying DecayingEwma. After you've called get, | |
241 | d_best is filled out with the best address for this collection */ | |
242 | struct DecayingEwmaCollection | |
243 | { | |
244 | void submit(const ComboAddress& remote, int usecs, struct timeval* now) | |
245 | { | |
246 | collection_t::iterator pos; | |
247 | for(pos=d_collection.begin(); pos != d_collection.end(); ++pos) | |
4957a608 BH |
248 | if(pos->first==remote) |
249 | break; | |
996c89cc | 250 | if(pos!=d_collection.end()) { |
4957a608 | 251 | pos->second.submit(usecs, now); |
996c89cc BH |
252 | } |
253 | else { | |
4957a608 BH |
254 | DecayingEwma de; |
255 | de.submit(usecs, now); | |
256 | d_collection.push_back(make_pair(remote, de)); | |
996c89cc BH |
257 | } |
258 | } | |
259 | ||
260 | double get(struct timeval* now) | |
261 | { | |
262 | if(d_collection.empty()) | |
4957a608 | 263 | return 0; |
996c89cc BH |
264 | double ret=numeric_limits<double>::max(); |
265 | double tmp; | |
266 | for(collection_t::iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) { | |
4957a608 BH |
267 | if((tmp=pos->second.get(now)) < ret) { |
268 | ret=tmp; | |
269 | d_best=pos->first; | |
270 | } | |
996c89cc BH |
271 | } |
272 | ||
273 | return ret; | |
274 | } | |
275 | ||
276 | bool stale(time_t limit) const | |
277 | { | |
278 | for(collection_t::const_iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) | |
4957a608 BH |
279 | if(!pos->second.stale(limit)) |
280 | return false; | |
996c89cc BH |
281 | return true; |
282 | } | |
283 | ||
284 | typedef vector<pair<ComboAddress, DecayingEwma> > collection_t; | |
285 | collection_t d_collection; | |
286 | ComboAddress d_best; | |
287 | }; | |
288 | ||
c0ea6e55 | 289 | typedef map<string, DecayingEwmaCollection, CIStringCompare> nsspeeds_t; |
49a699c4 | 290 | |
9fdf67d5 | 291 | |
c0ea6e55 BH |
292 | struct EDNSStatus |
293 | { | |
294 | EDNSStatus() : mode(UNKNOWN), modeSetAt(0), EDNSPingHitCount(0) {} | |
295 | enum EDNSMode { CONFIRMEDPINGER=-1, UNKNOWN=0, EDNSNOPING=1, EDNSPINGOK=2, EDNSIGNORANT=3, NOEDNS=4 } mode; | |
296 | time_t modeSetAt; | |
297 | int EDNSPingHitCount; | |
298 | }; | |
299 | ||
300 | typedef map<ComboAddress, EDNSStatus> ednsstatus_t; | |
bb4bdbaf | 301 | |
49a699c4 | 302 | |
bb4bdbaf | 303 | |
840c10ec | 304 | static bool s_noEDNSPing; |
4bfae16d | 305 | static bool s_noEDNS; |
c0ea6e55 | 306 | |
5605c067 BH |
307 | struct AuthDomain |
308 | { | |
2e5ae2b2 | 309 | vector<ComboAddress> d_servers; |
3b608765 | 310 | bool d_rdForward; |
5605c067 BH |
311 | typedef multi_index_container < |
312 | DNSResourceRecord, | |
313 | indexed_by < | |
314 | ordered_non_unique< | |
315 | composite_key< DNSResourceRecord, | |
4957a608 BH |
316 | member<DNSResourceRecord, string, &DNSResourceRecord::qname>, |
317 | member<DNSResourceRecord, QType, &DNSResourceRecord::qtype> | |
5605c067 BH |
318 | >, |
319 | composite_key_compare<CIStringCompare, std::less<QType> > | |
320 | > | |
321 | > | |
322 | > records_t; | |
323 | records_t d_records; | |
324 | }; | |
325 | ||
326 | ||
327 | typedef map<string, AuthDomain, CIStringCompare> domainmap_t; | |
49a699c4 | 328 | |
5605c067 | 329 | |
996c89cc | 330 | typedef Throttle<tuple<ComboAddress,string,uint16_t> > throttle_t; |
49a699c4 | 331 | |
fe213470 | 332 | struct timeval d_now; |
a9af3782 | 333 | static unsigned int s_maxnegttl; |
c3e753c7 | 334 | static unsigned int s_maxcachettl; |
1051f8a9 BH |
335 | static unsigned int s_packetcachettl; |
336 | static unsigned int s_packetcacheservfailttl; | |
337 | static bool s_nopacketcache; | |
a9af3782 | 338 | static string s_serverID; |
bb4bdbaf | 339 | |
49a699c4 BH |
340 | struct StaticStorage { |
341 | negcache_t negcache; | |
342 | nsspeeds_t nsSpeeds; | |
343 | ednsstatus_t ednsstatus; | |
344 | throttle_t throttle; | |
345 | domainmap_t* domainmap; | |
346 | }; | |
347 | static __thread StaticStorage* t_sstorage; | |
348 | ||
00a19ff7 BH |
349 | private: |
350 | struct GetBestNSAnswer; | |
7305df82 | 351 | int doResolveAt(set<string, CIStringCompare> nameservers, string auth, bool flawedNSSet, const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, |
4957a608 | 352 | int depth, set<GetBestNSAnswer>&beenthere); |
00a19ff7 | 353 | int doResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere); |
e93c956b | 354 | bool doOOBResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res); |
5605c067 | 355 | domainmap_t::const_iterator getBestAuthZone(string* qname); |
00a19ff7 BH |
356 | bool doCNAMECacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res); |
357 | bool doCacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res); | |
7305df82 | 358 | void getBestNSFromCache(const string &qname, set<DNSResourceRecord>&bestns, bool* flawedNSSet, int depth, set<GetBestNSAnswer>& beenthere); |
00a19ff7 | 359 | void addCruft(const string &qname, vector<DNSResourceRecord>& ret); |
7305df82 | 360 | string getBestNSNamesFromCache(const string &qname,set<string, CIStringCompare>& nsset, bool* flawedNSSet, int depth, set<GetBestNSAnswer>&beenthere); |
00a19ff7 BH |
361 | void addAuthorityRecords(const string& qname, vector<DNSResourceRecord>& ret, int depth); |
362 | ||
996c89cc | 363 | inline vector<string> shuffleInSpeedOrder(set<string, CIStringCompare> &nameservers, const string &prefix); |
00a19ff7 | 364 | bool moreSpecificThan(const string& a, const string &b); |
996c89cc | 365 | vector<ComboAddress> getAs(const string &qname, int depth, set<GetBestNSAnswer>& beenthere); |
c75a6a9e | 366 | |
00a19ff7 | 367 | private: |
c836dc19 BH |
368 | string d_prefix; |
369 | static bool s_log; | |
370 | bool d_cacheonly; | |
371 | bool d_nocache; | |
2188dcc3 | 372 | bool d_doEDNS0; |
c75a6a9e | 373 | |
00a19ff7 BH |
374 | struct GetBestNSAnswer |
375 | { | |
376 | string qname; | |
377 | set<DNSResourceRecord> bestns; | |
378 | bool operator<(const GetBestNSAnswer &b) const | |
379 | { | |
380 | if(qname<b.qname) | |
4957a608 | 381 | return true; |
00a19ff7 | 382 | if(qname==b.qname) |
4957a608 | 383 | return bestns<b.bestns; |
00a19ff7 BH |
384 | return false; |
385 | } | |
386 | }; | |
387 | ||
388 | }; | |
5c633640 | 389 | class Socket; |
a9af3782 | 390 | /* external functions, opaque to us */ |
5c633640 BH |
391 | int asendtcp(const string& data, Socket* sock); |
392 | int arecvtcp(string& data, int len, Socket* sock); | |
1d5b3ce6 BH |
393 | |
394 | ||
395 | struct PacketID | |
396 | { | |
787e5eab | 397 | PacketID() : id(0), type(0), sock(0), inNeeded(0), outPos(0), nearMisses(0), fd(-1) |
67770277 BH |
398 | { |
399 | memset(&remote, 0, sizeof(remote)); | |
400 | } | |
1d5b3ce6 BH |
401 | |
402 | uint16_t id; // wait for a specific id/remote pair | |
996c89cc | 403 | ComboAddress remote; // this is the remote |
0d5f0a9f | 404 | string domain; // this is the question |
787e5eab | 405 | uint16_t type; // and this is its type |
1d5b3ce6 BH |
406 | |
407 | Socket* sock; // or wait for an event on a TCP fd | |
408 | int inNeeded; // if this is set, we'll read until inNeeded bytes are read | |
409 | string inMSG; // they'll go here | |
410 | ||
411 | string outMSG; // the outgoing message that needs to be sent | |
412 | string::size_type outPos; // how far we are along in the outMSG | |
413 | ||
35ce8576 | 414 | mutable uint32_t nearMisses; // number of near misses - host correct, id wrong |
96f81a93 BH |
415 | typedef set<uint16_t > chain_t; |
416 | mutable chain_t chain; | |
4ef015cd | 417 | int fd; |
35ce8576 | 418 | |
1d5b3ce6 BH |
419 | bool operator<(const PacketID& b) const |
420 | { | |
421 | int ourSock= sock ? sock->getHandle() : 0; | |
422 | int bSock = b.sock ? b.sock->getHandle() : 0; | |
787e5eab | 423 | if( tie(remote, ourSock, type) < tie(b.remote, bSock, b.type)) |
0d5f0a9f | 424 | return true; |
787e5eab | 425 | if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type)) |
0d5f0a9f BH |
426 | return false; |
427 | ||
ec6480f3 | 428 | if(pdns_ilexicographical_compare(domain, b.domain)) |
96f81a93 | 429 | return true; |
ec6480f3 | 430 | if(pdns_ilexicographical_compare(b.domain, domain)) |
96f81a93 BH |
431 | return false; |
432 | ||
433 | return tie(fd, id) < tie(b.fd, b.id); | |
1d5b3ce6 BH |
434 | } |
435 | }; | |
436 | ||
96f81a93 BH |
437 | struct PacketIDBirthdayCompare: public binary_function<PacketID, PacketID, bool> |
438 | { | |
439 | bool operator()(const PacketID& a, const PacketID& b) const | |
440 | { | |
441 | int ourSock= a.sock ? a.sock->getHandle() : 0; | |
442 | int bSock = b.sock ? b.sock->getHandle() : 0; | |
787e5eab | 443 | if( tie(a.remote, ourSock, a.type) < tie(b.remote, bSock, b.type)) |
96f81a93 | 444 | return true; |
787e5eab | 445 | if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type)) |
96f81a93 BH |
446 | return false; |
447 | ||
ec6480f3 | 448 | return pdns_ilexicographical_compare(a.domain, b.domain); |
96f81a93 BH |
449 | } |
450 | }; | |
49a699c4 | 451 | extern __thread MemRecursorCache* t_RC; |
16beeaa4 | 452 | extern __thread RecursorPacketCache* t_packetCache; |
d2392145 | 453 | typedef MTasker<PacketID,string> MT_t; |
bb4bdbaf | 454 | extern __thread MT_t* MT; |
1d5b3ce6 BH |
455 | |
456 | struct RecursorStats | |
457 | { | |
458 | uint64_t servFails; | |
459 | uint64_t nxDomains; | |
460 | uint64_t noErrors; | |
fe213470 | 461 | uint64_t answers0_1, answers1_10, answers10_100, answers100_1000, answersSlow; |
574af7ea | 462 | uint64_t avgLatencyUsec; |
aaacf7f2 BH |
463 | uint64_t qcounter; |
464 | uint64_t tcpqcounter; | |
c8ddb7c2 BH |
465 | uint64_t unauthorizedUDP; |
466 | uint64_t unauthorizedTCP; | |
4e120339 | 467 | uint64_t tcpClientOverflow; |
0e9d9ce2 BH |
468 | uint64_t clientParseError; |
469 | uint64_t serverParseError; | |
01ed3112 | 470 | uint64_t unexpectedCount; |
7a132082 | 471 | uint64_t caseMismatchCount; |
0d5f0a9f | 472 | uint64_t spoofCount; |
998a4334 | 473 | uint64_t resourceLimits; |
85c32340 | 474 | uint64_t overCapacityDrops; |
996c89cc | 475 | uint64_t ipv6queries; |
96f81a93 | 476 | uint64_t chainResends; |
1ef00ba1 | 477 | uint64_t nsSetInvalidations; |
c0ea6e55 BH |
478 | uint64_t ednsPingMatches; |
479 | uint64_t ednsPingMismatches; | |
480 | uint64_t noPingOutQueries, noEdnsOutQueries; | |
61b26744 | 481 | uint64_t packetCacheHits; |
5e3de507 | 482 | time_t startupTime; |
996c89cc | 483 | |
a9af3782 BH |
484 | typedef vector<ComboAddress> remotes_t; |
485 | remotes_t remotes; | |
486 | int d_remotepos; | |
487 | void addRemote(const ComboAddress& remote) | |
488 | { | |
489 | if(!remotes.size()) | |
490 | return; | |
491 | ||
492 | remotes[(d_remotepos++) % remotes.size()]=remote; | |
493 | } | |
1d5b3ce6 BH |
494 | }; |
495 | ||
674cf0f6 | 496 | string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end); |
18af64a8 | 497 | void parseACLs(); |
1d5b3ce6 | 498 | extern RecursorStats g_stats; |
c3828c03 | 499 | extern unsigned int g_numThreads; |
739f6278 BH |
500 | |
501 | template<typename Index> | |
502 | std::pair<typename Index::iterator,bool> | |
503 | replacing_insert(Index& i,const typename Index::value_type& x) | |
504 | { | |
505 | std::pair<typename Index::iterator,bool> res=i.insert(x); | |
506 | if(!res.second)res.second=i.replace(res.first,x); | |
507 | return res; | |
508 | } | |
509 | ||
ee1ada80 BH |
510 | |
511 | std::string reloadAuthAndForwards(); | |
c1d73d94 | 512 | ComboAddress parseIPAndPort(const std::string& input, uint16_t port); |
1652a63e | 513 | ComboAddress getQueryLocalAddress(int family, uint16_t port); |
3427fa8a | 514 | typedef boost::function<void*(void)> pipefunc_t; |
49a699c4 | 515 | void broadcastFunction(const pipefunc_t& func, bool skipSelf = false); |
3427fa8a BH |
516 | |
517 | ||
13034931 | 518 | template<class T> T broadcastAccFunction(const boost::function<T*()>& func, bool skipSelf=false); |
3427fa8a | 519 | |
49a699c4 | 520 | SyncRes::domainmap_t* parseAuthAndForwards(); |
3427fa8a | 521 | |
13034931 BH |
522 | uint64_t* pleaseGetNsSpeedsSize(); |
523 | uint64_t* pleaseGetCacheSize(); | |
524 | uint64_t* pleaseGetNegCacheSize(); | |
525 | uint64_t* pleaseGetCacheHits(); | |
526 | uint64_t* pleaseGetCacheMisses(); | |
527 | uint64_t* pleaseGetConcurrentQueries(); | |
528 | uint64_t* pleaseGetThrottleSize(); | |
16beeaa4 BH |
529 | uint64_t* pleaseGetPacketCacheHits(); |
530 | uint64_t* pleaseGetPacketCacheSize(); | |
531 | ||
00a19ff7 | 532 | #endif |