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