sqlite3_datasrc.cc 27 KB

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