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