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