]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/syncres.cc
rec: Remove (wrong) debug message
[thirdparty/pdns.git] / pdns / syncres.cc
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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "arguments.hh"
27 #include "cachecleaner.hh"
28 #include "dns_random.hh"
29 #include "dnsparser.hh"
30 #include "dnsrecords.hh"
31 #include "ednssubnet.hh"
32 #include "logger.hh"
33 #include "lua-recursor4.hh"
34 #include "rec-lua-conf.hh"
35 #include "syncres.hh"
36 #include "validate-recursor.hh"
37
38 thread_local SyncRes::ThreadLocalStorage SyncRes::t_sstorage;
39
40 std::unordered_set<DNSName> SyncRes::s_delegationOnly;
41 std::unique_ptr<NetmaskGroup> SyncRes::s_dontQuery{nullptr};
42 NetmaskGroup SyncRes::s_ednssubnets;
43 SuffixMatchNode SyncRes::s_ednsdomains;
44 string SyncRes::s_serverID;
45 SyncRes::LogMode SyncRes::s_lm;
46
47 unsigned int SyncRes::s_maxnegttl;
48 unsigned int SyncRes::s_maxcachettl;
49 unsigned int SyncRes::s_maxqperq;
50 unsigned int SyncRes::s_maxtotusec;
51 unsigned int SyncRes::s_maxdepth;
52 unsigned int SyncRes::s_minimumTTL;
53 unsigned int SyncRes::s_packetcachettl;
54 unsigned int SyncRes::s_packetcacheservfailttl;
55 unsigned int SyncRes::s_serverdownmaxfails;
56 unsigned int SyncRes::s_serverdownthrottletime;
57 std::atomic<uint64_t> SyncRes::s_queries;
58 std::atomic<uint64_t> SyncRes::s_outgoingtimeouts;
59 std::atomic<uint64_t> SyncRes::s_outgoing4timeouts;
60 std::atomic<uint64_t> SyncRes::s_outgoing6timeouts;
61 std::atomic<uint64_t> SyncRes::s_outqueries;
62 std::atomic<uint64_t> SyncRes::s_tcpoutqueries;
63 std::atomic<uint64_t> SyncRes::s_throttledqueries;
64 std::atomic<uint64_t> SyncRes::s_dontqueries;
65 std::atomic<uint64_t> SyncRes::s_nodelegated;
66 std::atomic<uint64_t> SyncRes::s_unreachables;
67 uint8_t SyncRes::s_ecsipv4limit;
68 uint8_t SyncRes::s_ecsipv6limit;
69 bool SyncRes::s_doIPv6;
70 bool SyncRes::s_nopacketcache;
71 bool SyncRes::s_rootNXTrust;
72 bool SyncRes::s_noEDNS;
73
74 #define LOG(x) if(d_lm == Log) { L <<Logger::Warning << x; } else if(d_lm == Store) { d_trace << x; }
75
76 static void accountAuthLatency(int usec, int family)
77 {
78 if(family == AF_INET) {
79 if(usec < 1000)
80 g_stats.auth4Answers0_1++;
81 else if(usec < 10000)
82 g_stats.auth4Answers1_10++;
83 else if(usec < 100000)
84 g_stats.auth4Answers10_100++;
85 else if(usec < 1000000)
86 g_stats.auth4Answers100_1000++;
87 else
88 g_stats.auth4AnswersSlow++;
89 } else {
90 if(usec < 1000)
91 g_stats.auth6Answers0_1++;
92 else if(usec < 10000)
93 g_stats.auth6Answers1_10++;
94 else if(usec < 100000)
95 g_stats.auth6Answers10_100++;
96 else if(usec < 1000000)
97 g_stats.auth6Answers100_1000++;
98 else
99 g_stats.auth6AnswersSlow++;
100 }
101
102 }
103
104
105 SyncRes::SyncRes(const struct timeval& now) : d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
106 d_totUsec(0), d_now(now),
107 d_cacheonly(false), d_doDNSSEC(false), d_doEDNS0(false), d_lm(s_lm)
108
109 {
110 }
111
112 /** everything begins here - this is the entry point just after receiving a packet */
113 int SyncRes::beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSRecord>&ret)
114 {
115 vState state = Indeterminate;
116 s_queries++;
117 d_wasVariable=false;
118 d_wasOutOfBand=false;
119
120 if (doSpecialNamesResolve(qname, qtype, qclass, ret)) {
121 d_queryValidationState = Insecure;
122 return 0;
123 }
124
125 if( (qtype.getCode() == QType::AXFR) || (qtype.getCode() == QType::IXFR))
126 return -1;
127
128 if(qclass==QClass::ANY)
129 qclass=QClass::IN;
130 else if(qclass!=QClass::IN)
131 return -1;
132
133 set<GetBestNSAnswer> beenthere;
134 int res=doResolve(qname, qtype, ret, 0, beenthere, state);
135 d_queryValidationState = state;
136 return res;
137 }
138
139 /*! Handles all special, built-in names
140 * Fills ret with an answer and returns true if it handled the query.
141 *
142 * Handles the following queries (and their ANY variants):
143 *
144 * - localhost. IN A
145 * - localhost. IN AAAA
146 * - 1.0.0.127.in-addr.arpa. IN PTR
147 * - 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. IN PTR
148 * - version.bind. CH TXT
149 * - version.pdns. CH TXT
150 * - id.server. CH TXT
151 */
152 bool SyncRes::doSpecialNamesResolve(const DNSName &qname, const QType &qtype, const uint16_t qclass, vector<DNSRecord> &ret)
153 {
154 static const DNSName arpa("1.0.0.127.in-addr.arpa."), ip6_arpa("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa."),
155 localhost("localhost."), versionbind("version.bind."), idserver("id.server."), versionpdns("version.pdns.");
156
157 bool handled = false;
158 vector<pair<QType::typeenum, string> > answers;
159
160 if ((qname == arpa || qname == ip6_arpa) &&
161 qclass == QClass::IN) {
162 handled = true;
163 if (qtype == QType::PTR || qtype == QType::ANY)
164 answers.push_back({QType::PTR, "localhost."});
165 }
166
167 if (qname == localhost &&
168 qclass == QClass::IN) {
169 handled = true;
170 if (qtype == QType::A || qtype == QType::ANY)
171 answers.push_back({QType::A, "127.0.0.1"});
172 if (qtype == QType::AAAA || qtype == QType::ANY)
173 answers.push_back({QType::AAAA, "::1"});
174 }
175
176 if ((qname == versionbind || qname == idserver || qname == versionpdns) &&
177 qclass == QClass::CHAOS) {
178 handled = true;
179 if (qtype == QType::TXT || qtype == QType::ANY) {
180 if(qname == versionbind || qname == versionpdns)
181 answers.push_back({QType::TXT, "\""+::arg()["version-string"]+"\""});
182 else
183 answers.push_back({QType::TXT, "\""+s_serverID+"\""});
184 }
185 }
186
187 if (handled && !answers.empty()) {
188 ret.clear();
189 d_wasOutOfBand=true;
190
191 DNSRecord dr;
192 dr.d_name = qname;
193 dr.d_place = DNSResourceRecord::ANSWER;
194 dr.d_class = qclass;
195 dr.d_ttl = 86400;
196 for (const auto& ans : answers) {
197 dr.d_type = ans.first;
198 dr.d_content = DNSRecordContent::mastermake(ans.first, qclass, ans.second);
199 ret.push_back(dr);
200 }
201 }
202
203 return handled;
204 }
205
206
207 //! This is the 'out of band resolver', in other words, the authoritative server
208 void SyncRes::AuthDomain::addSOA(std::vector<DNSRecord>& records) const
209 {
210 SyncRes::AuthDomain::records_t::const_iterator ziter = d_records.find(boost::make_tuple(getName(), QType::SOA));
211 if (ziter != d_records.end()) {
212 DNSRecord dr = *ziter;
213 dr.d_place = DNSResourceRecord::AUTHORITY;
214 records.push_back(dr);
215 }
216 else {
217 // cerr<<qname<<": can't find SOA record '"<<getName()<<"' in our zone!"<<endl;
218 }
219 }
220
221 int SyncRes::AuthDomain::getRecords(const DNSName& qname, uint16_t qtype, std::vector<DNSRecord>& records) const
222 {
223 int result = RCode::NoError;
224 records.clear();
225
226 // partial lookup
227 std::pair<records_t::const_iterator,records_t::const_iterator> range = d_records.equal_range(tie(qname));
228
229 SyncRes::AuthDomain::records_t::const_iterator ziter;
230 bool somedata = false;
231
232 for(ziter = range.first; ziter != range.second; ++ziter) {
233 somedata = true;
234
235 if(qtype == QType::ANY || ziter->d_type == qtype || ziter->d_type == QType::CNAME) {
236 // let rest of nameserver do the legwork on this one
237 records.push_back(*ziter);
238 }
239 else if (ziter->d_type == QType::NS && ziter->d_name.countLabels() > getName().countLabels()) {
240 // we hit a delegation point!
241 DNSRecord dr = *ziter;
242 dr.d_place=DNSResourceRecord::AUTHORITY;
243 records.push_back(dr);
244 }
245 }
246
247 if (!records.empty()) {
248 /* We have found an exact match, we're done */
249 // cerr<<qname<<": exact match in zone '"<<getName()<<"'"<<endl;
250 return result;
251 }
252
253 if (somedata) {
254 /* We have records for that name, but not of the wanted qtype */
255 // cerr<<qname<<": found record in '"<<getName()<<"', but nothing of the right type, sending SOA"<<endl;
256 addSOA(records);
257
258 return result;
259 }
260
261 // cerr<<qname<<": nothing found so far in '"<<getName()<<"', trying wildcards"<<endl;
262 DNSName wcarddomain(qname);
263 while(wcarddomain != getName() && wcarddomain.chopOff()) {
264 // cerr<<qname<<": trying '*."<<wcarddomain<<"' in "<<getName()<<endl;
265 range = d_records.equal_range(boost::make_tuple(g_wildcarddnsname + wcarddomain));
266 if (range.first==range.second)
267 continue;
268
269 for(ziter = range.first; ziter != range.second; ++ziter) {
270 DNSRecord dr = *ziter;
271 // if we hit a CNAME, just answer that - rest of recursor will do the needful & follow
272 if(dr.d_type == qtype || qtype == QType::ANY || dr.d_type == QType::CNAME) {
273 dr.d_name = qname;
274 dr.d_place = DNSResourceRecord::ANSWER;
275 records.push_back(dr);
276 }
277 }
278
279 if (records.empty()) {
280 addSOA(records);
281 }
282
283 // cerr<<qname<<": in '"<<getName()<<"', had wildcard match on '*."<<wcarddomain<<"'"<<endl;
284 return result;
285 }
286
287 /* Nothing for this name, no wildcard, let's see if there is some NS */
288 DNSName nsdomain(qname);
289 while (nsdomain.chopOff() && nsdomain != getName()) {
290 range = d_records.equal_range(boost::make_tuple(nsdomain,QType::NS));
291 if(range.first == range.second)
292 continue;
293
294 for(ziter = range.first; ziter != range.second; ++ziter) {
295 DNSRecord dr = *ziter;
296 dr.d_place = DNSResourceRecord::AUTHORITY;
297 records.push_back(dr);
298 }
299 }
300
301 if(records.empty()) {
302 // cerr<<qname<<": no NS match in zone '"<<getName()<<"' either, handing out SOA"<<endl;
303 addSOA(records);
304 result = RCode::NXDomain;
305 }
306
307 return result;
308 }
309
310 bool SyncRes::doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, int& res) const
311 {
312 res = domain.getRecords(qname, qtype.getCode(), ret);
313 return true;
314 }
315
316 bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int& res)
317 {
318 string prefix;
319 if(doLog()) {
320 prefix=d_prefix;
321 prefix.append(depth, ' ');
322 }
323
324 DNSName authdomain(qname);
325 domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
326 if(iter==t_sstorage.domainmap->end() || !iter->second.isAuth()) {
327 LOG(prefix<<qname<<": auth storage has no zone for this query!"<<endl);
328 return false;
329 }
330
331 LOG(prefix<<qname<<": auth storage has data, zone='"<<authdomain<<"'"<<endl);
332 return doOOBResolve(iter->second, qname, qtype, ret, res);
333 }
334
335 void SyncRes::doEDNSDumpAndClose(int fd)
336 {
337 FILE* fp=fdopen(fd, "w");
338 if (!fp) {
339 return;
340 }
341 fprintf(fp,"IP Address\tMode\tMode last updated at\n");
342 for(const auto& eds : t_sstorage.ednsstatus) {
343 fprintf(fp, "%s\t%d\t%s", eds.first.toString().c_str(), (int)eds.second.mode, ctime(&eds.second.modeSetAt));
344 }
345
346 fclose(fp);
347 }
348
349 uint64_t SyncRes::doDumpNSSpeeds(int fd)
350 {
351 FILE* fp=fdopen(dup(fd), "w");
352 if(!fp)
353 return 0;
354 fprintf(fp, "; nsspeed dump from thread follows\n;\n");
355 uint64_t count=0;
356
357 for(const auto& i : t_sstorage.nsSpeeds)
358 {
359 count++;
360 fprintf(fp, "%s -> ", i.first.toString().c_str());
361 for(const auto& j : i.second.d_collection)
362 {
363 // typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
364 fprintf(fp, "%s/%f ", j.first.toString().c_str(), j.second.peek());
365 }
366 fprintf(fp, "\n");
367 }
368 fclose(fp);
369 return count;
370 }
371
372 /* so here is the story. First we complete the full resolution process for a domain name. And only THEN do we decide
373 to also do DNSSEC validation, which leads to new queries. To make this simple, we *always* ask for DNSSEC records
374 so that if there are RRSIGs for a name, we'll have them.
375
376 However, some hosts simply can't answer questions which ask for DNSSEC. This can manifest itself as:
377 * No answer
378 * FormErr
379 * Nonsense answer
380
381 The cause of "No answer" may be fragmentation, and it is tempting to probe if smaller answers would get through.
382 Another cause of "No answer" may simply be a network condition.
383 Nonsense answers are a clearer indication this host won't be able to do DNSSEC evah.
384
385 Previous implementations have suffered from turning off DNSSEC questions for an authoritative server based on timeouts.
386 A clever idea is to only turn off DNSSEC if we know a domain isn't signed anyhow. The problem with that really
387 clever idea however is that at this point in PowerDNS, we may simply not know that yet. All the DNSSEC thinking happens
388 elsewhere. It may not have happened yet.
389
390 For now this means we can't be clever, but will turn off DNSSEC if you reply with FormError or gibberish.
391 */
392
393 int SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional<Netmask>& srcmask, LWResult* res) const
394 {
395 /* what is your QUEST?
396 the goal is to get as many remotes as possible on the highest level of EDNS support
397 The levels are:
398
399 0) UNKNOWN Unknown state
400 1) EDNS: Honors EDNS0
401 2) EDNSIGNORANT: Ignores EDNS0, gives replies without EDNS0
402 3) NOEDNS: Generates FORMERR/NOTIMP on EDNS queries
403
404 Everybody starts out assumed to be '0'.
405 If '0', send out EDNS0
406 If you FORMERR us, go to '3',
407 If no EDNS in response, go to '2'
408 If '1', send out EDNS0
409 If FORMERR, downgrade to 3
410 If '2', keep on including EDNS0, see what happens
411 Same behaviour as 0
412 If '3', send bare queries
413 */
414
415 SyncRes::EDNSStatus* ednsstatus;
416 ednsstatus = &t_sstorage.ednsstatus[ip]; // does this include port? YES
417
418 if(ednsstatus->modeSetAt && ednsstatus->modeSetAt + 3600 < d_now.tv_sec) {
419 *ednsstatus=SyncRes::EDNSStatus();
420 // cerr<<"Resetting EDNS Status for "<<ip.toString()<<endl);
421 }
422
423 SyncRes::EDNSStatus::EDNSMode& mode=ednsstatus->mode;
424 SyncRes::EDNSStatus::EDNSMode oldmode = mode;
425 int EDNSLevel = 0;
426 auto luaconfsLocal = g_luaconfs.getLocal();
427 ResolveContext ctx;
428 #ifdef HAVE_PROTOBUF
429 ctx.d_initialRequestId = d_initialRequestId;
430 #endif
431
432 int ret;
433 for(int tries = 0; tries < 3; ++tries) {
434 // cerr<<"Remote '"<<ip.toString()<<"' currently in mode "<<mode<<endl;
435
436 if(mode==EDNSStatus::NOEDNS) {
437 g_stats.noEdnsOutQueries++;
438 EDNSLevel = 0; // level != mode
439 }
440 else if(ednsMANDATORY || mode==EDNSStatus::UNKNOWN || mode==EDNSStatus::EDNSOK || mode==EDNSStatus::EDNSIGNORANT)
441 EDNSLevel = 1;
442
443 if (d_asyncResolve) {
444 ret = d_asyncResolve(ip, domain, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, luaconfsLocal->outgoingProtobufServer, res);
445 }
446 else {
447 ret=asyncresolve(ip, domain, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, luaconfsLocal->outgoingProtobufServer, res);
448 }
449 if(ret < 0) {
450 return ret; // transport error, nothing to learn here
451 }
452
453 if(ret == 0) { // timeout, not doing anything with it now
454 return ret;
455 }
456 else if(mode==EDNSStatus::UNKNOWN || mode==EDNSStatus::EDNSOK || mode == EDNSStatus::EDNSIGNORANT ) {
457 if(res->d_rcode == RCode::FormErr || res->d_rcode == RCode::NotImp) {
458 // cerr<<"Downgrading to NOEDNS because of "<<RCode::to_s(res->d_rcode)<<" for query to "<<ip.toString()<<" for '"<<domain<<"'"<<endl;
459 mode = EDNSStatus::NOEDNS;
460 continue;
461 }
462 else if(!res->d_haveEDNS) {
463 if(mode != EDNSStatus::EDNSIGNORANT) {
464 mode = EDNSStatus::EDNSIGNORANT;
465 // cerr<<"We find that "<<ip.toString()<<" is an EDNS-ignorer for '"<<domain<<"', moving to mode 3"<<endl;
466 }
467 }
468 else {
469 mode = EDNSStatus::EDNSOK;
470 // cerr<<"We find that "<<ip.toString()<<" is EDNS OK!"<<endl;
471 }
472
473 }
474 if(oldmode != mode || !ednsstatus->modeSetAt)
475 ednsstatus->modeSetAt=d_now.tv_sec;
476 // cerr<<"Result: ret="<<ret<<", EDNS-level: "<<EDNSLevel<<", haveEDNS: "<<res->d_haveEDNS<<", new mode: "<<mode<<endl;
477 return ret;
478 }
479 return ret;
480 }
481
482 /*! This function will check the cache and go out to the internet if the answer is not in cache
483 *
484 * \param qname The name we need an answer for
485 * \param qtype
486 * \param ret The vector of DNSRecords we need to fill with the answers
487 * \param depth The recursion depth we are in
488 * \param beenthere
489 * \return DNS RCODE or -1 (Error) or -2 (RPZ hit)
490 */
491 int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state)
492 {
493 string prefix;
494 if(doLog()) {
495 prefix=d_prefix;
496 prefix.append(depth, ' ');
497 }
498
499 LOG(prefix<<qname<<": Wants "<< (d_doDNSSEC ? "" : "NO ") << "DNSSEC processing, "<<(d_requireAuthData ? "" : "NO ")<<"auth data in query for "<<qtype.getName()<<endl);
500
501 state = Indeterminate;
502
503 if(s_maxdepth && depth > s_maxdepth)
504 throw ImmediateServFailException("More than "+std::to_string(s_maxdepth)+" (max-recursion-depth) levels of recursion needed while resolving "+qname.toLogString());
505
506 int res=0;
507
508 // This is a difficult way of expressing "this is a normal query", i.e. not getRootNS.
509 if(!(d_updatingRootNS && qtype.getCode()==QType::NS && qname.isRoot())) {
510 if(d_cacheonly) { // very limited OOB support
511 LWResult lwr;
512 LOG(prefix<<qname<<": Recursion not requested for '"<<qname<<"|"<<qtype.getName()<<"', peeking at auth/forward zones"<<endl);
513 DNSName authname(qname);
514 domainmap_t::const_iterator iter=getBestAuthZone(&authname);
515 if(iter != t_sstorage.domainmap->end()) {
516 if(iter->second.isAuth()) {
517 ret.clear();
518 d_wasOutOfBand = doOOBResolve(qname, qtype, ret, depth, res);
519 return res;
520 }
521 else {
522 const vector<ComboAddress>& servers = iter->second.d_servers;
523 const ComboAddress remoteIP = servers.front();
524 LOG(prefix<<qname<<": forwarding query to hardcoded nameserver '"<< remoteIP.toStringWithPort()<<"' for zone '"<<authname<<"'"<<endl);
525
526 boost::optional<Netmask> nm;
527 res=asyncresolveWrapper(remoteIP, d_doDNSSEC, qname, qtype.getCode(), false, false, &d_now, nm, &lwr);
528 // filter out the good stuff from lwr.result()
529 if (res == 1) {
530 for(const auto& rec : lwr.d_records) {
531 if(rec.d_place == DNSResourceRecord::ANSWER)
532 ret.push_back(rec);
533 }
534 return 0;
535 }
536 else {
537 return RCode::ServFail;
538 }
539 }
540 }
541 }
542
543 if(!d_skipCNAMECheck && doCNAMECacheCheck(qname,qtype,ret,depth,res,state)) // will reroute us if needed
544 return res;
545
546 if(doCacheCheck(qname,qtype,ret,depth,res,state)) // we done
547 return res;
548 }
549
550 if(d_cacheonly)
551 return 0;
552
553 LOG(prefix<<qname<<": No cache hit for '"<<qname<<"|"<<qtype.getName()<<"', trying to find an appropriate NS record"<<endl);
554
555 DNSName subdomain(qname);
556 if(qtype == QType::DS) subdomain.chopOff();
557
558 NsSet nsset;
559 bool flawedNSSet=false;
560
561 computeZoneCuts(qname, g_rootdnsname, depth);
562
563 // the two retries allow getBestNSNamesFromCache&co to reprime the root
564 // hints, in case they ever go missing
565 for(int tries=0;tries<2 && nsset.empty();++tries) {
566 subdomain=getBestNSNamesFromCache(subdomain, qtype, nsset, &flawedNSSet, depth, beenthere); // pass beenthere to both occasions
567 }
568
569 state = getValidationStatus(subdomain);
570
571 LOG(prefix<<qname<<": initial validation status for "<<qname<<" inherited from "<<subdomain<<" is "<<vStates[state]<<endl);
572
573 if(!(res=doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere, state)))
574 return 0;
575
576 LOG(prefix<<qname<<": failed (res="<<res<<")"<<endl);
577
578 if (res == -2)
579 return res;
580
581 return res<0 ? RCode::ServFail : res;
582 }
583
584 #if 0
585 // for testing purposes
586 static bool ipv6First(const ComboAddress& a, const ComboAddress& b)
587 {
588 return !(a.sin4.sin_family < a.sin4.sin_family);
589 }
590 #endif
591
592 /** This function explicitly goes out for A or AAAA addresses
593 */
594 vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere)
595 {
596 typedef vector<DNSRecord> res_t;
597 res_t res;
598
599 typedef vector<ComboAddress> ret_t;
600 ret_t ret;
601
602 QType type;
603 bool oldRequireAuthData = d_requireAuthData;
604 d_requireAuthData = false;
605
606 for(int j=1; j<2+s_doIPv6; j++)
607 {
608 bool done=false;
609 switch(j) {
610 case 0:
611 type = QType::ANY;
612 break;
613 case 1:
614 type = QType::A;
615 break;
616 case 2:
617 type = QType::AAAA;
618 break;
619 }
620
621 vState newState = Indeterminate;
622 if(!doResolve(qname, type, res,depth+1, beenthere, newState) && !res.empty()) { // this consults cache, OR goes out
623 for(res_t::const_iterator i=res.begin(); i!= res.end(); ++i) {
624 if(i->d_type == QType::A || i->d_type == QType::AAAA) {
625 if(auto rec = std::dynamic_pointer_cast<ARecordContent>(i->d_content))
626 ret.push_back(rec->getCA(53));
627 else if(auto aaaarec = std::dynamic_pointer_cast<AAAARecordContent>(i->d_content))
628 ret.push_back(aaaarec->getCA(53));
629 done=true;
630 }
631 }
632 }
633 if(done) {
634 if(j==1 && s_doIPv6) { // we got an A record, see if we have some AAAA lying around
635 vector<DNSRecord> cset;
636 if(t_RC->get(d_now.tv_sec, qname, QType(QType::AAAA), false, &cset, d_requestor) > 0) {
637 for(auto k=cset.cbegin();k!=cset.cend();++k) {
638 if(k->d_ttl > (unsigned int)d_now.tv_sec ) {
639 if (auto drc = std::dynamic_pointer_cast<AAAARecordContent>(k->d_content)) {
640 ComboAddress ca=drc->getCA(53);
641 ret.push_back(ca);
642 }
643 }
644 }
645 }
646 }
647 break;
648 }
649 }
650
651 d_requireAuthData = oldRequireAuthData;
652
653 if(ret.size() > 1) {
654 random_shuffle(ret.begin(), ret.end(), dns_random);
655
656 // move 'best' address for this nameserver name up front
657 nsspeeds_t::iterator best = t_sstorage.nsSpeeds.find(qname);
658
659 if(best != t_sstorage.nsSpeeds.end())
660 for(ret_t::iterator i=ret.begin(); i != ret.end(); ++i) {
661 if(*i==best->second.d_best) { // got the fastest one
662 if(i!=ret.begin()) {
663 *i=*ret.begin();
664 *ret.begin()=best->second.d_best;
665 }
666 break;
667 }
668 }
669 }
670
671 return ret;
672 }
673
674 void SyncRes::getBestNSFromCache(const DNSName &qname, const QType& qtype, vector<DNSRecord>& bestns, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>& beenthere)
675 {
676 string prefix;
677 DNSName subdomain(qname);
678 if(doLog()) {
679 prefix=d_prefix;
680 prefix.append(depth, ' ');
681 }
682 bestns.clear();
683 bool brokeloop;
684 do {
685 brokeloop=false;
686 LOG(prefix<<qname<<": Checking if we have NS in cache for '"<<subdomain<<"'"<<endl);
687 vector<DNSRecord> ns;
688 *flawedNSSet = false;
689
690 if(t_RC->get(d_now.tv_sec, subdomain, QType(QType::NS), false, &ns, d_requestor) > 0) {
691 for(auto k=ns.cbegin();k!=ns.cend(); ++k) {
692 if(k->d_ttl > (unsigned int)d_now.tv_sec ) {
693 vector<DNSRecord> aset;
694
695 const DNSRecord& dr=*k;
696 auto nrr = getRR<NSRecordContent>(dr);
697 if(nrr && (!nrr->getNS().isPartOf(subdomain) || t_RC->get(d_now.tv_sec, nrr->getNS(), s_doIPv6 ? QType(QType::ADDR) : QType(QType::A),
698 false, doLog() ? &aset : nullptr, d_requestor) > 5)) {
699 bestns.push_back(dr);
700 LOG(prefix<<qname<<": NS (with ip, or non-glue) in cache for '"<<subdomain<<"' -> '"<<nrr->getNS()<<"'"<<endl);
701 LOG(prefix<<qname<<": within bailiwick: "<< nrr->getNS().isPartOf(subdomain));
702 if(!aset.empty()) {
703 LOG(", in cache, ttl="<<(unsigned int)(((time_t)aset.begin()->d_ttl- d_now.tv_sec ))<<endl);
704 }
705 else {
706 LOG(", not in cache / did not look at cache"<<endl);
707 }
708 }
709 else {
710 *flawedNSSet=true;
711 LOG(prefix<<qname<<": NS in cache for '"<<subdomain<<"', but needs glue ("<<nrr->getNS()<<") which we miss or is expired"<<endl);
712 }
713 }
714 }
715
716 if(!bestns.empty()) {
717 GetBestNSAnswer answer;
718 answer.qname=qname;
719 answer.qtype=qtype.getCode();
720 for(const auto& dr : bestns)
721 answer.bestns.insert(make_pair(dr.d_name, getRR<NSRecordContent>(dr)->getNS()));
722
723 if(beenthere.count(answer)) {
724 brokeloop=true;
725 LOG(prefix<<qname<<": We have NS in cache for '"<<subdomain<<"' but part of LOOP (already seen "<<answer.qname<<")! Trying less specific NS"<<endl);
726 ;
727 if(doLog())
728 for( set<GetBestNSAnswer>::const_iterator j=beenthere.begin();j!=beenthere.end();++j) {
729 bool neo = !(*j< answer || answer<*j);
730 LOG(prefix<<qname<<": beenthere"<<(neo?"*":"")<<": "<<j->qname<<"|"<<DNSRecordContent::NumberToType(j->qtype)<<" ("<<(unsigned int)j->bestns.size()<<")"<<endl);
731 }
732 bestns.clear();
733 }
734 else {
735 beenthere.insert(answer);
736 LOG(prefix<<qname<<": We have NS in cache for '"<<subdomain<<"' (flawedNSSet="<<*flawedNSSet<<")"<<endl);
737 return;
738 }
739 }
740 }
741 LOG(prefix<<qname<<": no valid/useful NS in cache for '"<<subdomain<<"'"<<endl);
742
743 if(subdomain.isRoot() && !brokeloop) {
744 // We lost the root NS records
745 primeHints();
746 LOG(prefix<<qname<<": reprimed the root"<<endl);
747 /* let's prevent an infinite loop */
748 if (!d_updatingRootNS) {
749 getRootNS(d_now, d_asyncResolve);
750 }
751 }
752 } while(subdomain.chopOff());
753 }
754
755 SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(DNSName* qname) const
756 {
757 SyncRes::domainmap_t::const_iterator ret;
758 do {
759 ret=t_sstorage.domainmap->find(*qname);
760 if(ret!=t_sstorage.domainmap->end())
761 break;
762 }while(qname->chopOff());
763 return ret;
764 }
765
766 /** doesn't actually do the work, leaves that to getBestNSFromCache */
767 DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType& qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>&beenthere)
768 {
769 DNSName subdomain(qname);
770 DNSName authdomain(qname);
771
772 domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
773 if(iter!=t_sstorage.domainmap->end()) {
774 if( iter->second.isAuth() )
775 // this gets picked up in doResolveAt, the empty DNSName, combined with the
776 // empty vector means 'we are auth for this zone'
777 nsset.insert({DNSName(), {{}, false}});
778 else {
779 // Again, picked up in doResolveAt. An empty DNSName, combined with a
780 // non-empty vector of ComboAddresses means 'this is a forwarded domain'
781 // This is actually picked up in retrieveAddressesForNS called from doResolveAt.
782 nsset.insert({DNSName(), {iter->second.d_servers, iter->second.shouldRecurse() }});
783 }
784 return authdomain;
785 }
786
787 vector<DNSRecord> bestns;
788 getBestNSFromCache(subdomain, qtype, bestns, flawedNSSet, depth, beenthere);
789
790 for(auto k=bestns.cbegin() ; k != bestns.cend(); ++k) {
791 // The actual resolver code will not even look at the ComboAddress or bool
792 nsset.insert({std::dynamic_pointer_cast<NSRecordContent>(k->d_content)->getNS(), {{}, false}});
793 if(k==bestns.cbegin())
794 subdomain=k->d_name;
795 }
796 return subdomain;
797 }
798
799 bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSRecord>& ret, unsigned int depth, int &res, vState& state)
800 {
801 string prefix;
802 if(doLog()) {
803 prefix=d_prefix;
804 prefix.append(depth, ' ');
805 }
806
807 if((depth>9 && d_outqueries>10 && d_throttledqueries>5) || depth > 15) {
808 LOG(prefix<<qname<<": recursing (CNAME or other indirection) too deep, depth="<<depth<<endl);
809 res=RCode::ServFail;
810 return true;
811 }
812
813 LOG(prefix<<qname<<": Looking for CNAME cache hit of '"<<qname<<"|CNAME"<<"'"<<endl);
814 vector<DNSRecord> cset;
815 vector<std::shared_ptr<RRSIGRecordContent>> signatures;
816 vector<std::shared_ptr<DNSRecord>> authorityRecs;
817 bool wasAuth;
818 if(t_RC->get(d_now.tv_sec, qname, QType(QType::CNAME), d_requireAuthData, &cset, d_requestor, d_doDNSSEC ? &signatures : nullptr, d_doDNSSEC ? &authorityRecs : nullptr, &d_wasVariable, &state, &wasAuth) > 0) {
819
820 for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
821 if(j->d_ttl>(unsigned int) d_now.tv_sec) {
822
823 if (validationEnabled() && wasAuth && state == Indeterminate && d_requireAuthData) {
824 /* This means we couldn't figure out the state when this entry was cached,
825 most likely because we hadn't computed the zone cuts yet. */
826 vState recordState = getValidationStatus(qname);
827 if (recordState == Secure) {
828 LOG(prefix<<qname<<": got Indeterminate state from the CNAME cache, validating.."<<endl);
829 state = SyncRes::validateRecordsWithSigs(depth, qname, QType(QType::CNAME), qname, cset, signatures);
830 if (state != Indeterminate) {
831 LOG(prefix<<qname<<": got Indeterminate state from the CNAME cache, new validation result is "<<vStates[state]<<endl);
832 t_RC->updateValidationStatus(qname, QType(QType::CNAME), d_requestor, d_requireAuthData, state);
833 }
834 }
835 }
836
837 LOG(prefix<<qname<<": Found cache CNAME hit for '"<< qname << "|CNAME" <<"' to '"<<j->d_content->getZoneRepresentation()<<"', validation state is "<<vStates[state]<<endl);
838
839 DNSRecord dr=*j;
840 dr.d_ttl-=d_now.tv_sec;
841 ret.push_back(dr);
842
843 for(const auto& signature : signatures) {
844 DNSRecord sigdr;
845 sigdr.d_type=QType::RRSIG;
846 sigdr.d_name=qname;
847 sigdr.d_ttl=j->d_ttl - d_now.tv_sec;
848 sigdr.d_content=signature;
849 sigdr.d_place=DNSResourceRecord::ANSWER;
850 sigdr.d_class=QClass::IN;
851 ret.push_back(sigdr);
852 }
853
854 for(const auto& rec : authorityRecs) {
855 DNSRecord dr(*rec);
856 dr.d_ttl=j->d_ttl - d_now.tv_sec;
857 ret.push_back(dr);
858 }
859
860 if(qtype != QType::CNAME) { // perhaps they really wanted a CNAME!
861 set<GetBestNSAnswer>beenthere;
862
863 vState cnameState = Indeterminate;
864 res=doResolve(std::dynamic_pointer_cast<CNAMERecordContent>(j->d_content)->getTarget(), qtype, ret, depth+1, beenthere, cnameState);
865 LOG(prefix<<qname<<": updating validation state for response to "<<qname<<" from "<<vStates[state]<<" with the state from the CNAME quest: "<<vStates[cnameState]<<endl);
866 updateValidationState(state, cnameState);
867 }
868 else
869 res=0;
870
871 return true;
872 }
873 }
874 }
875 LOG(prefix<<qname<<": No CNAME cache hit of '"<< qname << "|CNAME" <<"' found"<<endl);
876 return false;
877 }
878
879 /*!
880 * Convience function to push the records from records into ret with a new TTL
881 *
882 * \param records DNSRecords that need to go into ret
883 * \param ttl The new TTL for these records
884 * \param ret The vector of DNSRecords that should contian the records with the modified TTL
885 */
886 static void addTTLModifiedRecords(const vector<DNSRecord>& records, const uint32_t ttl, vector<DNSRecord>& ret) {
887 for (const auto& rec : records) {
888 DNSRecord r(rec);
889 r.d_ttl = ttl;
890 ret.push_back(r);
891 }
892 }
893
894
895 bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int &res, vState& state)
896 {
897 bool giveNegative=false;
898
899 string prefix;
900 if(doLog()) {
901 prefix=d_prefix;
902 prefix.append(depth, ' ');
903 }
904
905 // sqname and sqtype are used contain 'higher' names if we have them (e.g. powerdns.com|SOA when we find a negative entry for doesnotexists.powerdns.com|A)
906 DNSName sqname(qname);
907 QType sqt(qtype);
908 uint32_t sttl=0;
909 // cout<<"Lookup for '"<<qname<<"|"<<qtype.getName()<<"' -> "<<getLastLabel(qname)<<endl;
910
911 DNSName authname(qname);
912 vState cachedState;
913 bool wasForwardedOrAuth = false;
914 bool wasAuth = false;
915 domainmap_t::const_iterator iter=getBestAuthZone(&authname);
916 if(iter != t_sstorage.domainmap->end()) {
917 wasForwardedOrAuth = true;
918 const vector<ComboAddress>& servers = iter->second.d_servers;
919 if(servers.empty()) {
920 wasAuth = true;
921 }
922 }
923 NegCache::NegCacheEntry ne;
924
925 if(s_rootNXTrust &&
926 t_sstorage.negcache.getRootNXTrust(qname, d_now, ne) &&
927 ne.d_auth.isRoot() &&
928 !(wasForwardedOrAuth && !authname.isRoot())) { // when forwarding, the root may only neg-cache if it was forwarded to.
929 sttl = ne.d_ttd - d_now.tv_sec;
930 LOG(prefix<<qname<<": Entire name '"<<qname<<"', is negatively cached via '"<<ne.d_auth<<"' & '"<<ne.d_name<<"' for another "<<sttl<<" seconds"<<endl);
931 res = RCode::NXDomain;
932 giveNegative = true;
933 cachedState = ne.d_validationState;
934 }
935 else if (t_sstorage.negcache.get(qname, qtype, d_now, ne) &&
936 !(wasForwardedOrAuth && ne.d_auth != authname)) { // Only the authname nameserver can neg cache entries
937 res = 0;
938 sttl = ne.d_ttd - d_now.tv_sec;
939 giveNegative = true;
940 cachedState = ne.d_validationState;
941 if(ne.d_qtype.getCode()) {
942 LOG(prefix<<qname<<": "<<qtype.getName()<<" is negatively cached via '"<<ne.d_auth<<"' for another "<<sttl<<" seconds"<<endl);
943 res = RCode::NoError;
944 }
945 else {
946 LOG(prefix<<qname<<": Entire name '"<<qname<<"', is negatively cached via '"<<ne.d_auth<<"' for another "<<sttl<<" seconds"<<endl);
947 res = RCode::NXDomain;
948 }
949 if(d_doDNSSEC) {
950 addTTLModifiedRecords(ne.DNSSECRecords.records, sttl, ret);
951 addTTLModifiedRecords(ne.DNSSECRecords.signatures, sttl, ret);
952 }
953 }
954
955 if (giveNegative) {
956 // Transplant SOA to the returned packet
957 addTTLModifiedRecords(ne.authoritySOA.records, sttl, ret);
958 if(d_doDNSSEC)
959 addTTLModifiedRecords(ne.authoritySOA.signatures, sttl, ret);
960
961 LOG(prefix<<qname<<": updating validation state with negative cache content for "<<qname<<" to "<<vStates[cachedState]<<endl);
962 state = cachedState;
963 return true;
964 }
965
966 vector<DNSRecord> cset;
967 bool found=false, expired=false;
968 vector<std::shared_ptr<RRSIGRecordContent>> signatures;
969 vector<std::shared_ptr<DNSRecord>> authorityRecs;
970 uint32_t ttl=0;
971 bool wasCachedAuth;
972 if(t_RC->get(d_now.tv_sec, sqname, sqt, d_requireAuthData, &cset, d_requestor, d_doDNSSEC ? &signatures : nullptr, d_doDNSSEC ? &authorityRecs : nullptr, &d_wasVariable, &cachedState, &wasCachedAuth) > 0) {
973
974 LOG(prefix<<sqname<<": Found cache hit for "<<sqt.getName()<<": ");
975
976 if (validationEnabled() && sqt != QType::DNSKEY && wasCachedAuth && cachedState == Indeterminate && d_requireAuthData) {
977
978 /* This means we couldn't figure out the state when this entry was cached,
979 most likely because we hadn't computed the zone cuts yet. */
980 vState recordState = getValidationStatus(qname);
981 if (recordState == Secure) {
982 LOG(prefix<<sqname<<": got Indeterminate state from the cache, validating.."<<endl);
983 cachedState = SyncRes::validateRecordsWithSigs(depth, sqname, sqt, sqname, cset, signatures);
984
985 if (cachedState != Indeterminate) {
986 LOG(prefix<<qname<<": got Indeterminate state from the cache, validation result is "<<vStates[cachedState]<<endl);
987 t_RC->updateValidationStatus(sqname, sqt, d_requestor, d_requireAuthData, cachedState);
988 }
989 }
990 }
991
992 for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
993 LOG(j->d_content->getZoneRepresentation());
994 if(j->d_ttl>(unsigned int) d_now.tv_sec) {
995 DNSRecord dr=*j;
996 ttl = (dr.d_ttl-=d_now.tv_sec);
997 ret.push_back(dr);
998 LOG("[ttl="<<dr.d_ttl<<"] ");
999 found=true;
1000 }
1001 else {
1002 LOG("[expired] ");
1003 expired=true;
1004 }
1005 }
1006
1007 for(const auto& signature : signatures) {
1008 DNSRecord dr;
1009 dr.d_type=QType::RRSIG;
1010 dr.d_name=sqname;
1011 dr.d_ttl=ttl;
1012 dr.d_content=signature;
1013 dr.d_place = DNSResourceRecord::ANSWER;
1014 dr.d_class=QClass::IN;
1015 ret.push_back(dr);
1016 }
1017
1018 for(const auto& rec : authorityRecs) {
1019 DNSRecord dr(*rec);
1020 dr.d_ttl=ttl;
1021 ret.push_back(dr);
1022 }
1023
1024 LOG(endl);
1025 if(found && !expired) {
1026 if (!giveNegative)
1027 res=0;
1028 d_wasOutOfBand = wasAuth;
1029 LOG(prefix<<qname<<": updating validation state with cache content for "<<qname<<" to "<<vStates[cachedState]<<endl);
1030 state = cachedState;
1031 return true;
1032 }
1033 else
1034 LOG(prefix<<qname<<": cache had only stale entries"<<endl);
1035 }
1036
1037 return false;
1038 }
1039
1040 bool SyncRes::moreSpecificThan(const DNSName& a, const DNSName &b) const
1041 {
1042 return (a.isPartOf(b) && a.countLabels() > b.countLabels());
1043 }
1044
1045 struct speedOrder
1046 {
1047 speedOrder(map<DNSName,double> &speeds) : d_speeds(speeds) {}
1048 bool operator()(const DNSName &a, const DNSName &b) const
1049 {
1050 return d_speeds[a] < d_speeds[b];
1051 }
1052 map<DNSName, double>& d_speeds;
1053 };
1054
1055 inline vector<DNSName> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix)
1056 {
1057 vector<DNSName> rnameservers;
1058 rnameservers.reserve(tnameservers.size());
1059 for(const auto& tns:tnameservers) {
1060 rnameservers.push_back(tns.first);
1061 }
1062 map<DNSName, double> speeds;
1063
1064 for(const auto& val: rnameservers) {
1065 double speed;
1066 speed=t_sstorage.nsSpeeds[val].get(&d_now);
1067 speeds[val]=speed;
1068 }
1069 random_shuffle(rnameservers.begin(),rnameservers.end(), dns_random);
1070 speedOrder so(speeds);
1071 stable_sort(rnameservers.begin(),rnameservers.end(), so);
1072
1073 if(doLog()) {
1074 LOG(prefix<<"Nameservers: ");
1075 for(vector<DNSName>::const_iterator i=rnameservers.begin();i!=rnameservers.end();++i) {
1076 if(i!=rnameservers.begin()) {
1077 LOG(", ");
1078 if(!((i-rnameservers.begin())%3)) {
1079 LOG(endl<<prefix<<" ");
1080 }
1081 }
1082 LOG((i->empty() ? string("<empty>") : i->toString())<<"(" << (boost::format("%0.2f") % (speeds[*i]/1000.0)).str() <<"ms)");
1083 }
1084 LOG(endl);
1085 }
1086 return rnameservers;
1087 }
1088
1089 static bool magicAddrMatch(const QType& query, const QType& answer)
1090 {
1091 if(query.getCode() != QType::ADDR)
1092 return false;
1093 return answer.getCode() == QType::A || answer.getCode() == QType::AAAA;
1094 }
1095
1096 static const set<uint16_t> nsecTypes = {QType::NSEC, QType::NSEC3};
1097
1098 /* Fills the authoritySOA and DNSSECRecords fields from ne with those found in the records
1099 *
1100 * \param records The records to parse for the authority SOA and NSEC(3) records
1101 * \param ne The NegCacheEntry to be filled out (will not be cleared, only appended to
1102 */
1103 static void harvestNXRecords(const vector<DNSRecord>& records, NegCache::NegCacheEntry& ne) {
1104 for(const auto& rec : records) {
1105 if(rec.d_place != DNSResourceRecord::AUTHORITY)
1106 // RFC 4035 section 3.1.3. indicates that NSEC records MUST be placed in
1107 // the AUTHORITY section. Section 3.1.1 indicates that that RRSIGs for
1108 // records MUST be in the same section as the records they cover.
1109 // Hence, we ignore all records outside of the AUTHORITY section.
1110 continue;
1111
1112 if(rec.d_type == QType::RRSIG) {
1113 auto rrsig = getRR<RRSIGRecordContent>(rec);
1114 if(rrsig) {
1115 if(rrsig->d_type == QType::SOA) {
1116 ne.authoritySOA.signatures.push_back(rec);
1117 }
1118 if(nsecTypes.count(rrsig->d_type)) {
1119 ne.DNSSECRecords.signatures.push_back(rec);
1120 }
1121 }
1122 continue;
1123 }
1124 if(rec.d_type == QType::SOA) {
1125 ne.authoritySOA.records.push_back(rec);
1126 continue;
1127 }
1128 if(nsecTypes.count(rec.d_type)) {
1129 ne.DNSSECRecords.records.push_back(rec);
1130 continue;
1131 }
1132 }
1133 }
1134
1135 static cspmap_t harvestCSPFromNE(const NegCache::NegCacheEntry& ne)
1136 {
1137 cspmap_t cspmap;
1138 for(const auto& rec : ne.DNSSECRecords.signatures) {
1139 if(rec.d_type == QType::RRSIG) {
1140 auto rrc = getRR<RRSIGRecordContent>(rec);
1141 if (rrc) {
1142 cspmap[{rec.d_name,rrc->d_type}].signatures.push_back(rrc);
1143 }
1144 }
1145 }
1146 for(const auto& rec : ne.DNSSECRecords.records) {
1147 cspmap[{rec.d_name, rec.d_type}].records.push_back(rec.d_content);
1148 }
1149 return cspmap;
1150 }
1151
1152 // TODO remove after processRecords is fixed!
1153 // Adds the RRSIG for the SOA and the NSEC(3) + RRSIGs to ret
1154 static void addNXNSECS(vector<DNSRecord>&ret, const vector<DNSRecord>& records)
1155 {
1156 NegCache::NegCacheEntry ne;
1157 harvestNXRecords(records, ne);
1158 ret.insert(ret.end(), ne.authoritySOA.signatures.begin(), ne.authoritySOA.signatures.end());
1159 ret.insert(ret.end(), ne.DNSSECRecords.records.begin(), ne.DNSSECRecords.records.end());
1160 ret.insert(ret.end(), ne.DNSSECRecords.signatures.begin(), ne.DNSSECRecords.signatures.end());
1161 }
1162
1163 bool SyncRes::nameserversBlockedByRPZ(const DNSFilterEngine& dfe, const NsSet& nameservers)
1164 {
1165 if(d_wantsRPZ) {
1166 for (auto const &ns : nameservers) {
1167 d_appliedPolicy = dfe.getProcessingPolicy(ns.first, d_discardedPolicies);
1168 if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
1169 LOG(", however nameserver "<<ns.first<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
1170 return true;
1171 }
1172
1173 // Traverse all IP addresses for this NS to see if they have an RPN NSIP policy
1174 for (auto const &address : ns.second.first) {
1175 d_appliedPolicy = dfe.getProcessingPolicy(address, d_discardedPolicies);
1176 if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
1177 LOG(", however nameserver "<<ns.first<<" IP address "<<address.toString()<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
1178 return true;
1179 }
1180 }
1181 }
1182 }
1183 return false;
1184 }
1185
1186 bool SyncRes::nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress& remoteIP)
1187 {
1188 if (d_wantsRPZ) {
1189 d_appliedPolicy = dfe.getProcessingPolicy(remoteIP, d_discardedPolicies);
1190 if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) {
1191 LOG(" (blocked by RPZ policy '"+(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")+"')");
1192 return true;
1193 }
1194 }
1195 return false;
1196 }
1197
1198 vector<ComboAddress> SyncRes::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)
1199 {
1200 vector<ComboAddress> result;
1201
1202 if(!tns->empty()) {
1203 LOG(prefix<<qname<<": Trying to resolve NS '"<<*tns<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl);
1204 result = getAddrs(*tns, depth+2, beenthere);
1205 pierceDontQuery=false;
1206 }
1207 else {
1208 LOG(prefix<<qname<<": Domain has hardcoded nameserver");
1209
1210 result = nameservers[*tns].first;
1211 if(result.size() > 1) {
1212 LOG("s");
1213 }
1214 LOG(endl);
1215
1216 sendRDQuery = nameservers[*tns].second;
1217 pierceDontQuery=true;
1218 }
1219 return result;
1220 }
1221
1222 bool SyncRes::throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType& qtype, bool pierceDontQuery)
1223 {
1224 if(t_sstorage.throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0))) {
1225 LOG(prefix<<qname<<": server throttled "<<endl);
1226 s_throttledqueries++; d_throttledqueries++;
1227 return true;
1228 }
1229 else if(t_sstorage.throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()))) {
1230 LOG(prefix<<qname<<": query throttled "<<remoteIP.toString()<<", "<<qname<<"; "<<qtype.getName()<<endl);
1231 s_throttledqueries++; d_throttledqueries++;
1232 return true;
1233 }
1234 else if(!pierceDontQuery && s_dontQuery && s_dontQuery->match(&remoteIP)) {
1235 LOG(prefix<<qname<<": not sending query to " << remoteIP.toString() << ", blocked by 'dont-query' setting" << endl);
1236 s_dontqueries++;
1237 return true;
1238 }
1239 return false;
1240 }
1241
1242 bool SyncRes::validationEnabled() const
1243 {
1244 return g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate;
1245 }
1246
1247 uint32_t SyncRes::computeLowestTTD(const std::vector<DNSRecord>& records, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, uint32_t signaturesTTL) const
1248 {
1249 uint32_t lowestTTD = std::numeric_limits<uint32_t>::max();
1250 for(const auto& record : records)
1251 lowestTTD = min(lowestTTD, record.d_ttl);
1252
1253 if (validationEnabled() && !signatures.empty()) {
1254 /* if we are validating, we don't want to cache records after their signatures
1255 expires. */
1256 /* records TTL are now TTD, let's add 'now' to the signatures lowest TTL */
1257 lowestTTD = min(lowestTTD, static_cast<uint32_t>(signaturesTTL + d_now.tv_sec));
1258
1259 for(const auto& sig : signatures) {
1260 if (sig->d_siginception <= d_now.tv_sec && sig->d_sigexpire > d_now.tv_sec) {
1261 // we don't decerement d_sigexpire by 'now' because we actually want a TTD, not a TTL */
1262 lowestTTD = min(lowestTTD, static_cast<uint32_t>(sig->d_sigexpire));
1263 }
1264 }
1265 }
1266
1267 return lowestTTD;
1268 }
1269
1270 void SyncRes::updateValidationState(vState& state, const vState stateUpdate)
1271 {
1272 LOG(d_prefix<<"validation state was "<<std::string(vStates[state])<<", state update is "<<std::string(vStates[stateUpdate])<<endl);
1273
1274 if (stateUpdate == TA) {
1275 state = Secure;
1276 }
1277 else if (stateUpdate == NTA) {
1278 state = Insecure;
1279 }
1280 else if (stateUpdate == Bogus) {
1281 state = Bogus;
1282 }
1283 else if (state == Indeterminate) {
1284 state = stateUpdate;
1285 }
1286 else if (stateUpdate == Insecure) {
1287 if (state != Bogus) {
1288 state = Insecure;
1289 }
1290 }
1291 LOG(d_prefix<<" validation state is now "<<std::string(vStates[state])<<endl);
1292 }
1293
1294 vState SyncRes::getTA(const DNSName& zone, dsmap_t& ds)
1295 {
1296 auto luaLocal = g_luaconfs.getLocal();
1297
1298 if (luaLocal->dsAnchors.empty()) {
1299 /* We have no TA, everything is insecure */
1300 return Insecure;
1301 }
1302
1303 std::string reason;
1304 if (haveNegativeTrustAnchor(luaLocal->negAnchors, zone, reason)) {
1305 LOG(d_prefix<<": got NTA for "<<zone<<endl);
1306 return NTA;
1307 }
1308
1309 if (getTrustAnchor(luaLocal->dsAnchors, zone, ds)) {
1310 LOG(d_prefix<<": got TA for "<<zone<<endl);
1311 return TA;
1312 }
1313
1314 if (zone.isRoot()) {
1315 /* No TA for the root */
1316 return Insecure;
1317 }
1318
1319 return Indeterminate;
1320 }
1321
1322 static size_t countSupportedDS(const dsmap_t& dsmap)
1323 {
1324 size_t count = 0;
1325
1326 for (const auto& ds : dsmap) {
1327 if (isSupportedDS(ds)) {
1328 count++;
1329 }
1330 }
1331
1332 return count;
1333 }
1334
1335 vState SyncRes::getDSRecords(const DNSName& zone, dsmap_t& ds, bool taOnly, unsigned int depth)
1336 {
1337 vState result = getTA(zone, ds);
1338
1339 if (result != Indeterminate || taOnly) {
1340 if ((result == Secure || result == TA) && countSupportedDS(ds) == 0) {
1341 ds.clear();
1342 result = Insecure;
1343 }
1344
1345 return result;
1346 }
1347
1348 bool oldSkipCNAME = d_skipCNAMECheck;
1349 bool oldRequireAuthData = d_requireAuthData;
1350 d_skipCNAMECheck = true;
1351 d_requireAuthData = false;
1352
1353 std::set<GetBestNSAnswer> beenthere;
1354 std::vector<DNSRecord> dsrecords;
1355
1356 vState state = Indeterminate;
1357 int rcode = doResolve(zone, QType(QType::DS), dsrecords, depth + 1, beenthere, state);
1358 d_skipCNAMECheck = oldSkipCNAME;
1359 d_requireAuthData = oldRequireAuthData;
1360
1361 if (rcode == RCode::NoError || rcode == RCode::NXDomain) {
1362 if (state == Secure) {
1363 for (const auto& record : dsrecords) {
1364 if (record.d_type == QType::DS) {
1365 const auto dscontent = getRR<DSRecordContent>(record);
1366 if (dscontent && isSupportedDS(*dscontent)) {
1367 ds.insert(*dscontent);
1368 }
1369 }
1370 }
1371
1372 if (ds.empty()) {
1373 return Insecure;
1374 }
1375 }
1376
1377 return state;
1378 }
1379
1380 LOG(d_prefix<<": returning Bogus state from "<<__func__<<"("<<zone<<")"<<endl);
1381 return Bogus;
1382 }
1383
1384 vState SyncRes::getValidationStatus(const DNSName& subdomain)
1385 {
1386 vState result = Indeterminate;
1387
1388 if (!validationEnabled()) {
1389 return result;
1390 }
1391 DNSName name(subdomain);
1392 do {
1393 const auto& it = d_cutStates.find(name);
1394 if (it != d_cutStates.cend()) {
1395 LOG(d_prefix<<": got status "<<vStates[it->second]<<" for name "<<subdomain<<" (from "<<name<<")"<<endl);
1396 return it->second;
1397 }
1398 }
1399 while (name.chopOff());
1400
1401 return result;
1402 }
1403
1404 void SyncRes::computeZoneCuts(const DNSName& begin, const DNSName& end, unsigned int depth)
1405 {
1406 if(!begin.isPartOf(end)) {
1407 LOG(d_prefix<<" "<<end.toLogString()<<" is not part of "<<begin.toString()<<endl);
1408 throw PDNSException(end.toLogString() + " is not part of " + begin.toString());
1409 }
1410
1411 if (d_cutStates.count(begin) != 0) {
1412 return;
1413 }
1414
1415 dsmap_t ds;
1416 vState cutState = getDSRecords(end, ds, false, depth);
1417 if (cutState == TA) {
1418 cutState = Secure;
1419 }
1420 else if (cutState == NTA) {
1421 cutState = Insecure;
1422 }
1423 LOG(d_prefix<<": setting cut state for "<<end<<" to "<<vStates[cutState]<<endl);
1424 d_cutStates[end] = cutState;
1425
1426 if (!validationEnabled()) {
1427 return;
1428 }
1429
1430 DNSName qname(end);
1431 std::vector<string> labelsToAdd = begin.makeRelative(end).getRawLabels();
1432
1433 bool oldSkipCNAME = d_skipCNAMECheck;
1434 bool oldRequireAuthData = d_requireAuthData;
1435 d_skipCNAMECheck = true;
1436 d_requireAuthData = false;
1437
1438 while(qname != begin) {
1439 bool foundCut = false;
1440 if (labelsToAdd.empty())
1441 break;
1442
1443 qname.prependRawLabel(labelsToAdd.back());
1444 labelsToAdd.pop_back();
1445 LOG(d_prefix<<": - Looking for a cut at "<<qname<<endl);
1446
1447 const auto cutIt = d_cutStates.find(qname);
1448 if (cutIt != d_cutStates.cend()) {
1449 if (cutIt->second != Indeterminate) {
1450 LOG(d_prefix<<": - Cut already known at "<<qname<<endl);
1451 continue;
1452 }
1453 }
1454
1455 std::set<GetBestNSAnswer> beenthere;
1456 std::vector<DNSRecord> nsrecords;
1457
1458 vState state = Indeterminate;
1459 /* temporarily mark as Indeterminate, so that we won't enter an endless loop
1460 trying to determine that zone cut again. */
1461 d_cutStates[qname] = state;
1462 int rcode = doResolve(qname, QType(QType::NS), nsrecords, depth + 1, beenthere, state);
1463
1464 if (rcode == RCode::NoError && !nsrecords.empty()) {
1465 for (const auto& record : nsrecords) {
1466 if(record.d_type != QType::NS || record.d_name != qname)
1467 continue;
1468 foundCut = true;
1469 break;
1470 }
1471 if (foundCut) {
1472 LOG(d_prefix<<": - Found cut at "<<qname<<endl);
1473 /* if we get a Bogus state while retrieving the NS,
1474 the cut state is Bogus (we'll look for a (N)TA below though). */
1475 if (state == Bogus) {
1476 cutState = Bogus;
1477 }
1478 dsmap_t ds;
1479 vState newState = getDSRecords(qname, ds, cutState == Insecure || cutState == Bogus, depth);
1480 if (newState != Indeterminate) {
1481 cutState = newState;
1482 }
1483 LOG(d_prefix<<": New state for "<<qname<<" is "<<vStates[cutState]<<endl);
1484 if (cutState == TA) {
1485 cutState = Secure;
1486 }
1487 else if (cutState == NTA) {
1488 cutState = Insecure;
1489 }
1490 d_cutStates[qname] = cutState;
1491 }
1492 }
1493 if (!foundCut) {
1494 /* remove the temporary cut */
1495 LOG(d_prefix<<qname<<": removing cut state for "<<qname<<", was "<<vStates[d_cutStates[qname]]<<endl);
1496 d_cutStates.erase(qname);
1497 }
1498 }
1499
1500 d_skipCNAMECheck = oldSkipCNAME;
1501 d_requireAuthData = oldRequireAuthData;
1502
1503 LOG(d_prefix<<": list of cuts from "<<begin<<" to "<<end<<endl);
1504 for (const auto& cut : d_cutStates) {
1505 if (cut.first.isRoot() || (begin.isPartOf(cut.first) && cut.first.isPartOf(end))) {
1506 LOG(" - "<<cut.first<<": "<<vStates[cut.second]<<endl);
1507 }
1508 }
1509 }
1510
1511 vState SyncRes::validateDNSKeys(const DNSName& zone, const std::vector<DNSRecord>& dnskeys, const std::vector<std::shared_ptr<RRSIGRecordContent> >& signatures, unsigned int depth)
1512 {
1513 dsmap_t ds;
1514 if (!signatures.empty()) {
1515 DNSName signer = getSigner(signatures);
1516
1517 if (!signer.empty() && signer.isPartOf(zone)) {
1518 vState state = getDSRecords(signer, ds, false, depth);
1519
1520 if (state == TA) {
1521 state = Secure;
1522 }
1523 if (state != Secure) {
1524 if (state == NTA) {
1525 state = Insecure;
1526 }
1527 return state;
1528 }
1529 }
1530 }
1531
1532 skeyset_t tentativeKeys;
1533 std::vector<shared_ptr<DNSRecordContent> > toSign;
1534
1535 for (const auto& dnskey : dnskeys) {
1536 if (dnskey.d_type == QType::DNSKEY) {
1537 auto content = getRR<DNSKEYRecordContent>(dnskey);
1538 if (content) {
1539 tentativeKeys.insert(content);
1540 toSign.push_back(content);
1541 }
1542 }
1543 }
1544
1545 LOG(d_prefix<<": trying to validate "<<std::to_string(tentativeKeys.size())<<" DNSKEYs with "<<std::to_string(ds.size())<<" DS"<<endl);
1546 skeyset_t validatedKeys;
1547 validateDNSKeysAgainstDS(d_now.tv_sec, zone, ds, tentativeKeys, toSign, signatures, validatedKeys);
1548
1549 LOG(d_prefix<<": we now have "<<std::to_string(validatedKeys.size())<<" DNSKEYs"<<endl);
1550
1551 /* if we found at least one valid RRSIG covering the set,
1552 all tentative keys are validated keys. Otherwise it means
1553 we haven't found at least one DNSKEY and a matching RRSIG
1554 covering this set, this looks Bogus. */
1555 if (validatedKeys.size() != tentativeKeys.size()) {
1556 LOG(d_prefix<<": returning Bogus state from "<<__func__<<"("<<zone<<")"<<endl);
1557 return Bogus;
1558 }
1559
1560 return Secure;
1561 }
1562
1563 vState SyncRes::getDNSKeys(const DNSName& signer, skeyset_t& keys, unsigned int depth)
1564 {
1565 std::vector<DNSRecord> records;
1566 std::set<GetBestNSAnswer> beenthere;
1567 LOG(d_prefix<<"Retrieving DNSKeys for "<<signer<<endl);
1568
1569 vState state = Indeterminate;
1570 /* following CNAME might lead to us to the wrong DNSKEY */
1571 bool oldSkipCNAME = d_skipCNAMECheck;
1572 d_skipCNAMECheck = true;
1573 int rcode = doResolve(signer, QType(QType::DNSKEY), records, depth + 1, beenthere, state);
1574 d_skipCNAMECheck = oldSkipCNAME;
1575
1576 if (rcode == RCode::NoError) {
1577 if (state == Secure) {
1578 for (const auto& key : records) {
1579 if (key.d_type == QType::DNSKEY) {
1580 auto content = getRR<DNSKEYRecordContent>(key);
1581 if (content) {
1582 keys.insert(content);
1583 }
1584 }
1585 }
1586 }
1587 LOG(d_prefix<<"Retrieved "<<keys.size()<<" DNSKeys for "<<signer<<", state is "<<vStates[state]<<endl);
1588 return state;
1589 }
1590
1591 LOG(d_prefix<<"Returning Bogus state from "<<__func__<<"("<<signer<<")"<<endl);
1592 return Bogus;
1593 }
1594
1595 vState SyncRes::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)
1596 {
1597 skeyset_t keys;
1598 if (!signatures.empty()) {
1599 const DNSName signer = getSigner(signatures);
1600 if (!signer.empty() && name.isPartOf(signer)) {
1601 if (qtype == QType::DNSKEY && signer == qname) {
1602 /* we are already retrieving those keys, sorry */
1603 return Indeterminate;
1604 }
1605 vState state = getDNSKeys(signer, keys, depth);
1606 if (state != Secure) {
1607 return state;
1608 }
1609 }
1610 } else {
1611 LOG(d_prefix<<"Bogus!"<<endl);
1612 return Bogus;
1613 }
1614
1615 std::vector<std::shared_ptr<DNSRecordContent> > recordcontents;
1616 for (const auto& record : records) {
1617 recordcontents.push_back(record.d_content);
1618 }
1619
1620 LOG(d_prefix<<"Going to validate "<<recordcontents.size()<< " record contents with "<<signatures.size()<<" sigs and "<<keys.size()<<" keys for "<<name<<endl);
1621 if (validateWithKeySet(d_now.tv_sec, name, recordcontents, signatures, keys, false)) {
1622 LOG(d_prefix<<"Secure!"<<endl);
1623 return Secure;
1624 }
1625
1626 LOG(d_prefix<<"Bogus!"<<endl);
1627 return Bogus;
1628 }
1629
1630 RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, const boost::optional<Netmask> ednsmask, vState& state, bool& needWildcardProof)
1631 {
1632 struct CacheEntry
1633 {
1634 vector<DNSRecord> records;
1635 vector<shared_ptr<RRSIGRecordContent>> signatures;
1636 uint32_t signaturesTTL{std::numeric_limits<uint32_t>::max()};
1637 };
1638 struct CacheKey
1639 {
1640 DNSName name;
1641 uint16_t type;
1642 DNSResourceRecord::Place place;
1643 bool operator<(const CacheKey& rhs) const {
1644 return tie(name, type) < tie(rhs.name, rhs.type);
1645 }
1646 };
1647 typedef map<CacheKey, CacheEntry> tcache_t;
1648 tcache_t tcache;
1649
1650 string prefix;
1651 if(doLog()) {
1652 prefix=d_prefix;
1653 prefix.append(depth, ' ');
1654 }
1655
1656 std::vector<std::shared_ptr<DNSRecord>> authorityRecs;
1657 for(const auto& rec : lwr.d_records) {
1658 if(needWildcardProof) {
1659 if (nsecTypes.count(rec.d_type)) {
1660 authorityRecs.push_back(std::make_shared<DNSRecord>(rec));
1661 }
1662 else if (rec.d_type == QType::RRSIG) {
1663 auto rrsig = getRR<RRSIGRecordContent>(rec);
1664 if (rrsig && nsecTypes.count(rrsig->d_type)) {
1665 authorityRecs.push_back(std::make_shared<DNSRecord>(rec));
1666 }
1667 }
1668 }
1669 if(rec.d_type == QType::RRSIG) {
1670 auto rrsig = getRR<RRSIGRecordContent>(rec);
1671 if (rrsig) {
1672 unsigned int labelCount = rec.d_name.countLabels();
1673 /* As illustrated in rfc4035's Appendix B.6, the RRSIG label
1674 count can be lower than the name's label count if it was
1675 synthesized from the wildcard. Note that the difference might
1676 be > 1. */
1677 if (rec.d_name == qname && rrsig->d_labels < labelCount) {
1678 LOG(prefix<<qname<<": RRSIG indicates the name was expanded from a wildcard, we need a wildcard proof"<<endl);
1679 needWildcardProof = true;
1680 }
1681
1682 // cerr<<"Got an RRSIG for "<<DNSRecordContent::NumberToType(rrsig->d_type)<<" with name '"<<rec.d_name<<"'"<<endl;
1683 tcache[{rec.d_name, rrsig->d_type, rec.d_place}].signatures.push_back(rrsig);
1684 tcache[{rec.d_name, rrsig->d_type, rec.d_place}].signaturesTTL = std::min(tcache[{rec.d_name, rrsig->d_type, rec.d_place}].signaturesTTL, rec.d_ttl);
1685 }
1686 }
1687 }
1688
1689 // reap all answers from this packet that are acceptable
1690 for(auto& rec : lwr.d_records) {
1691 if(rec.d_type == QType::OPT) {
1692 LOG(prefix<<qname<<": OPT answer '"<<rec.d_name<<"' from '"<<auth<<"' nameservers" <<endl);
1693 continue;
1694 }
1695 LOG(prefix<<qname<<": accept answer '"<<rec.d_name<<"|"<<DNSRecordContent::NumberToType(rec.d_type)<<"|"<<rec.d_content->getZoneRepresentation()<<"' from '"<<auth<<"' nameservers? "<<(int)rec.d_place<<" ");
1696 if(rec.d_type == QType::ANY) {
1697 LOG("NO! - we don't accept 'ANY' data"<<endl);
1698 continue;
1699 }
1700
1701 if(rec.d_name.isPartOf(auth)) {
1702 if(rec.d_type == QType::RRSIG) {
1703 LOG("RRSIG - separate"<<endl);
1704 }
1705 else if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && rec.d_place==DNSResourceRecord::ANSWER && ((rec.d_type != QType::DNSKEY && rec.d_type != QType::DS) || rec.d_name != auth) && s_delegationOnly.count(auth)) {
1706 LOG("NO! Is from delegation-only zone"<<endl);
1707 s_nodelegated++;
1708 return RCode::NXDomain;
1709 }
1710 else {
1711 bool haveLogged = false;
1712 if (!t_sstorage.domainmap->empty()) {
1713 // Check if we are authoritative for a zone in this answer
1714 DNSName tmp_qname(rec.d_name);
1715 auto auth_domain_iter=getBestAuthZone(&tmp_qname);
1716 if(auth_domain_iter!=t_sstorage.domainmap->end() &&
1717 auth.countLabels() <= auth_domain_iter->first.countLabels()) {
1718 if (auth_domain_iter->first != auth) {
1719 LOG("NO! - we are authoritative for the zone "<<auth_domain_iter->first<<endl);
1720 continue;
1721 } else {
1722 LOG("YES! - This answer was ");
1723 if (!wasForwarded) {
1724 LOG("retrieved from the local auth store.");
1725 } else {
1726 LOG("received from a server we forward to.");
1727 }
1728 haveLogged = true;
1729 LOG(endl);
1730 }
1731 }
1732 }
1733 if (!haveLogged) {
1734 LOG("YES!"<<endl);
1735 }
1736
1737 rec.d_ttl=min(s_maxcachettl, rec.d_ttl);
1738
1739 DNSRecord dr(rec);
1740 dr.d_ttl += d_now.tv_sec;
1741 dr.d_place=DNSResourceRecord::ANSWER;
1742 tcache[{rec.d_name,rec.d_type,rec.d_place}].records.push_back(dr);
1743 }
1744 }
1745 else
1746 LOG("NO!"<<endl);
1747 }
1748
1749 // supplant
1750 for(tcache_t::iterator i = tcache.begin(); i != tcache.end(); ++i) {
1751 if((i->second.records.size() + i->second.signatures.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2)
1752 uint32_t lowestTTD=computeLowestTTD(i->second.records, i->second.signatures, i->second.signaturesTTL);
1753
1754 for(auto& record : i->second.records)
1755 record.d_ttl = lowestTTD; // boom
1756 }
1757
1758 // cout<<"Have "<<i->second.records.size()<<" records and "<<i->second.signatures.size()<<" signatures for "<<i->first.name;
1759 // cout<<'|'<<DNSRecordContent::NumberToType(i->first.type)<<endl;
1760 }
1761
1762 for(tcache_t::iterator i = tcache.begin(); i != tcache.end(); ++i) {
1763
1764 if(i->second.records.empty()) // this happens when we did store signatures, but passed on the records themselves
1765 continue;
1766
1767 vState recordState = getValidationStatus(auth);
1768 LOG(d_prefix<<": got status "<<vStates[recordState]<<" for record "<<i->first.name<<endl);
1769
1770 if (validationEnabled() && recordState == Secure) {
1771 if (lwr.d_aabit) {
1772 if (i->first.place != DNSResourceRecord::ADDITIONAL) {
1773 /* the additional entries can be insecure,
1774 like glue:
1775 "Glue address RRsets associated with delegations MUST NOT be signed"
1776 */
1777 if (i->first.type == QType::DNSKEY && i->first.place == DNSResourceRecord::ANSWER) {
1778 LOG(d_prefix<<"Validating DNSKEY for "<<i->first.name<<endl);
1779 recordState = validateDNSKeys(i->first.name, i->second.records, i->second.signatures, depth);
1780 }
1781 else {
1782 LOG(d_prefix<<"Validating non-additional record for "<<i->first.name<<endl);
1783 recordState = validateRecordsWithSigs(depth, qname, qtype, i->first.name, i->second.records, i->second.signatures);
1784 }
1785 }
1786 }
1787 else {
1788 /* for non authoritative answer, we only care about the DS record (or lack of) */
1789 if ((i->first.type == QType::DS || i->first.type == QType::NSEC || i->first.type == QType::NSEC3) && i->first.place == DNSResourceRecord::AUTHORITY) {
1790 LOG(d_prefix<<"Validating DS record for "<<i->first.name<<endl);
1791 recordState = validateRecordsWithSigs(depth, qname, qtype, i->first.name, i->second.records, i->second.signatures);
1792 }
1793 }
1794 updateValidationState(state, recordState);
1795 }
1796 else {
1797 if (validationEnabled()) {
1798 LOG(d_prefix<<"Skipping validation because the current state is "<<vStates[recordState]<<endl);
1799 }
1800 }
1801
1802 t_RC->replace(d_now.tv_sec, i->first.name, QType(i->first.type), i->second.records, i->second.signatures, authorityRecs, lwr.d_aabit, i->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, recordState);
1803
1804 if(i->first.place == DNSResourceRecord::ANSWER && ednsmask)
1805 d_wasVariable=true;
1806 }
1807
1808 return RCode::NoError;
1809 }
1810
1811 void SyncRes::getDenialValidationState(NegCache::NegCacheEntry& ne, vState& state, const dState expectedState, bool allowOptOut)
1812 {
1813 ne.d_validationState = state;
1814
1815 if (state == Secure) {
1816 cspmap_t csp = harvestCSPFromNE(ne);
1817 dState res = getDenial(csp, ne.d_name, ne.d_qtype.getCode());
1818 if (res != expectedState) {
1819 if (res == OPTOUT && allowOptOut) {
1820 LOG(d_prefix<<"OPT-out denial found for "<<ne.d_name<<", retuning Insecure"<<endl);
1821 ne.d_validationState = Secure;
1822 updateValidationState(state, Insecure);
1823 return;
1824 }
1825 else if (res == INSECURE) {
1826 LOG(d_prefix<<"Insecure denial found for "<<ne.d_name<<", retuning Insecure"<<endl);
1827 ne.d_validationState = Insecure;
1828 }
1829 if (res == NXDOMAIN && expectedState == NXQTYPE) {
1830 /* might happen for empty non-terminal, have fun */
1831 return;
1832 }
1833 else {
1834 LOG(d_prefix<<"Invalid denial found for "<<ne.d_name<<", retuning Bogus"<<endl);
1835 ne.d_validationState = Bogus;
1836 }
1837 updateValidationState(state, ne.d_validationState);
1838 }
1839 }
1840 }
1841
1842 bool SyncRes::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, bool needWildcardProof)
1843 {
1844 bool done = false;
1845
1846 for(auto& rec : lwr.d_records) {
1847 if (rec.d_type!=QType::OPT && rec.d_class!=QClass::IN)
1848 continue;
1849
1850 if(rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::SOA &&
1851 lwr.d_rcode==RCode::NXDomain && qname.isPartOf(rec.d_name) && rec.d_name.isPartOf(auth)) {
1852 LOG(prefix<<qname<<": got negative caching indication for name '"<<qname<<"' (accept="<<rec.d_name.isPartOf(auth)<<"), newtarget='"<<newtarget<<"'"<<endl);
1853
1854 rec.d_ttl = min(rec.d_ttl, s_maxnegttl);
1855 if(newtarget.empty()) // only add a SOA if we're not going anywhere after this
1856 ret.push_back(rec);
1857 if(!wasVariable()) {
1858 NegCache::NegCacheEntry ne;
1859
1860 ne.d_ttd = d_now.tv_sec + rec.d_ttl;
1861 ne.d_name = qname;
1862 ne.d_qtype = QType(0); // this encodes 'whole record'
1863 ne.d_auth = rec.d_name;
1864 harvestNXRecords(lwr.d_records, ne);
1865 getDenialValidationState(ne, state, NXDOMAIN, false);
1866 t_sstorage.negcache.add(ne);
1867 if(s_rootNXTrust && ne.d_auth.isRoot() && auth.isRoot()) {
1868 ne.d_name = ne.d_name.getLastLabel();
1869 t_sstorage.negcache.add(ne);
1870 }
1871 }
1872
1873 negindic=true;
1874 }
1875 else if(rec.d_place==DNSResourceRecord::ANSWER && rec.d_type==QType::CNAME && (!(qtype==QType(QType::CNAME))) && rec.d_name == qname) {
1876 ret.push_back(rec);
1877 if (auto content = getRR<CNAMERecordContent>(rec)) {
1878 newtarget=content->getTarget();
1879 }
1880 }
1881 else if((rec.d_type==QType::RRSIG || rec.d_type==QType::NSEC || rec.d_type==QType::NSEC3) && rec.d_place==DNSResourceRecord::ANSWER) {
1882 if(rec.d_type != QType::RRSIG || rec.d_name == qname)
1883 ret.push_back(rec); // enjoy your DNSSEC
1884 }
1885 else if(needWildcardProof && (rec.d_type==QType::RRSIG || rec.d_type==QType::NSEC || rec.d_type==QType::NSEC3) && rec.d_place==DNSResourceRecord::AUTHORITY) {
1886 ret.push_back(rec); // enjoy your DNSSEC
1887 }
1888 // for ANY answers we *must* have an authoritative answer, unless we are forwarding recursively
1889 else if(rec.d_place==DNSResourceRecord::ANSWER && rec.d_name == qname &&
1890 (
1891 rec.d_type==qtype.getCode() || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, QType(rec.d_type)) ) ) || sendRDQuery
1892 )
1893 )
1894 {
1895 LOG(prefix<<qname<<": answer is in: resolved to '"<< rec.d_content->getZoneRepresentation()<<"|"<<DNSRecordContent::NumberToType(rec.d_type)<<"'"<<endl);
1896
1897 done=true;
1898 ret.push_back(rec);
1899 }
1900 else if(rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::NS && qname.isPartOf(rec.d_name)) {
1901 if(moreSpecificThan(rec.d_name,auth)) {
1902 newauth=rec.d_name;
1903 LOG(prefix<<qname<<": got NS record '"<<rec.d_name<<"' -> '"<<rec.d_content->getZoneRepresentation()<<"'"<<endl);
1904 realreferral=true;
1905 }
1906 else {
1907 LOG(prefix<<qname<<": got upwards/level NS record '"<<rec.d_name<<"' -> '"<<rec.d_content->getZoneRepresentation()<<"', had '"<<auth<<"'"<<endl);
1908 }
1909 if (auto content = getRR<NSRecordContent>(rec)) {
1910 nsset.insert(content->getNS());
1911 }
1912 }
1913 else if(rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::DS && qname.isPartOf(rec.d_name)) {
1914 LOG(prefix<<qname<<": got DS record '"<<rec.d_name<<"' -> '"<<rec.d_content->getZoneRepresentation()<<"'"<<endl);
1915 }
1916 else if(realreferral && rec.d_place==DNSResourceRecord::AUTHORITY && (rec.d_type==QType::NSEC || rec.d_type==QType::NSEC3) && newauth.isPartOf(auth)) {
1917 /* we might have received a denial of the DS, let's check */
1918 if (state == Secure) {
1919 NegCache::NegCacheEntry ne;
1920 ne.d_auth = auth;
1921 ne.d_ttd = d_now.tv_sec + rec.d_ttl;
1922 ne.d_name = newauth;
1923 ne.d_qtype = QType::DS;
1924 harvestNXRecords(lwr.d_records, ne);
1925 cspmap_t csp = harvestCSPFromNE(ne);
1926 dState denialState = getDenial(csp, newauth, QType::DS);
1927 if (denialState == NXQTYPE || denialState == OPTOUT || denialState == INSECURE) {
1928 ne.d_validationState = Secure;
1929 rec.d_ttl = min(s_maxnegttl, rec.d_ttl);
1930 LOG(prefix<<qname<<": got negative indication of DS record for '"<<newauth<<"'"<<endl);
1931 updateValidationState(state, Insecure);
1932 auto cut = d_cutStates.find(newauth);
1933 if (cut != d_cutStates.end()) {
1934 if (cut->second == Indeterminate) {
1935 cut->second = state;
1936 }
1937 }
1938 else {
1939 LOG(prefix<<qname<<": setting cut state for "<<newauth<<" to "<<vStates[state]<<endl);
1940 d_cutStates[newauth] = state;
1941 }
1942 if(!wasVariable()) {
1943 t_sstorage.negcache.add(ne);
1944 }
1945 }
1946 }
1947 }
1948 else if(!done && rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::SOA &&
1949 lwr.d_rcode==RCode::NoError && qname.isPartOf(rec.d_name)) {
1950 LOG(prefix<<qname<<": got negative caching indication for '"<< qname<<"|"<<qtype.getName()<<"'"<<endl);
1951
1952 if(!newtarget.empty()) {
1953 LOG(prefix<<qname<<": Hang on! Got a redirect to '"<<newtarget<<"' already"<<endl);
1954 }
1955 else {
1956 rec.d_ttl = min(s_maxnegttl, rec.d_ttl);
1957 ret.push_back(rec);
1958 if(!wasVariable()) {
1959 NegCache::NegCacheEntry ne;
1960 ne.d_auth = rec.d_name;
1961 ne.d_ttd = d_now.tv_sec + rec.d_ttl;
1962 ne.d_name = qname;
1963 ne.d_qtype = qtype;
1964 harvestNXRecords(lwr.d_records, ne);
1965 getDenialValidationState(ne, state, NXQTYPE, qtype == QType::DS);
1966 if(qtype.getCode()) { // prevents us from blacking out a whole domain
1967 t_sstorage.negcache.add(ne);
1968 }
1969 }
1970 negindic=true;
1971 }
1972 }
1973 }
1974
1975 return done;
1976 }
1977
1978 bool SyncRes::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)
1979 {
1980 int resolveret;
1981 s_outqueries++;
1982 d_outqueries++;
1983
1984 if(d_outqueries + d_throttledqueries > s_maxqperq) {
1985 throw ImmediateServFailException("more than "+std::to_string(s_maxqperq)+" (max-qperq) queries sent while resolving "+qname.toLogString());
1986 }
1987
1988 if(s_maxtotusec && d_totUsec > s_maxtotusec) {
1989 throw ImmediateServFailException("Too much time waiting for "+qname.toLogString()+"|"+qtype.getName()+", timeouts: "+std::to_string(d_timeouts) +", throttles: "+std::to_string(d_throttledqueries) + ", queries: "+std::to_string(d_outqueries)+", "+std::to_string(d_totUsec/1000)+"msec");
1990 }
1991
1992 if(doTCP) {
1993 LOG(prefix<<qname<<": using TCP with "<< remoteIP.toStringWithPort() <<endl);
1994 s_tcpoutqueries++;
1995 d_tcpoutqueries++;
1996 }
1997
1998 if(d_pdl && d_pdl->preoutquery(remoteIP, d_requestor, qname, qtype, doTCP, lwr.d_records, resolveret)) {
1999 LOG(prefix<<qname<<": query handled by Lua"<<endl);
2000 }
2001 else {
2002 ednsmask=getEDNSSubnetMask(d_requestor, qname, remoteIP);
2003 if(ednsmask) {
2004 LOG(prefix<<qname<<": Adding EDNS Client Subnet Mask "<<ednsmask->toString()<<" to query"<<endl);
2005 }
2006 resolveret = asyncresolveWrapper(remoteIP, d_doDNSSEC, qname, qtype.getCode(),
2007 doTCP, sendRDQuery, &d_now, ednsmask, &lwr); // <- we go out on the wire!
2008 if(ednsmask) {
2009 LOG(prefix<<qname<<": Received EDNS Client Subnet Mask "<<ednsmask->toString()<<" on response"<<endl);
2010 }
2011 }
2012
2013 /* preoutquery killed the query by setting dq.rcode to -3 */
2014 if(resolveret==-3) {
2015 throw ImmediateServFailException("Query killed by policy");
2016 }
2017
2018 d_totUsec += lwr.d_usec;
2019 accountAuthLatency(lwr.d_usec, remoteIP.sin4.sin_family);
2020
2021 if(resolveret != 1) {
2022 /* Error while resolving */
2023 if(resolveret == 0) {
2024 /* Time out */
2025
2026 LOG(prefix<<qname<<": timeout resolving after "<<lwr.d_usec/1000.0<<"msec "<< (doTCP ? "over TCP" : "")<<endl);
2027 d_timeouts++;
2028 s_outgoingtimeouts++;
2029
2030 if(remoteIP.sin4.sin_family == AF_INET)
2031 s_outgoing4timeouts++;
2032 else
2033 s_outgoing6timeouts++;
2034 }
2035 else if(resolveret == -2) {
2036 /* OS resource limit reached */
2037 LOG(prefix<<qname<<": hit a local resource limit resolving"<< (doTCP ? " over TCP" : "")<<", probable error: "<<stringerror()<<endl);
2038 g_stats.resourceLimits++;
2039 }
2040 else {
2041 /* -1 means server unreachable */
2042 s_unreachables++;
2043 d_unreachables++;
2044 LOG(prefix<<qname<<": error resolving from "<<remoteIP.toString()<< (doTCP ? " over TCP" : "") <<", possible error: "<<strerror(errno)<< endl);
2045 }
2046
2047 if(resolveret != -2) { // don't account for resource limits, they are our own fault
2048 t_sstorage.nsSpeeds[nsName].submit(remoteIP, 1000000, &d_now); // 1 sec
2049
2050 // code below makes sure we don't filter COM or the root
2051 if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && t_sstorage.fails.incr(remoteIP) >= s_serverdownmaxfails) {
2052 LOG(prefix<<qname<<": Max fails reached resolving on "<< remoteIP.toString() <<". Going full throttle for "<< s_serverdownthrottletime <<" seconds" <<endl);
2053 // mark server as down
2054 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0), s_serverdownthrottletime, 10000);
2055 }
2056 else if (resolveret == -1) {
2057 // unreachable, 1 minute or 100 queries
2058 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 60, 100);
2059 }
2060 else {
2061 // timeout
2062 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 10, 5);
2063 }
2064 }
2065
2066 return false;
2067 }
2068
2069 /* we got an answer */
2070 if(lwr.d_rcode==RCode::ServFail || lwr.d_rcode==RCode::Refused) {
2071 LOG(prefix<<qname<<": "<<nsName<<" ("<<remoteIP.toString()<<") returned a "<< (lwr.d_rcode==RCode::ServFail ? "ServFail" : "Refused") << ", trying sibling IP or NS"<<endl);
2072 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 60, 3);
2073 return false;
2074 }
2075
2076 /* this server sent a valid answer, mark it backup up if it was down */
2077 if(s_serverdownmaxfails > 0) {
2078 t_sstorage.fails.clear(remoteIP);
2079 }
2080
2081 if(lwr.d_tcbit) {
2082 *truncated = true;
2083
2084 if (doTCP) {
2085 LOG(prefix<<qname<<": truncated bit set, over TCP?"<<endl);
2086 /* let's treat that as a ServFail answer from this server */
2087 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()), 60, 3);
2088 return false;
2089 }
2090
2091 return true;
2092 }
2093
2094 return true;
2095 }
2096
2097 bool SyncRes::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)
2098 {
2099 string prefix;
2100 if(doLog()) {
2101 prefix=d_prefix;
2102 prefix.append(depth, ' ');
2103 }
2104
2105 if(s_minimumTTL) {
2106 for(auto& rec : lwr.d_records) {
2107 rec.d_ttl = max(rec.d_ttl, s_minimumTTL);
2108 }
2109 }
2110
2111 bool needWildcardProof = false;
2112 *rcode = updateCacheFromRecords(depth, lwr, qname, qtype, auth, wasForwarded, ednsmask, state, needWildcardProof);
2113 if (*rcode != RCode::NoError) {
2114 return true;
2115 }
2116
2117 LOG(prefix<<qname<<": determining status after receiving this packet"<<endl);
2118
2119 set<DNSName> nsset;
2120 bool realreferral=false, negindic=false;
2121 DNSName newauth;
2122 DNSName newtarget;
2123
2124 bool done = processRecords(prefix, qname, qtype, auth, lwr, sendRDQuery, ret, nsset, newtarget, newauth, realreferral, negindic, state, needWildcardProof);
2125
2126 if(done){
2127 LOG(prefix<<qname<<": status=got results, this level of recursion done"<<endl);
2128 *rcode = RCode::NoError;
2129 return true;
2130 }
2131
2132 if(!newtarget.empty()) {
2133 if(newtarget == qname) {
2134 LOG(prefix<<qname<<": status=got a CNAME referral to self, returning SERVFAIL"<<endl);
2135 *rcode = RCode::ServFail;
2136 return true;
2137 }
2138
2139 if(depth > 10) {
2140 LOG(prefix<<qname<<": status=got a CNAME referral, but recursing too deep, returning SERVFAIL"<<endl);
2141 *rcode = RCode::ServFail;
2142 return true;
2143 }
2144
2145 LOG(prefix<<qname<<": status=got a CNAME referral, starting over with "<<newtarget<<endl);
2146
2147 set<GetBestNSAnswer> beenthere2;
2148 vState cnameState = Indeterminate;
2149 *rcode = doResolve(newtarget, qtype, ret, depth + 1, beenthere2, cnameState);
2150 LOG(prefix<<qname<<": updating validation state for response to "<<qname<<" from "<<vStates[state]<<" with the state from the CNAME quest: "<<vStates[cnameState]<<endl);
2151 updateValidationState(state, cnameState);
2152 return true;
2153 }
2154
2155 if(lwr.d_rcode == RCode::NXDomain) {
2156 LOG(prefix<<qname<<": status=NXDOMAIN, we are done "<<(negindic ? "(have negative SOA)" : "")<<endl);
2157
2158 if(d_doDNSSEC)
2159 addNXNSECS(ret, lwr.d_records);
2160
2161 *rcode = RCode::NXDomain;
2162 return true;
2163 }
2164
2165 if(nsset.empty() && !lwr.d_rcode && (negindic || lwr.d_aabit || sendRDQuery)) {
2166 LOG(prefix<<qname<<": status=noerror, other types may exist, but we are done "<<(negindic ? "(have negative SOA) " : "")<<(lwr.d_aabit ? "(have aa bit) " : "")<<endl);
2167
2168 if(d_doDNSSEC)
2169 addNXNSECS(ret, lwr.d_records);
2170
2171 *rcode = RCode::NoError;
2172 return true;
2173 }
2174
2175 if(realreferral) {
2176 LOG(prefix<<qname<<": status=did not resolve, got "<<(unsigned int)nsset.size()<<" NS, ");
2177
2178 nameservers.clear();
2179 for (auto const &nameserver : nsset) {
2180 if (d_wantsRPZ) {
2181 d_appliedPolicy = dfe.getProcessingPolicy(nameserver, d_discardedPolicies);
2182 if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { // client query needs an RPZ response
2183 LOG("however "<<nameserver<<" was blocked by RPZ policy '"<<(d_appliedPolicy.d_name ? *d_appliedPolicy.d_name : "")<<"'"<<endl);
2184 *rcode = -2;
2185 return true;
2186 }
2187 }
2188 nameservers.insert({nameserver, {{}, false}});
2189 }
2190 LOG("looping to them"<<endl);
2191 *gotNewServers = true;
2192 auth=newauth;
2193
2194 return false;
2195 }
2196
2197 return false;
2198 }
2199
2200 /** returns:
2201 * -1 in case of no results
2202 * -2 when a FilterEngine Policy was hit
2203 * rcode otherwise
2204 */
2205 int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype,
2206 vector<DNSRecord>&ret,
2207 unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state)
2208 {
2209 auto luaconfsLocal = g_luaconfs.getLocal();
2210 string prefix;
2211 if(doLog()) {
2212 prefix=d_prefix;
2213 prefix.append(depth, ' ');
2214 }
2215
2216 LOG(prefix<<qname<<": Cache consultations done, have "<<(unsigned int)nameservers.size()<<" NS to contact");
2217
2218 if (nameserversBlockedByRPZ(luaconfsLocal->dfe, nameservers)) {
2219 return -2;
2220 }
2221
2222 LOG(endl);
2223
2224 for(;;) { // we may get more specific nameservers
2225 vector<DNSName > rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname.toString()+": ") : string() );
2226
2227 for(auto tns=rnameservers.cbegin();;++tns) {
2228 if(tns==rnameservers.cend()) {
2229 LOG(prefix<<qname<<": Failed to resolve via any of the "<<(unsigned int)rnameservers.size()<<" offered NS at level '"<<auth<<"'"<<endl);
2230 if(!auth.isRoot() && flawedNSSet) {
2231 LOG(prefix<<qname<<": Ageing nameservers for level '"<<auth<<"', next query might succeed"<<endl);
2232
2233 if(t_RC->doAgeCache(d_now.tv_sec, auth, QType::NS, 10))
2234 g_stats.nsSetInvalidations++;
2235 }
2236 return -1;
2237 }
2238
2239 // this line needs to identify the 'self-resolving' behaviour, but we get it wrong now
2240 if(qname == *tns && qtype.getCode()==QType::A && rnameservers.size() > (size_t)(1+1*s_doIPv6)) {
2241 LOG(prefix<<qname<<": Not using NS to resolve itself! ("<<(1+tns-rnameservers.cbegin())<<"/"<<rnameservers.size()<<")"<<endl);
2242 continue;
2243 }
2244
2245 typedef vector<ComboAddress> remoteIPs_t;
2246 remoteIPs_t remoteIPs;
2247 remoteIPs_t::const_iterator remoteIP;
2248 bool pierceDontQuery=false;
2249 bool sendRDQuery=false;
2250 boost::optional<Netmask> ednsmask;
2251 LWResult lwr;
2252 const bool wasForwarded = tns->empty() && (!nameservers[*tns].first.empty());
2253 int rcode = RCode::NoError;
2254 bool gotNewServers = false;
2255
2256 if(tns->empty() && !wasForwarded) {
2257 LOG(prefix<<qname<<": Domain is out-of-band"<<endl);
2258 state = Insecure;
2259 d_wasOutOfBand = doOOBResolve(qname, qtype, lwr.d_records, depth, lwr.d_rcode);
2260 lwr.d_tcbit=false;
2261 lwr.d_aabit=true;
2262
2263 /* we have received an answer, are we done ? */
2264 bool done = processAnswer(depth, lwr, qname, qtype, auth, false, ednsmask, sendRDQuery, nameservers, ret, luaconfsLocal->dfe, &gotNewServers, &rcode, state);
2265 if (done) {
2266 return rcode;
2267 }
2268 if (gotNewServers) {
2269 break;
2270 }
2271 }
2272 else {
2273 /* if tns is empty, retrieveAddressesForNS() knows we have hardcoded servers (i.e. "forwards") */
2274 remoteIPs = retrieveAddressesForNS(prefix, qname, tns, depth, beenthere, rnameservers, nameservers, sendRDQuery, pierceDontQuery, flawedNSSet);
2275
2276 if(remoteIPs.empty()) {
2277 LOG(prefix<<qname<<": Failed to get IP for NS "<<*tns<<", trying next if available"<<endl);
2278 flawedNSSet=true;
2279 continue;
2280 }
2281 else {
2282 bool hitPolicy{false};
2283 LOG(prefix<<qname<<": Resolved '"<<auth<<"' NS "<<*tns<<" to: ");
2284 for(remoteIP = remoteIPs.cbegin(); remoteIP != remoteIPs.cend(); ++remoteIP) {
2285 if(remoteIP != remoteIPs.cbegin()) {
2286 LOG(", ");
2287 }
2288 LOG(remoteIP->toString());
2289 if(nameserverIPBlockedByRPZ(luaconfsLocal->dfe, *remoteIP)) {
2290 hitPolicy = true;
2291 }
2292 }
2293 LOG(endl);
2294 if (hitPolicy) //implies d_wantsRPZ
2295 return -2;
2296 }
2297
2298 for(remoteIP = remoteIPs.cbegin(); remoteIP != remoteIPs.cend(); ++remoteIP) {
2299 LOG(prefix<<qname<<": Trying IP "<< remoteIP->toStringWithPort() <<", asking '"<<qname<<"|"<<qtype.getName()<<"'"<<endl);
2300
2301 if (throttledOrBlocked(prefix, *remoteIP, qname, qtype, pierceDontQuery)) {
2302 continue;
2303 }
2304
2305 bool truncated = false;
2306 bool gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery,
2307 *tns, *remoteIP, false, &truncated);
2308 if (gotAnswer && truncated ) {
2309 /* retry, over TCP this time */
2310 gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery,
2311 *tns, *remoteIP, true, &truncated);
2312 }
2313
2314 if (!gotAnswer) {
2315 continue;
2316 }
2317
2318 LOG(prefix<<qname<<": Got "<<(unsigned int)lwr.d_records.size()<<" answers from "<<*tns<<" ("<< remoteIP->toString() <<"), rcode="<<lwr.d_rcode<<" ("<<RCode::to_s(lwr.d_rcode)<<"), aa="<<lwr.d_aabit<<", in "<<lwr.d_usec/1000<<"ms"<<endl);
2319
2320 /* // for you IPv6 fanatics :-)
2321 if(remoteIP->sin4.sin_family==AF_INET6)
2322 lwr.d_usec/=3;
2323 */
2324 // cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
2325
2326 t_sstorage.nsSpeeds[*tns].submit(*remoteIP, lwr.d_usec, &d_now);
2327
2328 /* we have received an answer, are we done ? */
2329 bool done = processAnswer(depth, lwr, qname, qtype, auth, wasForwarded, ednsmask, sendRDQuery, nameservers, ret, luaconfsLocal->dfe, &gotNewServers, &rcode, state);
2330 if (done) {
2331 return rcode;
2332 }
2333 if (gotNewServers) {
2334 break;
2335 }
2336 /* was lame */
2337 t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100);
2338 }
2339
2340 if (gotNewServers) {
2341 break;
2342 }
2343
2344 if(remoteIP == remoteIPs.cend()) // we tried all IP addresses, none worked
2345 continue;
2346
2347 }
2348 }
2349 }
2350 return -1;
2351 }
2352
2353 boost::optional<Netmask> SyncRes::getEDNSSubnetMask(const ComboAddress& local, const DNSName&dn, const ComboAddress& rem)
2354 {
2355 boost::optional<Netmask> result;
2356 ComboAddress trunc;
2357 uint8_t bits;
2358 if(d_incomingECSFound) {
2359 if (d_incomingECS->source.getBits() == 0) {
2360 /* RFC7871 says we MUST NOT send any ECS if the source scope is 0 */
2361 return result;
2362 }
2363 trunc = d_incomingECS->source.getMaskedNetwork();
2364 bits = d_incomingECS->source.getBits();
2365 }
2366 else if(!local.isIPv4() || local.sin4.sin_addr.s_addr) { // detect unset 'requestor'
2367 trunc = local;
2368 bits = local.isIPv4() ? 32 : 128;
2369 }
2370 else {
2371 /* nothing usable */
2372 return result;
2373 }
2374
2375 if(s_ednsdomains.check(dn) || s_ednssubnets.match(rem)) {
2376 bits = std::min(bits, (trunc.isIPv4() ? s_ecsipv4limit : s_ecsipv6limit));
2377 trunc.truncate(bits);
2378 return boost::optional<Netmask>(Netmask(trunc, bits));
2379 }
2380
2381 return result;
2382 }
2383
2384 void SyncRes::parseEDNSSubnetWhitelist(const std::string& wlist)
2385 {
2386 vector<string> parts;
2387 stringtok(parts, wlist, ",; ");
2388 for(const auto& a : parts) {
2389 try {
2390 s_ednssubnets.addMask(Netmask(a));
2391 }
2392 catch(...) {
2393 s_ednsdomains.add(DNSName(a));
2394 }
2395 }
2396 }
2397
2398 // used by PowerDNSLua - note that this neglects to add the packet count & statistics back to pdns_ercursor.cc
2399 int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<DNSRecord>& ret)
2400 {
2401 struct timeval now;
2402 gettimeofday(&now, 0);
2403
2404 SyncRes sr(now);
2405 int res = sr.beginResolve(qname, QType(qtype), qclass, ret);
2406
2407 return res;
2408 }
2409
2410 int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback) {
2411 SyncRes sr(now);
2412 sr.setDoEDNS0(true);
2413 sr.setUpdatingRootNS();
2414 sr.setDoDNSSEC(g_dnssecmode != DNSSECMode::Off);
2415 sr.setAsyncCallback(asyncCallback);
2416
2417 vector<DNSRecord> ret;
2418 int res=-1;
2419 try {
2420 res=sr.beginResolve(g_rootdnsname, QType(QType::NS), 1, ret);
2421 if (g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate) {
2422 auto state = sr.getValidationState();
2423 if (state == Bogus)
2424 throw PDNSException("Got Bogus validation result for .|NS");
2425 }
2426 return res;
2427 }
2428 catch(const PDNSException& e) {
2429 L<<Logger::Error<<"Failed to update . records, got an exception: "<<e.reason<<endl;
2430 }
2431 catch(const ImmediateServFailException& e) {
2432 L<<Logger::Error<<"Failed to update . records, got an exception: "<<e.reason<<endl;
2433 }
2434 catch(const std::exception& e) {
2435 L<<Logger::Error<<"Failed to update . records, got an exception: "<<e.what()<<endl;
2436 }
2437 catch(...) {
2438 L<<Logger::Error<<"Failed to update . records, got an exception"<<endl;
2439 }
2440
2441 if(!res) {
2442 L<<Logger::Notice<<"Refreshed . records"<<endl;
2443 }
2444 else
2445 L<<Logger::Error<<"Failed to update . records, RCODE="<<res<<endl;
2446
2447 return res;
2448 }