sqlite3_datasrc.cc 32 KB

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