sqlite3_datasrc.cc 28 KB

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