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