data_source.cc 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <cassert>
  16. #include <iomanip>
  17. #include <iostream>
  18. #include <vector>
  19. #include <boost/shared_ptr.hpp>
  20. #include <boost/foreach.hpp>
  21. #include <datasrc/cache.h>
  22. #include <datasrc/data_source.h>
  23. #include <datasrc/query.h>
  24. #include <datasrc/logger.h>
  25. #include <util/encode/base32hex.h>
  26. #include <util/hash/sha1.h>
  27. #include <util/buffer.h>
  28. #include <dns/message.h>
  29. #include <dns/name.h>
  30. #include <dns/rcode.h>
  31. #include <dns/rdataclass.h>
  32. #include <dns/rrset.h>
  33. #include <dns/rrsetlist.h>
  34. #include <cc/data.h>
  35. #define RETERR(x) do { \
  36. DataSrc::Result r = (x); \
  37. if (r != DataSrc::SUCCESS) \
  38. return (r); \
  39. } while (0)
  40. using namespace std;
  41. using namespace isc::util;
  42. using namespace isc::util::encode;
  43. using namespace isc::util::hash;
  44. using namespace isc::dns;
  45. using namespace isc::dns::rdata;
  46. namespace {
  47. struct MatchRRsetForType {
  48. MatchRRsetForType(const RRType rrtype) : rrtype_(rrtype) {}
  49. bool operator()(RRsetPtr rrset) {
  50. return (rrset->getType() == rrtype_);
  51. }
  52. const RRType rrtype_;
  53. };
  54. // This is a helper to retrieve a specified RR type of RRset from RRsetList.
  55. // In our case the data source search logic should ensure that the class is
  56. // valid. We use this find logic of our own so that we can support both
  57. // specific RR class queries (normal case) and class ANY queries.
  58. RRsetPtr
  59. findRRsetFromList(RRsetList& list, const RRType rrtype) {
  60. RRsetList::iterator it(find_if(list.begin(), list.end(),
  61. MatchRRsetForType(rrtype)));
  62. return (it != list.end() ? *it : RRsetPtr());
  63. }
  64. }
  65. namespace isc {
  66. namespace datasrc {
  67. typedef boost::shared_ptr<const Nsec3Param> ConstNsec3ParamPtr;
  68. class ZoneInfo {
  69. public:
  70. ZoneInfo(DataSrc* ts,
  71. const isc::dns::Name& n,
  72. const isc::dns::RRClass& c,
  73. const isc::dns::RRType& t = isc::dns::RRType::ANY()) :
  74. top_source_(ts),
  75. dsm_(((t == RRType::DS() && n.getLabelCount() != 1)
  76. ? n.split(1, n.getLabelCount() - 1) : n),
  77. c)
  78. {}
  79. const Name* getEnclosingZone() {
  80. if (dsm_.getEnclosingZone() == NULL) {
  81. top_source_->findClosestEnclosure(dsm_);
  82. }
  83. return (dsm_.getEnclosingZone());
  84. }
  85. const DataSrc* getDataSource() {
  86. if (dsm_.getDataSource() == NULL) {
  87. top_source_->findClosestEnclosure(dsm_);
  88. }
  89. return (dsm_.getDataSource());
  90. }
  91. private:
  92. const DataSrc* top_source_;
  93. DataSrcMatch dsm_;
  94. };
  95. // Add a task to the query task queue to look up additional data
  96. // (i.e., address records for the names included in NS or MX records)
  97. void
  98. getAdditional(Query& q, ConstRRsetPtr rrset) {
  99. if (!q.wantAdditional()) {
  100. return;
  101. }
  102. RdataIteratorPtr it = rrset->getRdataIterator();
  103. for (; !it->isLast(); it->next()) {
  104. const Rdata& rd(it->getCurrent());
  105. if (rrset->getType() == RRType::NS()) {
  106. const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
  107. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_GET_NS_ADDITIONAL).
  108. arg(ns.getNSName()).arg(rrset->getName());
  109. q.tasks().push(QueryTaskPtr(
  110. new QueryTask(q, ns.getNSName(),
  111. Message::SECTION_ADDITIONAL,
  112. QueryTask::GLUE_QUERY,
  113. QueryTask::GETADDITIONAL)));
  114. } else if (rrset->getType() == RRType::MX()) {
  115. const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
  116. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_GET_MX_ADDITIONAL).
  117. arg(mx.getMXName()).arg(rrset->getName());
  118. q.tasks().push(QueryTaskPtr(
  119. new QueryTask(q, mx.getMXName(),
  120. Message::SECTION_ADDITIONAL,
  121. QueryTask::NOGLUE_QUERY,
  122. QueryTask::GETADDITIONAL)));
  123. }
  124. }
  125. }
  126. // Synthesize a CNAME answer, for the benefit of clients that don't
  127. // understand DNAME
  128. void
  129. synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
  130. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_SYNTH_CNAME).
  131. arg(rrset->getName());
  132. RdataIteratorPtr it = rrset->getRdataIterator();
  133. // More than one DNAME RR in the RRset is illegal, so we only have
  134. // to process the first one.
  135. if (it->isLast()) {
  136. logger.error(DATASRC_QUERY_EMPTY_DNAME).arg(rrset->getName());
  137. return;
  138. }
  139. const Rdata& rd(it->getCurrent());
  140. const generic::DNAME& dname = dynamic_cast<const generic::DNAME&>(rd);
  141. const Name& dname_target(dname.getDname());
  142. RRsetPtr cname(new RRset(task->qname, rrset->getClass(), RRType::CNAME(),
  143. rrset->getTTL()));
  144. const int qnlen = task->qname.getLabelCount();
  145. const int dnlen = rrset->getName().getLabelCount();
  146. assert(qnlen > dnlen);
  147. const Name& prefix(task->qname.split(0, qnlen - dnlen));
  148. cname->addRdata(generic::CNAME(prefix.concatenate(dname_target)));
  149. target.addRRset(cname);
  150. }
  151. // Add a task to the query task queue to look up the data pointed
  152. // to by a CNAME record
  153. void
  154. chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
  155. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_FOLLOW_CNAME).
  156. arg(rrset->getName());
  157. RdataIteratorPtr it = rrset->getRdataIterator();
  158. // More than one CNAME RR in the RRset is illegal, so we only have
  159. // to process the first one.
  160. if (it->isLast()) {
  161. logger.error(DATASRC_QUERY_EMPTY_CNAME).arg(rrset->getName());
  162. return;
  163. }
  164. // Stop chasing CNAMES after 16 lookups, to prevent loops
  165. if (q.tooMany()) {
  166. logger.error(DATASRC_QUERY_TOO_MANY_CNAMES).arg(rrset->getName());
  167. return;
  168. }
  169. q.tasks().push(QueryTaskPtr(
  170. new QueryTask(q, dynamic_cast<const generic::CNAME&>
  171. (it->getCurrent()).getCname(),
  172. task->qtype, Message::SECTION_ANSWER,
  173. QueryTask::FOLLOWCNAME)));
  174. }
  175. // Check the cache for data which can answer the current query task.
  176. bool
  177. checkCache(QueryTask& task, RRsetList& target) {
  178. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_CHECK_CACHE).
  179. arg(task.qname).arg(task.qtype);
  180. HotCache& cache = task.q.getCache();
  181. RRsetList rrsets;
  182. RRsetPtr rrset;
  183. int count = 0;
  184. uint32_t flags = 0, cflags = 0;
  185. bool hit = false, found = false;
  186. switch (task.op) {
  187. case QueryTask::SIMPLE_QUERY: // Find exact RRset
  188. // ANY queries must be handled by the low-level data source,
  189. // or the results won't be guaranteed to be complete
  190. if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
  191. LOG_DEBUG(logger, DBG_TRACE_DATA,
  192. DATASRC_QUERY_NO_CACHE_ANY_SIMPLE).arg(task.qname).
  193. arg(task.qtype).arg(task.qclass);
  194. break;
  195. }
  196. hit = cache.retrieve(task.qname, task.qclass, task.qtype, rrset, flags);
  197. if (hit) {
  198. if (rrset) {
  199. rrsets.addRRset(rrset);
  200. target.append(rrsets);
  201. }
  202. // Reset the referral flag and treat CNAME as "not found".
  203. // This emulates the behavior of the sqlite3 data source.
  204. // XXX: this is not ideal in that the responsibility for handling
  205. // operation specific cases is spread over various classes at
  206. // different abstraction levels. For longer terms we should
  207. // revisit the whole datasource/query design, and clarify this
  208. // point better.
  209. flags &= ~DataSrc::REFERRAL;
  210. if ((flags & DataSrc::CNAME_FOUND) != 0) {
  211. flags &= ~DataSrc::CNAME_FOUND;
  212. flags |= DataSrc::TYPE_NOT_FOUND;
  213. }
  214. task.flags = flags;
  215. return (true);
  216. }
  217. break;
  218. case QueryTask::AUTH_QUERY: // Find exact RRset or CNAME
  219. if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
  220. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_NO_CACHE_ANY_AUTH).
  221. arg(task.qname).arg(task.qtype).arg(task.qclass);
  222. break;
  223. }
  224. hit = cache.retrieve(task.qname, task.qclass, task.qtype, rrset, flags);
  225. if (!hit || !rrset || (flags & DataSrc::CNAME_FOUND) != 0) {
  226. hit = cache.retrieve(task.qname, task.qclass, RRType::CNAME(),
  227. rrset, flags);
  228. if (!rrset) {
  229. // If we don't have a positive cache, forget it; otherwise the
  230. // intermediate result may confuse the subsequent processing.
  231. hit = false;
  232. }
  233. }
  234. if (hit) {
  235. if (rrset) {
  236. rrsets.addRRset(rrset);
  237. target.append(rrsets);
  238. }
  239. task.flags = flags;
  240. return (true);
  241. }
  242. break;
  243. case QueryTask::GLUE_QUERY: // Find addresses
  244. case QueryTask::NOGLUE_QUERY:
  245. // (XXX: need to figure out how to deal with noglue case)
  246. flags = 0;
  247. hit = cache.retrieve(task.qname, task.qclass, RRType::A(),
  248. rrset, cflags);
  249. if (hit) {
  250. flags |= cflags;
  251. ++count;
  252. if (rrset) {
  253. rrsets.addRRset(rrset);
  254. found = true;
  255. }
  256. }
  257. hit = cache.retrieve(task.qname, task.qclass, RRType::AAAA(),
  258. rrset, flags);
  259. if (hit) {
  260. flags |= cflags;
  261. ++count;
  262. if (rrset) {
  263. rrsets.addRRset(rrset);
  264. found = true;
  265. }
  266. }
  267. if (count == 2) {
  268. if (found) {
  269. flags &= ~DataSrc::TYPE_NOT_FOUND;
  270. target.append(rrsets);
  271. }
  272. task.flags = flags;
  273. return (true);
  274. }
  275. break;
  276. case QueryTask::REF_QUERY: // Find NS, DS and/or DNAME
  277. flags = count = 0;
  278. hit = cache.retrieve(task.qname, task.qclass, RRType::NS(),
  279. rrset, cflags);
  280. if (hit) {
  281. flags |= cflags;
  282. ++count;
  283. if (rrset) {
  284. rrsets.addRRset(rrset);
  285. found = true;
  286. }
  287. }
  288. hit = cache.retrieve(task.qname, task.qclass, RRType::DS(),
  289. rrset, flags);
  290. if (hit) {
  291. flags |= cflags;
  292. ++count;
  293. if (rrset) {
  294. rrsets.addRRset(rrset);
  295. found = true;
  296. }
  297. }
  298. hit = cache.retrieve(task.qname, task.qclass, RRType::DNAME(),
  299. rrset, flags);
  300. if (hit) {
  301. flags |= cflags;
  302. ++count;
  303. if (rrset) {
  304. rrsets.addRRset(rrset);
  305. found = true;
  306. }
  307. }
  308. if (count == 3) {
  309. if (found) {
  310. flags &= ~DataSrc::TYPE_NOT_FOUND;
  311. flags &= DataSrc::REFERRAL;
  312. target.append(rrsets);
  313. }
  314. task.flags = flags;
  315. return (true);
  316. }
  317. break;
  318. }
  319. return (false);
  320. }
  321. // Carry out the query specified in a QueryTask object
  322. DataSrc::Result
  323. doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
  324. HotCache& cache = task.q.getCache();
  325. RRsetPtr rrset;
  326. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_DO_QUERY).arg(task.qname).
  327. arg(task.qtype);
  328. // First off, make sure at least we have a matching zone in some data
  329. // source. We must do this before checking the cache, because it can
  330. // happen that the matching zone has been removed after an RRset of that
  331. // zone is cached. Such inconsistency will cause various problems,
  332. // including a crash.
  333. const DataSrc* ds = zoneinfo.getDataSource();
  334. const Name* const zonename = zoneinfo.getEnclosingZone();
  335. if (ds == NULL) {
  336. task.flags |= DataSrc::NO_SUCH_ZONE;
  337. logger.info(DATASRC_QUERY_NO_ZONE).arg(task.qname).arg(task.qclass);
  338. return (DataSrc::SUCCESS);
  339. }
  340. // Then check the cache for matching data
  341. if (checkCache(task, target)) {
  342. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_CACHED).
  343. arg(task.qname).arg(task.qtype);
  344. return (DataSrc::SUCCESS);
  345. }
  346. // Requested data weren't in the cache (or were, but had expired),
  347. // so now we proceed with the low-level data source lookup, and cache
  348. // whatever we find.
  349. DataSrc::Result result;
  350. switch (task.op) {
  351. case QueryTask::SIMPLE_QUERY:
  352. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_SIMPLE).
  353. arg(task.qname).arg(task.qtype);
  354. result = ds->findExactRRset(task.qname, task.qclass, task.qtype,
  355. target, task.flags, zonename);
  356. if (result != DataSrc::SUCCESS) {
  357. logger.error(DATASRC_QUERY_SIMPLE_FAIL).arg(result);
  358. return (result);
  359. }
  360. if (task.qclass == RRClass::ANY()) {
  361. // XXX: Currently, RRsetList::findRRset() doesn't handle
  362. // ANY queries, and without that we can't cache the results,
  363. // so we just return in that case.
  364. return (result);
  365. }
  366. if (task.flags == 0) {
  367. rrset = target.findRRset(task.qtype, task.qclass);
  368. assert(rrset);
  369. cache.addPositive(rrset, task.flags);
  370. } else {
  371. cache.addNegative(task.qname, task.qclass, task.qtype, task.flags);
  372. }
  373. return (result);
  374. case QueryTask::AUTH_QUERY:
  375. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_AUTH).
  376. arg(task.qname).arg(task.qtype);
  377. result = ds->findRRset(task.qname, task.qclass, task.qtype,
  378. target, task.flags, zonename);
  379. if (result != DataSrc::SUCCESS) {
  380. logger.error(DATASRC_QUERY_AUTH_FAIL).arg(result);
  381. return (result);
  382. }
  383. if (task.qclass == RRClass::ANY()) {
  384. return (result);
  385. }
  386. if (task.qtype == RRType::ANY()) {
  387. BOOST_FOREACH(RRsetPtr rr, target) {
  388. cache.addPositive(rr, task.flags);
  389. }
  390. } else if ((task.flags & DataSrc::CNAME_FOUND) != 0) {
  391. cache.addNegative(task.qname, task.qclass, task.qtype, task.flags);
  392. rrset = target.findRRset(RRType::CNAME(), task.qclass);
  393. assert(rrset);
  394. cache.addPositive(rrset, task.flags);
  395. } else if ((task.flags & DataSrc::DATA_NOT_FOUND) == 0) {
  396. if (task.qtype != RRType::CNAME()) {
  397. cache.addNegative(task.qname, task.qclass, RRType::CNAME(),
  398. task.flags);
  399. }
  400. rrset = target.findRRset(task.qtype, task.qclass);
  401. assert(rrset);
  402. cache.addPositive(rrset, task.flags);
  403. } else {
  404. cache.addNegative(task.qname, task.qclass, task.qtype, task.flags);
  405. }
  406. return (result);
  407. case QueryTask::GLUE_QUERY:
  408. case QueryTask::NOGLUE_QUERY:
  409. LOG_DEBUG(logger, DBG_TRACE_DATA, task.op == QueryTask::GLUE_QUERY ?
  410. DATASRC_QUERY_IS_GLUE : DATASRC_QUERY_IS_NOGLUE).
  411. arg(task.qname).arg(task.qtype);
  412. result = ds->findAddrs(task.qname, task.qclass, target,
  413. task.flags, zonename);
  414. if (result != DataSrc::SUCCESS) {
  415. logger.error(task.op == QueryTask::GLUE_QUERY ?
  416. DATASRC_QUERY_GLUE_FAIL : DATASRC_QUERY_NOGLUE_FAIL).
  417. arg(result);
  418. return (result);
  419. }
  420. if (task.qclass == RRClass::ANY()) {
  421. return (result);
  422. }
  423. rrset = target.findRRset(RRType::A(), task.qclass);
  424. if (rrset) {
  425. cache.addPositive(rrset, task.flags);
  426. } else {
  427. cache.addNegative(task.qname, task.qclass, RRType::A(), task.flags);
  428. }
  429. rrset = target.findRRset(RRType::AAAA(), task.qclass);
  430. if (rrset) {
  431. cache.addPositive(rrset, task.flags);
  432. } else {
  433. cache.addNegative(task.qname, task.qclass, RRType::AAAA(),
  434. task.flags);
  435. }
  436. return (result);
  437. case QueryTask::REF_QUERY:
  438. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_REF).
  439. arg(task.qname).arg(task.qtype);
  440. result = ds->findReferral(task.qname, task.qclass, target,
  441. task.flags, zonename);
  442. if (result != DataSrc::SUCCESS) {
  443. logger.error(DATASRC_QUERY_REF_FAIL).arg(result);
  444. return (result);
  445. }
  446. if (task.qclass == RRClass::ANY()) {
  447. return (result);
  448. }
  449. rrset = target.findRRset(RRType::NS(), task.qclass);
  450. if (rrset) {
  451. cache.addPositive(rrset, task.flags);
  452. } else {
  453. cache.addNegative(task.qname, task.qclass, RRType::NS(),
  454. task.flags);
  455. }
  456. rrset = target.findRRset(RRType::DS(), task.qclass);
  457. if (rrset) {
  458. cache.addPositive(rrset, task.flags);
  459. } else {
  460. cache.addNegative(task.qname, task.qclass, RRType::DS(),
  461. task.flags);
  462. }
  463. rrset = target.findRRset(RRType::DNAME(), task.qclass);
  464. if (rrset) {
  465. cache.addPositive(rrset, task.flags);
  466. } else {
  467. cache.addNegative(task.qname, task.qclass, RRType::DNAME(),
  468. task.flags);
  469. }
  470. return (result);
  471. }
  472. // Not reached
  473. logger.error(DATASRC_QUERY_INVALID_OP);
  474. return (DataSrc::ERROR);
  475. }
  476. // Add an RRset (and its associated RRSIG) to a message section,
  477. // checking first to ensure that there isn't already an RRset with
  478. // the same name and type.
  479. inline void
  480. addToMessage(Query& q, const Message::Section sect, RRsetPtr rrset,
  481. bool no_dnssec = false)
  482. {
  483. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_RRSET).
  484. arg(rrset->getName()).arg(rrset->getType());
  485. Message& m = q.message();
  486. if (no_dnssec) {
  487. if (rrset->getType() == RRType::RRSIG() ||
  488. !m.hasRRset(sect, rrset->getName(), rrset->getClass(),
  489. rrset->getType())) {
  490. m.addRRset(sect, rrset, false);
  491. }
  492. } else {
  493. if (!m.hasRRset(sect, rrset->getName(), rrset->getClass(),
  494. rrset->getType())) {
  495. m.addRRset(sect, rrset, q.wantDnssec());
  496. }
  497. }
  498. }
  499. // Copy referral information into the authority section of a message
  500. inline void
  501. copyAuth(Query& q, RRsetList& auth) {
  502. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_COPY_AUTH);
  503. BOOST_FOREACH(RRsetPtr rrset, auth) {
  504. if (rrset->getType() == RRType::DNAME()) {
  505. continue;
  506. }
  507. if (rrset->getType() == RRType::DS() && !q.wantDnssec()) {
  508. continue;
  509. }
  510. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  511. getAdditional(q, rrset);
  512. }
  513. }
  514. // Query for referrals (i.e., NS/DS or DNAME) at a given name
  515. inline bool
  516. refQuery(const Query& q, const Name& name, ZoneInfo& zoneinfo,
  517. RRsetList& target)
  518. {
  519. QueryTask newtask(q, name, QueryTask::REF_QUERY);
  520. if (doQueryTask(newtask, zoneinfo, target) != DataSrc::SUCCESS) {
  521. // Lookup failed
  522. return (false);
  523. }
  524. // Referral bit is expected, so clear it when checking flags
  525. if ((newtask.flags & ~DataSrc::REFERRAL) != 0) {
  526. return (false);
  527. }
  528. return (true);
  529. }
  530. // Match downward, from the zone apex to the query name, looking for
  531. // referrals. Note that we exclude the apex name and query name themselves;
  532. // they'll be handled in a normal lookup in the zone.
  533. inline bool
  534. hasDelegation(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo) {
  535. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_DELEGATION).
  536. arg(task->qname);
  537. const Name* const zonename = zoneinfo.getEnclosingZone();
  538. if (zonename == NULL) {
  539. if (task->state == QueryTask::GETANSWER) {
  540. q.message().setRcode(Rcode::REFUSED());
  541. }
  542. return (false);
  543. }
  544. const int diff = task->qname.getLabelCount() - zonename->getLabelCount();
  545. if (diff > 1) {
  546. bool found = false;
  547. RRsetList ref;
  548. for (int i = diff - 1; i > 0; --i) {
  549. const Name sub(task->qname.split(i));
  550. if (refQuery(q, sub, zoneinfo, ref)) {
  551. found = true;
  552. break;
  553. }
  554. }
  555. // Found a referral while getting additional data
  556. // for something other than NS; we skip it.
  557. if (found && task->op == QueryTask::NOGLUE_QUERY) {
  558. return (true);
  559. }
  560. // Found a referral while getting answer data;
  561. // send a delegation.
  562. if (found) {
  563. RRsetPtr r = findRRsetFromList(ref, RRType::DNAME());
  564. if (r != NULL) {
  565. RRsetList syn;
  566. addToMessage(q, Message::SECTION_ANSWER, r);
  567. q.message().setHeaderFlag(Message::HEADERFLAG_AA);
  568. synthesizeCname(task, r, syn);
  569. if (syn.size() == 1) {
  570. RRsetPtr cname_rrset = findRRsetFromList(syn,
  571. RRType::CNAME());
  572. addToMessage(q, Message::SECTION_ANSWER, cname_rrset);
  573. chaseCname(q, task, cname_rrset);
  574. return (true);
  575. }
  576. }
  577. copyAuth(q, ref);
  578. return (true);
  579. }
  580. }
  581. // We appear to have authoritative data; set the header
  582. // flag. (We may clear it later if we find a referral
  583. // at the actual qname node.)
  584. if (task->op == QueryTask::AUTH_QUERY &&
  585. task->state == QueryTask::GETANSWER) {
  586. q.message().setHeaderFlag(Message::HEADERFLAG_AA);
  587. }
  588. return (false);
  589. }
  590. inline DataSrc::Result
  591. addSOA(Query& q, ZoneInfo& zoneinfo) {
  592. RRsetList soa;
  593. const Name* const zonename = zoneinfo.getEnclosingZone();
  594. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_SOA).arg(*zonename);
  595. QueryTask newtask(q, *zonename, RRType::SOA(), QueryTask::SIMPLE_QUERY);
  596. RETERR(doQueryTask(newtask, zoneinfo, soa));
  597. if (newtask.flags != 0) {
  598. return (DataSrc::ERROR);
  599. }
  600. addToMessage(q, Message::SECTION_AUTHORITY,
  601. findRRsetFromList(soa, RRType::SOA()));
  602. return (DataSrc::SUCCESS);
  603. }
  604. inline DataSrc::Result
  605. addNSEC(Query& q, const Name& name, ZoneInfo& zoneinfo) {
  606. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_NSEC).arg(name);
  607. RRsetList nsec;
  608. QueryTask newtask(q, name, RRType::NSEC(), QueryTask::SIMPLE_QUERY);
  609. RETERR(doQueryTask(newtask, zoneinfo, nsec));
  610. if (newtask.flags == 0) {
  611. addToMessage(q, Message::SECTION_AUTHORITY,
  612. findRRsetFromList(nsec, RRType::NSEC()));
  613. }
  614. return (DataSrc::SUCCESS);
  615. }
  616. inline DataSrc::Result
  617. getNsec3(Query& q, ZoneInfo& zoneinfo, string& hash, RRsetPtr& target) {
  618. const DataSrc* ds = zoneinfo.getDataSource();
  619. const Name* const zonename = zoneinfo.getEnclosingZone();
  620. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_NSEC3).arg(*zonename);
  621. if (ds == NULL) {
  622. q.message().setRcode(Rcode::SERVFAIL());
  623. logger.error(DATASRC_QUERY_NO_DS_NSEC3).arg(*zonename);
  624. return (DataSrc::ERROR);
  625. }
  626. RRsetList rl;
  627. RETERR(ds->findCoveringNSEC3(*zonename, hash, rl));
  628. target = rl.findRRset(RRType::NSEC3(), q.qclass());
  629. return (DataSrc::SUCCESS);
  630. }
  631. ConstNsec3ParamPtr
  632. getNsec3Param(Query& q, ZoneInfo& zoneinfo) {
  633. DataSrc::Result result;
  634. RRsetList nsec3param;
  635. const Name* const zonename = zoneinfo.getEnclosingZone();
  636. QueryTask newtask(q, *zonename, RRType::NSEC3PARAM(),
  637. QueryTask::SIMPLE_QUERY);
  638. result = doQueryTask(newtask, zoneinfo, nsec3param);
  639. newtask.flags &= ~DataSrc::REFERRAL;
  640. if (result != DataSrc::SUCCESS || newtask.flags != 0) {
  641. return (ConstNsec3ParamPtr());
  642. }
  643. RRsetPtr rrset = nsec3param.findRRset(RRType::NSEC3PARAM(), q.qclass());
  644. if (!rrset) {
  645. return (ConstNsec3ParamPtr());
  646. }
  647. // XXX: currently only one NSEC3 chain per zone is supported;
  648. // we will need to revisit this.
  649. RdataIteratorPtr it = rrset->getRdataIterator();
  650. if (it->isLast()) {
  651. return (ConstNsec3ParamPtr());
  652. }
  653. const generic::NSEC3PARAM& np =
  654. dynamic_cast<const generic::NSEC3PARAM&>(it->getCurrent());
  655. return (ConstNsec3ParamPtr(new Nsec3Param(np.getHashalg(), np.getFlags(),
  656. np.getIterations(),
  657. np.getSalt())));
  658. }
  659. inline DataSrc::Result
  660. proveNX(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, const bool wildcard) {
  661. Message& m = q.message();
  662. const Name* const zonename = zoneinfo.getEnclosingZone();
  663. ConstNsec3ParamPtr nsec3 = getNsec3Param(q, zoneinfo);
  664. if (nsec3 != NULL) {
  665. // Attach the NSEC3 record covering the QNAME
  666. RRsetPtr rrset;
  667. string hash1(nsec3->getHash(task->qname));
  668. RETERR(getNsec3(q, zoneinfo, hash1, rrset));
  669. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  670. // If this is an NXRRSET or NOERROR/NODATA, we're done
  671. if ((task->flags & DataSrc::TYPE_NOT_FOUND) != 0) {
  672. return (DataSrc::SUCCESS);
  673. }
  674. // Find the closest provable enclosing name for QNAME
  675. Name enclosure(*zonename);
  676. const int diff = task->qname.getLabelCount() -
  677. enclosure.getLabelCount();
  678. string hash2;
  679. for (int i = 1; i <= diff; ++i) {
  680. enclosure = task->qname.split(i);
  681. string nodehash(nsec3->getHash(enclosure));
  682. if (nodehash == hash1) {
  683. break;
  684. }
  685. hash2 = nodehash;
  686. RRsetList rl;
  687. // hash2 will be overwritten with the actual hash found;
  688. // we don't want to use one until we find an exact match
  689. RETERR(getNsec3(q, zoneinfo, hash2, rrset));
  690. if (hash2 == nodehash) {
  691. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  692. break;
  693. }
  694. }
  695. // If we are processing a wildcard answer, we're done.
  696. if (wildcard) {
  697. return (DataSrc::SUCCESS);
  698. }
  699. // Otherwise, there is no wildcard record, so we must add a
  700. // covering NSEC3 to prove that it doesn't exist.
  701. string hash3(nsec3->getHash(Name("*").concatenate(enclosure)));
  702. RETERR(getNsec3(q, zoneinfo, hash3, rrset));
  703. if (hash3 != hash1 && hash3 != hash2) {
  704. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  705. }
  706. } else {
  707. Name nsecname(task->qname);
  708. if ((task->flags & DataSrc::NAME_NOT_FOUND) != 0 || wildcard) {
  709. const DataSrc* ds = zoneinfo.getDataSource();
  710. if (ds == NULL) {
  711. m.setRcode(Rcode::SERVFAIL());
  712. logger.error(DATASRC_QUERY_NO_DS_NSEC).arg(*zonename);
  713. return (DataSrc::ERROR);
  714. }
  715. ds->findPreviousName(task->qname, nsecname, zonename);
  716. }
  717. RETERR(addNSEC(q, nsecname, zoneinfo));
  718. if ((task->flags & DataSrc::TYPE_NOT_FOUND) != 0 ||
  719. nsecname == *zonename)
  720. {
  721. return (DataSrc::SUCCESS);
  722. }
  723. // If we are processing a wildcard answer, we're done.
  724. if (wildcard) {
  725. return (DataSrc::SUCCESS);
  726. }
  727. // Otherwise, there is no wildcard record, so we must add an
  728. // NSEC for the zone to prove the wildcard doesn't exist.
  729. RETERR(addNSEC(q, *zonename, zoneinfo));
  730. }
  731. return (DataSrc::SUCCESS);
  732. }
  733. // Attempt a wildcard lookup
  734. inline DataSrc::Result
  735. tryWildcard(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, bool& found) {
  736. LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_WILDCARD).arg(task->qname);
  737. Message& m = q.message();
  738. DataSrc::Result result;
  739. found = false;
  740. if ((task->flags & DataSrc::NAME_NOT_FOUND) == 0 ||
  741. (task->state != QueryTask::GETANSWER &&
  742. task->state != QueryTask::FOLLOWCNAME)) {
  743. return (DataSrc::SUCCESS);
  744. }
  745. const Name* const zonename = zoneinfo.getEnclosingZone();
  746. const int diff = task->qname.getLabelCount() - zonename->getLabelCount();
  747. if (diff < 1) {
  748. return (DataSrc::SUCCESS);
  749. }
  750. RRsetList wild;
  751. const Name star("*");
  752. bool cname = false;
  753. for (int i = 1; i <= diff; ++i) {
  754. const Name& wname(star.concatenate(task->qname.split(i)));
  755. QueryTask newtask(q, wname, task->qtype, Message::SECTION_ANSWER,
  756. QueryTask::AUTH_QUERY);
  757. result = doQueryTask(newtask, zoneinfo, wild);
  758. if (result == DataSrc::SUCCESS) {
  759. if (newtask.flags == 0) {
  760. task->flags &= ~DataSrc::NAME_NOT_FOUND;
  761. task->flags &= ~DataSrc::TYPE_NOT_FOUND;
  762. found = true;
  763. break;
  764. } else if ((newtask.flags & DataSrc::CNAME_FOUND) != 0) {
  765. task->flags &= ~DataSrc::NAME_NOT_FOUND;
  766. task->flags &= ~DataSrc::TYPE_NOT_FOUND;
  767. task->flags |= DataSrc::CNAME_FOUND;
  768. found = true;
  769. cname = true;
  770. break;
  771. } else if ((newtask.flags & DataSrc::TYPE_NOT_FOUND) != 0) {
  772. task->flags &= ~DataSrc::NAME_NOT_FOUND;
  773. task->flags |= DataSrc::TYPE_NOT_FOUND;
  774. break;
  775. }
  776. }
  777. }
  778. // A wildcard was found.
  779. if (found) {
  780. // Prove the nonexistence of the name we were looking for
  781. if (q.wantDnssec()) {
  782. result = proveNX(q, task, zoneinfo, true);
  783. if (result != DataSrc::SUCCESS) {
  784. m.setRcode(Rcode::SERVFAIL());
  785. logger.error(DATASRC_QUERY_WILDCARD_PROVE_NX_FAIL).
  786. arg(task->qname).arg(result);
  787. return (DataSrc::ERROR);
  788. }
  789. }
  790. // Add the data to the answer section (but with the name changed to
  791. // match the qname), and then continue as if this were a normal
  792. // answer: if a CNAME, chase the target, otherwise add authority.
  793. if (cname) {
  794. RRsetPtr rrset = findRRsetFromList(wild, RRType::CNAME());
  795. if (rrset != NULL) {
  796. rrset->setName(task->qname);
  797. addToMessage(q, Message::SECTION_ANSWER, rrset);
  798. chaseCname(q, task, rrset);
  799. }
  800. } else {
  801. BOOST_FOREACH (RRsetPtr rrset, wild) {
  802. rrset->setName(task->qname);
  803. addToMessage(q, Message::SECTION_ANSWER, rrset);
  804. }
  805. RRsetList auth;
  806. if (!refQuery(q, *zonename, zoneinfo, auth)) {
  807. logger.error(DATASRC_QUERY_WILDCARD_REFERRAL).arg(task->qname).
  808. arg(result);
  809. return (DataSrc::ERROR);
  810. }
  811. copyAuth(q, auth);
  812. }
  813. }
  814. return (DataSrc::SUCCESS);
  815. }
  816. //
  817. // doQuery: Processes a query.
  818. //
  819. void
  820. DataSrc::doQuery(Query& q) {
  821. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_QUERY_PROCESS).arg(q.qname()).
  822. arg(q.qtype()).arg(q.qclass());
  823. Message& m = q.message();
  824. vector<RRsetPtr> additional;
  825. // Record the fact that the query is being processed by the
  826. // current data source.
  827. q.setDatasrc(this);
  828. // Process the query task queue. (The queue is initialized
  829. // and the first task placed on it by the Query constructor.)
  830. m.setHeaderFlag(Message::HEADERFLAG_AA, false);
  831. while (!q.tasks().empty()) {
  832. QueryTaskPtr task = q.tasks().front();
  833. q.tasks().pop();
  834. // Can't query directly for RRSIG.
  835. if (task->qtype == RRType::RRSIG()) {
  836. m.setRcode(Rcode::REFUSED());
  837. logger.warn(DATASRC_QUERY_RRSIG).arg(task->qname);
  838. return;
  839. }
  840. // These task types should never be on the task queue.
  841. if (task->op == QueryTask::SIMPLE_QUERY ||
  842. task->op == QueryTask::REF_QUERY) {
  843. m.setRcode(Rcode::SERVFAIL());
  844. logger.error(DATASRC_QUERY_MISPLACED_TASK);
  845. return;
  846. }
  847. ZoneInfo zoneinfo(this, task->qname, task->qclass, task->qtype);
  848. RRsetList data;
  849. Result result = SUCCESS;
  850. // For these query task types, if there is more than
  851. // one level between the zone name and qname, we need to
  852. // check the intermediate nodes for referrals.
  853. if ((task->op == QueryTask::AUTH_QUERY ||
  854. task->op == QueryTask::NOGLUE_QUERY) &&
  855. hasDelegation(q, task, zoneinfo)) {
  856. continue;
  857. }
  858. result = doQueryTask(*task, zoneinfo, data);
  859. if (result != SUCCESS) {
  860. m.setRcode(Rcode::SERVFAIL());
  861. logger.error(DATASRC_QUERY_TASK_FAIL).arg(result);
  862. return;
  863. }
  864. // No such zone. If we're chasing cnames or adding additional
  865. // data, that's okay, but if doing an original query, return
  866. // REFUSED.
  867. if (task->flags == NO_SUCH_ZONE) {
  868. if (task->state == QueryTask::GETANSWER) {
  869. m.setRcode(Rcode::REFUSED());
  870. // No need to log it here, it was already logged in doQueryTask
  871. return;
  872. }
  873. continue;
  874. }
  875. // Query found a referral; let's find out if that was expected--
  876. // i.e., if an NS was at the zone apex, or if we were querying
  877. // specifically for, and found, a DS, NSEC, or DNAME record.
  878. const Name* const zonename = zoneinfo.getEnclosingZone();
  879. if ((task->flags & REFERRAL) != 0 &&
  880. (zonename->getLabelCount() == task->qname.getLabelCount() ||
  881. ((task->qtype == RRType::NSEC() ||
  882. task->qtype == RRType::DS() ||
  883. task->qtype == RRType::DNAME()) &&
  884. findRRsetFromList(data, task->qtype)))) {
  885. task->flags &= ~REFERRAL;
  886. }
  887. if (result == SUCCESS && task->flags == 0) {
  888. bool have_ns = false, need_auth = false;
  889. switch (task->state) {
  890. case QueryTask::GETANSWER:
  891. case QueryTask::FOLLOWCNAME:
  892. BOOST_FOREACH(RRsetPtr rrset, data) {
  893. addToMessage(q, task->section, rrset);
  894. if (q.tasks().empty()) {
  895. need_auth = true;
  896. }
  897. getAdditional(q, rrset);
  898. if (rrset->getType() == RRType::NS()) {
  899. have_ns = true;
  900. }
  901. }
  902. q.setStatus(Query::ANSWERED);
  903. if (need_auth && !have_ns) {
  904. // Data found, no additional processing needed.
  905. // Add the NS records for the enclosing zone to
  906. // the authority section.
  907. RRsetList auth;
  908. if (!refQuery(q, Name(*zonename), zoneinfo, auth) ||
  909. !findRRsetFromList(auth, RRType::NS())) {
  910. logger.error(DATASRC_QUERY_MISSING_NS).arg(*zonename);
  911. isc_throw(DataSourceError,
  912. "NS RR not found in " << *zonename << "/" <<
  913. q.qclass());
  914. }
  915. copyAuth(q, auth);
  916. }
  917. continue;
  918. case QueryTask::GETADDITIONAL:
  919. // Got additional data. Do not add it to the message
  920. // yet; instead store it and copy it in at the end
  921. // (this allow RRSIGs to be omitted if necessary).
  922. BOOST_FOREACH(RRsetPtr rrset, data) {
  923. if (q.status() == Query::ANSWERED &&
  924. rrset->getName() == q.qname() &&
  925. rrset->getType() == q.qtype()) {
  926. continue;
  927. }
  928. additional.push_back(rrset);
  929. }
  930. continue;
  931. default:
  932. logger.error(DATASRC_UNEXPECTED_QUERY_STATE);
  933. isc_throw (Unexpected, "unexpected query state");
  934. }
  935. } else if (result == ERROR || result == NOT_IMPLEMENTED) {
  936. m.setRcode(Rcode::SERVFAIL());
  937. logger.error(DATASRC_QUERY_FAIL);
  938. return;
  939. } else if ((task->flags & CNAME_FOUND) != 0) {
  940. // The qname node contains a CNAME. Add a new task to the
  941. // queue to look up its target.
  942. RRsetPtr rrset = findRRsetFromList(data, RRType::CNAME());
  943. if (rrset != NULL) {
  944. addToMessage(q, task->section, rrset);
  945. chaseCname(q, task, rrset);
  946. }
  947. continue;
  948. } else if ((task->flags & REFERRAL) != 0) {
  949. // The qname node contains an out-of-zone referral.
  950. if (task->state == QueryTask::GETANSWER) {
  951. RRsetList auth;
  952. m.setHeaderFlag(Message::HEADERFLAG_AA, false);
  953. if (!refQuery(q, task->qname, zoneinfo, auth)) {
  954. m.setRcode(Rcode::SERVFAIL());
  955. logger.error(DATASRC_QUERY_BAD_REFERRAL).arg(task->qname);
  956. return;
  957. }
  958. BOOST_FOREACH (RRsetPtr rrset, auth) {
  959. if (rrset->getType() == RRType::NS()) {
  960. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  961. } else if (rrset->getType() == task->qtype) {
  962. addToMessage(q, Message::SECTION_ANSWER, rrset);
  963. } else if (rrset->getType() == RRType::DS() &&
  964. q.wantDnssec()) {
  965. addToMessage(q, Message::SECTION_AUTHORITY, rrset);
  966. }
  967. getAdditional(q, rrset);
  968. }
  969. }
  970. continue;
  971. } else if ((task->flags & (NAME_NOT_FOUND|TYPE_NOT_FOUND)) != 0) {
  972. // No data found at this qname/qtype.
  973. // If we were looking for additional data, we should simply
  974. // ignore this result.
  975. if (task->state == QueryTask::GETADDITIONAL) {
  976. continue;
  977. }
  978. // If we were looking for answer data, not additional,
  979. // and the name was not found, we need to find out whether
  980. // there are any relevant wildcards.
  981. bool wildcard_found = false;
  982. result = tryWildcard(q, task, zoneinfo, wildcard_found);
  983. if (result != SUCCESS) {
  984. m.setRcode(Rcode::SERVFAIL());
  985. logger.error(DATASRC_QUERY_WILDCARD_FAIL).arg(task->qname);
  986. return;
  987. }
  988. if (wildcard_found) {
  989. continue;
  990. }
  991. // If we've reached this point, there is definitely no answer.
  992. // If we were chasing cnames or adding additional data, that's
  993. // okay, but if we were doing an original query, reply with the
  994. // SOA in the authority section. For NAME_NOT_FOUND, set
  995. // NXDOMAIN, and also add the previous NSEC to the authority
  996. // section. For TYPE_NOT_FOUND, do not set an error rcode,
  997. // and send the current NSEC in the authority section.
  998. if (task->state == QueryTask::GETANSWER) {
  999. if ((task->flags & NAME_NOT_FOUND) != 0) {
  1000. m.setRcode(Rcode::NXDOMAIN());
  1001. }
  1002. result = addSOA(q, zoneinfo);
  1003. if (result != SUCCESS) {
  1004. logger.error(DATASRC_QUERY_MISSING_SOA).arg(*zonename);
  1005. isc_throw(DataSourceError,
  1006. "SOA RR not found in " << *zonename <<
  1007. "/" << q.qclass());
  1008. }
  1009. }
  1010. Name nsecname(task->qname);
  1011. if ((task->flags & NAME_NOT_FOUND) != 0) {
  1012. const DataSrc* ds = zoneinfo.getDataSource();
  1013. ds->findPreviousName(task->qname, nsecname, zonename);
  1014. }
  1015. if (q.wantDnssec()) {
  1016. result = proveNX(q, task, zoneinfo, false);
  1017. if (result != DataSrc::SUCCESS) {
  1018. m.setRcode(Rcode::SERVFAIL());
  1019. logger.error(DATASRC_QUERY_PROVE_NX_FAIL).arg(task->qname);
  1020. return;
  1021. }
  1022. }
  1023. return;
  1024. } else {
  1025. // Should never be reached!
  1026. m.setRcode(Rcode::SERVFAIL());
  1027. logger.error(DATASRC_QUERY_UNKNOWN_RESULT);
  1028. return;
  1029. }
  1030. }
  1031. // We're done, so now copy in the additional data:
  1032. // data first, then signatures. (If we run out of
  1033. // space, signatures in additional section are
  1034. // optional.)
  1035. BOOST_FOREACH(RRsetPtr rrset, additional) {
  1036. addToMessage(q, Message::SECTION_ADDITIONAL, rrset, true);
  1037. }
  1038. if (q.wantDnssec()) {
  1039. BOOST_FOREACH(RRsetPtr rrset, additional) {
  1040. if (rrset->getRRsig()) {
  1041. addToMessage(q, Message::SECTION_ADDITIONAL, rrset->getRRsig(),
  1042. true);
  1043. }
  1044. }
  1045. }
  1046. }
  1047. DataSrc::Result
  1048. DataSrc::findAddrs(const Name& qname, const RRClass& qclass,
  1049. RRsetList& target, uint32_t& flags,
  1050. const Name* zonename) const
  1051. {
  1052. Result r;
  1053. bool a = false, aaaa = false;
  1054. flags = 0;
  1055. r = findExactRRset(qname, qclass, RRType::A(), target, flags, zonename);
  1056. if (r == SUCCESS && flags == 0) {
  1057. a = true;
  1058. }
  1059. flags = 0;
  1060. r = findExactRRset(qname, qclass, RRType::AAAA(), target, flags,
  1061. zonename);
  1062. if (r == SUCCESS && flags == 0) {
  1063. aaaa = true;
  1064. }
  1065. if (!a && !aaaa) {
  1066. flags = TYPE_NOT_FOUND;
  1067. } else {
  1068. flags = 0;
  1069. }
  1070. return (SUCCESS);
  1071. }
  1072. DataSrc::Result
  1073. DataSrc::findReferral(const Name& qname, const RRClass& qclass,
  1074. RRsetList& target, uint32_t& flags,
  1075. const Name* zonename) const
  1076. {
  1077. Result r;
  1078. bool ns = false, ds = false, dname = false;
  1079. flags = 0;
  1080. r = findExactRRset(qname, qclass, RRType::NS(), target, flags, zonename);
  1081. if (r == SUCCESS && flags == 0) {
  1082. ns = true;
  1083. } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
  1084. return (SUCCESS);
  1085. }
  1086. flags = 0;
  1087. r = findExactRRset(qname, qclass, RRType::DS(), target, flags, zonename);
  1088. if (r == SUCCESS && flags == 0) {
  1089. ds = true;
  1090. } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
  1091. return (SUCCESS);
  1092. }
  1093. flags = 0;
  1094. r = findExactRRset(qname, qclass, RRType::DNAME(), target, flags, zonename);
  1095. if (r == SUCCESS && flags == 0) {
  1096. dname = true;
  1097. } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
  1098. return (SUCCESS);
  1099. }
  1100. if (!ns && !dname && !ds) {
  1101. flags = TYPE_NOT_FOUND;
  1102. } else {
  1103. flags = 0;
  1104. }
  1105. return (SUCCESS);
  1106. }
  1107. void
  1108. MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src) {
  1109. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_META_ADD);
  1110. if (getClass() != RRClass::ANY() && data_src->getClass() != getClass()) {
  1111. logger.error(DATASRC_META_ADD_CLASS_MISMATCH).
  1112. arg(data_src->getClass()).arg(getClass());
  1113. isc_throw(Unexpected, "class mismatch");
  1114. }
  1115. data_sources.push_back(data_src);
  1116. }
  1117. void
  1118. MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src) {
  1119. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_META_REMOVE);
  1120. std::vector<ConstDataSrcPtr>::iterator it, itr;
  1121. for (it = data_sources.begin(); it != data_sources.end(); ++it) {
  1122. if (*it == data_src) {
  1123. itr = it;
  1124. }
  1125. }
  1126. data_sources.erase(itr);
  1127. }
  1128. void
  1129. MetaDataSrc::findClosestEnclosure(DataSrcMatch& match) const {
  1130. if (getClass() != match.getClass() &&
  1131. getClass() != RRClass::ANY() && match.getClass() != RRClass::ANY()) {
  1132. return;
  1133. }
  1134. BOOST_FOREACH (ConstDataSrcPtr data_src, data_sources) {
  1135. data_src->findClosestEnclosure(match);
  1136. }
  1137. }
  1138. DataSrcMatch::~DataSrcMatch() {
  1139. delete closest_name_;
  1140. }
  1141. void
  1142. DataSrcMatch::update(const DataSrc& new_source, const Name& container) {
  1143. if (getClass() != new_source.getClass() && getClass() != RRClass::ANY() &&
  1144. new_source.getClass() != RRClass::ANY())
  1145. {
  1146. return;
  1147. }
  1148. if (closest_name_ == NULL) {
  1149. const NameComparisonResult::NameRelation cmp =
  1150. getName().compare(container).getRelation();
  1151. if (cmp != NameComparisonResult::EQUAL &&
  1152. cmp != NameComparisonResult::SUBDOMAIN)
  1153. {
  1154. return;
  1155. }
  1156. closest_name_ = new Name(container);
  1157. best_source_ = &new_source;
  1158. return;
  1159. }
  1160. if (container.compare(*closest_name_).getRelation() ==
  1161. NameComparisonResult::SUBDOMAIN) {
  1162. Name* newname = new Name(container);
  1163. delete closest_name_;
  1164. closest_name_ = newname;
  1165. best_source_ = &new_source;
  1166. }
  1167. }
  1168. Nsec3Param::Nsec3Param(const uint8_t a, const uint8_t f, const uint16_t i,
  1169. const std::vector<uint8_t>& s) :
  1170. algorithm_(a), flags_(f), iterations_(i), salt_(s)
  1171. {}
  1172. string
  1173. Nsec3Param::getHash(const Name& name) const {
  1174. OutputBuffer buf(0);
  1175. name.toWire(buf);
  1176. uint8_t digest[SHA1_HASHSIZE];
  1177. const uint8_t* input = static_cast<const uint8_t*>(buf.getData());
  1178. size_t inlength = buf.getLength();
  1179. const uint8_t saltlen = salt_.size();
  1180. int n = 0;
  1181. SHA1Context sha;
  1182. do {
  1183. SHA1Reset(&sha);
  1184. SHA1Input(&sha, input, inlength);
  1185. SHA1Input(&sha, &salt_[0], saltlen);
  1186. SHA1Result(&sha, digest);
  1187. input = digest;
  1188. inlength = SHA1_HASHSIZE;
  1189. } while (n++ < iterations_);
  1190. return (encodeBase32Hex(vector<uint8_t>(digest, digest + SHA1_HASHSIZE)));
  1191. }
  1192. DataSrc::Result
  1193. DataSrc::init(isc::data::ConstElementPtr) {
  1194. return (NOT_IMPLEMENTED);
  1195. }
  1196. DataSrc::Result
  1197. MetaDataSrc::findRRset(const isc::dns::Name&,
  1198. const isc::dns::RRClass&,
  1199. const isc::dns::RRType&,
  1200. isc::dns::RRsetList&,
  1201. uint32_t&,
  1202. const isc::dns::Name*) const
  1203. {
  1204. return (NOT_IMPLEMENTED);
  1205. }
  1206. DataSrc::Result
  1207. MetaDataSrc::findExactRRset(const isc::dns::Name&,
  1208. const isc::dns::RRClass&,
  1209. const isc::dns::RRType&,
  1210. isc::dns::RRsetList&,
  1211. uint32_t&,
  1212. const isc::dns::Name*) const
  1213. {
  1214. return (NOT_IMPLEMENTED);
  1215. }
  1216. DataSrc::Result
  1217. MetaDataSrc::findAddrs(const isc::dns::Name&,
  1218. const isc::dns::RRClass&,
  1219. isc::dns::RRsetList&,
  1220. uint32_t&,
  1221. const isc::dns::Name*) const
  1222. {
  1223. return (NOT_IMPLEMENTED);
  1224. }
  1225. DataSrc::Result
  1226. MetaDataSrc::findReferral(const isc::dns::Name&,
  1227. const isc::dns::RRClass&,
  1228. isc::dns::RRsetList&,
  1229. uint32_t&,
  1230. const isc::dns::Name*) const
  1231. {
  1232. return (NOT_IMPLEMENTED);
  1233. }
  1234. DataSrc::Result
  1235. MetaDataSrc::findPreviousName(const isc::dns::Name&,
  1236. isc::dns::Name&,
  1237. const isc::dns::Name*) const
  1238. {
  1239. return (NOT_IMPLEMENTED);
  1240. }
  1241. DataSrc::Result
  1242. MetaDataSrc::findCoveringNSEC3(const isc::dns::Name&,
  1243. std::string&,
  1244. isc::dns::RRsetList&) const
  1245. {
  1246. return (NOT_IMPLEMENTED);
  1247. }
  1248. }
  1249. }