2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
30 #include <unordered_set>
37 #include <boost/optional.hpp>
38 #include <boost/circular_buffer.hpp>
39 #include <boost/utility.hpp>
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>
48 #include "validate.hh"
49 #include "ednssubnet.hh"
50 #include "filterpo.hh"
51 #include "negcache.hh"
59 #include <boost/uuid/uuid.hpp>
61 #include "fstrm_logger.hh"
62 #endif /* HAVE_FSTRM */
65 extern GlobalStateHolder<SuffixMatchNode> g_dontThrottleNames;
66 extern GlobalStateHolder<NetmaskGroup> g_dontThrottleNetmasks;
78 template<class Thing> class Throttle : public boost::noncopyable
81 Throttle() : d_limit(3), d_ttl(60), d_last_clean(time(nullptr))
90 typedef map<Thing,entry> cont_t;
92 bool shouldThrottle(time_t now, const Thing& t)
94 if(now > d_last_clean + 300 ) {
97 for(typename cont_t::iterator i=d_cont.begin();i!=d_cont.end();) {
98 if( i->second.ttd < now) {
106 typename cont_t::iterator i=d_cont.find(t);
109 if(now > i->second.ttd || i->second.count == 0) {
115 return true; // still listed, still blocked
117 void throttle(time_t now, const Thing& t, time_t ttl=0, unsigned int tries=0)
119 typename cont_t::iterator i=d_cont.find(t);
120 entry e={ now+(ttl ? ttl : d_ttl), tries ? tries : d_limit};
122 if(i==d_cont.end()) {
125 else if(i->second.ttd > e.ttd || (i->second.count) < e.count)
129 unsigned int size() const
131 return (unsigned int)d_cont.size();
134 const cont_t& getThrottleMap() const
145 unsigned int d_limit;
152 /** Class that implements a decaying EWMA.
153 This class keeps an exponentially weighted moving average which, additionally, decays over time.
154 The decaying is only done on get.
159 DecayingEwma() : d_val(0.0)
162 d_last.tv_sec = d_last.tv_usec = 0;
166 DecayingEwma(const DecayingEwma& orig) : d_last(orig.d_last), d_lastget(orig.d_lastget), d_val(orig.d_val), d_needinit(orig.d_needinit)
170 void submit(int val, const struct timeval* tv)
172 struct timeval now=*tv;
181 float diff= makeFloat(d_last - now);
184 double factor=exp(diff)/2.0; // might be '0.5', or 0.0001
185 d_val=(float)((1-factor)*val+ (float)factor*d_val);
189 double get(const struct timeval* tv)
191 struct timeval now=*tv;
192 float diff=makeFloat(d_lastget-now);
194 float factor=exp(diff/60.0f); // is 1.0 or less
195 return d_val*=factor;
198 double peek(void) const
203 bool stale(time_t limit) const
205 return limit > d_lastget.tv_sec;
209 struct timeval d_last; // stores time
210 struct timeval d_lastget; // stores time
215 template<class Thing> class Counters : public boost::noncopyable
221 unsigned long value(const Thing& t) const
223 typename cont_t::const_iterator i=d_cont.find(t);
225 if(i==d_cont.end()) {
228 return (unsigned long)i->second;
230 unsigned long incr(const Thing& t)
232 typename cont_t::iterator i=d_cont.find(t);
234 if(i==d_cont.end()) {
239 if (i->second < std::numeric_limits<unsigned long>::max())
241 return (unsigned long)i->second;
244 unsigned long decr(const Thing& t)
246 typename cont_t::iterator i=d_cont.find(t);
248 if(i!=d_cont.end() && --i->second == 0) {
252 return (unsigned long)i->second;
254 void clear(const Thing& t)
256 typename cont_t::iterator i=d_cont.find(t);
258 if(i!=d_cont.end()) {
268 return d_cont.size();
271 typedef map<Thing,unsigned long> cont_t;
276 class SyncRes : public boost::noncopyable
279 enum LogMode { LogNone, Log, Store};
280 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;
284 EDNSStatus() : mode(UNKNOWN), modeSetAt(0) {}
285 enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode;
289 //! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
290 /** Modelled to work mostly like the underlying DecayingEwma. After you've called get,
291 d_best is filled out with the best address for this collection */
292 struct DecayingEwmaCollection
294 void submit(const ComboAddress& remote, int usecs, const struct timeval* now)
296 d_collection[remote].submit(usecs, now);
299 double get(const struct timeval* now)
301 if(d_collection.empty())
303 double ret=std::numeric_limits<double>::max();
305 for (auto& entry : d_collection) {
306 if((tmp = entry.second.get(now)) < ret) {
315 bool stale(time_t limit) const
317 for(const auto& entry : d_collection)
318 if(!entry.second.stale(limit))
323 void purge(const std::map<ComboAddress, double>& keep)
325 for (auto iter = d_collection.begin(); iter != d_collection.end(); ) {
326 if (keep.find(iter->first) != keep.end()) {
330 iter = d_collection.erase(iter);
335 typedef std::map<ComboAddress, DecayingEwma> collection_t;
336 collection_t d_collection;
340 typedef map<DNSName, DecayingEwmaCollection> nsspeeds_t;
341 typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
343 vState getDSRecords(const DNSName& zone, dsmap_t& ds, bool onlyTA, unsigned int depth, bool bogusOnNXD=true, bool* foundCut=nullptr);
348 typedef multi_index_container <
352 composite_key< DNSRecord,
353 member<DNSRecord, DNSName, &DNSRecord::d_name>,
354 member<DNSRecord, uint16_t, &DNSRecord::d_type>
356 composite_key_compare<std::less<DNSName>, std::less<uint16_t> >
362 vector<ComboAddress> d_servers;
364 bool d_rdForward{false};
366 int getRecords(const DNSName& qname, uint16_t qtype, std::vector<DNSRecord>& records) const;
369 return d_servers.empty();
371 bool isForward() const
375 bool shouldRecurse() const
379 const DNSName& getName() const
385 void addSOA(std::vector<DNSRecord>& records) const;
388 typedef map<DNSName, AuthDomain> domainmap_t;
389 typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
390 typedef Counters<ComboAddress> fails_t;
392 struct ThreadLocalStorage {
396 ednsstatus_t ednsstatus;
398 std::shared_ptr<domainmap_t> domainmap;
401 static void setDefaultLogMode(LogMode lm)
405 static uint64_t doEDNSDump(int fd);
406 static uint64_t doDumpNSSpeeds(int fd);
407 static uint64_t doDumpThrottleMap(int fd);
408 static int getRootNS(struct timeval now, asyncresolve_t asyncCallback);
409 static void clearDelegationOnly()
411 s_delegationOnly.clear();
413 static void addDelegationOnly(const DNSName& name)
415 s_delegationOnly.insert(name);
417 static void addDontQuery(const std::string& mask)
420 s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
422 s_dontQuery->addMask(mask);
424 static void addDontQuery(const Netmask& mask)
427 s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
429 s_dontQuery->addMask(mask);
431 static void clearDontQuery()
433 s_dontQuery = nullptr;
435 static void parseEDNSSubnetWhitelist(const std::string& wlist);
436 static void parseEDNSSubnetAddFor(const std::string& subnetlist);
437 static void addEDNSLocalSubnet(const std::string& subnet)
439 s_ednslocalsubnets.addMask(subnet);
441 static void addEDNSRemoteSubnet(const std::string& subnet)
443 s_ednsremotesubnets.addMask(subnet);
445 static void addEDNSDomain(const DNSName& domain)
447 s_ednsdomains.add(domain);
449 static void clearEDNSLocalSubnets()
451 s_ednslocalsubnets.clear();
453 static void clearEDNSRemoteSubnets()
455 s_ednsremotesubnets.clear();
457 static void clearEDNSDomains()
459 s_ednsdomains = SuffixMatchNode();
461 static void pruneNSSpeeds(time_t limit)
463 for(auto i = t_sstorage.nsSpeeds.begin(), end = t_sstorage.nsSpeeds.end(); i != end; ) {
464 if(i->second.stale(limit)) {
465 i = t_sstorage.nsSpeeds.erase(i);
472 static uint64_t getNSSpeedsSize()
474 return t_sstorage.nsSpeeds.size();
476 static void submitNSSpeed(const DNSName& server, const ComboAddress& ca, uint32_t usec, const struct timeval* now)
478 t_sstorage.nsSpeeds[server].submit(ca, usec, now);
480 static void clearNSSpeeds()
482 t_sstorage.nsSpeeds.clear();
484 static EDNSStatus::EDNSMode getEDNSStatus(const ComboAddress& server)
486 const auto& it = t_sstorage.ednsstatus.find(server);
487 if (it == t_sstorage.ednsstatus.end())
488 return EDNSStatus::UNKNOWN;
490 return it->second.mode;
492 static uint64_t getEDNSStatusesSize()
494 return t_sstorage.ednsstatus.size();
496 static void clearEDNSStatuses()
498 t_sstorage.ednsstatus.clear();
500 static uint64_t getThrottledServersSize()
502 return t_sstorage.throttle.size();
504 static void clearThrottle()
506 t_sstorage.throttle.clear();
508 static bool isThrottled(time_t now, const ComboAddress& server, const DNSName& target, uint16_t qtype)
510 return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, target, qtype));
512 static bool isThrottled(time_t now, const ComboAddress& server)
514 return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, "", 0));
516 static void doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries)
518 t_sstorage.throttle.throttle(now, boost::make_tuple(server, "", 0), duration, tries);
520 static uint64_t getFailedServersSize()
522 return t_sstorage.fails.size();
524 static void clearFailedServers()
526 t_sstorage.fails.clear();
528 static unsigned long getServerFailsCount(const ComboAddress& server)
530 return t_sstorage.fails.value(server);
533 static void clearNegCache()
535 t_sstorage.negcache.clear();
538 static uint64_t getNegCacheSize()
540 return t_sstorage.negcache.size();
543 static void pruneNegCache(unsigned int maxEntries)
545 t_sstorage.negcache.prune(maxEntries);
548 static uint64_t wipeNegCache(const DNSName& name, bool subtree = false)
550 return t_sstorage.negcache.wipe(name, subtree);
553 static void setDomainMap(std::shared_ptr<domainmap_t> newMap)
555 t_sstorage.domainmap = newMap;
558 static const std::shared_ptr<domainmap_t> getDomainMap()
560 return t_sstorage.domainmap;
563 static void setECSScopeZeroAddress(const Netmask& scopeZeroMask)
565 s_ecsScopeZero.source = scopeZeroMask;
568 static void clearECSStats()
570 s_ecsqueries.store(0);
571 s_ecsresponses.store(0);
573 for (size_t idx = 0; idx < 32; idx++) {
574 SyncRes::s_ecsResponsesBySubnetSize4[idx].store(0);
577 for (size_t idx = 0; idx < 128; idx++) {
578 SyncRes::s_ecsResponsesBySubnetSize6[idx].store(0);
582 explicit SyncRes(const struct timeval& now);
584 int beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSRecord>&ret);
588 d_prefix="["+itoa(id)+"] ";
591 void setLogMode(LogMode lm)
598 return d_lm != LogNone;
601 bool setCacheOnly(bool state = true)
603 bool old = d_cacheonly;
608 void setQNameMinimization(bool state=true)
610 d_qNameMinimization=state;
613 void setDoEDNS0(bool state=true)
618 void setDoDNSSEC(bool state=true)
623 void setDNSSECValidationRequested(bool requested=true)
625 d_DNSSECValidationRequested = requested;
628 bool isDNSSECValidationRequested() const
630 return d_DNSSECValidationRequested;
633 bool shouldValidate() const
635 return d_DNSSECValidationRequested && !d_wasOutOfBand;
638 void setWantsRPZ(bool state=true)
643 bool getWantsRPZ() const
648 string getTrace() const
650 return d_trace.str();
653 bool getQNameMinimization() const
655 return d_qNameMinimization;
658 void setLuaEngine(shared_ptr<RecursorLua4> pdl)
663 bool wasVariable() const
665 return d_wasVariable;
668 bool wasOutOfBand() const
670 return d_wasOutOfBand;
673 struct timeval getNow() const
678 void setSkipCNAMECheck(bool skip = false)
680 d_skipCNAMECheck = skip;
683 void setQuerySource(const ComboAddress& requestor, boost::optional<const EDNSSubnetOpts&> incomingECS);
686 void setInitialRequestId(boost::optional<const boost::uuids::uuid&> initialRequestId)
688 d_initialRequestId = initialRequestId;
691 void setOutgoingProtobufServers(std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& servers)
693 d_outgoingProtobufServers = servers;
698 void setFrameStreamServers(std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>>& servers)
700 d_frameStreamServers = servers;
702 #endif /* HAVE_FSTRM */
704 void setAsyncCallback(asyncresolve_t func)
706 d_asyncResolve = func;
709 vState getValidationState() const
711 return d_queryValidationState;
714 static thread_local ThreadLocalStorage t_sstorage;
716 static std::atomic<uint64_t> s_queries;
717 static std::atomic<uint64_t> s_outgoingtimeouts;
718 static std::atomic<uint64_t> s_outgoing4timeouts;
719 static std::atomic<uint64_t> s_outgoing6timeouts;
720 static std::atomic<uint64_t> s_throttledqueries;
721 static std::atomic<uint64_t> s_dontqueries;
722 static std::atomic<uint64_t> s_authzonequeries;
723 static std::atomic<uint64_t> s_outqueries;
724 static std::atomic<uint64_t> s_tcpoutqueries;
725 static std::atomic<uint64_t> s_nodelegated;
726 static std::atomic<uint64_t> s_unreachables;
727 static std::atomic<uint64_t> s_ecsqueries;
728 static std::atomic<uint64_t> s_ecsresponses;
729 static std::map<uint8_t, std::atomic<uint64_t>> s_ecsResponsesBySubnetSize4;
730 static std::map<uint8_t, std::atomic<uint64_t>> s_ecsResponsesBySubnetSize6;
732 static string s_serverID;
733 static unsigned int s_minimumTTL;
734 static unsigned int s_minimumECSTTL;
735 static unsigned int s_maxqperq;
736 static unsigned int s_maxtotusec;
737 static unsigned int s_maxdepth;
738 static unsigned int s_maxnegttl;
739 static unsigned int s_maxbogusttl;
740 static unsigned int s_maxcachettl;
741 static unsigned int s_packetcachettl;
742 static unsigned int s_packetcacheservfailttl;
743 static unsigned int s_serverdownmaxfails;
744 static unsigned int s_serverdownthrottletime;
745 static unsigned int s_ecscachelimitttl;
746 static uint8_t s_ecsipv4limit;
747 static uint8_t s_ecsipv6limit;
748 static uint8_t s_ecsipv4cachelimit;
749 static uint8_t s_ecsipv6cachelimit;
750 static bool s_doIPv6;
751 static bool s_noEDNSPing;
752 static bool s_noEDNS;
753 static bool s_rootNXTrust;
754 static bool s_nopacketcache;
755 static bool s_qnameminimization;
757 std::unordered_map<std::string,bool> d_discardedPolicies;
758 DNSFilterEngine::Policy d_appliedPolicy;
759 unsigned int d_authzonequeries;
760 unsigned int d_outqueries;
761 unsigned int d_tcpoutqueries;
762 unsigned int d_throttledqueries;
763 unsigned int d_timeouts;
764 unsigned int d_unreachables;
765 unsigned int d_totUsec;
768 ComboAddress d_requestor;
769 ComboAddress d_cacheRemote;
771 static std::unordered_set<DNSName> s_delegationOnly;
772 static NetmaskGroup s_ednslocalsubnets;
773 static NetmaskGroup s_ednsremotesubnets;
774 static SuffixMatchNode s_ednsdomains;
775 static EDNSSubnetOpts s_ecsScopeZero;
777 static std::unique_ptr<NetmaskGroup> s_dontQuery;
778 const static std::unordered_set<uint16_t> s_redirectionQTypes;
780 struct GetBestNSAnswer
783 set<pair<DNSName,DNSName> > bestns;
784 uint8_t qtype; // only A and AAAA anyhow
785 bool operator<(const GetBestNSAnswer &b) const
787 return boost::tie(qname, qtype, bestns) <
788 boost::tie(b.qname, b.qtype, b.bestns);
792 typedef std::map<DNSName,vState> zonesStates_t;
793 enum StopAtDelegation { DontStop, Stop, Stopped };
795 int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret,
796 unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state, StopAtDelegation* stopAtDelegation);
797 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);
798 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);
800 int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state);
801 int doResolveNoQNameMinimization(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL);
802 bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, int& res);
803 bool doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res);
804 domainmap_t::const_iterator getBestAuthZone(DNSName* qname) const;
805 bool doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse);
806 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);
807 void getBestNSFromCache(const DNSName &qname, const QType &qtype, vector<DNSRecord>&bestns, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>& beenthere);
808 DNSName getBestNSNamesFromCache(const DNSName &qname, const QType &qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>&beenthere);
810 inline vector<std::pair<DNSName, double>> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
811 inline vector<ComboAddress> shuffleForwardSpeed(const vector<ComboAddress> &rnameservers, const string &prefix, const bool wasRd);
812 bool moreSpecificThan(const DNSName& a, const DNSName &b) const;
813 vector<ComboAddress> getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly);
815 bool nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers);
816 bool nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress&);
817 bool throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType& qtype, bool pierceDontQuery);
819 vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<std::pair<DNSName, double>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, double>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly);
821 void sanitizeRecords(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, bool rdQuery);
822 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);
823 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);
825 bool doSpecialNamesResolve(const DNSName &qname, const QType &qtype, const uint16_t qclass, vector<DNSRecord> &ret);
827 int asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional<Netmask>& srcmask, LWResult* res, bool* chained) const;
829 boost::optional<Netmask> getEDNSSubnetMask(const DNSName&dn, const ComboAddress& rem);
831 bool validationEnabled() const;
832 uint32_t computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, uint32_t signaturesTTL) const;
833 void updateValidationState(vState& state, const vState stateUpdate);
834 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);
835 vState validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord>& dnskeys, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, unsigned int depth);
836 vState getDNSKeys(const DNSName& signer, skeyset_t& keys, unsigned int depth);
837 dState getDenialValidationState(const NegCache::NegCacheEntry& ne, const vState state, const dState expectedState, bool referralToUnsigned);
838 void updateDenialValidationState(vState& neValidationState, const DNSName& neName, vState& state, const dState denialState, const dState expectedState, bool allowOptOut);
839 void computeNegCacheValidationStatus(const NegCache::NegCacheEntry* ne, const DNSName& qname, const QType& qtype, const int res, vState& state, unsigned int depth);
840 vState getTA(const DNSName& zone, dsmap_t& ds);
841 bool haveExactValidationStatus(const DNSName& domain);
842 vState getValidationStatus(const DNSName& subdomain, bool allowIndeterminate=true);
843 void updateValidationStatusInCache(const DNSName &qname, const QType& qt, bool aa, vState newState) const;
845 bool lookForCut(const DNSName& qname, unsigned int depth, const vState existingState, vState& newState);
846 void computeZoneCuts(const DNSName& begin, const DNSName& end, unsigned int depth);
848 void setUpdatingRootNS()
850 d_updatingRootNS = true;
853 zonesStates_t d_cutStates;
854 ostringstream d_trace;
855 shared_ptr<RecursorLua4> d_pdl;
856 boost::optional<Netmask> d_outgoingECSNetwork;
857 std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>> d_outgoingProtobufServers{nullptr};
858 std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>> d_frameStreamServers{nullptr};
860 boost::optional<const boost::uuids::uuid&> d_initialRequestId;
862 asyncresolve_t d_asyncResolve{nullptr};
863 struct timeval d_now;
865 vState d_queryValidationState{Indeterminate};
867 /* When d_cacheonly is set to true, we will only check the cache.
868 * This is set when the RD bit is unset in the incoming query
872 bool d_DNSSECValidationRequested{false};
873 bool d_doEDNS0{true};
874 bool d_requireAuthData{true};
875 bool d_skipCNAMECheck{false};
876 bool d_updatingRootNS{false};
877 bool d_wantsRPZ{true};
878 bool d_wasOutOfBand{false};
879 bool d_wasVariable{false};
880 bool d_qNameMinimization{false};
886 /* external functions, opaque to us */
887 int asendtcp(const string& data, Socket* sock);
888 int arecvtcp(string& data, size_t len, Socket* sock, bool incompleteOkay);
893 PacketID() : id(0), type(0), sock(0), inNeeded(0), inIncompleteOkay(false), outPos(0), nearMisses(0), fd(-1)
898 uint16_t id; // wait for a specific id/remote pair
899 uint16_t type; // and this is its type
900 ComboAddress remote; // this is the remote
901 DNSName domain; // this is the question
903 Socket* sock; // or wait for an event on a TCP fd
904 string inMSG; // they'll go here
905 size_t inNeeded; // if this is set, we'll read until inNeeded bytes are read
906 bool inIncompleteOkay;
908 string outMSG; // the outgoing message that needs to be sent
909 string::size_type outPos; // how far we are along in the outMSG
911 typedef set<uint16_t > chain_t;
912 mutable chain_t chain;
913 mutable uint32_t nearMisses; // number of near misses - host correct, id wrong
916 bool operator<(const PacketID& b) const
918 int ourSock= sock ? sock->getHandle() : 0;
919 int bSock = b.sock ? b.sock->getHandle() : 0;
920 if( tie(remote, ourSock, type) < tie(b.remote, bSock, b.type))
922 if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type))
925 return tie(domain, fd, id) < tie(b.domain, b.fd, b.id);
929 struct PacketIDBirthdayCompare: public std::binary_function<PacketID, PacketID, bool>
931 bool operator()(const PacketID& a, const PacketID& b) const
933 int ourSock= a.sock ? a.sock->getHandle() : 0;
934 int bSock = b.sock ? b.sock->getHandle() : 0;
935 if( tie(a.remote, ourSock, a.type) < tie(b.remote, bSock, b.type))
937 if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
940 return a.domain < b.domain;
943 extern thread_local std::unique_ptr<MemRecursorCache> t_RC;
944 extern thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
945 typedef MTasker<PacketID,string> MT_t;
950 std::atomic<uint64_t> servFails;
951 std::atomic<uint64_t> nxDomains;
952 std::atomic<uint64_t> noErrors;
953 std::atomic<uint64_t> answers0_1, answers1_10, answers10_100, answers100_1000, answersSlow;
954 std::atomic<uint64_t> auth4Answers0_1, auth4Answers1_10, auth4Answers10_100, auth4Answers100_1000, auth4AnswersSlow;
955 std::atomic<uint64_t> auth6Answers0_1, auth6Answers1_10, auth6Answers10_100, auth6Answers100_1000, auth6AnswersSlow;
956 std::atomic<uint64_t> ourtime0_1, ourtime1_2, ourtime2_4, ourtime4_8, ourtime8_16, ourtime16_32, ourtimeSlow;
957 double avgLatencyUsec{0};
958 double avgLatencyOursUsec{0};
959 std::atomic<uint64_t> qcounter; // not increased for unauth packets
960 std::atomic<uint64_t> ipv6qcounter;
961 std::atomic<uint64_t> tcpqcounter;
962 std::atomic<uint64_t> unauthorizedUDP; // when this is increased, qcounter isn't
963 std::atomic<uint64_t> unauthorizedTCP; // when this is increased, qcounter isn't
964 std::atomic<uint64_t> policyDrops;
965 std::atomic<uint64_t> tcpClientOverflow;
966 std::atomic<uint64_t> clientParseError;
967 std::atomic<uint64_t> serverParseError;
968 std::atomic<uint64_t> tooOldDrops;
969 std::atomic<uint64_t> truncatedDrops;
970 std::atomic<uint64_t> queryPipeFullDrops;
971 std::atomic<uint64_t> unexpectedCount;
972 std::atomic<uint64_t> caseMismatchCount;
973 std::atomic<uint64_t> spoofCount;
974 std::atomic<uint64_t> resourceLimits;
975 std::atomic<uint64_t> overCapacityDrops;
976 std::atomic<uint64_t> ipv6queries;
977 std::atomic<uint64_t> chainResends;
978 std::atomic<uint64_t> nsSetInvalidations;
979 std::atomic<uint64_t> ednsPingMatches;
980 std::atomic<uint64_t> ednsPingMismatches;
981 std::atomic<uint64_t> noPingOutQueries, noEdnsOutQueries;
982 std::atomic<uint64_t> packetCacheHits;
983 std::atomic<uint64_t> noPacketError;
984 std::atomic<uint64_t> ignoredCount;
985 std::atomic<uint64_t> emptyQueriesCount;
987 std::atomic<uint64_t> dnssecQueries;
988 std::atomic<uint64_t> dnssecAuthenticDataQueries;
989 std::atomic<uint64_t> dnssecCheckDisabledQueries;
990 std::atomic<uint64_t> variableResponses;
991 unsigned int maxMThreadStackUsage;
992 std::atomic<uint64_t> dnssecValidations; // should be the sum of all dnssecResult* stats
993 std::map<vState, std::atomic<uint64_t> > dnssecResults;
994 std::map<DNSFilterEngine::PolicyKind, std::atomic<uint64_t> > policyResults;
995 std::atomic<uint64_t> rebalancedQueries{0};
998 //! represents a running TCP/IP client session
999 class TCPConnection : public boost::noncopyable
1002 TCPConnection(int fd, const ComboAddress& addr);
1011 const ComboAddress d_remote;
1012 size_t queriesCount{0};
1013 enum stateenum {BYTE0, BYTE1, GETQUESTION, DONE} state{BYTE0};
1015 uint16_t bytesread{0};
1017 static unsigned int getCurrentConnections() { return s_currentConnections; }
1020 static AtomicCounter s_currentConnections; //!< total number of current TCP connections
1023 class ImmediateServFailException
1026 ImmediateServFailException(string r) : reason(r) {};
1028 string reason; //! Print this to tell the user what went wrong
1031 typedef boost::circular_buffer<ComboAddress> addrringbuf_t;
1032 extern thread_local std::unique_ptr<addrringbuf_t> t_servfailremotes, t_largeanswerremotes, t_remotes, t_bogusremotes, t_timeouts;
1034 extern thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName,uint16_t> > > t_queryring, t_servfailqueryring, t_bogusqueryring;
1035 extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
1036 string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
1037 string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_iterator end);
1039 extern RecursorStats g_stats;
1040 extern unsigned int g_networkTimeoutMsec;
1041 extern unsigned int g_numThreads;
1042 extern uint16_t g_outgoingEDNSBufsize;
1043 extern std::atomic<uint32_t> g_maxCacheEntries, g_maxPacketCacheEntries;
1044 extern bool g_lowercaseOutgoing;
1047 std::string reloadAuthAndForwards();
1048 ComboAddress parseIPAndPort(const std::string& input, uint16_t port);
1049 ComboAddress getQueryLocalAddress(int family, uint16_t port);
1050 typedef boost::function<void*(void)> pipefunc_t;
1051 void broadcastFunction(const pipefunc_t& func);
1052 void distributeAsyncFunction(const std::string& question, const pipefunc_t& func);
1054 int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<DNSRecord>& ret);
1056 template<class T> T broadcastAccFunction(const boost::function<T*()>& func);
1058 std::shared_ptr<SyncRes::domainmap_t> parseAuthAndForwards();
1059 uint64_t* pleaseGetNsSpeedsSize();
1060 uint64_t* pleaseGetCacheSize();
1061 uint64_t* pleaseGetNegCacheSize();
1062 uint64_t* pleaseGetCacheHits();
1063 uint64_t* pleaseGetCacheMisses();
1064 uint64_t* pleaseGetConcurrentQueries();
1065 uint64_t* pleaseGetThrottleSize();
1066 uint64_t* pleaseGetPacketCacheHits();
1067 uint64_t* pleaseGetPacketCacheSize();
1068 uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree=false);
1069 uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree);
1070 uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree=false);
1071 void doCarbonDump(void*);
1072 void primeHints(void);
1074 extern __thread struct timeval g_now;
1079 vector<uint64_t> times;
1080 ThreadTimes& operator+=(const ThreadTimes& rhs)
1082 times.push_back(rhs.msec);