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