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