You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1949 lines
58 KiB

  1. /*
  2. * This file is part of GNUnet
  3. * Copyright (C) 2013 GNUnet e.V.
  4. *
  5. * GNUnet is free software: you can redistribute it and/or modify it
  6. * under the terms of the GNU Affero General Public License as published
  7. * by the Free Software Foundation, either version 3 of the License,
  8. * or (at your option) any later version.
  9. *
  10. * GNUnet is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. SPDX-License-Identifier: AGPL3.0-or-later
  18. */
  19. /**
  20. * @file psycstore/plugin_psycstore_sqlite.c
  21. * @brief sqlite-based psycstore backend
  22. * @author Gabor X Toth
  23. * @author Christian Grothoff
  24. */
  25. /*
  26. * FIXME: SQLite3 only supports signed 64-bit integers natively,
  27. * thus it can only store 63 bits of the uint64_t's.
  28. */
  29. #include "platform.h"
  30. #include "gnunet_psycstore_plugin.h"
  31. #include "gnunet_psycstore_service.h"
  32. #include "gnunet_multicast_service.h"
  33. #include "gnunet_crypto_lib.h"
  34. #include "gnunet_psyc_util_lib.h"
  35. #include "psycstore.h"
  36. #include <sqlite3.h>
  37. /**
  38. * After how many ms "busy" should a DB operation fail for good? A
  39. * low value makes sure that we are more responsive to requests
  40. * (especially PUTs). A high value guarantees a higher success rate
  41. * (SELECTs in iterate can take several seconds despite LIMIT=1).
  42. *
  43. * The default value of 1s should ensure that users do not experience
  44. * huge latencies while at the same time allowing operations to
  45. * succeed with reasonable probability.
  46. */
  47. #define BUSY_TIMEOUT_MS 1000
  48. #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
  49. /**
  50. * Log an error message at log-level 'level' that indicates
  51. * a failure of the command 'cmd' on file 'filename'
  52. * with the message given by strerror(errno).
  53. */
  54. #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s (%d)\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh), sqlite3_errcode(db->dbh)); } while(0)
  55. #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__)
  56. enum Transactions {
  57. TRANSACTION_NONE = 0,
  58. TRANSACTION_STATE_MODIFY,
  59. TRANSACTION_STATE_SYNC,
  60. };
  61. /**
  62. * Context for all functions in this plugin.
  63. */
  64. struct Plugin
  65. {
  66. const struct GNUNET_CONFIGURATION_Handle *cfg;
  67. /**
  68. * Database filename.
  69. */
  70. char *fn;
  71. /**
  72. * Native SQLite database handle.
  73. */
  74. sqlite3 *dbh;
  75. /**
  76. * Current transaction.
  77. */
  78. enum Transactions transaction;
  79. sqlite3_stmt *transaction_begin;
  80. sqlite3_stmt *transaction_commit;
  81. sqlite3_stmt *transaction_rollback;
  82. /**
  83. * Precompiled SQL for channel_key_store()
  84. */
  85. sqlite3_stmt *insert_channel_key;
  86. /**
  87. * Precompiled SQL for slave_key_store()
  88. */
  89. sqlite3_stmt *insert_slave_key;
  90. /**
  91. * Precompiled SQL for membership_store()
  92. */
  93. sqlite3_stmt *insert_membership;
  94. /**
  95. * Precompiled SQL for membership_test()
  96. */
  97. sqlite3_stmt *select_membership;
  98. /**
  99. * Precompiled SQL for fragment_store()
  100. */
  101. sqlite3_stmt *insert_fragment;
  102. /**
  103. * Precompiled SQL for message_add_flags()
  104. */
  105. sqlite3_stmt *update_message_flags;
  106. /**
  107. * Precompiled SQL for fragment_get()
  108. */
  109. sqlite3_stmt *select_fragments;
  110. /**
  111. * Precompiled SQL for fragment_get()
  112. */
  113. sqlite3_stmt *select_latest_fragments;
  114. /**
  115. * Precompiled SQL for message_get()
  116. */
  117. sqlite3_stmt *select_messages;
  118. /**
  119. * Precompiled SQL for message_get()
  120. */
  121. sqlite3_stmt *select_latest_messages;
  122. /**
  123. * Precompiled SQL for message_get_fragment()
  124. */
  125. sqlite3_stmt *select_message_fragment;
  126. /**
  127. * Precompiled SQL for counters_get_message()
  128. */
  129. sqlite3_stmt *select_counters_message;
  130. /**
  131. * Precompiled SQL for counters_get_state()
  132. */
  133. sqlite3_stmt *select_counters_state;
  134. /**
  135. * Precompiled SQL for state_modify_end()
  136. */
  137. sqlite3_stmt *update_state_hash_message_id;
  138. /**
  139. * Precompiled SQL for state_sync_end()
  140. */
  141. sqlite3_stmt *update_max_state_message_id;
  142. /**
  143. * Precompiled SQL for state_modify_op()
  144. */
  145. sqlite3_stmt *insert_state_current;
  146. /**
  147. * Precompiled SQL for state_modify_end()
  148. */
  149. sqlite3_stmt *delete_state_empty;
  150. /**
  151. * Precompiled SQL for state_set_signed()
  152. */
  153. sqlite3_stmt *update_state_signed;
  154. /**
  155. * Precompiled SQL for state_sync()
  156. */
  157. sqlite3_stmt *insert_state_sync;
  158. /**
  159. * Precompiled SQL for state_sync()
  160. */
  161. sqlite3_stmt *delete_state;
  162. /**
  163. * Precompiled SQL for state_sync()
  164. */
  165. sqlite3_stmt *insert_state_from_sync;
  166. /**
  167. * Precompiled SQL for state_sync()
  168. */
  169. sqlite3_stmt *delete_state_sync;
  170. /**
  171. * Precompiled SQL for state_get_signed()
  172. */
  173. sqlite3_stmt *select_state_signed;
  174. /**
  175. * Precompiled SQL for state_get()
  176. */
  177. sqlite3_stmt *select_state_one;
  178. /**
  179. * Precompiled SQL for state_get_prefix()
  180. */
  181. sqlite3_stmt *select_state_prefix;
  182. };
  183. #if DEBUG_PSYCSTORE
  184. static void
  185. sql_trace (void *cls, const char *sql)
  186. {
  187. LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql);
  188. }
  189. #endif
  190. /**
  191. * @brief Prepare a SQL statement
  192. *
  193. * @param dbh handle to the database
  194. * @param sql SQL statement, UTF-8 encoded
  195. * @param stmt set to the prepared statement
  196. * @return 0 on success
  197. */
  198. static int
  199. sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt)
  200. {
  201. char *tail;
  202. int result;
  203. result = sqlite3_prepare_v2 (dbh, sql, strlen (sql), stmt,
  204. (const char **) &tail);
  205. LOG (GNUNET_ERROR_TYPE_DEBUG,
  206. "Prepared `%s' / %p: %d\n", sql, *stmt, result);
  207. if (result != SQLITE_OK)
  208. LOG (GNUNET_ERROR_TYPE_ERROR,
  209. _("Error preparing SQL query: %s\n %s\n"),
  210. sqlite3_errmsg (dbh), sql);
  211. return result;
  212. }
  213. /**
  214. * @brief Prepare a SQL statement
  215. *
  216. * @param dbh handle to the database
  217. * @param sql SQL statement, UTF-8 encoded
  218. * @return 0 on success
  219. */
  220. static int
  221. sql_exec (sqlite3 *dbh, const char *sql)
  222. {
  223. int result;
  224. result = sqlite3_exec (dbh, sql, NULL, NULL, NULL);
  225. LOG (GNUNET_ERROR_TYPE_DEBUG,
  226. "Executed `%s' / %d\n", sql, result);
  227. if (result != SQLITE_OK)
  228. LOG (GNUNET_ERROR_TYPE_ERROR,
  229. _("Error executing SQL query: %s\n %s\n"),
  230. sqlite3_errmsg (dbh), sql);
  231. return result;
  232. }
  233. /**
  234. * Initialize the database connections and associated
  235. * data structures (create tables and indices
  236. * as needed as well).
  237. *
  238. * @param plugin the plugin context (state for this module)
  239. * @return GNUNET_OK on success
  240. */
  241. static int
  242. database_setup (struct Plugin *plugin)
  243. {
  244. char *filename;
  245. if (GNUNET_OK !=
  246. GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "psycstore-sqlite",
  247. "FILENAME", &filename))
  248. {
  249. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
  250. "psycstore-sqlite", "FILENAME");
  251. return GNUNET_SYSERR;
  252. }
  253. if (GNUNET_OK != GNUNET_DISK_file_test (filename))
  254. {
  255. if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
  256. {
  257. GNUNET_break (0);
  258. GNUNET_free (filename);
  259. return GNUNET_SYSERR;
  260. }
  261. }
  262. /* filename should be UTF-8-encoded. If it isn't, it's a bug */
  263. plugin->fn = filename;
  264. /* Open database and precompile statements */
  265. if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
  266. {
  267. LOG (GNUNET_ERROR_TYPE_ERROR,
  268. _("Unable to initialize SQLite: %s.\n"),
  269. sqlite3_errmsg (plugin->dbh));
  270. return GNUNET_SYSERR;
  271. }
  272. #if DEBUG_PSYCSTORE
  273. sqlite3_trace (plugin->dbh, &sql_trace, NULL);
  274. #endif
  275. sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
  276. sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL");
  277. sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
  278. sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL");
  279. sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"");
  280. #if ! DEBUG_PSYCSTORE
  281. sql_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE");
  282. #endif
  283. sql_exec (plugin->dbh, "PRAGMA page_size=4096");
  284. sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS);
  285. /* Create tables */
  286. sql_exec (plugin->dbh,
  287. "CREATE TABLE IF NOT EXISTS channels (\n"
  288. " id INTEGER PRIMARY KEY,\n"
  289. " pub_key BLOB(32) UNIQUE,\n"
  290. " max_state_message_id INTEGER,\n" // last applied state message ID
  291. " state_hash_message_id INTEGER\n" // last message ID with a state hash
  292. ");");
  293. sql_exec (plugin->dbh,
  294. "CREATE TABLE IF NOT EXISTS slaves (\n"
  295. " id INTEGER PRIMARY KEY,\n"
  296. " pub_key BLOB(32) UNIQUE\n"
  297. ");");
  298. sql_exec (plugin->dbh,
  299. "CREATE TABLE IF NOT EXISTS membership (\n"
  300. " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
  301. " slave_id INTEGER NOT NULL REFERENCES slaves(id),\n"
  302. " did_join INTEGER NOT NULL,\n"
  303. " announced_at INTEGER NOT NULL,\n"
  304. " effective_since INTEGER NOT NULL,\n"
  305. " group_generation INTEGER NOT NULL\n"
  306. ");");
  307. sql_exec (plugin->dbh,
  308. "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id "
  309. "ON membership (channel_id, slave_id);");
  310. /** @todo messages table: add method_name column */
  311. sql_exec (plugin->dbh,
  312. "CREATE TABLE IF NOT EXISTS messages (\n"
  313. " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
  314. " hop_counter INTEGER NOT NULL,\n"
  315. " signature BLOB,\n"
  316. " purpose BLOB,\n"
  317. " fragment_id INTEGER NOT NULL,\n"
  318. " fragment_offset INTEGER NOT NULL,\n"
  319. " message_id INTEGER NOT NULL,\n"
  320. " group_generation INTEGER NOT NULL,\n"
  321. " multicast_flags INTEGER NOT NULL,\n"
  322. " psycstore_flags INTEGER NOT NULL,\n"
  323. " data BLOB,\n"
  324. " PRIMARY KEY (channel_id, fragment_id),\n"
  325. " UNIQUE (channel_id, message_id, fragment_offset)\n"
  326. ");");
  327. sql_exec (plugin->dbh,
  328. "CREATE TABLE IF NOT EXISTS state (\n"
  329. " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
  330. " name TEXT NOT NULL,\n"
  331. " value_current BLOB,\n"
  332. " value_signed BLOB,\n"
  333. " PRIMARY KEY (channel_id, name)\n"
  334. ");");
  335. sql_exec (plugin->dbh,
  336. "CREATE TABLE IF NOT EXISTS state_sync (\n"
  337. " channel_id INTEGER NOT NULL REFERENCES channels(id),\n"
  338. " name TEXT NOT NULL,\n"
  339. " value BLOB,\n"
  340. " PRIMARY KEY (channel_id, name)\n"
  341. ");");
  342. /* Prepare statements */
  343. sql_prepare (plugin->dbh, "BEGIN;", &plugin->transaction_begin);
  344. sql_prepare (plugin->dbh, "COMMIT;", &plugin->transaction_commit);
  345. sql_prepare (plugin->dbh, "ROLLBACK;", &plugin->transaction_rollback);
  346. sql_prepare (plugin->dbh,
  347. "INSERT OR IGNORE INTO channels (pub_key) VALUES (?);",
  348. &plugin->insert_channel_key);
  349. sql_prepare (plugin->dbh,
  350. "INSERT OR IGNORE INTO slaves (pub_key) VALUES (?);",
  351. &plugin->insert_slave_key);
  352. sql_prepare (plugin->dbh,
  353. "INSERT INTO membership\n"
  354. " (channel_id, slave_id, did_join, announced_at,\n"
  355. " effective_since, group_generation)\n"
  356. "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
  357. " (SELECT id FROM slaves WHERE pub_key = ?),\n"
  358. " ?, ?, ?, ?);",
  359. &plugin->insert_membership);
  360. sql_prepare (plugin->dbh,
  361. "SELECT did_join FROM membership\n"
  362. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  363. " AND slave_id = (SELECT id FROM slaves WHERE pub_key = ?)\n"
  364. " AND effective_since <= ? AND did_join = 1\n"
  365. "ORDER BY announced_at DESC LIMIT 1;",
  366. &plugin->select_membership);
  367. sql_prepare (plugin->dbh,
  368. "INSERT OR IGNORE INTO messages\n"
  369. " (channel_id, hop_counter, signature, purpose,\n"
  370. " fragment_id, fragment_offset, message_id,\n"
  371. " group_generation, multicast_flags, psycstore_flags, data)\n"
  372. "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n"
  373. " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
  374. &plugin->insert_fragment);
  375. sql_prepare (plugin->dbh,
  376. "UPDATE messages\n"
  377. "SET psycstore_flags = psycstore_flags | ?\n"
  378. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  379. " AND message_id = ? AND fragment_offset = 0;",
  380. &plugin->update_message_flags);
  381. sql_prepare (plugin->dbh,
  382. "SELECT hop_counter, signature, purpose, fragment_id,\n"
  383. " fragment_offset, message_id, group_generation,\n"
  384. " multicast_flags, psycstore_flags, data\n"
  385. "FROM messages\n"
  386. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  387. " AND ? <= fragment_id AND fragment_id <= ?;",
  388. &plugin->select_fragments);
  389. /** @todo select_messages: add method_prefix filter */
  390. sql_prepare (plugin->dbh,
  391. "SELECT hop_counter, signature, purpose, fragment_id,\n"
  392. " fragment_offset, message_id, group_generation,\n"
  393. " multicast_flags, psycstore_flags, data\n"
  394. "FROM messages\n"
  395. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  396. " AND ? <= message_id AND message_id <= ?"
  397. "LIMIT ?;",
  398. &plugin->select_messages);
  399. sql_prepare (plugin->dbh,
  400. "SELECT * FROM\n"
  401. "(SELECT hop_counter, signature, purpose, fragment_id,\n"
  402. " fragment_offset, message_id, group_generation,\n"
  403. " multicast_flags, psycstore_flags, data\n"
  404. " FROM messages\n"
  405. " WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  406. " ORDER BY fragment_id DESC\n"
  407. " LIMIT ?)\n"
  408. "ORDER BY fragment_id;",
  409. &plugin->select_latest_fragments);
  410. /** @todo select_latest_messages: add method_prefix filter */
  411. sql_prepare (plugin->dbh,
  412. "SELECT hop_counter, signature, purpose, fragment_id,\n"
  413. " fragment_offset, message_id, group_generation,\n"
  414. " multicast_flags, psycstore_flags, data\n"
  415. "FROM messages\n"
  416. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  417. " AND message_id IN\n"
  418. " (SELECT message_id\n"
  419. " FROM messages\n"
  420. " WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  421. " GROUP BY message_id\n"
  422. " ORDER BY message_id\n"
  423. " DESC LIMIT ?)\n"
  424. "ORDER BY fragment_id;",
  425. &plugin->select_latest_messages);
  426. sql_prepare (plugin->dbh,
  427. "SELECT hop_counter, signature, purpose, fragment_id,\n"
  428. " fragment_offset, message_id, group_generation,\n"
  429. " multicast_flags, psycstore_flags, data\n"
  430. "FROM messages\n"
  431. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  432. " AND message_id = ? AND fragment_offset = ?;",
  433. &plugin->select_message_fragment);
  434. sql_prepare (plugin->dbh,
  435. "SELECT fragment_id, message_id, group_generation\n"
  436. "FROM messages\n"
  437. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  438. "ORDER BY fragment_id DESC LIMIT 1;",
  439. &plugin->select_counters_message);
  440. sql_prepare (plugin->dbh,
  441. "SELECT max_state_message_id\n"
  442. "FROM channels\n"
  443. "WHERE pub_key = ? AND max_state_message_id IS NOT NULL;",
  444. &plugin->select_counters_state);
  445. sql_prepare (plugin->dbh,
  446. "UPDATE channels\n"
  447. "SET max_state_message_id = ?\n"
  448. "WHERE pub_key = ?;",
  449. &plugin->update_max_state_message_id);
  450. sql_prepare (plugin->dbh,
  451. "UPDATE channels\n"
  452. "SET state_hash_message_id = ?\n"
  453. "WHERE pub_key = ?;",
  454. &plugin->update_state_hash_message_id);
  455. sql_prepare (plugin->dbh,
  456. "INSERT OR REPLACE INTO state\n"
  457. " (channel_id, name, value_current, value_signed)\n"
  458. "SELECT new.channel_id, new.name,\n"
  459. " new.value_current, old.value_signed\n"
  460. "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n"
  461. " AS channel_id,\n"
  462. " ? AS name, ? AS value_current) AS new\n"
  463. "LEFT JOIN (SELECT channel_id, name, value_signed\n"
  464. " FROM state) AS old\n"
  465. "ON new.channel_id = old.channel_id AND new.name = old.name;",
  466. &plugin->insert_state_current);
  467. sql_prepare (plugin->dbh,
  468. "DELETE FROM state\n"
  469. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  470. " AND (value_current IS NULL OR length(value_current) = 0)\n"
  471. " AND (value_signed IS NULL OR length(value_signed) = 0);",
  472. &plugin->delete_state_empty);
  473. sql_prepare (plugin->dbh,
  474. "UPDATE state\n"
  475. "SET value_signed = value_current\n"
  476. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
  477. &plugin->update_state_signed);
  478. sql_prepare (plugin->dbh,
  479. "DELETE FROM state\n"
  480. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
  481. &plugin->delete_state);
  482. sql_prepare (plugin->dbh,
  483. "INSERT INTO state_sync (channel_id, name, value)\n"
  484. "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);",
  485. &plugin->insert_state_sync);
  486. sql_prepare (plugin->dbh,
  487. "INSERT INTO state\n"
  488. " (channel_id, name, value_current, value_signed)\n"
  489. "SELECT channel_id, name, value, value\n"
  490. "FROM state_sync\n"
  491. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
  492. &plugin->insert_state_from_sync);
  493. sql_prepare (plugin->dbh,
  494. "DELETE FROM state_sync\n"
  495. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);",
  496. &plugin->delete_state_sync);
  497. sql_prepare (plugin->dbh,
  498. "SELECT value_current\n"
  499. "FROM state\n"
  500. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  501. " AND name = ?;",
  502. &plugin->select_state_one);
  503. sql_prepare (plugin->dbh,
  504. "SELECT name, value_current\n"
  505. "FROM state\n"
  506. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n"
  507. " AND (name = ? OR substr(name, 1, ?) = ?);",
  508. &plugin->select_state_prefix);
  509. sql_prepare (plugin->dbh,
  510. "SELECT name, value_signed\n"
  511. "FROM state\n"
  512. "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)"
  513. " AND value_signed IS NOT NULL;",
  514. &plugin->select_state_signed);
  515. return GNUNET_OK;
  516. }
  517. /**
  518. * Shutdown database connection and associate data
  519. * structures.
  520. * @param plugin the plugin context (state for this module)
  521. */
  522. static void
  523. database_shutdown (struct Plugin *plugin)
  524. {
  525. int result;
  526. sqlite3_stmt *stmt;
  527. while (NULL != (stmt = sqlite3_next_stmt (plugin->dbh, NULL)))
  528. {
  529. result = sqlite3_finalize (stmt);
  530. if (SQLITE_OK != result)
  531. LOG (GNUNET_ERROR_TYPE_WARNING,
  532. "Failed to close statement %p: %d\n", stmt, result);
  533. }
  534. if (SQLITE_OK != sqlite3_close (plugin->dbh))
  535. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
  536. GNUNET_free_non_null (plugin->fn);
  537. }
  538. /**
  539. * Execute a prepared statement with a @a channel_key argument.
  540. *
  541. * @param plugin Plugin handle.
  542. * @param stmt Statement to execute.
  543. * @param channel_key Public key of the channel.
  544. *
  545. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  546. */
  547. static int
  548. exec_channel (struct Plugin *plugin, sqlite3_stmt *stmt,
  549. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key)
  550. {
  551. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  552. sizeof (*channel_key), SQLITE_STATIC))
  553. {
  554. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  555. "sqlite3_bind");
  556. }
  557. else if (SQLITE_DONE != sqlite3_step (stmt))
  558. {
  559. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  560. "sqlite3_step");
  561. }
  562. if (SQLITE_OK != sqlite3_reset (stmt))
  563. {
  564. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  565. "sqlite3_reset");
  566. return GNUNET_SYSERR;
  567. }
  568. return GNUNET_OK;
  569. }
  570. /**
  571. * Begin a transaction.
  572. */
  573. static int
  574. transaction_begin (struct Plugin *plugin, enum Transactions transaction)
  575. {
  576. sqlite3_stmt *stmt = plugin->transaction_begin;
  577. if (SQLITE_DONE != sqlite3_step (stmt))
  578. {
  579. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  580. "sqlite3_step");
  581. }
  582. if (SQLITE_OK != sqlite3_reset (stmt))
  583. {
  584. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  585. "sqlite3_reset");
  586. return GNUNET_SYSERR;
  587. }
  588. plugin->transaction = transaction;
  589. return GNUNET_OK;
  590. }
  591. /**
  592. * Commit current transaction.
  593. */
  594. static int
  595. transaction_commit (struct Plugin *plugin)
  596. {
  597. sqlite3_stmt *stmt = plugin->transaction_commit;
  598. if (SQLITE_DONE != sqlite3_step (stmt))
  599. {
  600. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  601. "sqlite3_step");
  602. }
  603. if (SQLITE_OK != sqlite3_reset (stmt))
  604. {
  605. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  606. "sqlite3_reset");
  607. return GNUNET_SYSERR;
  608. }
  609. plugin->transaction = TRANSACTION_NONE;
  610. return GNUNET_OK;
  611. }
  612. /**
  613. * Roll back current transaction.
  614. */
  615. static int
  616. transaction_rollback (struct Plugin *plugin)
  617. {
  618. sqlite3_stmt *stmt = plugin->transaction_rollback;
  619. if (SQLITE_DONE != sqlite3_step (stmt))
  620. {
  621. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  622. "sqlite3_step");
  623. }
  624. if (SQLITE_OK != sqlite3_reset (stmt))
  625. {
  626. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  627. "sqlite3_reset");
  628. return GNUNET_SYSERR;
  629. }
  630. plugin->transaction = TRANSACTION_NONE;
  631. return GNUNET_OK;
  632. }
  633. static int
  634. channel_key_store (struct Plugin *plugin,
  635. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key)
  636. {
  637. sqlite3_stmt *stmt = plugin->insert_channel_key;
  638. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  639. sizeof (*channel_key), SQLITE_STATIC))
  640. {
  641. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  642. "sqlite3_bind");
  643. }
  644. else if (SQLITE_DONE != sqlite3_step (stmt))
  645. {
  646. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  647. "sqlite3_step");
  648. }
  649. if (SQLITE_OK != sqlite3_reset (stmt))
  650. {
  651. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  652. "sqlite3_reset");
  653. return GNUNET_SYSERR;
  654. }
  655. return GNUNET_OK;
  656. }
  657. static int
  658. slave_key_store (struct Plugin *plugin,
  659. const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key)
  660. {
  661. sqlite3_stmt *stmt = plugin->insert_slave_key;
  662. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key,
  663. sizeof (*slave_key), SQLITE_STATIC))
  664. {
  665. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  666. "sqlite3_bind");
  667. }
  668. else if (SQLITE_DONE != sqlite3_step (stmt))
  669. {
  670. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  671. "sqlite3_step");
  672. }
  673. if (SQLITE_OK != sqlite3_reset (stmt))
  674. {
  675. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  676. "sqlite3_reset");
  677. return GNUNET_SYSERR;
  678. }
  679. return GNUNET_OK;
  680. }
  681. /**
  682. * Store join/leave events for a PSYC channel in order to be able to answer
  683. * membership test queries later.
  684. *
  685. * @see GNUNET_PSYCSTORE_membership_store()
  686. *
  687. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  688. */
  689. static int
  690. sqlite_membership_store (void *cls,
  691. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  692. const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
  693. int did_join,
  694. uint64_t announced_at,
  695. uint64_t effective_since,
  696. uint64_t group_generation)
  697. {
  698. struct Plugin *plugin = cls;
  699. sqlite3_stmt *stmt = plugin->insert_membership;
  700. GNUNET_assert (TRANSACTION_NONE == plugin->transaction);
  701. if (announced_at > INT64_MAX ||
  702. effective_since > INT64_MAX ||
  703. group_generation > INT64_MAX)
  704. {
  705. GNUNET_break (0);
  706. return GNUNET_SYSERR;
  707. }
  708. if (GNUNET_OK != channel_key_store (plugin, channel_key)
  709. || GNUNET_OK != slave_key_store (plugin, slave_key))
  710. return GNUNET_SYSERR;
  711. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  712. sizeof (*channel_key), SQLITE_STATIC)
  713. || SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
  714. sizeof (*slave_key), SQLITE_STATIC)
  715. || SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join)
  716. || SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at)
  717. || SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since)
  718. || SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation))
  719. {
  720. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  721. "sqlite3_bind");
  722. }
  723. else if (SQLITE_DONE != sqlite3_step (stmt))
  724. {
  725. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  726. "sqlite3_step");
  727. }
  728. if (SQLITE_OK != sqlite3_reset (stmt))
  729. {
  730. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  731. "sqlite3_reset");
  732. return GNUNET_SYSERR;
  733. }
  734. return GNUNET_OK;
  735. }
  736. /**
  737. * Test if a member was admitted to the channel at the given message ID.
  738. *
  739. * @see GNUNET_PSYCSTORE_membership_test()
  740. *
  741. * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
  742. * #GNUNET_SYSERR if there was en error.
  743. */
  744. static int
  745. membership_test (void *cls,
  746. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  747. const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
  748. uint64_t message_id)
  749. {
  750. struct Plugin *plugin = cls;
  751. sqlite3_stmt *stmt = plugin->select_membership;
  752. int ret = GNUNET_SYSERR;
  753. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  754. sizeof (*channel_key), SQLITE_STATIC)
  755. || SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key,
  756. sizeof (*slave_key), SQLITE_STATIC)
  757. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
  758. {
  759. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  760. "sqlite3_bind");
  761. }
  762. else
  763. {
  764. switch (sqlite3_step (stmt))
  765. {
  766. case SQLITE_DONE:
  767. ret = GNUNET_NO;
  768. break;
  769. case SQLITE_ROW:
  770. ret = GNUNET_YES;
  771. }
  772. }
  773. if (SQLITE_OK != sqlite3_reset (stmt))
  774. {
  775. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  776. "sqlite3_reset");
  777. }
  778. return ret;
  779. }
  780. /**
  781. * Store a message fragment sent to a channel.
  782. *
  783. * @see GNUNET_PSYCSTORE_fragment_store()
  784. *
  785. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  786. */
  787. static int
  788. fragment_store (void *cls,
  789. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  790. const struct GNUNET_MULTICAST_MessageHeader *msg,
  791. uint32_t psycstore_flags)
  792. {
  793. struct Plugin *plugin = cls;
  794. sqlite3_stmt *stmt = plugin->insert_fragment;
  795. GNUNET_assert (TRANSACTION_NONE == plugin->transaction);
  796. uint64_t fragment_id = GNUNET_ntohll (msg->fragment_id);
  797. uint64_t fragment_offset = GNUNET_ntohll (msg->fragment_offset);
  798. uint64_t message_id = GNUNET_ntohll (msg->message_id);
  799. uint64_t group_generation = GNUNET_ntohll (msg->group_generation);
  800. if (fragment_id > INT64_MAX || fragment_offset > INT64_MAX ||
  801. message_id > INT64_MAX || group_generation > INT64_MAX)
  802. {
  803. LOG (GNUNET_ERROR_TYPE_ERROR,
  804. "Tried to store fragment with a field > INT64_MAX: "
  805. "%lu, %lu, %lu, %lu\n", fragment_id, fragment_offset,
  806. message_id, group_generation);
  807. GNUNET_break (0);
  808. return GNUNET_SYSERR;
  809. }
  810. if (GNUNET_OK != channel_key_store (plugin, channel_key))
  811. return GNUNET_SYSERR;
  812. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  813. sizeof (*channel_key), SQLITE_STATIC)
  814. || SQLITE_OK != sqlite3_bind_int64 (stmt, 2, ntohl (msg->hop_counter) )
  815. || SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature,
  816. sizeof (msg->signature), SQLITE_STATIC)
  817. || SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose,
  818. sizeof (msg->purpose), SQLITE_STATIC)
  819. || SQLITE_OK != sqlite3_bind_int64 (stmt, 5, fragment_id)
  820. || SQLITE_OK != sqlite3_bind_int64 (stmt, 6, fragment_offset)
  821. || SQLITE_OK != sqlite3_bind_int64 (stmt, 7, message_id)
  822. || SQLITE_OK != sqlite3_bind_int64 (stmt, 8, group_generation)
  823. || SQLITE_OK != sqlite3_bind_int64 (stmt, 9, ntohl (msg->flags))
  824. || SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags)
  825. || SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1],
  826. ntohs (msg->header.size)
  827. - sizeof (*msg), SQLITE_STATIC))
  828. {
  829. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  830. "sqlite3_bind");
  831. }
  832. else if (SQLITE_DONE != sqlite3_step (stmt))
  833. {
  834. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  835. "sqlite3_step");
  836. }
  837. if (SQLITE_OK != sqlite3_reset (stmt))
  838. {
  839. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  840. "sqlite3_reset");
  841. return GNUNET_SYSERR;
  842. }
  843. return GNUNET_OK;
  844. }
  845. /**
  846. * Set additional flags for a given message.
  847. *
  848. * They are OR'd with any existing flags set.
  849. *
  850. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  851. */
  852. static int
  853. message_add_flags (void *cls,
  854. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  855. uint64_t message_id,
  856. uint32_t psycstore_flags)
  857. {
  858. struct Plugin *plugin = cls;
  859. sqlite3_stmt *stmt = plugin->update_message_flags;
  860. int ret = GNUNET_SYSERR;
  861. if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags)
  862. || SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key,
  863. sizeof (*channel_key), SQLITE_STATIC)
  864. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id))
  865. {
  866. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  867. "sqlite3_bind");
  868. }
  869. else
  870. {
  871. switch (sqlite3_step (stmt))
  872. {
  873. case SQLITE_DONE:
  874. ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO;
  875. break;
  876. default:
  877. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  878. "sqlite3_step");
  879. }
  880. }
  881. if (SQLITE_OK != sqlite3_reset (stmt))
  882. {
  883. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  884. "sqlite3_reset");
  885. return GNUNET_SYSERR;
  886. }
  887. return ret;
  888. }
  889. static int
  890. fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb,
  891. void *cb_cls)
  892. {
  893. int data_size = sqlite3_column_bytes (stmt, 9);
  894. struct GNUNET_MULTICAST_MessageHeader *msg
  895. = GNUNET_malloc (sizeof (*msg) + data_size);
  896. msg->header.size = htons (sizeof (*msg) + data_size);
  897. msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
  898. msg->hop_counter = htonl ((uint32_t) sqlite3_column_int64 (stmt, 0));
  899. GNUNET_memcpy (&msg->signature,
  900. sqlite3_column_blob (stmt, 1),
  901. sqlite3_column_bytes (stmt, 1));
  902. GNUNET_memcpy (&msg->purpose,
  903. sqlite3_column_blob (stmt, 2),
  904. sqlite3_column_bytes (stmt, 2));
  905. msg->fragment_id = GNUNET_htonll (sqlite3_column_int64 (stmt, 3));
  906. msg->fragment_offset = GNUNET_htonll (sqlite3_column_int64 (stmt, 4));
  907. msg->message_id = GNUNET_htonll (sqlite3_column_int64 (stmt, 5));
  908. msg->group_generation = GNUNET_htonll (sqlite3_column_int64 (stmt, 6));
  909. msg->flags = htonl (sqlite3_column_int64 (stmt, 7));
  910. GNUNET_memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size);
  911. return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8));
  912. }
  913. static int
  914. fragment_select (struct Plugin *plugin, sqlite3_stmt *stmt,
  915. uint64_t *returned_fragments,
  916. GNUNET_PSYCSTORE_FragmentCallback cb, void *cb_cls)
  917. {
  918. int ret = GNUNET_SYSERR;
  919. int sql_ret;
  920. do
  921. {
  922. sql_ret = sqlite3_step (stmt);
  923. switch (sql_ret)
  924. {
  925. case SQLITE_DONE:
  926. if (ret != GNUNET_OK)
  927. ret = GNUNET_NO;
  928. break;
  929. case SQLITE_ROW:
  930. ret = fragment_row (stmt, cb, cb_cls);
  931. (*returned_fragments)++;
  932. if (ret != GNUNET_YES)
  933. sql_ret = SQLITE_DONE;
  934. break;
  935. default:
  936. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  937. "sqlite3_step");
  938. }
  939. }
  940. while (sql_ret == SQLITE_ROW);
  941. return ret;
  942. }
  943. /**
  944. * Retrieve a message fragment range by fragment ID.
  945. *
  946. * @see GNUNET_PSYCSTORE_fragment_get()
  947. *
  948. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  949. */
  950. static int
  951. fragment_get (void *cls,
  952. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  953. uint64_t first_fragment_id,
  954. uint64_t last_fragment_id,
  955. uint64_t *returned_fragments,
  956. GNUNET_PSYCSTORE_FragmentCallback cb,
  957. void *cb_cls)
  958. {
  959. struct Plugin *plugin = cls;
  960. sqlite3_stmt *stmt = plugin->select_fragments;
  961. int ret = GNUNET_SYSERR;
  962. *returned_fragments = 0;
  963. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  964. sizeof (*channel_key),
  965. SQLITE_STATIC)
  966. || SQLITE_OK != sqlite3_bind_int64 (stmt, 2, first_fragment_id)
  967. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, last_fragment_id))
  968. {
  969. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  970. "sqlite3_bind");
  971. }
  972. else
  973. {
  974. ret = fragment_select (plugin, stmt, returned_fragments, cb, cb_cls);
  975. }
  976. if (SQLITE_OK != sqlite3_reset (stmt))
  977. {
  978. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  979. "sqlite3_reset");
  980. }
  981. return ret;
  982. }
  983. /**
  984. * Retrieve a message fragment range by fragment ID.
  985. *
  986. * @see GNUNET_PSYCSTORE_fragment_get_latest()
  987. *
  988. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  989. */
  990. static int
  991. fragment_get_latest (void *cls,
  992. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  993. uint64_t fragment_limit,
  994. uint64_t *returned_fragments,
  995. GNUNET_PSYCSTORE_FragmentCallback cb,
  996. void *cb_cls)
  997. {
  998. struct Plugin *plugin = cls;
  999. sqlite3_stmt *stmt = plugin->select_latest_fragments;
  1000. int ret = GNUNET_SYSERR;
  1001. *returned_fragments = 0;
  1002. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1003. sizeof (*channel_key),
  1004. SQLITE_STATIC)
  1005. || SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_limit))
  1006. {
  1007. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1008. "sqlite3_bind");
  1009. }
  1010. else
  1011. {
  1012. ret = fragment_select (plugin, stmt, returned_fragments, cb, cb_cls);
  1013. }
  1014. if (SQLITE_OK != sqlite3_reset (stmt))
  1015. {
  1016. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1017. "sqlite3_reset");
  1018. }
  1019. return ret;
  1020. }
  1021. /**
  1022. * Retrieve all fragments of a message ID range.
  1023. *
  1024. * @see GNUNET_PSYCSTORE_message_get()
  1025. *
  1026. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1027. */
  1028. static int
  1029. message_get (void *cls,
  1030. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1031. uint64_t first_message_id,
  1032. uint64_t last_message_id,
  1033. uint64_t fragment_limit,
  1034. uint64_t *returned_fragments,
  1035. GNUNET_PSYCSTORE_FragmentCallback cb,
  1036. void *cb_cls)
  1037. {
  1038. struct Plugin *plugin = cls;
  1039. sqlite3_stmt *stmt = plugin->select_messages;
  1040. int ret = GNUNET_SYSERR;
  1041. *returned_fragments = 0;
  1042. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1043. sizeof (*channel_key),
  1044. SQLITE_STATIC)
  1045. || SQLITE_OK != sqlite3_bind_int64 (stmt, 2, first_message_id)
  1046. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, last_message_id)
  1047. || SQLITE_OK != sqlite3_bind_int64 (stmt, 4,
  1048. (0 != fragment_limit)
  1049. ? fragment_limit
  1050. : INT64_MAX))
  1051. {
  1052. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1053. "sqlite3_bind");
  1054. }
  1055. else
  1056. {
  1057. ret = fragment_select (plugin, stmt, returned_fragments, cb, cb_cls);
  1058. }
  1059. if (SQLITE_OK != sqlite3_reset (stmt))
  1060. {
  1061. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1062. "sqlite3_reset");
  1063. }
  1064. return ret;
  1065. }
  1066. /**
  1067. * Retrieve all fragments of the latest messages.
  1068. *
  1069. * @see GNUNET_PSYCSTORE_message_get_latest()
  1070. *
  1071. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1072. */
  1073. static int
  1074. message_get_latest (void *cls,
  1075. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1076. uint64_t message_limit,
  1077. uint64_t *returned_fragments,
  1078. GNUNET_PSYCSTORE_FragmentCallback cb,
  1079. void *cb_cls)
  1080. {
  1081. struct Plugin *plugin = cls;
  1082. sqlite3_stmt *stmt = plugin->select_latest_messages;
  1083. int ret = GNUNET_SYSERR;
  1084. *returned_fragments = 0;
  1085. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1086. sizeof (*channel_key),
  1087. SQLITE_STATIC)
  1088. || SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key,
  1089. sizeof (*channel_key),
  1090. SQLITE_STATIC)
  1091. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_limit))
  1092. {
  1093. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1094. "sqlite3_bind");
  1095. }
  1096. else
  1097. {
  1098. ret = fragment_select (plugin, stmt, returned_fragments, cb, cb_cls);
  1099. }
  1100. if (SQLITE_OK != sqlite3_reset (stmt))
  1101. {
  1102. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1103. "sqlite3_reset");
  1104. }
  1105. return ret;
  1106. }
  1107. /**
  1108. * Retrieve a fragment of message specified by its message ID and fragment
  1109. * offset.
  1110. *
  1111. * @see GNUNET_PSYCSTORE_message_get_fragment()
  1112. *
  1113. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1114. */
  1115. static int
  1116. message_get_fragment (void *cls,
  1117. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1118. uint64_t message_id,
  1119. uint64_t fragment_offset,
  1120. GNUNET_PSYCSTORE_FragmentCallback cb,
  1121. void *cb_cls)
  1122. {
  1123. struct Plugin *plugin = cls;
  1124. sqlite3_stmt *stmt = plugin->select_message_fragment;
  1125. int ret = GNUNET_SYSERR;
  1126. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1127. sizeof (*channel_key),
  1128. SQLITE_STATIC)
  1129. || SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id)
  1130. || SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset))
  1131. {
  1132. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1133. "sqlite3_bind");
  1134. }
  1135. else
  1136. {
  1137. switch (sqlite3_step (stmt))
  1138. {
  1139. case SQLITE_DONE:
  1140. ret = GNUNET_NO;
  1141. break;
  1142. case SQLITE_ROW:
  1143. ret = fragment_row (stmt, cb, cb_cls);
  1144. break;
  1145. default:
  1146. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1147. "sqlite3_step");
  1148. }
  1149. }
  1150. if (SQLITE_OK != sqlite3_reset (stmt))
  1151. {
  1152. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1153. "sqlite3_reset");
  1154. }
  1155. return ret;
  1156. }
  1157. /**
  1158. * Retrieve the max. values of message counters for a channel.
  1159. *
  1160. * @see GNUNET_PSYCSTORE_counters_get()
  1161. *
  1162. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1163. */
  1164. static int
  1165. counters_message_get (void *cls,
  1166. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1167. uint64_t *max_fragment_id,
  1168. uint64_t *max_message_id,
  1169. uint64_t *max_group_generation)
  1170. {
  1171. struct Plugin *plugin = cls;
  1172. sqlite3_stmt *stmt = plugin->select_counters_message;
  1173. int ret = GNUNET_SYSERR;
  1174. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1175. sizeof (*channel_key),
  1176. SQLITE_STATIC))
  1177. {
  1178. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1179. "sqlite3_bind");
  1180. }
  1181. else
  1182. {
  1183. switch (sqlite3_step (stmt))
  1184. {
  1185. case SQLITE_DONE:
  1186. ret = GNUNET_NO;
  1187. break;
  1188. case SQLITE_ROW:
  1189. *max_fragment_id = sqlite3_column_int64 (stmt, 0);
  1190. *max_message_id = sqlite3_column_int64 (stmt, 1);
  1191. *max_group_generation = sqlite3_column_int64 (stmt, 2);
  1192. ret = GNUNET_OK;
  1193. break;
  1194. default:
  1195. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1196. "sqlite3_step");
  1197. }
  1198. }
  1199. if (SQLITE_OK != sqlite3_reset (stmt))
  1200. {
  1201. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1202. "sqlite3_reset");
  1203. }
  1204. return ret;
  1205. }
  1206. /**
  1207. * Retrieve the max. values of state counters for a channel.
  1208. *
  1209. * @see GNUNET_PSYCSTORE_counters_get()
  1210. *
  1211. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1212. */
  1213. static int
  1214. counters_state_get (void *cls,
  1215. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1216. uint64_t *max_state_message_id)
  1217. {
  1218. struct Plugin *plugin = cls;
  1219. sqlite3_stmt *stmt = plugin->select_counters_state;
  1220. int ret = GNUNET_SYSERR;
  1221. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1222. sizeof (*channel_key),
  1223. SQLITE_STATIC))
  1224. {
  1225. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1226. "sqlite3_bind");
  1227. }
  1228. else
  1229. {
  1230. switch (sqlite3_step (stmt))
  1231. {
  1232. case SQLITE_DONE:
  1233. ret = GNUNET_NO;
  1234. break;
  1235. case SQLITE_ROW:
  1236. *max_state_message_id = sqlite3_column_int64 (stmt, 0);
  1237. ret = GNUNET_OK;
  1238. break;
  1239. default:
  1240. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1241. "sqlite3_step");
  1242. }
  1243. }
  1244. if (SQLITE_OK != sqlite3_reset (stmt))
  1245. {
  1246. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1247. "sqlite3_reset");
  1248. }
  1249. return ret;
  1250. }
  1251. /**
  1252. * Assign a value to a state variable.
  1253. *
  1254. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1255. */
  1256. static int
  1257. state_assign (struct Plugin *plugin, sqlite3_stmt *stmt,
  1258. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1259. const char *name, const void *value, size_t value_size)
  1260. {
  1261. int ret = GNUNET_SYSERR;
  1262. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1263. sizeof (*channel_key), SQLITE_STATIC)
  1264. || SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC)
  1265. || SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size,
  1266. SQLITE_STATIC))
  1267. {
  1268. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1269. "sqlite3_bind");
  1270. }
  1271. else
  1272. {
  1273. switch (sqlite3_step (stmt))
  1274. {
  1275. case SQLITE_DONE:
  1276. ret = 0 < sqlite3_total_changes (plugin->dbh) ? GNUNET_OK : GNUNET_NO;
  1277. break;
  1278. default:
  1279. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1280. "sqlite3_step");
  1281. }
  1282. }
  1283. if (SQLITE_OK != sqlite3_reset (stmt))
  1284. {
  1285. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1286. "sqlite3_reset");
  1287. return GNUNET_SYSERR;
  1288. }
  1289. return ret;
  1290. }
  1291. static int
  1292. update_message_id (struct Plugin *plugin, sqlite3_stmt *stmt,
  1293. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1294. uint64_t message_id)
  1295. {
  1296. if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, message_id)
  1297. || SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key,
  1298. sizeof (*channel_key), SQLITE_STATIC))
  1299. {
  1300. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1301. "sqlite3_bind");
  1302. }
  1303. else if (SQLITE_DONE != sqlite3_step (stmt))
  1304. {
  1305. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1306. "sqlite3_step");
  1307. }
  1308. if (SQLITE_OK != sqlite3_reset (stmt))
  1309. {
  1310. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1311. "sqlite3_reset");
  1312. return GNUNET_SYSERR;
  1313. }
  1314. return GNUNET_OK;
  1315. }
  1316. /**
  1317. * Begin modifying current state.
  1318. */
  1319. static int
  1320. state_modify_begin (void *cls,
  1321. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1322. uint64_t message_id, uint64_t state_delta)
  1323. {
  1324. struct Plugin *plugin = cls;
  1325. if (state_delta > 0)
  1326. {
  1327. /**
  1328. * We can only apply state modifiers in the current message if modifiers in
  1329. * the previous stateful message (message_id - state_delta) were already
  1330. * applied.
  1331. */
  1332. uint64_t max_state_message_id = 0;
  1333. int ret = counters_state_get (plugin, channel_key, &max_state_message_id);
  1334. switch (ret)
  1335. {
  1336. case GNUNET_OK:
  1337. case GNUNET_NO: // no state yet
  1338. ret = GNUNET_OK;
  1339. break;
  1340. default:
  1341. return ret;
  1342. }
  1343. if (max_state_message_id < message_id - state_delta)
  1344. return GNUNET_NO; /* some stateful messages not yet applied */
  1345. else if (message_id - state_delta < max_state_message_id)
  1346. return GNUNET_NO; /* changes already applied */
  1347. }
  1348. if (TRANSACTION_NONE != plugin->transaction)
  1349. {
  1350. /** @todo FIXME: wait for other transaction to finish */
  1351. return GNUNET_SYSERR;
  1352. }
  1353. return transaction_begin (plugin, TRANSACTION_STATE_MODIFY);
  1354. }
  1355. /**
  1356. * Set the current value of state variable.
  1357. *
  1358. * @see GNUNET_PSYCSTORE_state_modify()
  1359. *
  1360. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1361. */
  1362. static int
  1363. state_modify_op (void *cls,
  1364. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1365. enum GNUNET_PSYC_Operator op,
  1366. const char *name, const void *value, size_t value_size)
  1367. {
  1368. struct Plugin *plugin = cls;
  1369. GNUNET_assert (TRANSACTION_STATE_MODIFY == plugin->transaction);
  1370. switch (op)
  1371. {
  1372. case GNUNET_PSYC_OP_ASSIGN:
  1373. return state_assign (plugin, plugin->insert_state_current, channel_key,
  1374. name, value, value_size);
  1375. default: /** @todo implement more state operations */
  1376. GNUNET_break (0);
  1377. return GNUNET_SYSERR;
  1378. }
  1379. }
  1380. /**
  1381. * End modifying current state.
  1382. */
  1383. static int
  1384. state_modify_end (void *cls,
  1385. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1386. uint64_t message_id)
  1387. {
  1388. struct Plugin *plugin = cls;
  1389. GNUNET_assert (TRANSACTION_STATE_MODIFY == plugin->transaction);
  1390. return
  1391. GNUNET_OK == exec_channel (plugin, plugin->delete_state_empty, channel_key)
  1392. && GNUNET_OK == update_message_id (plugin,
  1393. plugin->update_max_state_message_id,
  1394. channel_key, message_id)
  1395. && GNUNET_OK == transaction_commit (plugin)
  1396. ? GNUNET_OK : GNUNET_SYSERR;
  1397. }
  1398. /**
  1399. * Begin state synchronization.
  1400. */
  1401. static int
  1402. state_sync_begin (void *cls,
  1403. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key)
  1404. {
  1405. struct Plugin *plugin = cls;
  1406. return exec_channel (plugin, plugin->delete_state_sync, channel_key);
  1407. }
  1408. /**
  1409. * Assign current value of a state variable.
  1410. *
  1411. * @see GNUNET_PSYCSTORE_state_modify()
  1412. *
  1413. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1414. */
  1415. static int
  1416. state_sync_assign (void *cls,
  1417. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1418. const char *name, const void *value, size_t value_size)
  1419. {
  1420. struct Plugin *plugin = cls;
  1421. return state_assign (cls, plugin->insert_state_sync, channel_key,
  1422. name, value, value_size);
  1423. }
  1424. /**
  1425. * End modifying current state.
  1426. */
  1427. static int
  1428. state_sync_end (void *cls,
  1429. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1430. uint64_t max_state_message_id,
  1431. uint64_t state_hash_message_id)
  1432. {
  1433. struct Plugin *plugin = cls;
  1434. int ret = GNUNET_SYSERR;
  1435. if (TRANSACTION_NONE != plugin->transaction)
  1436. {
  1437. /** @todo FIXME: wait for other transaction to finish */
  1438. return GNUNET_SYSERR;
  1439. }
  1440. GNUNET_OK == transaction_begin (plugin, TRANSACTION_STATE_SYNC)
  1441. && GNUNET_OK == exec_channel (plugin, plugin->delete_state, channel_key)
  1442. && GNUNET_OK == exec_channel (plugin, plugin->insert_state_from_sync,
  1443. channel_key)
  1444. && GNUNET_OK == exec_channel (plugin, plugin->delete_state_sync,
  1445. channel_key)
  1446. && GNUNET_OK == update_message_id (plugin,
  1447. plugin->update_state_hash_message_id,
  1448. channel_key, state_hash_message_id)
  1449. && GNUNET_OK == update_message_id (plugin,
  1450. plugin->update_max_state_message_id,
  1451. channel_key, max_state_message_id)
  1452. && GNUNET_OK == transaction_commit (plugin)
  1453. ? ret = GNUNET_OK
  1454. : transaction_rollback (plugin);
  1455. return ret;
  1456. }
  1457. /**
  1458. * Delete the whole state.
  1459. *
  1460. * @see GNUNET_PSYCSTORE_state_reset()
  1461. *
  1462. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1463. */
  1464. static int
  1465. state_reset (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key)
  1466. {
  1467. struct Plugin *plugin = cls;
  1468. return exec_channel (plugin, plugin->delete_state, channel_key);
  1469. }
  1470. /**
  1471. * Update signed values of state variables in the state store.
  1472. *
  1473. * @see GNUNET_PSYCSTORE_state_hash_update()
  1474. *
  1475. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1476. */
  1477. static int
  1478. state_update_signed (void *cls,
  1479. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key)
  1480. {
  1481. struct Plugin *plugin = cls;
  1482. return exec_channel (plugin, plugin->update_state_signed, channel_key);
  1483. }
  1484. /**
  1485. * Retrieve a state variable by name.
  1486. *
  1487. * @see GNUNET_PSYCSTORE_state_get()
  1488. *
  1489. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1490. */
  1491. static int
  1492. state_get (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1493. const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
  1494. {
  1495. struct Plugin *plugin = cls;
  1496. int ret = GNUNET_SYSERR;
  1497. sqlite3_stmt *stmt = plugin->select_state_one;
  1498. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1499. sizeof (*channel_key),
  1500. SQLITE_STATIC)
  1501. || SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC))
  1502. {
  1503. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1504. "sqlite3_bind");
  1505. }
  1506. else
  1507. {
  1508. switch (sqlite3_step (stmt))
  1509. {
  1510. case SQLITE_DONE:
  1511. ret = GNUNET_NO;
  1512. break;
  1513. case SQLITE_ROW:
  1514. ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0),
  1515. sqlite3_column_bytes (stmt, 0));
  1516. break;
  1517. default:
  1518. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1519. "sqlite3_step");
  1520. }
  1521. }
  1522. if (SQLITE_OK != sqlite3_reset (stmt))
  1523. {
  1524. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1525. "sqlite3_reset");
  1526. }
  1527. return ret;
  1528. }
  1529. /**
  1530. * Retrieve all state variables for a channel with the given prefix.
  1531. *
  1532. * @see GNUNET_PSYCSTORE_state_get_prefix()
  1533. *
  1534. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1535. */
  1536. static int
  1537. state_get_prefix (void *cls, const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1538. const char *name, GNUNET_PSYCSTORE_StateCallback cb,
  1539. void *cb_cls)
  1540. {
  1541. struct Plugin *plugin = cls;
  1542. int ret = GNUNET_SYSERR;
  1543. sqlite3_stmt *stmt = plugin->select_state_prefix;
  1544. size_t name_len = strlen (name);
  1545. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1546. sizeof (*channel_key), SQLITE_STATIC)
  1547. || SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC)
  1548. || SQLITE_OK != sqlite3_bind_int (stmt, 3, name_len)
  1549. || SQLITE_OK != sqlite3_bind_text (stmt, 4, name, name_len, SQLITE_STATIC))
  1550. {
  1551. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1552. "sqlite3_bind");
  1553. }
  1554. else
  1555. {
  1556. int sql_ret;
  1557. do
  1558. {
  1559. sql_ret = sqlite3_step (stmt);
  1560. switch (sql_ret)
  1561. {
  1562. case SQLITE_DONE:
  1563. if (ret != GNUNET_OK)
  1564. ret = GNUNET_NO;
  1565. break;
  1566. case SQLITE_ROW:
  1567. ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
  1568. sqlite3_column_blob (stmt, 1),
  1569. sqlite3_column_bytes (stmt, 1));
  1570. if (ret != GNUNET_YES)
  1571. sql_ret = SQLITE_DONE;
  1572. break;
  1573. default:
  1574. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1575. "sqlite3_step");
  1576. }
  1577. }
  1578. while (sql_ret == SQLITE_ROW);
  1579. }
  1580. if (SQLITE_OK != sqlite3_reset (stmt))
  1581. {
  1582. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1583. "sqlite3_reset");
  1584. }
  1585. return ret;
  1586. }
  1587. /**
  1588. * Retrieve all signed state variables for a channel.
  1589. *
  1590. * @see GNUNET_PSYCSTORE_state_get_signed()
  1591. *
  1592. * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  1593. */
  1594. static int
  1595. state_get_signed (void *cls,
  1596. const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
  1597. GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls)
  1598. {
  1599. struct Plugin *plugin = cls;
  1600. int ret = GNUNET_SYSERR;
  1601. sqlite3_stmt *stmt = plugin->select_state_signed;
  1602. if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key,
  1603. sizeof (*channel_key), SQLITE_STATIC))
  1604. {
  1605. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1606. "sqlite3_bind");
  1607. }
  1608. else
  1609. {
  1610. int sql_ret;
  1611. do
  1612. {
  1613. sql_ret = sqlite3_step (stmt);
  1614. switch (sql_ret)
  1615. {
  1616. case SQLITE_DONE:
  1617. if (ret != GNUNET_OK)
  1618. ret = GNUNET_NO;
  1619. break;
  1620. case SQLITE_ROW:
  1621. ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0),
  1622. sqlite3_column_blob (stmt, 1),
  1623. sqlite3_column_bytes (stmt, 1));
  1624. if (ret != GNUNET_YES)
  1625. sql_ret = SQLITE_DONE;
  1626. break;
  1627. default:
  1628. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1629. "sqlite3_step");
  1630. }
  1631. }
  1632. while (sql_ret == SQLITE_ROW);
  1633. }
  1634. if (SQLITE_OK != sqlite3_reset (stmt))
  1635. {
  1636. LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
  1637. "sqlite3_reset");
  1638. }
  1639. return ret;
  1640. }
  1641. /**
  1642. * Entry point for the plugin.
  1643. *
  1644. * @param cls The struct GNUNET_CONFIGURATION_Handle.
  1645. * @return NULL on error, otherwise the plugin context
  1646. */
  1647. void *
  1648. libgnunet_plugin_psycstore_sqlite_init (void *cls)
  1649. {
  1650. static struct Plugin plugin;
  1651. const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
  1652. struct GNUNET_PSYCSTORE_PluginFunctions *api;
  1653. if (NULL != plugin.cfg)
  1654. return NULL; /* can only initialize once! */
  1655. memset (&plugin, 0, sizeof (struct Plugin));
  1656. plugin.cfg = cfg;
  1657. if (GNUNET_OK != database_setup (&plugin))
  1658. {
  1659. database_shutdown (&plugin);
  1660. return NULL;
  1661. }
  1662. api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions);
  1663. api->cls = &plugin;
  1664. api->membership_store = &sqlite_membership_store;
  1665. api->membership_test = &membership_test;
  1666. api->fragment_store = &fragment_store;
  1667. api->message_add_flags = &message_add_flags;
  1668. api->fragment_get = &fragment_get;
  1669. api->fragment_get_latest = &fragment_get_latest;
  1670. api->message_get = &message_get;
  1671. api->message_get_latest = &message_get_latest;
  1672. api->message_get_fragment = &message_get_fragment;
  1673. api->counters_message_get = &counters_message_get;
  1674. api->counters_state_get = &counters_state_get;
  1675. api->state_modify_begin = &state_modify_begin;
  1676. api->state_modify_op = &state_modify_op;
  1677. api->state_modify_end = &state_modify_end;
  1678. api->state_sync_begin = &state_sync_begin;
  1679. api->state_sync_assign = &state_sync_assign;
  1680. api->state_sync_end = &state_sync_end;
  1681. api->state_reset = &state_reset;
  1682. api->state_update_signed = &state_update_signed;
  1683. api->state_get = &state_get;
  1684. api->state_get_prefix = &state_get_prefix;
  1685. api->state_get_signed = &state_get_signed;
  1686. LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n"));
  1687. return api;
  1688. }
  1689. /**
  1690. * Exit point from the plugin.
  1691. *
  1692. * @param cls The plugin context (as returned by "init")
  1693. * @return Always NULL
  1694. */
  1695. void *
  1696. libgnunet_plugin_psycstore_sqlite_done (void *cls)
  1697. {
  1698. struct GNUNET_PSYCSTORE_PluginFunctions *api = cls;
  1699. struct Plugin *plugin = api->cls;
  1700. database_shutdown (plugin);
  1701. plugin->cfg = NULL;
  1702. GNUNET_free (api);
  1703. LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n");
  1704. return NULL;
  1705. }
  1706. /* end of plugin_psycstore_sqlite.c */