]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/syncres.hh
Lua config for dnstap works in basic testing.
[thirdparty/pdns.git] / pdns / syncres.hh
1 /*
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 */
22 #pragma once
23 #include <string>
24 #include <atomic>
25 #include "utility.hh"
26 #include "dns.hh"
27 #include "qtype.hh"
28 #include <vector>
29 #include <set>
30 #include <unordered_set>
31 #include <map>
32 #include <cmath>
33 #include <iostream>
34 #include <utility>
35 #include "misc.hh"
36 #include "lwres.hh"
37 #include <boost/optional.hpp>
38 #include <boost/circular_buffer.hpp>
39 #include <boost/utility.hpp>
40 #include "sstuff.hh"
41 #include "recursor_cache.hh"
42 #include "recpacketcache.hh"
43 #include <boost/tuple/tuple.hpp>
44 #include <boost/optional.hpp>
45 #include <boost/tuple/tuple_comparison.hpp>
46 #include "mtasker.hh"
47 #include "iputils.hh"
48 #include "validate.hh"
49 #include "ednssubnet.hh"
50 #include "filterpo.hh"
51 #include "negcache.hh"
52
53 #ifdef HAVE_CONFIG_H
54 #include "config.h"
55 #endif
56
57 #ifdef HAVE_PROTOBUF
58 #include <boost/uuid/uuid.hpp>
59 #ifdef HAVE_FSTRM
60 #include "fstrm_logger.hh"
61 #endif /* HAVE_FSTRM */
62 #endif
63
64 class RecursorLua4;
65
66 typedef map<
67 DNSName,
68 pair<
69 vector<ComboAddress>,
70 bool
71 >
72 > NsSet;
73
74 template<class Thing> class Throttle : public boost::noncopyable
75 {
76 public:
77 Throttle() : d_limit(3), d_ttl(60), d_last_clean(time(nullptr))
78 {
79 }
80
81 struct entry
82 {
83 time_t ttd;
84 unsigned int count;
85 };
86 typedef map<Thing,entry> cont_t;
87
88 bool shouldThrottle(time_t now, const Thing& t)
89 {
90 if(now > d_last_clean + 300 ) {
91
92 d_last_clean=now;
93 for(typename cont_t::iterator i=d_cont.begin();i!=d_cont.end();) {
94 if( i->second.ttd < now) {
95 d_cont.erase(i++);
96 }
97 else
98 ++i;
99 }
100 }
101
102 typename cont_t::iterator i=d_cont.find(t);
103 if(i==d_cont.end())
104 return false;
105 if(now > i->second.ttd || i->second.count == 0) {
106 d_cont.erase(i);
107 return false;
108 }
109 i->second.count--;
110
111 return true; // still listed, still blocked
112 }
113 void throttle(time_t now, const Thing& t, time_t ttl=0, unsigned int tries=0)
114 {
115 typename cont_t::iterator i=d_cont.find(t);
116 entry e={ now+(ttl ? ttl : d_ttl), tries ? tries : d_limit};
117
118 if(i==d_cont.end()) {
119 d_cont[t]=e;
120 }
121 else if(i->second.ttd > e.ttd || (i->second.count) < e.count)
122 d_cont[t]=e;
123 }
124
125 unsigned int size() const
126 {
127 return (unsigned int)d_cont.size();
128 }
129
130 const cont_t& getThrottleMap() const
131 {
132 return d_cont;
133 }
134
135 void clear()
136 {
137 d_cont.clear();
138 }
139
140 private:
141 unsigned int d_limit;
142 time_t d_ttl;
143 time_t d_last_clean;
144 cont_t d_cont;
145 };
146
147
148 /** Class that implements a decaying EWMA.
149 This class keeps an exponentially weighted moving average which, additionally, decays over time.
150 The decaying is only done on get.
151 */
152 class DecayingEwma
153 {
154 public:
155 DecayingEwma() : d_val(0.0)
156 {
157 d_needinit=true;
158 d_last.tv_sec = d_last.tv_usec = 0;
159 d_lastget=d_last;
160 }
161
162 DecayingEwma(const DecayingEwma& orig) : d_last(orig.d_last), d_lastget(orig.d_lastget), d_val(orig.d_val), d_needinit(orig.d_needinit)
163 {
164 }
165
166 void submit(int val, const struct timeval* tv)
167 {
168 struct timeval now=*tv;
169
170 if(d_needinit) {
171 d_last=now;
172 d_lastget=now;
173 d_needinit=false;
174 d_val = val;
175 }
176 else {
177 float diff= makeFloat(d_last - now);
178
179 d_last=now;
180 double factor=exp(diff)/2.0; // might be '0.5', or 0.0001
181 d_val=(float)((1-factor)*val+ (float)factor*d_val);
182 }
183 }
184
185 double get(const struct timeval* tv)
186 {
187 struct timeval now=*tv;
188 float diff=makeFloat(d_lastget-now);
189 d_lastget=now;
190 float factor=exp(diff/60.0f); // is 1.0 or less
191 return d_val*=factor;
192 }
193
194 double peek(void) const
195 {
196 return d_val;
197 }
198
199 bool stale(time_t limit) const
200 {
201 return limit > d_lastget.tv_sec;
202 }
203
204 private:
205 struct timeval d_last; // stores time
206 struct timeval d_lastget; // stores time
207 float d_val;
208 bool d_needinit;
209 };
210
211 template<class Thing> class Counters : public boost::noncopyable
212 {
213 public:
214 Counters()
215 {
216 }
217 unsigned long value(const Thing& t) const
218 {
219 typename cont_t::const_iterator i=d_cont.find(t);
220
221 if(i==d_cont.end()) {
222 return 0;
223 }
224 return (unsigned long)i->second;
225 }
226 unsigned long incr(const Thing& t)
227 {
228 typename cont_t::iterator i=d_cont.find(t);
229
230 if(i==d_cont.end()) {
231 d_cont[t]=1;
232 return 1;
233 }
234 else {
235 if (i->second < std::numeric_limits<unsigned long>::max())
236 i->second++;
237 return (unsigned long)i->second;
238 }
239 }
240 unsigned long decr(const Thing& t)
241 {
242 typename cont_t::iterator i=d_cont.find(t);
243
244 if(i!=d_cont.end() && --i->second == 0) {
245 d_cont.erase(i);
246 return 0;
247 } else
248 return (unsigned long)i->second;
249 }
250 void clear(const Thing& t)
251 {
252 typename cont_t::iterator i=d_cont.find(t);
253
254 if(i!=d_cont.end()) {
255 d_cont.erase(i);
256 }
257 }
258 void clear()
259 {
260 d_cont.clear();
261 }
262 size_t size() const
263 {
264 return d_cont.size();
265 }
266 private:
267 typedef map<Thing,unsigned long> cont_t;
268 cont_t d_cont;
269 };
270
271
272 class SyncRes : public boost::noncopyable
273 {
274 public:
275 enum LogMode { LogNone, Log, Store};
276 typedef std::function<int(const ComboAddress& ip, const DNSName& qdomain, int qtype, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult *lwr, bool* chained)> asyncresolve_t;
277
278 struct EDNSStatus
279 {
280 EDNSStatus() : mode(UNKNOWN), modeSetAt(0) {}
281 enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode;
282 time_t modeSetAt;
283 };
284
285 //! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
286 /** Modelled to work mostly like the underlying DecayingEwma. After you've called get,
287 d_best is filled out with the best address for this collection */
288 struct DecayingEwmaCollection
289 {
290 void submit(const ComboAddress& remote, int usecs, const struct timeval* now)
291 {
292 d_collection[remote].submit(usecs, now);
293 }
294
295 double get(const struct timeval* now)
296 {
297 if(d_collection.empty())
298 return 0;
299 double ret=std::numeric_limits<double>::max();
300 double tmp;
301 for (auto& entry : d_collection) {
302 if((tmp = entry.second.get(now)) < ret) {
303 ret=tmp;
304 d_best=entry.first;
305 }
306 }
307
308 return ret;
309 }
310
311 bool stale(time_t limit) const
312 {
313 for(const auto& entry : d_collection)
314 if(!entry.second.stale(limit))
315 return false;
316 return true;
317 }
318
319 void purge(const std::map<ComboAddress, double>& keep)
320 {
321 for (auto iter = d_collection.begin(); iter != d_collection.end(); ) {
322 if (keep.find(iter->first) != keep.end()) {
323 ++iter;
324 }
325 else {
326 iter = d_collection.erase(iter);
327 }
328 }
329 }
330
331 typedef std::map<ComboAddress, DecayingEwma> collection_t;
332 collection_t d_collection;
333 ComboAddress d_best;
334 };
335
336 typedef map<DNSName, DecayingEwmaCollection> nsspeeds_t;
337 typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
338
339 vState getDSRecords(const DNSName& zone, dsmap_t& ds, bool onlyTA, unsigned int depth, bool bogusOnNXD=true, bool* foundCut=nullptr);
340
341 class AuthDomain
342 {
343 public:
344 typedef multi_index_container <
345 DNSRecord,
346 indexed_by <
347 ordered_non_unique<
348 composite_key< DNSRecord,
349 member<DNSRecord, DNSName, &DNSRecord::d_name>,
350 member<DNSRecord, uint16_t, &DNSRecord::d_type>
351 >,
352 composite_key_compare<std::less<DNSName>, std::less<uint16_t> >
353 >
354 >
355 > records_t;
356
357 records_t d_records;
358 vector<ComboAddress> d_servers;
359 DNSName d_name;
360 bool d_rdForward{false};
361
362 int getRecords(const DNSName& qname, uint16_t qtype, std::vector<DNSRecord>& records) const;
363 bool isAuth() const
364 {
365 return d_servers.empty();
366 }
367 bool isForward() const
368 {
369 return !isAuth();
370 }
371 bool shouldRecurse() const
372 {
373 return d_rdForward;
374 }
375 const DNSName& getName() const
376 {
377 return d_name;
378 }
379
380 private:
381 void addSOA(std::vector<DNSRecord>& records) const;
382 };
383
384 typedef map<DNSName, AuthDomain> domainmap_t;
385 typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
386 typedef Counters<ComboAddress> fails_t;
387
388 struct ThreadLocalStorage {
389 NegCache negcache;
390 nsspeeds_t nsSpeeds;
391 throttle_t throttle;
392 ednsstatus_t ednsstatus;
393 fails_t fails;
394 std::shared_ptr<domainmap_t> domainmap;
395 };
396
397 static void setDefaultLogMode(LogMode lm)
398 {
399 s_lm = lm;
400 }
401 static uint64_t doEDNSDump(int fd);
402 static uint64_t doDumpNSSpeeds(int fd);
403 static uint64_t doDumpThrottleMap(int fd);
404 static int getRootNS(struct timeval now, asyncresolve_t asyncCallback);
405 static void clearDelegationOnly()
406 {
407 s_delegationOnly.clear();
408 }
409 static void addDelegationOnly(const DNSName& name)
410 {
411 s_delegationOnly.insert(name);
412 }
413 static void addDontQuery(const std::string& mask)
414 {
415 if (!s_dontQuery)
416 s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
417
418 s_dontQuery->addMask(mask);
419 }
420 static void addDontQuery(const Netmask& mask)
421 {
422 if (!s_dontQuery)
423 s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
424
425 s_dontQuery->addMask(mask);
426 }
427 static void clearDontQuery()
428 {
429 s_dontQuery = nullptr;
430 }
431 static void parseEDNSSubnetWhitelist(const std::string& wlist);
432 static void parseEDNSSubnetAddFor(const std::string& subnetlist);
433 static void addEDNSLocalSubnet(const std::string& subnet)
434 {
435 s_ednslocalsubnets.addMask(subnet);
436 }
437 static void addEDNSRemoteSubnet(const std::string& subnet)
438 {
439 s_ednsremotesubnets.addMask(subnet);
440 }
441 static void addEDNSDomain(const DNSName& domain)
442 {
443 s_ednsdomains.add(domain);
444 }
445 static void clearEDNSLocalSubnets()
446 {
447 s_ednslocalsubnets.clear();
448 }
449 static void clearEDNSRemoteSubnets()
450 {
451 s_ednsremotesubnets.clear();
452 }
453 static void clearEDNSDomains()
454 {
455 s_ednsdomains = SuffixMatchNode();
456 }
457 static void pruneNSSpeeds(time_t limit)
458 {
459 for(auto i = t_sstorage.nsSpeeds.begin(), end = t_sstorage.nsSpeeds.end(); i != end; ) {
460 if(i->second.stale(limit)) {
461 i = t_sstorage.nsSpeeds.erase(i);
462 }
463 else {
464 ++i;
465 }
466 }
467 }
468 static uint64_t getNSSpeedsSize()
469 {
470 return t_sstorage.nsSpeeds.size();
471 }
472 static void submitNSSpeed(const DNSName& server, const ComboAddress& ca, uint32_t usec, const struct timeval* now)
473 {
474 t_sstorage.nsSpeeds[server].submit(ca, usec, now);
475 }
476 static void clearNSSpeeds()
477 {
478 t_sstorage.nsSpeeds.clear();
479 }
480 static EDNSStatus::EDNSMode getEDNSStatus(const ComboAddress& server)
481 {
482 const auto& it = t_sstorage.ednsstatus.find(server);
483 if (it == t_sstorage.ednsstatus.end())
484 return EDNSStatus::UNKNOWN;
485
486 return it->second.mode;
487 }
488 static uint64_t getEDNSStatusesSize()
489 {
490 return t_sstorage.ednsstatus.size();
491 }
492 static void clearEDNSStatuses()
493 {
494 t_sstorage.ednsstatus.clear();
495 }
496 static uint64_t getThrottledServersSize()
497 {
498 return t_sstorage.throttle.size();
499 }
500 static void clearThrottle()
501 {
502 t_sstorage.throttle.clear();
503 }
504 static bool isThrottled(time_t now, const ComboAddress& server, const DNSName& target, uint16_t qtype)
505 {
506 return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, target, qtype));
507 }
508 static bool isThrottled(time_t now, const ComboAddress& server)
509 {
510 return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, "", 0));
511 }
512 static void doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries)
513 {
514 t_sstorage.throttle.throttle(now, boost::make_tuple(server, "", 0), duration, tries);
515 }
516 static uint64_t getFailedServersSize()
517 {
518 return t_sstorage.fails.size();
519 }
520 static void clearFailedServers()
521 {
522 t_sstorage.fails.clear();
523 }
524 static unsigned long getServerFailsCount(const ComboAddress& server)
525 {
526 return t_sstorage.fails.value(server);
527 }
528
529 static void clearNegCache()
530 {
531 t_sstorage.negcache.clear();
532 }
533
534 static uint64_t getNegCacheSize()
535 {
536 return t_sstorage.negcache.size();
537 }
538
539 static void pruneNegCache(unsigned int maxEntries)
540 {
541 t_sstorage.negcache.prune(maxEntries);
542 }
543
544 static uint64_t wipeNegCache(const DNSName& name, bool subtree = false)
545 {
546 return t_sstorage.negcache.wipe(name, subtree);
547 }
548
549 static void setDomainMap(std::shared_ptr<domainmap_t> newMap)
550 {
551 t_sstorage.domainmap = newMap;
552 }
553
554 static const std::shared_ptr<domainmap_t> getDomainMap()
555 {
556 return t_sstorage.domainmap;
557 }
558
559 static void setECSScopeZeroAddress(const Netmask& scopeZeroMask)
560 {
561 s_ecsScopeZero.source = scopeZeroMask;
562 }
563
564 explicit SyncRes(const struct timeval& now);
565
566 int beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSRecord>&ret);
567 void setId(int id)
568 {
569 if(doLog())
570 d_prefix="["+itoa(id)+"] ";
571 }
572
573 void setLogMode(LogMode lm)
574 {
575 d_lm = lm;
576 }
577
578 bool doLog() const
579 {
580 return d_lm != LogNone;
581 }
582
583 void setCacheOnly(bool state=true)
584 {
585 d_cacheonly=state;
586 }
587
588 void setDoEDNS0(bool state=true)
589 {
590 d_doEDNS0=state;
591 }
592
593 void setDoDNSSEC(bool state=true)
594 {
595 d_doDNSSEC=state;
596 }
597
598 void setDNSSECValidationRequested(bool requested=true)
599 {
600 d_DNSSECValidationRequested = requested;
601 }
602
603 bool isDNSSECValidationRequested() const
604 {
605 return d_DNSSECValidationRequested;
606 }
607
608 bool shouldValidate() const
609 {
610 return d_DNSSECValidationRequested && !d_wasOutOfBand;
611 }
612
613 void setWantsRPZ(bool state=true)
614 {
615 d_wantsRPZ=state;
616 }
617
618 bool getWantsRPZ() const
619 {
620 return d_wantsRPZ;
621 }
622
623 string getTrace() const
624 {
625 return d_trace.str();
626 }
627
628 void setLuaEngine(shared_ptr<RecursorLua4> pdl)
629 {
630 d_pdl = pdl;
631 }
632
633 bool wasVariable() const
634 {
635 return d_wasVariable;
636 }
637
638 bool wasOutOfBand() const
639 {
640 return d_wasOutOfBand;
641 }
642
643 struct timeval getNow() const
644 {
645 return d_now;
646 }
647
648 void setSkipCNAMECheck(bool skip = false)
649 {
650 d_skipCNAMECheck = skip;
651 }
652
653 void setQuerySource(const ComboAddress& requestor, boost::optional<const EDNSSubnetOpts&> incomingECS);
654
655 #ifdef HAVE_PROTOBUF
656 void setInitialRequestId(boost::optional<const boost::uuids::uuid&> initialRequestId)
657 {
658 d_initialRequestId = initialRequestId;
659 }
660
661 void setOutgoingProtobufServers(std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& servers)
662 {
663 d_outgoingProtobufServers = servers;
664 }
665 #endif
666
667 #ifdef HAVE_FSTRM
668 void setFrameStreamServers(std::shared_ptr<std::vector<std::unique_ptr<RemoteLoggerInterface>>>& servers)
669 {
670 d_frameStreamServers = servers;
671 }
672 #endif /* HAVE_FSTRM */
673
674 void setAsyncCallback(asyncresolve_t func)
675 {
676 d_asyncResolve = func;
677 }
678
679 vState getValidationState() const
680 {
681 return d_queryValidationState;
682 }
683
684 static thread_local ThreadLocalStorage t_sstorage;
685
686 static std::atomic<uint64_t> s_queries;
687 static std::atomic<uint64_t> s_outgoingtimeouts;
688 static std::atomic<uint64_t> s_outgoing4timeouts;
689 static std::atomic<uint64_t> s_outgoing6timeouts;
690 static std::atomic<uint64_t> s_throttledqueries;
691 static std::atomic<uint64_t> s_dontqueries;
692 static std::atomic<uint64_t> s_authzonequeries;
693 static std::atomic<uint64_t> s_outqueries;
694 static std::atomic<uint64_t> s_tcpoutqueries;
695 static std::atomic<uint64_t> s_nodelegated;
696 static std::atomic<uint64_t> s_unreachables;
697 static std::atomic<uint64_t> s_ecsqueries;
698 static std::atomic<uint64_t> s_ecsresponses;
699
700 static string s_serverID;
701 static unsigned int s_minimumTTL;
702 static unsigned int s_maxqperq;
703 static unsigned int s_maxtotusec;
704 static unsigned int s_maxdepth;
705 static unsigned int s_maxnegttl;
706 static unsigned int s_maxbogusttl;
707 static unsigned int s_maxcachettl;
708 static unsigned int s_packetcachettl;
709 static unsigned int s_packetcacheservfailttl;
710 static unsigned int s_serverdownmaxfails;
711 static unsigned int s_serverdownthrottletime;
712 static uint8_t s_ecsipv4limit;
713 static uint8_t s_ecsipv6limit;
714 static bool s_doIPv6;
715 static bool s_noEDNSPing;
716 static bool s_noEDNS;
717 static bool s_rootNXTrust;
718 static bool s_nopacketcache;
719
720 std::unordered_map<std::string,bool> d_discardedPolicies;
721 DNSFilterEngine::Policy d_appliedPolicy;
722 unsigned int d_authzonequeries;
723 unsigned int d_outqueries;
724 unsigned int d_tcpoutqueries;
725 unsigned int d_throttledqueries;
726 unsigned int d_timeouts;
727 unsigned int d_unreachables;
728 unsigned int d_totUsec;
729
730 private:
731 ComboAddress d_requestor;
732 ComboAddress d_cacheRemote;
733
734 static std::unordered_set<DNSName> s_delegationOnly;
735 static NetmaskGroup s_ednslocalsubnets;
736 static NetmaskGroup s_ednsremotesubnets;
737 static SuffixMatchNode s_ednsdomains;
738 static EDNSSubnetOpts s_ecsScopeZero;
739 static LogMode s_lm;
740 static std::unique_ptr<NetmaskGroup> s_dontQuery;
741
742 struct GetBestNSAnswer
743 {
744 DNSName qname;
745 set<pair<DNSName,DNSName> > bestns;
746 uint8_t qtype; // only A and AAAA anyhow
747 bool operator<(const GetBestNSAnswer &b) const
748 {
749 return boost::tie(qname, qtype, bestns) <
750 boost::tie(b.qname, b.qtype, b.bestns);
751 }
752 };
753
754 typedef std::map<DNSName,vState> zonesStates_t;
755
756 int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret,
757 unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state);
758 bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool* truncated);
759 bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, DNSName& auth, bool wasForwarded, const boost::optional<Netmask> ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector<DNSRecord>& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state);
760
761 int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state);
762 bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, int& res);
763 bool doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res);
764 domainmap_t::const_iterator getBestAuthZone(DNSName* qname) const;
765 bool doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse);
766 bool doCacheCheck(const DNSName &qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state);
767 void getBestNSFromCache(const DNSName &qname, const QType &qtype, vector<DNSRecord>&bestns, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>& beenthere);
768 DNSName getBestNSNamesFromCache(const DNSName &qname, const QType &qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>&beenthere);
769
770 inline vector<DNSName> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
771 inline vector<ComboAddress> shuffleForwardSpeed(const vector<ComboAddress> &rnameservers, const string &prefix, const bool wasRd);
772 bool moreSpecificThan(const DNSName& a, const DNSName &b) const;
773 vector<ComboAddress> getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly);
774
775 bool nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers);
776 bool nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress&);
777 bool throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType& qtype, bool pierceDontQuery);
778
779 vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<DNSName >::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<DNSName >& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly);
780
781 void sanitizeRecords(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, bool rdQuery);
782 RCode::rcodes_ updateCacheFromRecords(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, const boost::optional<Netmask>, vState& state, bool& needWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery);
783 bool processRecords(const std::string& prefix, const DNSName& qname, const QType& qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector<DNSRecord>& ret, set<DNSName>& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const unsigned int wildcardLabelsCount);
784
785 bool doSpecialNamesResolve(const DNSName &qname, const QType &qtype, const uint16_t qclass, vector<DNSRecord> &ret);
786
787 int asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional<Netmask>& srcmask, LWResult* res, bool* chained) const;
788
789 boost::optional<Netmask> getEDNSSubnetMask(const DNSName&dn, const ComboAddress& rem);
790
791 bool validationEnabled() const;
792 uint32_t computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, uint32_t signaturesTTL) const;
793 void updateValidationState(vState& state, const vState stateUpdate);
794 vState validateRecordsWithSigs(unsigned int depth, const DNSName& qname, const QType& qtype, const DNSName& name, const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures);
795 vState validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord>& dnskeys, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, unsigned int depth);
796 vState getDNSKeys(const DNSName& signer, skeyset_t& keys, unsigned int depth);
797 dState getDenialValidationState(const NegCache::NegCacheEntry& ne, const vState state, const dState expectedState, bool referralToUnsigned);
798 void updateDenialValidationState(vState& neValidationState, const DNSName& neName, vState& state, const dState denialState, const dState expectedState, bool allowOptOut);
799 void computeNegCacheValidationStatus(const NegCache::NegCacheEntry* ne, const DNSName& qname, const QType& qtype, const int res, vState& state, unsigned int depth);
800 vState getTA(const DNSName& zone, dsmap_t& ds);
801 bool haveExactValidationStatus(const DNSName& domain);
802 vState getValidationStatus(const DNSName& subdomain, bool allowIndeterminate=true);
803 void updateValidationStatusInCache(const DNSName &qname, const QType& qt, bool aa, vState newState) const;
804
805 bool lookForCut(const DNSName& qname, unsigned int depth, const vState existingState, vState& newState);
806 void computeZoneCuts(const DNSName& begin, const DNSName& end, unsigned int depth);
807
808 void setUpdatingRootNS()
809 {
810 d_updatingRootNS = true;
811 }
812
813 zonesStates_t d_cutStates;
814 ostringstream d_trace;
815 shared_ptr<RecursorLua4> d_pdl;
816 boost::optional<Netmask> d_outgoingECSNetwork;
817 std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>> d_outgoingProtobufServers{nullptr};
818 std::shared_ptr<std::vector<std::unique_ptr<RemoteLoggerInterface>>> d_frameStreamServers{nullptr};
819 #ifdef HAVE_PROTOBUF
820 boost::optional<const boost::uuids::uuid&> d_initialRequestId;
821 #endif
822 asyncresolve_t d_asyncResolve{nullptr};
823 struct timeval d_now;
824 string d_prefix;
825 vState d_queryValidationState{Indeterminate};
826
827 /* When d_cacheonly is set to true, we will only check the cache.
828 * This is set when the RD bit is unset in the incoming query
829 */
830 bool d_cacheonly;
831 bool d_doDNSSEC;
832 bool d_DNSSECValidationRequested{false};
833 bool d_doEDNS0{true};
834 bool d_requireAuthData{true};
835 bool d_skipCNAMECheck{false};
836 bool d_updatingRootNS{false};
837 bool d_wantsRPZ{true};
838 bool d_wasOutOfBand{false};
839 bool d_wasVariable{false};
840
841 LogMode d_lm;
842 };
843
844 class Socket;
845 /* external functions, opaque to us */
846 int asendtcp(const string& data, Socket* sock);
847 int arecvtcp(string& data, size_t len, Socket* sock, bool incompleteOkay);
848
849
850 struct PacketID
851 {
852 PacketID() : id(0), type(0), sock(0), inNeeded(0), inIncompleteOkay(false), outPos(0), nearMisses(0), fd(-1)
853 {
854 remote.reset();
855 }
856
857 uint16_t id; // wait for a specific id/remote pair
858 uint16_t type; // and this is its type
859 ComboAddress remote; // this is the remote
860 DNSName domain; // this is the question
861
862 Socket* sock; // or wait for an event on a TCP fd
863 string inMSG; // they'll go here
864 size_t inNeeded; // if this is set, we'll read until inNeeded bytes are read
865 bool inIncompleteOkay;
866
867 string outMSG; // the outgoing message that needs to be sent
868 string::size_type outPos; // how far we are along in the outMSG
869
870 typedef set<uint16_t > chain_t;
871 mutable chain_t chain;
872 mutable uint32_t nearMisses; // number of near misses - host correct, id wrong
873 int fd;
874
875 bool operator<(const PacketID& b) const
876 {
877 int ourSock= sock ? sock->getHandle() : 0;
878 int bSock = b.sock ? b.sock->getHandle() : 0;
879 if( tie(remote, ourSock, type) < tie(b.remote, bSock, b.type))
880 return true;
881 if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type))
882 return false;
883
884 return tie(domain, fd, id) < tie(b.domain, b.fd, b.id);
885 }
886 };
887
888 struct PacketIDBirthdayCompare: public std::binary_function<PacketID, PacketID, bool>
889 {
890 bool operator()(const PacketID& a, const PacketID& b) const
891 {
892 int ourSock= a.sock ? a.sock->getHandle() : 0;
893 int bSock = b.sock ? b.sock->getHandle() : 0;
894 if( tie(a.remote, ourSock, a.type) < tie(b.remote, bSock, b.type))
895 return true;
896 if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
897 return false;
898
899 return a.domain < b.domain;
900 }
901 };
902 extern thread_local std::unique_ptr<MemRecursorCache> t_RC;
903 extern thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
904 typedef MTasker<PacketID,string> MT_t;
905 MT_t* getMT();
906
907 struct RecursorStats
908 {
909 std::atomic<uint64_t> servFails;
910 std::atomic<uint64_t> nxDomains;
911 std::atomic<uint64_t> noErrors;
912 std::atomic<uint64_t> answers0_1, answers1_10, answers10_100, answers100_1000, answersSlow;
913 std::atomic<uint64_t> auth4Answers0_1, auth4Answers1_10, auth4Answers10_100, auth4Answers100_1000, auth4AnswersSlow;
914 std::atomic<uint64_t> auth6Answers0_1, auth6Answers1_10, auth6Answers10_100, auth6Answers100_1000, auth6AnswersSlow;
915 std::atomic<uint64_t> ourtime0_1, ourtime1_2, ourtime2_4, ourtime4_8, ourtime8_16, ourtime16_32, ourtimeSlow;
916 double avgLatencyUsec{0};
917 double avgLatencyOursUsec{0};
918 std::atomic<uint64_t> qcounter; // not increased for unauth packets
919 std::atomic<uint64_t> ipv6qcounter;
920 std::atomic<uint64_t> tcpqcounter;
921 std::atomic<uint64_t> unauthorizedUDP; // when this is increased, qcounter isn't
922 std::atomic<uint64_t> unauthorizedTCP; // when this is increased, qcounter isn't
923 std::atomic<uint64_t> policyDrops;
924 std::atomic<uint64_t> tcpClientOverflow;
925 std::atomic<uint64_t> clientParseError;
926 std::atomic<uint64_t> serverParseError;
927 std::atomic<uint64_t> tooOldDrops;
928 std::atomic<uint64_t> truncatedDrops;
929 std::atomic<uint64_t> queryPipeFullDrops;
930 std::atomic<uint64_t> unexpectedCount;
931 std::atomic<uint64_t> caseMismatchCount;
932 std::atomic<uint64_t> spoofCount;
933 std::atomic<uint64_t> resourceLimits;
934 std::atomic<uint64_t> overCapacityDrops;
935 std::atomic<uint64_t> ipv6queries;
936 std::atomic<uint64_t> chainResends;
937 std::atomic<uint64_t> nsSetInvalidations;
938 std::atomic<uint64_t> ednsPingMatches;
939 std::atomic<uint64_t> ednsPingMismatches;
940 std::atomic<uint64_t> noPingOutQueries, noEdnsOutQueries;
941 std::atomic<uint64_t> packetCacheHits;
942 std::atomic<uint64_t> noPacketError;
943 std::atomic<uint64_t> ignoredCount;
944 std::atomic<uint64_t> emptyQueriesCount;
945 time_t startupTime;
946 std::atomic<uint64_t> dnssecQueries;
947 std::atomic<uint64_t> dnssecAuthenticDataQueries;
948 std::atomic<uint64_t> dnssecCheckDisabledQueries;
949 std::atomic<uint64_t> variableResponses;
950 unsigned int maxMThreadStackUsage;
951 std::atomic<uint64_t> dnssecValidations; // should be the sum of all dnssecResult* stats
952 std::map<vState, std::atomic<uint64_t> > dnssecResults;
953 std::map<DNSFilterEngine::PolicyKind, std::atomic<uint64_t> > policyResults;
954 };
955
956 //! represents a running TCP/IP client session
957 class TCPConnection : public boost::noncopyable
958 {
959 public:
960 TCPConnection(int fd, const ComboAddress& addr);
961 ~TCPConnection();
962
963 int getFD() const
964 {
965 return d_fd;
966 }
967
968 std::string data;
969 const ComboAddress d_remote;
970 size_t queriesCount{0};
971 enum stateenum {BYTE0, BYTE1, GETQUESTION, DONE} state{BYTE0};
972 uint16_t qlen{0};
973 uint16_t bytesread{0};
974
975 static unsigned int getCurrentConnections() { return s_currentConnections; }
976 private:
977 const int d_fd;
978 static AtomicCounter s_currentConnections; //!< total number of current TCP connections
979 };
980
981 class ImmediateServFailException
982 {
983 public:
984 ImmediateServFailException(string r) : reason(r) {};
985
986 string reason; //! Print this to tell the user what went wrong
987 };
988
989 typedef boost::circular_buffer<ComboAddress> addrringbuf_t;
990 extern thread_local std::unique_ptr<addrringbuf_t> t_servfailremotes, t_largeanswerremotes, t_remotes, t_bogusremotes, t_timeouts;
991
992 extern thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName,uint16_t> > > t_queryring, t_servfailqueryring, t_bogusqueryring;
993 extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
994 string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
995 string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_iterator end);
996 void parseACLs();
997 extern RecursorStats g_stats;
998 extern unsigned int g_networkTimeoutMsec;
999 extern unsigned int g_numThreads;
1000 extern uint16_t g_outgoingEDNSBufsize;
1001 extern std::atomic<uint32_t> g_maxCacheEntries, g_maxPacketCacheEntries;
1002 extern bool g_lowercaseOutgoing;
1003
1004
1005 std::string reloadAuthAndForwards();
1006 ComboAddress parseIPAndPort(const std::string& input, uint16_t port);
1007 ComboAddress getQueryLocalAddress(int family, uint16_t port);
1008 typedef boost::function<void*(void)> pipefunc_t;
1009 void broadcastFunction(const pipefunc_t& func);
1010 void distributeAsyncFunction(const std::string& question, const pipefunc_t& func);
1011
1012 int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<DNSRecord>& ret);
1013
1014 template<class T> T broadcastAccFunction(const boost::function<T*()>& func);
1015
1016 std::shared_ptr<SyncRes::domainmap_t> parseAuthAndForwards();
1017 uint64_t* pleaseGetNsSpeedsSize();
1018 uint64_t* pleaseGetCacheSize();
1019 uint64_t* pleaseGetNegCacheSize();
1020 uint64_t* pleaseGetCacheHits();
1021 uint64_t* pleaseGetCacheMisses();
1022 uint64_t* pleaseGetConcurrentQueries();
1023 uint64_t* pleaseGetThrottleSize();
1024 uint64_t* pleaseGetPacketCacheHits();
1025 uint64_t* pleaseGetPacketCacheSize();
1026 uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree=false);
1027 uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree);
1028 uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree=false);
1029 void doCarbonDump(void*);
1030 void primeHints(void);
1031
1032 extern __thread struct timeval g_now;