sqlite3_datasrc.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  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 <string>
  15. #include <sstream>
  16. #include <sqlite3.h>
  17. #include <datasrc/sqlite3_datasrc.h>
  18. #include <datasrc/logger.h>
  19. #include <dns/rrttl.h>
  20. #include <dns/rdata.h>
  21. #include <dns/rdataclass.h>
  22. #include <dns/rrset.h>
  23. #include <dns/rrsetlist.h>
  24. using namespace std;
  25. using namespace isc::dns;
  26. using namespace isc::dns::rdata;
  27. namespace isc {
  28. namespace datasrc {
  29. struct Sqlite3Parameters {
  30. Sqlite3Parameters() : db_(NULL), version_(-1),
  31. q_zone_(NULL), q_record_(NULL), q_addrs_(NULL), q_referral_(NULL),
  32. q_any_(NULL), q_count_(NULL), q_previous_(NULL), q_nsec3_(NULL),
  33. q_prevnsec3_(NULL)
  34. {}
  35. sqlite3* db_;
  36. int version_;
  37. sqlite3_stmt* q_zone_;
  38. sqlite3_stmt* q_record_;
  39. sqlite3_stmt* q_addrs_;
  40. sqlite3_stmt* q_referral_;
  41. sqlite3_stmt* q_any_;
  42. sqlite3_stmt* q_count_;
  43. sqlite3_stmt* q_previous_;
  44. sqlite3_stmt* q_nsec3_;
  45. sqlite3_stmt* q_prevnsec3_;
  46. };
  47. namespace {
  48. const char* const SCHEMA_LIST[] = {
  49. "CREATE TABLE schema_version (version INTEGER NOT NULL)",
  50. "INSERT INTO schema_version VALUES (1)",
  51. "CREATE TABLE zones (id INTEGER PRIMARY KEY, "
  52. "name STRING NOT NULL COLLATE NOCASE, "
  53. "rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN', "
  54. "dnssec BOOLEAN NOT NULL DEFAULT 0)",
  55. "CREATE INDEX zones_byname ON zones (name)",
  56. "CREATE TABLE records (id INTEGER PRIMARY KEY, "
  57. "zone_id INTEGER NOT NULL, name STRING NOT NULL COLLATE NOCASE, "
  58. "rname STRING NOT NULL COLLATE NOCASE, ttl INTEGER NOT NULL, "
  59. "rdtype STRING NOT NULL COLLATE NOCASE, sigtype STRING COLLATE NOCASE, "
  60. "rdata STRING NOT NULL)",
  61. "CREATE INDEX records_byname ON records (name)",
  62. "CREATE INDEX records_byrname ON records (rname)",
  63. "CREATE TABLE nsec3 (id INTEGER PRIMARY KEY, zone_id INTEGER NOT NULL, "
  64. "hash STRING NOT NULL COLLATE NOCASE, "
  65. "owner STRING NOT NULL COLLATE NOCASE, "
  66. "ttl INTEGER NOT NULL, rdtype STRING NOT NULL COLLATE NOCASE, "
  67. "rdata STRING NOT NULL)",
  68. "CREATE INDEX nsec3_byhash ON nsec3 (hash)",
  69. NULL
  70. };
  71. const char* const q_zone_str = "SELECT id FROM zones WHERE name=?1";
  72. const char* const q_record_str = "SELECT rdtype, ttl, sigtype, rdata "
  73. "FROM records WHERE zone_id=?1 AND name=?2 AND "
  74. "((rdtype=?3 OR sigtype=?3) OR "
  75. "(rdtype='CNAME' OR sigtype='CNAME') OR "
  76. "(rdtype='NS' OR sigtype='NS'))";
  77. const char* const q_addrs_str = "SELECT rdtype, ttl, sigtype, rdata "
  78. "FROM records WHERE zone_id=?1 AND name=?2 AND "
  79. "(rdtype='A' OR sigtype='A' OR rdtype='AAAA' OR sigtype='AAAA')";
  80. const char* const q_referral_str = "SELECT rdtype, ttl, sigtype, rdata FROM "
  81. "records WHERE zone_id=?1 AND name=?2 AND"
  82. "(rdtype='NS' OR sigtype='NS' OR rdtype='DS' OR sigtype='DS' OR "
  83. "rdtype='DNAME' OR sigtype='DNAME')";
  84. const char* const q_any_str = "SELECT rdtype, ttl, sigtype, rdata "
  85. "FROM records WHERE zone_id=?1 AND name=?2";
  86. const char* const q_count_str = "SELECT COUNT(*) FROM records "
  87. "WHERE zone_id=?1 AND rname LIKE (?2 || '%');";
  88. const char* const q_previous_str = "SELECT name FROM records "
  89. "WHERE zone_id=?1 AND rdtype = 'NSEC' AND "
  90. "rname < $2 ORDER BY rname DESC LIMIT 1";
  91. const char* const q_nsec3_str = "SELECT rdtype, ttl, rdata FROM nsec3 "
  92. "WHERE zone_id = ?1 AND hash = $2";
  93. const char* const q_prevnsec3_str = "SELECT hash FROM nsec3 "
  94. "WHERE zone_id = ?1 AND hash <= $2 ORDER BY hash DESC LIMIT 1";
  95. }
  96. //
  97. // Find the exact zone match. Return -1 if not found, or the zone's
  98. // ID if found. This will always be >= 0 if found.
  99. //
  100. int
  101. Sqlite3DataSrc::hasExactZone(const char* const name) const {
  102. int rc;
  103. sqlite3_reset(dbparameters->q_zone_);
  104. rc = sqlite3_bind_text(dbparameters->q_zone_, 1, name, -1, SQLITE_STATIC);
  105. if (rc != SQLITE_OK) {
  106. isc_throw(Sqlite3Error, "Could not bind " << name <<
  107. " to SQL statement (zone)");
  108. }
  109. rc = sqlite3_step(dbparameters->q_zone_);
  110. const int i = (rc == SQLITE_ROW) ?
  111. sqlite3_column_int(dbparameters->q_zone_, 0) : -1;
  112. sqlite3_reset(dbparameters->q_zone_);
  113. return (i);
  114. }
  115. namespace {
  116. int
  117. importSqlite3Rows(sqlite3_stmt* query, const Name& qname, const RRClass& qclass,
  118. const RRType& qtype, const bool nsec3_tree,
  119. RRsetList& result_sets, uint32_t& flags)
  120. {
  121. int rows = 0;
  122. int rc = sqlite3_step(query);
  123. const bool qtype_is_any = (qtype == RRType::ANY());
  124. while (rc == SQLITE_ROW) {
  125. const char* type = (const char*)sqlite3_column_text(query, 0);
  126. int ttl = sqlite3_column_int(query, 1);
  127. const char* sigtype = NULL;
  128. const char* rdata;
  129. if (nsec3_tree) {
  130. rdata = (const char*)sqlite3_column_text(query, 2);
  131. if (RRType(type) == RRType::RRSIG()) {
  132. sigtype = "NSEC3";
  133. }
  134. } else {
  135. sigtype = (const char*)sqlite3_column_text(query, 2);
  136. rdata = (const char*)sqlite3_column_text(query, 3);
  137. }
  138. const RRType base_rrtype(sigtype != NULL ? sigtype : type);
  139. // found an NS; we need to inform the caller that this might be a
  140. // referral, but we do not return the NS RRset to the caller
  141. // unless asked for it.
  142. if (base_rrtype == RRType::NS()) {
  143. flags |= DataSrc::REFERRAL;
  144. if (!qtype_is_any && qtype != RRType::NS()) {
  145. rc = sqlite3_step(query);
  146. continue;
  147. }
  148. }
  149. ++rows;
  150. // Looking for something else but found CNAME
  151. if (base_rrtype == RRType::CNAME() && qtype != RRType::CNAME()) {
  152. if (qtype == RRType::NSEC()) {
  153. // NSEC query, just skip the CNAME
  154. rc = sqlite3_step(query);
  155. continue;
  156. } else if (!qtype_is_any) {
  157. // include the CNAME, but don't flag it for chasing if
  158. // this is an ANY query
  159. flags |= DataSrc::CNAME_FOUND;
  160. }
  161. }
  162. RRsetPtr rrset = result_sets.findRRset(base_rrtype, qclass);
  163. if (rrset == NULL) {
  164. rrset = RRsetPtr(new RRset(qname, qclass, base_rrtype, RRTTL(ttl)));
  165. result_sets.addRRset(rrset);
  166. }
  167. if (sigtype == NULL && base_rrtype == rrset->getType()) {
  168. rrset->addRdata(createRdata(rrset->getType(), qclass, rdata));
  169. if (ttl > rrset->getTTL().getValue()) {
  170. rrset->setTTL(RRTTL(ttl));
  171. }
  172. } else if (sigtype != NULL && base_rrtype == rrset->getType()) {
  173. RdataPtr rrsig = createRdata(RRType::RRSIG(), qclass, rdata);
  174. if (rrset->getRRsig()) {
  175. rrset->getRRsig()->addRdata(rrsig);
  176. } else {
  177. RRsetPtr sigs = RRsetPtr(new RRset(qname, qclass,
  178. RRType::RRSIG(),
  179. RRTTL(ttl)));
  180. sigs->addRdata(rrsig);
  181. rrset->addRRsig(sigs);
  182. }
  183. if (ttl > rrset->getRRsig()->getTTL().getValue()) {
  184. rrset->getRRsig()->setTTL(RRTTL(ttl));
  185. }
  186. }
  187. rc = sqlite3_step(query);
  188. }
  189. return (rows);
  190. }
  191. }
  192. int
  193. Sqlite3DataSrc::findRecords(const Name& name, const RRType& rdtype,
  194. RRsetList& target, const Name* zonename,
  195. const Mode mode, uint32_t& flags) const
  196. {
  197. if (logger.isDebugEnabled(DBG_TRACE_DETAILED)) {
  198. logger.debug(DBG_TRACE_DETAILED, DATASRC_SQLITE_FINDREC,
  199. name.toText().c_str(), rdtype.toText().c_str());
  200. }
  201. flags = 0;
  202. int zone_id = (zonename == NULL) ? findClosest(name, NULL) :
  203. findClosest(*zonename, NULL);
  204. if (zone_id < 0) {
  205. flags = NO_SUCH_ZONE;
  206. return (0);
  207. }
  208. sqlite3_stmt* query;
  209. switch (mode) {
  210. case ADDRESS:
  211. query = dbparameters->q_addrs_;
  212. break;
  213. case DELEGATION:
  214. query = dbparameters->q_referral_;
  215. break;
  216. default:
  217. if (rdtype == RRType::ANY()) {
  218. query = dbparameters->q_any_;
  219. } else {
  220. query = dbparameters->q_record_;
  221. }
  222. break;
  223. }
  224. sqlite3_reset(query);
  225. sqlite3_clear_bindings(query);
  226. int rc;
  227. rc = sqlite3_bind_int(query, 1, zone_id);
  228. if (rc != SQLITE_OK) {
  229. isc_throw(Sqlite3Error, "Could not bind zone ID " << zone_id <<
  230. " to SQL statement (query)");
  231. }
  232. const string name_text = name.toText();
  233. rc = sqlite3_bind_text(query, 2, name_text.c_str(), -1, SQLITE_STATIC);
  234. if (rc != SQLITE_OK) {
  235. isc_throw(Sqlite3Error, "Could not bind name " << name_text <<
  236. " to SQL statement (query)");
  237. }
  238. const string rdtype_text = rdtype.toText();
  239. if (query == dbparameters->q_record_) {
  240. rc = sqlite3_bind_text(query, 3, rdtype_text.c_str(), -1,
  241. SQLITE_STATIC);
  242. if (rc != SQLITE_OK) {
  243. isc_throw(Sqlite3Error, "Could not bind RR type " <<
  244. rdtype.toText() << " to SQL statement (query)");
  245. }
  246. }
  247. const int rows = importSqlite3Rows(query, name, getClass(), rdtype, false,
  248. target, flags);
  249. sqlite3_reset(query);
  250. if (rows > 0) {
  251. return (rows);
  252. }
  253. //
  254. // No rows were found. We need to find out whether there are
  255. // any RRs with that name to determine whether this is NXDOMAIN or
  256. // NXRRSET
  257. //
  258. sqlite3_reset(dbparameters->q_count_);
  259. sqlite3_clear_bindings(dbparameters->q_count_);
  260. rc = sqlite3_bind_int(dbparameters->q_count_, 1, zone_id);
  261. if (rc != SQLITE_OK) {
  262. isc_throw(Sqlite3Error, "Could not bind zone ID " << zone_id <<
  263. " to SQL statement (qcount)");
  264. }
  265. const string revname_text = name.reverse().toText();
  266. rc = sqlite3_bind_text(dbparameters->q_count_, 2, revname_text.c_str(),
  267. -1, SQLITE_STATIC);
  268. if (rc != SQLITE_OK) {
  269. isc_throw(Sqlite3Error, "Could not bind name " << name.reverse() <<
  270. " to SQL statement (qcount)");
  271. }
  272. rc = sqlite3_step(dbparameters->q_count_);
  273. if (rc == SQLITE_ROW) {
  274. if (sqlite3_column_int(dbparameters->q_count_, 0) != 0) {
  275. flags |= TYPE_NOT_FOUND;
  276. sqlite3_reset(dbparameters->q_count_);
  277. return (0);
  278. }
  279. }
  280. flags |= NAME_NOT_FOUND;
  281. sqlite3_reset(dbparameters->q_count_);
  282. return (0);
  283. }
  284. //
  285. // Search for the closest enclosing zone. Will return -1 if not found,
  286. // >= 0 if found. If position is not NULL, it will be filled in with the
  287. // longest match found.
  288. //
  289. int
  290. Sqlite3DataSrc::findClosest(const Name& name, unsigned int* position) const {
  291. const unsigned int nlabels = name.getLabelCount();
  292. for (unsigned int i = 0; i < nlabels; ++i) {
  293. const Name matchname(name.split(i));
  294. const int rc = hasExactZone(matchname.toText().c_str());
  295. if (rc >= 0) {
  296. if (position != NULL) {
  297. *position = i;
  298. }
  299. return (rc);
  300. }
  301. }
  302. return (-1);
  303. }
  304. void
  305. Sqlite3DataSrc::findClosestEnclosure(DataSrcMatch& match) const {
  306. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  307. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_ENCLOSURE,
  308. match.getName().toText().c_str());
  309. }
  310. if (match.getClass() != getClass() && match.getClass() != RRClass::ANY()) {
  311. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_ENCLOSURE_BAD_CLASS,
  312. getClass().toText().c_str(),
  313. match.getClass().toText().c_str());
  314. return;
  315. }
  316. unsigned int position;
  317. if (findClosest(match.getName(), &position) == -1) {
  318. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_ENCLOSURE_NOTFOUND);
  319. return;
  320. }
  321. match.update(*this, match.getName().split(position));
  322. }
  323. DataSrc::Result
  324. Sqlite3DataSrc::findPreviousName(const Name& qname,
  325. Name& target,
  326. const Name* zonename) const
  327. {
  328. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  329. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_PREVIOUS,
  330. qname.toText().c_str());
  331. }
  332. const int zone_id = (zonename == NULL) ?
  333. findClosest(qname, NULL) : findClosest(*zonename, NULL);
  334. if (zone_id < 0) {
  335. logger.error(DATASRC_SQLITE_PREVIOUS_NO_ZONE, qname.toText().c_str());
  336. return (ERROR);
  337. }
  338. sqlite3_reset(dbparameters->q_previous_);
  339. sqlite3_clear_bindings(dbparameters->q_previous_);
  340. int rc = sqlite3_bind_int(dbparameters->q_previous_, 1, zone_id);
  341. if (rc != SQLITE_OK) {
  342. isc_throw(Sqlite3Error, "Could not bind zone ID " << zone_id <<
  343. " to SQL statement (qprevious)");
  344. }
  345. const string revname_text = qname.reverse().toText();
  346. rc = sqlite3_bind_text(dbparameters->q_previous_, 2,
  347. revname_text.c_str(), -1, SQLITE_STATIC);
  348. if (rc != SQLITE_OK) {
  349. isc_throw(Sqlite3Error, "Could not bind name " << qname <<
  350. " to SQL statement (qprevious)");
  351. }
  352. rc = sqlite3_step(dbparameters->q_previous_);
  353. if (rc != SQLITE_ROW) {
  354. sqlite3_reset(dbparameters->q_previous_);
  355. return (ERROR);
  356. }
  357. // XXX: bad cast. we should revisit this.
  358. target = Name((const char*)sqlite3_column_text(dbparameters->q_previous_,
  359. 0));
  360. sqlite3_reset(dbparameters->q_previous_);
  361. return (SUCCESS);
  362. }
  363. DataSrc::Result
  364. Sqlite3DataSrc::findCoveringNSEC3(const Name& zonename,
  365. string& hashstr,
  366. RRsetList& target) const
  367. {
  368. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  369. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_FIND_NSEC3,
  370. zonename.toText().c_str(), hashstr.c_str());
  371. }
  372. const int zone_id = findClosest(zonename, NULL);
  373. if (zone_id < 0) {
  374. logger.error(DATASRC_SQLITE_FIND_NSEC3_NO_ZONE,
  375. zonename.toText().c_str());
  376. return (ERROR);
  377. }
  378. sqlite3_reset(dbparameters->q_prevnsec3_);
  379. sqlite3_clear_bindings(dbparameters->q_prevnsec3_);
  380. int rc = sqlite3_bind_int(dbparameters->q_prevnsec3_, 1, zone_id);
  381. if (rc != SQLITE_OK) {
  382. isc_throw(Sqlite3Error, "Could not bind zone ID " << zone_id <<
  383. " to SQL statement (previous NSEC3)");
  384. }
  385. rc = sqlite3_bind_text(dbparameters->q_prevnsec3_, 2, hashstr.c_str(),
  386. -1, SQLITE_STATIC);
  387. if (rc != SQLITE_OK) {
  388. isc_throw(Sqlite3Error, "Could not bind hash " << hashstr <<
  389. " to SQL statement (previous NSEC3)");
  390. }
  391. rc = sqlite3_step(dbparameters->q_prevnsec3_);
  392. const char* hash;
  393. if (rc == SQLITE_ROW) {
  394. hash = (const char*) sqlite3_column_text(dbparameters->q_prevnsec3_, 0);
  395. } else {
  396. // We need to find the final NSEC3 in the chain.
  397. // A valid NSEC3 hash is in base32, which contains no
  398. // letters higher than V, so a search for the previous
  399. // NSEC3 from "w" will always find it.
  400. sqlite3_reset(dbparameters->q_prevnsec3_);
  401. rc = sqlite3_bind_text(dbparameters->q_prevnsec3_, 2, "w", -1,
  402. SQLITE_STATIC);
  403. if (rc != SQLITE_OK) {
  404. isc_throw(Sqlite3Error, "Could not bind \"w\""
  405. " to SQL statement (previous NSEC3)");
  406. }
  407. rc = sqlite3_step(dbparameters->q_prevnsec3_);
  408. if (rc != SQLITE_ROW) {
  409. return (ERROR);
  410. }
  411. hash = (const char*) sqlite3_column_text(dbparameters->q_prevnsec3_, 0);
  412. }
  413. sqlite3_reset(dbparameters->q_nsec3_);
  414. sqlite3_clear_bindings(dbparameters->q_nsec3_);
  415. rc = sqlite3_bind_int(dbparameters->q_nsec3_, 1, zone_id);
  416. if (rc != SQLITE_OK) {
  417. isc_throw(Sqlite3Error, "Could not bind zone ID " << zone_id <<
  418. " to SQL statement (NSEC3)");
  419. }
  420. rc = sqlite3_bind_text(dbparameters->q_nsec3_, 2, hash, -1, SQLITE_STATIC);
  421. if (rc != SQLITE_OK) {
  422. isc_throw(Sqlite3Error, "Could not bind hash " << hash <<
  423. " to SQL statement (NSEC3)");
  424. }
  425. DataSrc::Result result = SUCCESS;
  426. uint32_t flags = 0;
  427. if (importSqlite3Rows(dbparameters->q_nsec3_,
  428. Name(hash).concatenate(zonename),
  429. getClass(), RRType::NSEC3(), true, target,
  430. flags) == 0 || flags != 0) {
  431. result = ERROR;
  432. }
  433. hashstr = string(hash);
  434. sqlite3_reset(dbparameters->q_nsec3_);
  435. return (result);
  436. }
  437. DataSrc::Result
  438. Sqlite3DataSrc::findRRset(const Name& qname,
  439. const RRClass& qclass,
  440. const RRType& qtype,
  441. RRsetList& target,
  442. uint32_t& flags,
  443. const Name* zonename) const
  444. {
  445. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  446. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_FIND,
  447. qname.toText().c_str(), qtype.toText().c_str());
  448. }
  449. if (qclass != getClass() && qclass != RRClass::ANY()) {
  450. logger.error(DATASRC_SQLITE_FIND_BAD_CLASS,
  451. getClass().toText().c_str(), qclass.toText().c_str());
  452. return (ERROR);
  453. }
  454. findRecords(qname, qtype, target, zonename, NORMAL, flags);
  455. return (SUCCESS);
  456. }
  457. DataSrc::Result
  458. Sqlite3DataSrc::findExactRRset(const Name& qname,
  459. const RRClass& qclass,
  460. const RRType& qtype,
  461. RRsetList& target,
  462. uint32_t& flags,
  463. const Name* zonename) const
  464. {
  465. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  466. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_FINDEXACT,
  467. qname.toText().c_str(), qtype.toText().c_str());
  468. }
  469. if (qclass != getClass() && qclass != RRClass::ANY()) {
  470. logger.error(DATASRC_SQLITE_FINDEXACT_BAD_CLASS,
  471. getClass().toText().c_str(), qclass.toText().c_str());
  472. return (ERROR);
  473. }
  474. findRecords(qname, qtype, target, zonename, NORMAL, flags);
  475. // Ignore referrals in this case
  476. flags &= ~REFERRAL;
  477. // CNAMEs don't count in this case
  478. if (flags & CNAME_FOUND) {
  479. flags &= ~CNAME_FOUND;
  480. flags |= TYPE_NOT_FOUND;
  481. }
  482. return (SUCCESS);
  483. }
  484. DataSrc::Result
  485. Sqlite3DataSrc::findAddrs(const Name& qname,
  486. const RRClass& qclass,
  487. RRsetList& target,
  488. uint32_t& flags,
  489. const Name* zonename) const
  490. {
  491. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  492. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_FINDADDRS,
  493. qname.toText().c_str());
  494. }
  495. if (qclass != getClass() && qclass != RRClass::ANY()) {
  496. logger.error(DATASRC_SQLITE_FINDADDRS_BAD_CLASS,
  497. getClass().toText().c_str(), qclass.toText().c_str());
  498. return (ERROR);
  499. }
  500. findRecords(qname, RRType::ANY(), target, zonename, ADDRESS, flags);
  501. return (SUCCESS);
  502. }
  503. DataSrc::Result
  504. Sqlite3DataSrc::findReferral(const Name& qname,
  505. const RRClass& qclass,
  506. RRsetList& target,
  507. uint32_t& flags,
  508. const Name* zonename) const
  509. {
  510. if (logger.isDebugEnabled(DBG_TRACE_DATA)) {
  511. logger.debug(DBG_TRACE_DATA, DATASRC_SQLITE_FINDREF,
  512. qname.toText().c_str());
  513. }
  514. if (qclass != getClass() && qclass != RRClass::ANY()) {
  515. logger.error(DATASRC_SQLITE_FINDREF_BAD_CLASS,
  516. getClass().toText().c_str(), qclass.toText().c_str());
  517. return (ERROR);
  518. }
  519. findRecords(qname, RRType::ANY(), target, zonename, DELEGATION, flags);
  520. return (SUCCESS);
  521. }
  522. Sqlite3DataSrc::Sqlite3DataSrc() :
  523. dbparameters(new Sqlite3Parameters)
  524. {
  525. logger.debug(DBG_TRACE_BASIC, DATASRC_SQLITE_CREATE);
  526. }
  527. Sqlite3DataSrc::~Sqlite3DataSrc() {
  528. logger.debug(DBG_TRACE_BASIC, DATASRC_SQLITE_DESTROY);
  529. if (dbparameters->db_ != NULL) {
  530. close();
  531. }
  532. delete dbparameters;
  533. }
  534. DataSrc::Result
  535. Sqlite3DataSrc::init(isc::data::ConstElementPtr config) {
  536. if (config && config->contains("database_file")) {
  537. open(config->get("database_file")->stringValue());
  538. } else {
  539. isc_throw(DataSourceError, "No SQLite database file specified");
  540. }
  541. return (SUCCESS);
  542. }
  543. namespace {
  544. // This is a helper class to initialize a Sqlite3 DB safely. An object of
  545. // this class encapsulates all temporary resources that are necessary for
  546. // the initialization, and release them in the destructor. Once everything
  547. // is properly initialized, the move() method moves the allocated resources
  548. // to the main object in an exception free manner. This way, the main code
  549. // for the initialization can be exception safe, and can provide the strong
  550. // exception guarantee.
  551. class Sqlite3Initializer {
  552. public:
  553. ~Sqlite3Initializer() {
  554. if (params_.q_zone_ != NULL) {
  555. sqlite3_finalize(params_.q_zone_);
  556. }
  557. if (params_.q_record_ != NULL) {
  558. sqlite3_finalize(params_.q_record_);
  559. }
  560. if (params_.q_addrs_ != NULL) {
  561. sqlite3_finalize(params_.q_addrs_);
  562. }
  563. if (params_.q_referral_ != NULL) {
  564. sqlite3_finalize(params_.q_referral_);
  565. }
  566. if (params_.q_any_ != NULL) {
  567. sqlite3_finalize(params_.q_any_);
  568. }
  569. if (params_.q_count_ != NULL) {
  570. sqlite3_finalize(params_.q_count_);
  571. }
  572. if (params_.q_previous_ != NULL) {
  573. sqlite3_finalize(params_.q_previous_);
  574. }
  575. if (params_.q_nsec3_ != NULL) {
  576. sqlite3_finalize(params_.q_nsec3_);
  577. }
  578. if (params_.q_prevnsec3_ != NULL) {
  579. sqlite3_finalize(params_.q_prevnsec3_);
  580. }
  581. if (params_.db_ != NULL) {
  582. sqlite3_close(params_.db_);
  583. }
  584. }
  585. void move(Sqlite3Parameters* dst) {
  586. *dst = params_;
  587. params_ = Sqlite3Parameters(); // clear everything
  588. }
  589. Sqlite3Parameters params_;
  590. };
  591. sqlite3_stmt*
  592. prepare(sqlite3* const db, const char* const statement) {
  593. sqlite3_stmt* prepared = NULL;
  594. if (sqlite3_prepare_v2(db, statement, -1, &prepared, NULL) != SQLITE_OK) {
  595. isc_throw(Sqlite3Error, "Could not prepare SQLite statement: " <<
  596. statement);
  597. }
  598. return (prepared);
  599. }
  600. void
  601. checkAndSetupSchema(Sqlite3Initializer* initializer) {
  602. sqlite3* const db = initializer->params_.db_;
  603. sqlite3_stmt* prepared = NULL;
  604. if (sqlite3_prepare_v2(db, "SELECT version FROM schema_version", -1,
  605. &prepared, NULL) == SQLITE_OK &&
  606. sqlite3_step(prepared) == SQLITE_ROW) {
  607. initializer->params_.version_ = sqlite3_column_int(prepared, 0);
  608. sqlite3_finalize(prepared);
  609. } else {
  610. logger.info(DATASRC_SQLITE_SETUP);
  611. if (prepared != NULL) {
  612. sqlite3_finalize(prepared);
  613. }
  614. for (int i = 0; SCHEMA_LIST[i] != NULL; ++i) {
  615. if (sqlite3_exec(db, SCHEMA_LIST[i], NULL, NULL, NULL) !=
  616. SQLITE_OK) {
  617. isc_throw(Sqlite3Error,
  618. "Failed to set up schema " << SCHEMA_LIST[i]);
  619. }
  620. }
  621. }
  622. initializer->params_.q_zone_ = prepare(db, q_zone_str);
  623. initializer->params_.q_record_ = prepare(db, q_record_str);
  624. initializer->params_.q_addrs_ = prepare(db, q_addrs_str);
  625. initializer->params_.q_referral_ = prepare(db, q_referral_str);
  626. initializer->params_.q_any_ = prepare(db, q_any_str);
  627. initializer->params_.q_count_ = prepare(db, q_count_str);
  628. initializer->params_.q_previous_ = prepare(db, q_previous_str);
  629. initializer->params_.q_nsec3_ = prepare(db, q_nsec3_str);
  630. initializer->params_.q_prevnsec3_ = prepare(db, q_prevnsec3_str);
  631. }
  632. }
  633. //
  634. // Open the database.
  635. //
  636. void
  637. Sqlite3DataSrc::open(const string& name) {
  638. logger.debug(DBG_TRACE_BASIC, DATASRC_SQLITE_OPEN, name.c_str());
  639. if (dbparameters->db_ != NULL) {
  640. isc_throw(DataSourceError, "Duplicate SQLite open with " << name);
  641. }
  642. Sqlite3Initializer initializer;
  643. if (sqlite3_open(name.c_str(), &initializer.params_.db_) != 0) {
  644. isc_throw(Sqlite3Error, "Cannot open SQLite database file: " << name);
  645. }
  646. checkAndSetupSchema(&initializer);
  647. initializer.move(dbparameters);
  648. }
  649. //
  650. // Close the database.
  651. //
  652. DataSrc::Result
  653. Sqlite3DataSrc::close(void) {
  654. logger.debug(DBG_TRACE_BASIC, DATASRC_SQLITE_CLOSE);
  655. if (dbparameters->db_ == NULL) {
  656. isc_throw(DataSourceError,
  657. "SQLite data source is being closed before open");
  658. }
  659. // XXX: sqlite3_finalize() could fail. What should we do in that case?
  660. sqlite3_finalize(dbparameters->q_zone_);
  661. dbparameters->q_zone_ = NULL;
  662. sqlite3_finalize(dbparameters->q_record_);
  663. dbparameters->q_record_ = NULL;
  664. sqlite3_finalize(dbparameters->q_addrs_);
  665. dbparameters->q_addrs_ = NULL;
  666. sqlite3_finalize(dbparameters->q_referral_);
  667. dbparameters->q_referral_ = NULL;
  668. sqlite3_finalize(dbparameters->q_any_);
  669. dbparameters->q_any_ = NULL;
  670. sqlite3_finalize(dbparameters->q_count_);
  671. dbparameters->q_count_ = NULL;
  672. sqlite3_finalize(dbparameters->q_previous_);
  673. dbparameters->q_previous_ = NULL;
  674. sqlite3_finalize(dbparameters->q_prevnsec3_);
  675. dbparameters->q_prevnsec3_ = NULL;
  676. sqlite3_finalize(dbparameters->q_nsec3_);
  677. dbparameters->q_nsec3_ = NULL;
  678. sqlite3_close(dbparameters->db_);
  679. dbparameters->db_ = NULL;
  680. return (SUCCESS);
  681. }
  682. }
  683. }