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