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