diff options
author | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
---|---|---|
committer | Gabor X Toth <*@tg-x.net> | 2013-09-03 22:33:21 +0000 |
commit | eb9556bf2983ca19a5cbcf7cf460a0b2509b290a (patch) | |
tree | 285d31e951f7ecf9308b22257adcadd5b07d80ea /src/psycstore | |
parent | 37bafa60a6f0e447cb5b61547404f0902fa7ad41 (diff) | |
download | gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.tar.gz gnunet-eb9556bf2983ca19a5cbcf7cf460a0b2509b290a.zip |
PSYCstore SQLite backend; API fixes/enhancements
Diffstat (limited to 'src/psycstore')
-rw-r--r-- | src/psycstore/Makefile.am | 13 | ||||
-rw-r--r-- | src/psycstore/gnunet-service-psycstore.c | 59 | ||||
-rw-r--r-- | src/psycstore/plugin_psycstore_sqlite.c | 1172 | ||||
-rw-r--r-- | src/psycstore/psycstore.conf | 2 | ||||
-rw-r--r-- | src/psycstore/psycstore.h | 28 | ||||
-rw-r--r-- | src/psycstore/psycstore_api.c | 44 | ||||
-rw-r--r-- | src/psycstore/test_plugin_psycstore.c | 375 | ||||
-rw-r--r-- | src/psycstore/test_plugin_psycstore_sqlite.conf | 2 | ||||
-rw-r--r-- | src/psycstore/test_psycstore.c | 33 | ||||
-rw-r--r-- | src/psycstore/test_psycstore.conf | 11 |
10 files changed, 1486 insertions, 253 deletions
diff --git a/src/psycstore/Makefile.am b/src/psycstore/Makefile.am index 48f8d5ff7..6f5c7187f 100644 --- a/src/psycstore/Makefile.am +++ b/src/psycstore/Makefile.am | |||
@@ -22,7 +22,7 @@ endif | |||
22 | if HAVE_SQLITE | 22 | if HAVE_SQLITE |
23 | SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la | 23 | SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la |
24 | if HAVE_TESTING | 24 | if HAVE_TESTING |
25 | #SQLITE_TESTS = test_plugin_psycstore_sqlite | 25 | SQLITE_TESTS = test_plugin_psycstore_sqlite |
26 | endif | 26 | endif |
27 | endif | 27 | endif |
28 | 28 | ||
@@ -99,3 +99,14 @@ EXTRA_DIST = \ | |||
99 | test_psycstore.conf | 99 | test_psycstore.conf |
100 | 100 | ||
101 | 101 | ||
102 | test_plugin_psycstore_sqlite_SOURCES = \ | ||
103 | test_plugin_psycstore.c | ||
104 | test_plugin_psycstore_sqlite_LDADD = \ | ||
105 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
106 | $(top_builddir)/src/util/libgnunetutil.la | ||
107 | |||
108 | test_plugin_psycstore_postgres_SOURCES = \ | ||
109 | test_plugin_psycstore.c | ||
110 | test_plugin_psycstore_postgres_LDADD = \ | ||
111 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
112 | $(top_builddir)/src/util/libgnunetutil.la | ||
diff --git a/src/psycstore/gnunet-service-psycstore.c b/src/psycstore/gnunet-service-psycstore.c index d8f7a2690..5bc35d227 100644 --- a/src/psycstore/gnunet-service-psycstore.c +++ b/src/psycstore/gnunet-service-psycstore.c | |||
@@ -101,27 +101,72 @@ send_result_code (struct GNUNET_SERVER_Client *client, | |||
101 | uint32_t result_code, | 101 | uint32_t result_code, |
102 | const char *emsg) | 102 | const char *emsg) |
103 | { | 103 | { |
104 | struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm; | 104 | struct ResultCodeMessage *rcm; |
105 | size_t elen; | 105 | size_t elen; |
106 | 106 | ||
107 | if (NULL == emsg) | 107 | if (NULL == emsg) |
108 | elen = 0; | 108 | elen = 0; |
109 | else | 109 | else |
110 | elen = strlen (emsg) + 1; | 110 | elen = strlen (emsg) + 1; |
111 | rcm = GNUNET_malloc (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) + elen); | 111 | rcm = GNUNET_malloc (sizeof (struct ResultCodeMessage) + elen); |
112 | rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE); | 112 | rcm->header.type = htons (GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE); |
113 | rcm->header.size = htons (sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) + elen); | 113 | rcm->header.size = htons (sizeof (struct ResultCodeMessage) + elen); |
114 | rcm->result_code = htonl (result_code); | 114 | rcm->result_code = htonl (result_code); |
115 | memcpy (&rcm[1], emsg, elen); | 115 | memcpy (&rcm[1], emsg, elen); |
116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
117 | "Sending result %d (%s) to client\n", | 117 | "Sending result %d (%s) to client\n", |
118 | (int) result_code, | 118 | (int) result_code, |
119 | emsg); | 119 | emsg); |
120 | GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, GNUNET_NO); | 120 | GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, |
121 | GNUNET_NO); | ||
121 | GNUNET_free (rcm); | 122 | GNUNET_free (rcm); |
122 | } | 123 | } |
123 | 124 | ||
124 | 125 | ||
126 | static void | ||
127 | handle_membership_store (void *cls, | ||
128 | struct GNUNET_SERVER_Client *client, | ||
129 | const struct GNUNET_MessageHeader *message) | ||
130 | { | ||
131 | const struct MembershipStoreMessage *msg = | ||
132 | (const struct MembershipStoreMessage *) message; | ||
133 | |||
134 | int res = db->membership_store (db->cls, msg->channel_key, msg->slave_key, | ||
135 | msg->did_join, msg->announced_at, | ||
136 | msg->effective_since, msg->group_generation); | ||
137 | |||
138 | if (res != GNUNET_OK) | ||
139 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
140 | _("Failed to store membership information!\n")); | ||
141 | |||
142 | send_result_code (client, res, NULL); | ||
143 | } | ||
144 | |||
145 | |||
146 | static void | ||
147 | handle_membership_test (void *cls, | ||
148 | struct GNUNET_SERVER_Client *client, | ||
149 | const struct GNUNET_MessageHeader *message) | ||
150 | { | ||
151 | const struct MembershipTestMessage *msg = | ||
152 | (const struct MembershipTestMessage *) message; | ||
153 | |||
154 | int res = db->membership_test (db->cls, msg->channel_key, msg->slave_key, | ||
155 | msg->message_id); | ||
156 | switch (res) | ||
157 | { | ||
158 | case GNUNET_YES: | ||
159 | case GNUNET_NO: | ||
160 | break; | ||
161 | default: | ||
162 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
163 | _("Failed to test membership!\n")); | ||
164 | } | ||
165 | |||
166 | send_result_code (client, res, NULL); | ||
167 | } | ||
168 | |||
169 | |||
125 | /** | 170 | /** |
126 | * Handle PSYCstore clients. | 171 | * Handle PSYCstore clients. |
127 | * | 172 | * |
@@ -135,6 +180,12 @@ run (void *cls, | |||
135 | const struct GNUNET_CONFIGURATION_Handle *c) | 180 | const struct GNUNET_CONFIGURATION_Handle *c) |
136 | { | 181 | { |
137 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 182 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
183 | {&handle_membership_store, NULL, | ||
184 | GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE, | ||
185 | sizeof (struct MembershipStoreMessage)}, | ||
186 | {&handle_membership_test, NULL, | ||
187 | GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST, | ||
188 | sizeof (struct MembershipTestMessage)}, | ||
138 | {NULL, NULL, 0, 0} | 189 | {NULL, NULL, 0, 0} |
139 | }; | 190 | }; |
140 | 191 | ||
diff --git a/src/psycstore/plugin_psycstore_sqlite.c b/src/psycstore/plugin_psycstore_sqlite.c index 8bec31f12..f214e1c60 100644 --- a/src/psycstore/plugin_psycstore_sqlite.c +++ b/src/psycstore/plugin_psycstore_sqlite.c | |||
@@ -25,9 +25,16 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | ||
29 | * FIXME: SQLite3 only supports signed 64-bit integers natively, | ||
30 | * thus it can only store 63 bits of the uint64_t's. | ||
31 | */ | ||
32 | |||
28 | #include "platform.h" | 33 | #include "platform.h" |
29 | #include "gnunet_psycstore_plugin.h" | 34 | #include "gnunet_psycstore_plugin.h" |
30 | #include "gnunet_psycstore_service.h" | 35 | #include "gnunet_psycstore_service.h" |
36 | #include "gnunet_multicast_service.h" | ||
37 | #include "gnunet_crypto_lib.h" | ||
31 | #include "psycstore.h" | 38 | #include "psycstore.h" |
32 | #include <sqlite3.h> | 39 | #include <sqlite3.h> |
33 | 40 | ||
@@ -43,13 +50,14 @@ t * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
43 | */ | 50 | */ |
44 | #define BUSY_TIMEOUT_MS 1000 | 51 | #define BUSY_TIMEOUT_MS 1000 |
45 | 52 | ||
53 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
46 | 54 | ||
47 | /** | 55 | /** |
48 | * Log an error message at log-level 'level' that indicates | 56 | * Log an error message at log-level 'level' that indicates |
49 | * a failure of the command 'cmd' on file 'filename' | 57 | * a failure of the command 'cmd' on file 'filename' |
50 | * with the message given by strerror(errno). | 58 | * with the message given by strerror(errno). |
51 | */ | 59 | */ |
52 | #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "psycstore-sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) | 60 | #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) |
53 | 61 | ||
54 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) | 62 | #define LOG(kind,...) GNUNET_log_from (kind, "psycstore-sqlite", __VA_ARGS__) |
55 | 63 | ||
@@ -100,9 +108,9 @@ struct Plugin | |||
100 | sqlite3_stmt *insert_fragment; | 108 | sqlite3_stmt *insert_fragment; |
101 | 109 | ||
102 | /** | 110 | /** |
103 | * Precompiled SQL for fragment_add_flags() | 111 | * Precompiled SQL for message_add_flags() |
104 | */ | 112 | */ |
105 | sqlite3_stmt *update_fragment_flags; | 113 | sqlite3_stmt *update_message_flags; |
106 | 114 | ||
107 | /** | 115 | /** |
108 | * Precompiled SQL for fragment_get() | 116 | * Precompiled SQL for fragment_get() |
@@ -122,12 +130,12 @@ struct Plugin | |||
122 | /** | 130 | /** |
123 | * Precompiled SQL for counters_get_master() | 131 | * Precompiled SQL for counters_get_master() |
124 | */ | 132 | */ |
125 | sqlite3_stmt *select_master_counters; | 133 | sqlite3_stmt *select_counters_master; |
126 | 134 | ||
127 | /** | 135 | /** |
128 | * Precompiled SQL for counters_get_slave() | 136 | * Precompiled SQL for counters_get_slave() |
129 | */ | 137 | */ |
130 | sqlite3_stmt *select_slave_counters; | 138 | sqlite3_stmt *select_counters_slave; |
131 | 139 | ||
132 | 140 | ||
133 | /** | 141 | /** |
@@ -136,11 +144,6 @@ struct Plugin | |||
136 | sqlite3_stmt *insert_state_current; | 144 | sqlite3_stmt *insert_state_current; |
137 | 145 | ||
138 | /** | 146 | /** |
139 | * Precompiled SQL for state_set() | ||
140 | */ | ||
141 | sqlite3_stmt *update_state_current; | ||
142 | |||
143 | /** | ||
144 | * Precompiled SQL for state_set_signed() | 147 | * Precompiled SQL for state_set_signed() |
145 | */ | 148 | */ |
146 | sqlite3_stmt *update_state_signed; | 149 | sqlite3_stmt *update_state_signed; |
@@ -166,6 +169,11 @@ struct Plugin | |||
166 | sqlite3_stmt *delete_state_sync; | 169 | sqlite3_stmt *delete_state_sync; |
167 | 170 | ||
168 | /** | 171 | /** |
172 | * Precompiled SQL for state_get_signed() | ||
173 | */ | ||
174 | sqlite3_stmt *select_state_signed; | ||
175 | |||
176 | /** | ||
169 | * Precompiled SQL for state_get() | 177 | * Precompiled SQL for state_get() |
170 | */ | 178 | */ |
171 | sqlite3_stmt *select_state_one; | 179 | sqlite3_stmt *select_state_one; |
@@ -177,6 +185,15 @@ struct Plugin | |||
177 | 185 | ||
178 | }; | 186 | }; |
179 | 187 | ||
188 | #if DEBUG_PSYCSTORE | ||
189 | |||
190 | static void | ||
191 | sql_trace (void *cls, const char *sql) | ||
192 | { | ||
193 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQL query:\n%s\n", sql); | ||
194 | } | ||
195 | |||
196 | #endif | ||
180 | 197 | ||
181 | /** | 198 | /** |
182 | * @brief Prepare a SQL statement | 199 | * @brief Prepare a SQL statement |
@@ -208,8 +225,7 @@ sql_prepare (sqlite3 *dbh, const char *sql, sqlite3_stmt **stmt) | |||
208 | * @brief Prepare a SQL statement | 225 | * @brief Prepare a SQL statement |
209 | * | 226 | * |
210 | * @param dbh handle to the database | 227 | * @param dbh handle to the database |
211 | * @param zSql SQL statement, UTF-8 encoded | 228 | * @param sql SQL statement, UTF-8 encoded |
212 | * @param ppStmt set to the prepared statement | ||
213 | * @return 0 on success | 229 | * @return 0 on success |
214 | */ | 230 | */ |
215 | static int | 231 | static int |
@@ -262,7 +278,7 @@ database_setup (struct Plugin *plugin) | |||
262 | plugin->fn = filename; | 278 | plugin->fn = filename; |
263 | 279 | ||
264 | /* Open database and precompile statements */ | 280 | /* Open database and precompile statements */ |
265 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | 281 | if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh)) |
266 | { | 282 | { |
267 | LOG (GNUNET_ERROR_TYPE_ERROR, | 283 | LOG (GNUNET_ERROR_TYPE_ERROR, |
268 | _("Unable to initialize SQLite: %s.\n"), | 284 | _("Unable to initialize SQLite: %s.\n"), |
@@ -270,6 +286,10 @@ database_setup (struct Plugin *plugin) | |||
270 | return GNUNET_SYSERR; | 286 | return GNUNET_SYSERR; |
271 | } | 287 | } |
272 | 288 | ||
289 | #if DEBUG_PSYCSTORE | ||
290 | sqlite3_trace (plugin->dbh, &sql_trace, NULL); | ||
291 | #endif | ||
292 | |||
273 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); | 293 | sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY"); |
274 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); | 294 | sql_exec (plugin->dbh, "PRAGMA synchronous=NORMAL"); |
275 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); | 295 | sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF"); |
@@ -284,62 +304,62 @@ database_setup (struct Plugin *plugin) | |||
284 | /* Create tables */ | 304 | /* Create tables */ |
285 | 305 | ||
286 | sql_exec (plugin->dbh, | 306 | sql_exec (plugin->dbh, |
287 | "CREATE TABLE IF NOT EXISTS channels (" | 307 | "CREATE TABLE IF NOT EXISTS channels (\n" |
288 | " id INTEGER PRIMARY KEY," | 308 | " id INTEGER PRIMARY KEY,\n" |
289 | " pub_key BLOB UNIQUE" | 309 | " pub_key BLOB UNIQUE\n" |
290 | ");"); | 310 | ");"); |
291 | 311 | ||
292 | sql_exec (plugin->dbh, | 312 | sql_exec (plugin->dbh, |
293 | "CREATE TABLE IF NOT EXISTS slaves (" | 313 | "CREATE TABLE IF NOT EXISTS slaves (\n" |
294 | " id INTEGER PRIMARY KEY," | 314 | " id INTEGER PRIMARY KEY,\n" |
295 | " pub_key BLOB UNIQUE" | 315 | " pub_key BLOB UNIQUE\n" |
296 | ");"); | 316 | ");"); |
297 | 317 | ||
298 | sql_exec (plugin->dbh, | 318 | sql_exec (plugin->dbh, |
299 | "CREATE TABLE IF NOT EXISTS membership (" | 319 | "CREATE TABLE IF NOT EXISTS membership (\n" |
300 | " channel_id INTEGER NOT NULL REFERENCES channels(id)," | 320 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
301 | " slave_id INTEGER NOT NULL REFERENCES slaves(id)," | 321 | " slave_id INTEGER NOT NULL REFERENCES slaves(id),\n" |
302 | " did_join INTEGER NOT NULL," | 322 | " did_join INTEGER NOT NULL,\n" |
303 | " announced_at INTEGER NOT NULL," | 323 | " announced_at INTEGER NOT NULL,\n" |
304 | " effective_since INTEGER NOT NULL," | 324 | " effective_since INTEGER NOT NULL,\n" |
305 | " group_generation INTEGER NOT NULL" | 325 | " group_generation INTEGER NOT NULL\n" |
306 | ");"); | 326 | ");"); |
307 | sql_exec (plugin->dbh, | 327 | sql_exec (plugin->dbh, |
308 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " | 328 | "CREATE INDEX IF NOT EXISTS idx_membership_channel_id_slave_id " |
309 | "ON membership (channel_id, slave_id);"); | 329 | "ON membership (channel_id, slave_id);"); |
310 | 330 | ||
311 | sql_exec (plugin->dbh, | 331 | sql_exec (plugin->dbh, |
312 | "CREATE TABLE IF NOT EXISTS messages (" | 332 | "CREATE TABLE IF NOT EXISTS messages (\n" |
313 | " channel_id INTEGER NOT NULL," | 333 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
314 | " hop_counter INTEGER NOT NULL," | 334 | " hop_counter INTEGER NOT NULL,\n" |
315 | " signature BLOB," | 335 | " signature BLOB,\n" |
316 | " purpose BLOB," | 336 | " purpose BLOB,\n" |
317 | " fragment_id INTEGER NOT NULL," | 337 | " fragment_id INTEGER NOT NULL,\n" |
318 | " fragment_offset INTEGER NOT NULL," | 338 | " fragment_offset INTEGER NOT NULL,\n" |
319 | " message_id INTEGER NOT NULL," | 339 | " message_id INTEGER NOT NULL,\n" |
320 | " group_generation INTEGER NOT NULL," | 340 | " group_generation INTEGER NOT NULL,\n" |
321 | " multicast_flags INTEGER NOT NULL," | 341 | " multicast_flags INTEGER NOT NULL,\n" |
322 | " psyc_flags INTEGER NOT NULL," | 342 | " psycstore_flags INTEGER NOT NULL,\n" |
323 | " data BLOB," | 343 | " data BLOB,\n" |
324 | " PRIMARY KEY (channel_id, fragment_id)," | 344 | " PRIMARY KEY (channel_id, fragment_id),\n" |
325 | " UNIQUE (channel_id, message_id, fragment_offset)" | 345 | " UNIQUE (channel_id, message_id, fragment_offset)\n" |
326 | ");"); | 346 | ");"); |
327 | 347 | ||
328 | sql_exec (plugin->dbh, | 348 | sql_exec (plugin->dbh, |
329 | "CREATE TABLE IF NOT EXISTS state (" | 349 | "CREATE TABLE IF NOT EXISTS state (\n" |
330 | " channel_id INTEGER NOT NULL," | 350 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
331 | " name TEXT NOT NULL," | 351 | " name TEXT NOT NULL,\n" |
332 | " value_current BLOB, " | 352 | " value_current BLOB,\n" |
333 | " value_signed BLOB, " | 353 | " value_signed BLOB,\n" |
334 | " PRIMARY KEY (channel_id, name)" | 354 | " PRIMARY KEY (channel_id, name)\n" |
335 | ");"); | 355 | ");"); |
336 | 356 | ||
337 | sql_exec (plugin->dbh, | 357 | sql_exec (plugin->dbh, |
338 | "CREATE TABLE IF NOT EXISTS state_sync (" | 358 | "CREATE TABLE IF NOT EXISTS state_sync (\n" |
339 | " channel_id INTEGER NOT NULL," | 359 | " channel_id INTEGER NOT NULL REFERENCES channels(id),\n" |
340 | " name TEXT NOT NULL," | 360 | " name TEXT NOT NULL,\n" |
341 | " value BLOB, " | 361 | " value BLOB,\n" |
342 | " PRIMARY KEY (channel_id, name)" | 362 | " PRIMARY KEY (channel_id, name)\n" |
343 | ");"); | 363 | ");"); |
344 | 364 | ||
345 | /* Prepare statements */ | 365 | /* Prepare statements */ |
@@ -353,132 +373,143 @@ database_setup (struct Plugin *plugin) | |||
353 | &plugin->insert_slave_key); | 373 | &plugin->insert_slave_key); |
354 | 374 | ||
355 | sql_prepare (plugin->dbh, | 375 | sql_prepare (plugin->dbh, |
356 | "INSERT INTO membership " | 376 | "INSERT INTO membership\n" |
357 | " (channel_id, slave_id, did_join, announced_at, " | 377 | " (channel_id, slave_id, did_join, announced_at,\n" |
358 | " effective_since, group_generation) " | 378 | " effective_since, group_generation)\n" |
359 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 379 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
360 | " (SELECT id FROM slaves WHERE pub_key = ?), " | 380 | " (SELECT id FROM slaves WHERE pub_key = ?),\n" |
361 | " ?, ?, ?, ?);", | 381 | " ?, ?, ?, ?);", |
362 | &plugin->insert_membership); | 382 | &plugin->insert_membership); |
363 | 383 | ||
364 | sql_prepare (plugin->dbh, | 384 | sql_prepare (plugin->dbh, |
365 | "SELECT did_join FROM membership " | 385 | "SELECT did_join FROM membership\n" |
366 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 386 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
367 | " AND slave_id = ? AND effective_since <= ? " | 387 | " AND slave_id = (SELECT id FROM slaves WHERE pub_key = ?)\n" |
388 | " AND effective_since <= ? AND did_join = 1\n" | ||
368 | "ORDER BY announced_at DESC LIMIT 1;", | 389 | "ORDER BY announced_at DESC LIMIT 1;", |
369 | &plugin->select_membership); | 390 | &plugin->select_membership); |
370 | 391 | ||
371 | sql_prepare (plugin->dbh, | 392 | sql_prepare (plugin->dbh, |
372 | "INSERT INTO messages " | 393 | "INSERT INTO messages\n" |
373 | " (channel_id, hop_counter, signature, purpose, " | 394 | " (channel_id, hop_counter, signature, purpose,\n" |
374 | " fragment_id, fragment_offset, message_id, " | 395 | " fragment_id, fragment_offset, message_id,\n" |
375 | " group_generation, multicast_flags, psyc_flags, data) " | 396 | " group_generation, multicast_flags, psycstore_flags, data)\n" |
376 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), " | 397 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?),\n" |
377 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", | 398 | " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", |
378 | &plugin->insert_fragment); | 399 | &plugin->insert_fragment); |
379 | 400 | ||
380 | sql_prepare (plugin->dbh, | 401 | sql_prepare (plugin->dbh, |
381 | "UPDATE messages " | 402 | "UPDATE messages\n" |
382 | "SET multicast_flags = multicast_flags | ?, " | 403 | "SET psycstore_flags = psycstore_flags | ?\n" |
383 | " psyc_flags = psyc_flags | ? " | 404 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
384 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 405 | " AND message_id = ? AND fragment_offset = 0;", |
385 | " AND message_id = ?;", | 406 | &plugin->update_message_flags); |
386 | &plugin->update_fragment_flags); | ||
387 | 407 | ||
388 | sql_prepare (plugin->dbh, | 408 | sql_prepare (plugin->dbh, |
389 | "SELECT hop_counter, signature, purpose, " | 409 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
390 | " fragment_offset, message_id, group_generation, " | 410 | " fragment_offset, message_id, group_generation,\n" |
391 | " multicast_flags, psyc_flags, data " | 411 | " multicast_flags, psycstore_flags, data\n" |
392 | "FROM messages " | 412 | "FROM messages\n" |
393 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 413 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
394 | " AND fragment_id = ?;", | 414 | " AND fragment_id = ?;", |
395 | &plugin->select_fragment); | 415 | &plugin->select_fragment); |
396 | 416 | ||
397 | sql_prepare (plugin->dbh, | 417 | sql_prepare (plugin->dbh, |
398 | "SELECT hop_counter, signature, purpose, " | 418 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
399 | " fragment_id, fragment_offset, group_generation, " | 419 | " fragment_offset, message_id, group_generation,\n" |
400 | " multicast_flags, psyc_flags, data " | 420 | " multicast_flags, psycstore_flags, data\n" |
401 | "FROM messages " | 421 | "FROM messages\n" |
402 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 422 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
403 | " AND message_id = ?;", | 423 | " AND message_id = ?;", |
404 | &plugin->select_message); | 424 | &plugin->select_message); |
405 | 425 | ||
406 | sql_prepare (plugin->dbh, | 426 | sql_prepare (plugin->dbh, |
407 | "SELECT hop_counter, signature, purpose, " | 427 | "SELECT hop_counter, signature, purpose, fragment_id,\n" |
408 | " fragment_id, message_id, group_generation, " | 428 | " fragment_offset, message_id, group_generation,\n" |
409 | " multicast_flags, psyc_flags, data " | 429 | " multicast_flags, psycstore_flags, data\n" |
410 | "FROM messages " | 430 | "FROM messages\n" |
411 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 431 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
412 | " AND message_id = ? AND fragment_offset = ?;", | 432 | " AND message_id = ? AND fragment_offset = ?;", |
413 | &plugin->select_message_fragment); | 433 | &plugin->select_message_fragment); |
414 | 434 | ||
415 | sql_prepare (plugin->dbh, | 435 | sql_prepare (plugin->dbh, |
416 | "SELECT max(fragment_id), max(message_id), max(group_generation) " | 436 | "SELECT fragment_id, message_id, group_generation\n" |
417 | "FROM messages " | 437 | "FROM messages\n" |
418 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 438 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
419 | &plugin->select_master_counters); | 439 | "ORDER BY fragment_id DESC LIMIT 1;", |
440 | &plugin->select_counters_master); | ||
420 | 441 | ||
421 | sql_prepare (plugin->dbh, | 442 | sql_prepare (plugin->dbh, |
422 | "SELECT max(message_id) " | 443 | "SELECT message_id\n" |
423 | "FROM messages " | 444 | "FROM messages\n" |
424 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 445 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
425 | " AND psyc_flags & ?;", | 446 | " AND psycstore_flags & ?\n" |
426 | &plugin->select_slave_counters); | 447 | "ORDER BY message_id DESC LIMIT 1", |
448 | &plugin->select_counters_slave); | ||
427 | 449 | ||
428 | sql_prepare (plugin->dbh, | 450 | sql_prepare (plugin->dbh, |
429 | "INSERT OR REPLACE INTO state (channel_id, name, value_current) " | 451 | "INSERT OR REPLACE INTO state\n" |
430 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 452 | " (channel_id, name, value_current, value_signed)\n" |
453 | "SELECT new.channel_id, new.name,\n" | ||
454 | " new.value_current, old.value_signed\n" | ||
455 | "FROM (SELECT (SELECT id FROM channels WHERE pub_key = ?)\n" | ||
456 | " AS channel_id,\n" | ||
457 | " ? AS name, ? AS value_current) AS new\n" | ||
458 | "LEFT JOIN (SELECT channel_id, name, value_signed\n" | ||
459 | " FROM state) AS old\n" | ||
460 | "ON new.channel_id = old.channel_id AND new.name = old.name;", | ||
431 | &plugin->insert_state_current); | 461 | &plugin->insert_state_current); |
432 | 462 | ||
433 | sql_prepare (plugin->dbh, | 463 | sql_prepare (plugin->dbh, |
434 | "UPDATE state " | 464 | "UPDATE state\n" |
435 | "SET value_current = ? " | 465 | "SET value_signed = value_current\n" |
436 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 466 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
437 | " AND name = ?;", | ||
438 | &plugin->update_state_current); | ||
439 | |||
440 | sql_prepare (plugin->dbh, | ||
441 | "UPDATE state " | ||
442 | "SET value_signed = value_current " | ||
443 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) ", | ||
444 | &plugin->update_state_signed); | 467 | &plugin->update_state_signed); |
445 | 468 | ||
446 | sql_prepare (plugin->dbh, | 469 | sql_prepare (plugin->dbh, |
447 | "INSERT INTO state_sync (channel_id, name, value) " | 470 | "INSERT INTO state_sync (channel_id, name, value)\n" |
448 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", | 471 | "VALUES ((SELECT id FROM channels WHERE pub_key = ?), ?, ?);", |
449 | &plugin->insert_state_sync); | 472 | &plugin->insert_state_sync); |
450 | 473 | ||
451 | sql_prepare (plugin->dbh, | 474 | sql_prepare (plugin->dbh, |
452 | "DELETE FROM state " | 475 | "DELETE FROM state\n" |
453 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 476 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
454 | &plugin->delete_state); | 477 | &plugin->delete_state); |
455 | 478 | ||
456 | sql_prepare (plugin->dbh, | 479 | sql_prepare (plugin->dbh, |
457 | "INSERT INTO state " | 480 | "INSERT INTO state\n" |
458 | " (channel_id, name, value_current, value_signed) " | 481 | " (channel_id, name, value_current, value_signed)\n" |
459 | "SELECT channel_id, name, value, value " | 482 | "SELECT channel_id, name, value, value\n" |
460 | "FROM state_sync " | 483 | "FROM state_sync\n" |
461 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 484 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
462 | &plugin->insert_state_from_sync); | 485 | &plugin->insert_state_from_sync); |
463 | 486 | ||
464 | sql_prepare (plugin->dbh, | 487 | sql_prepare (plugin->dbh, |
465 | "DELETE FROM state_sync " | 488 | "DELETE FROM state_sync\n" |
466 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", | 489 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?);", |
467 | &plugin->delete_state_sync); | 490 | &plugin->delete_state_sync); |
468 | 491 | ||
469 | sql_prepare (plugin->dbh, | 492 | sql_prepare (plugin->dbh, |
470 | "SELECT value_current " | 493 | "SELECT value_current\n" |
471 | "FROM state " | 494 | "FROM state\n" |
472 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?) " | 495 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
473 | " AND name = ?;", | 496 | " AND name = ?;", |
474 | &plugin->select_state_one); | 497 | &plugin->select_state_one); |
475 | 498 | ||
476 | sql_prepare (plugin->dbh, | 499 | sql_prepare (plugin->dbh, |
477 | "SELECT value_current " | 500 | "SELECT name, value_current\n" |
478 | "FROM state " | 501 | "FROM state\n" |
479 | "WHERE name LIKE ? OR name LIKE ?;", | 502 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)\n" |
503 | " AND name = ? OR name LIKE ?;", | ||
480 | &plugin->select_state_prefix); | 504 | &plugin->select_state_prefix); |
481 | 505 | ||
506 | sql_prepare (plugin->dbh, | ||
507 | "SELECT name, value_signed\n" | ||
508 | "FROM state\n" | ||
509 | "WHERE channel_id = (SELECT id FROM channels WHERE pub_key = ?)" | ||
510 | " AND value_signed IS NOT NULL;", | ||
511 | &plugin->select_state_signed); | ||
512 | |||
482 | return GNUNET_OK; | 513 | return GNUNET_OK; |
483 | } | 514 | } |
484 | 515 | ||
@@ -509,8 +540,8 @@ database_shutdown (struct Plugin *plugin) | |||
509 | if (NULL != plugin->insert_fragment) | 540 | if (NULL != plugin->insert_fragment) |
510 | sqlite3_finalize (plugin->insert_fragment); | 541 | sqlite3_finalize (plugin->insert_fragment); |
511 | 542 | ||
512 | if (NULL != plugin->update_fragment_flags) | 543 | if (NULL != plugin->update_message_flags) |
513 | sqlite3_finalize (plugin->update_fragment_flags); | 544 | sqlite3_finalize (plugin->update_message_flags); |
514 | 545 | ||
515 | if (NULL != plugin->select_fragment) | 546 | if (NULL != plugin->select_fragment) |
516 | sqlite3_finalize (plugin->select_fragment); | 547 | sqlite3_finalize (plugin->select_fragment); |
@@ -521,18 +552,15 @@ database_shutdown (struct Plugin *plugin) | |||
521 | if (NULL != plugin->select_message_fragment) | 552 | if (NULL != plugin->select_message_fragment) |
522 | sqlite3_finalize (plugin->select_message_fragment); | 553 | sqlite3_finalize (plugin->select_message_fragment); |
523 | 554 | ||
524 | if (NULL != plugin->select_master_counters) | 555 | if (NULL != plugin->select_counters_master) |
525 | sqlite3_finalize (plugin->select_master_counters); | 556 | sqlite3_finalize (plugin->select_counters_master); |
526 | 557 | ||
527 | if (NULL != plugin->select_slave_counters) | 558 | if (NULL != plugin->select_counters_slave) |
528 | sqlite3_finalize (plugin->select_slave_counters); | 559 | sqlite3_finalize (plugin->select_counters_slave); |
529 | 560 | ||
530 | if (NULL != plugin->insert_state_current) | 561 | if (NULL != plugin->insert_state_current) |
531 | sqlite3_finalize (plugin->insert_state_current); | 562 | sqlite3_finalize (plugin->insert_state_current); |
532 | 563 | ||
533 | if (NULL != plugin->update_state_current) | ||
534 | sqlite3_finalize (plugin->update_state_current); | ||
535 | |||
536 | if (NULL != plugin->update_state_signed) | 564 | if (NULL != plugin->update_state_signed) |
537 | sqlite3_finalize (plugin->update_state_signed); | 565 | sqlite3_finalize (plugin->update_state_signed); |
538 | 566 | ||
@@ -579,6 +607,65 @@ database_shutdown (struct Plugin *plugin) | |||
579 | } | 607 | } |
580 | 608 | ||
581 | 609 | ||
610 | static int | ||
611 | channel_key_store (struct Plugin *plugin, | ||
612 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
613 | { | ||
614 | sqlite3_stmt *stmt = plugin->insert_channel_key; | ||
615 | |||
616 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
617 | sizeof (*channel_key), SQLITE_STATIC)) | ||
618 | { | ||
619 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
620 | "insert_channel_key (bind)"); | ||
621 | } | ||
622 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
623 | { | ||
624 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
625 | "insert_channel_key (step)"); | ||
626 | } | ||
627 | |||
628 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
629 | { | ||
630 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
631 | "insert_channel_key (reset)"); | ||
632 | return GNUNET_SYSERR; | ||
633 | } | ||
634 | |||
635 | return GNUNET_OK; | ||
636 | } | ||
637 | |||
638 | |||
639 | static int | ||
640 | slave_key_store (struct Plugin *plugin, | ||
641 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key) | ||
642 | { | ||
643 | sqlite3_stmt *stmt = plugin->insert_slave_key; | ||
644 | |||
645 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, slave_key, | ||
646 | sizeof (*slave_key), SQLITE_STATIC)) | ||
647 | { | ||
648 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
649 | "insert_slave_key (bind)"); | ||
650 | } | ||
651 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
652 | { | ||
653 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
654 | "insert_slave_key (step)"); | ||
655 | } | ||
656 | |||
657 | |||
658 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
659 | { | ||
660 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
661 | "insert_slave_key (reset)"); | ||
662 | return GNUNET_SYSERR; | ||
663 | } | ||
664 | |||
665 | return GNUNET_OK; | ||
666 | } | ||
667 | |||
668 | |||
582 | /** | 669 | /** |
583 | * Store join/leave events for a PSYC channel in order to be able to answer | 670 | * Store join/leave events for a PSYC channel in order to be able to answer |
584 | * membership test queries later. | 671 | * membership test queries later. |
@@ -587,17 +674,56 @@ database_shutdown (struct Plugin *plugin) | |||
587 | * | 674 | * |
588 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 675 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
589 | */ | 676 | */ |
590 | int | 677 | static int |
591 | libgnunet_plugin_psycstore_sqlite_membership_store | 678 | membership_store (void *cls, |
592 | (void *cls, | 679 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
593 | const struct GNUNET_HashCode *channel_key, | 680 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
594 | const struct GNUNET_HashCode *slave_key, | 681 | int did_join, |
595 | int did_join, | 682 | uint64_t announced_at, |
596 | uint64_t announced_at, | 683 | uint64_t effective_since, |
597 | uint64_t effective_since, | 684 | uint64_t group_generation) |
598 | uint64_t group_generation) { | 685 | { |
686 | if (announced_at > INT64_MAX || | ||
687 | effective_since > INT64_MAX || | ||
688 | group_generation > INT64_MAX) | ||
689 | { | ||
690 | GNUNET_break (0); | ||
691 | return GNUNET_SYSERR; | ||
692 | } | ||
693 | |||
694 | struct Plugin *plugin = cls; | ||
695 | sqlite3_stmt *stmt = plugin->insert_membership; | ||
599 | 696 | ||
697 | if (GNUNET_OK != channel_key_store (plugin, channel_key) || | ||
698 | GNUNET_OK != slave_key_store (plugin, slave_key)) | ||
699 | return GNUNET_SYSERR; | ||
600 | 700 | ||
701 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
702 | sizeof (*channel_key), SQLITE_STATIC) || | ||
703 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
704 | sizeof (*slave_key), SQLITE_STATIC) || | ||
705 | SQLITE_OK != sqlite3_bind_int (stmt, 3, did_join) || | ||
706 | SQLITE_OK != sqlite3_bind_int64 (stmt, 4, announced_at) || | ||
707 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, effective_since) || | ||
708 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, group_generation)) | ||
709 | { | ||
710 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
711 | "insert_membership (bind)"); | ||
712 | } | ||
713 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
714 | { | ||
715 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
716 | "insert_membership (step)"); | ||
717 | } | ||
718 | |||
719 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
720 | { | ||
721 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
722 | "insert_membership (reset)"); | ||
723 | return GNUNET_SYSERR; | ||
724 | } | ||
725 | |||
726 | return GNUNET_OK; | ||
601 | } | 727 | } |
602 | 728 | ||
603 | /** | 729 | /** |
@@ -608,14 +734,44 @@ libgnunet_plugin_psycstore_sqlite_membership_store | |||
608 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, | 734 | * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not, |
609 | * #GNUNET_SYSERR if there was en error. | 735 | * #GNUNET_SYSERR if there was en error. |
610 | */ | 736 | */ |
611 | int | 737 | static int |
612 | libgnunet_plugin_psycstore_sqlite_membership_test | 738 | membership_test (void *cls, |
613 | (void *cls, | 739 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
614 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 740 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, |
615 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | 741 | uint64_t message_id) |
616 | uint64_t message_id, | 742 | { |
617 | uint64_t group_generation) { | 743 | struct Plugin *plugin = cls; |
744 | sqlite3_stmt *stmt = plugin->select_membership; | ||
745 | int ret = GNUNET_SYSERR; | ||
746 | |||
747 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
748 | sizeof (*channel_key), SQLITE_STATIC) || | ||
749 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, slave_key, | ||
750 | sizeof (*slave_key), SQLITE_STATIC) || | ||
751 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
752 | { | ||
753 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
754 | "select_membership (bind)"); | ||
755 | } | ||
756 | else | ||
757 | { | ||
758 | switch (sqlite3_step (stmt)) | ||
759 | { | ||
760 | case SQLITE_DONE: | ||
761 | ret = GNUNET_NO; | ||
762 | break; | ||
763 | case SQLITE_ROW: | ||
764 | ret = GNUNET_YES; | ||
765 | } | ||
766 | } | ||
618 | 767 | ||
768 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
769 | { | ||
770 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
771 | "select_membership (reset)"); | ||
772 | } | ||
773 | |||
774 | return ret; | ||
619 | } | 775 | } |
620 | 776 | ||
621 | /** | 777 | /** |
@@ -625,30 +781,141 @@ libgnunet_plugin_psycstore_sqlite_membership_test | |||
625 | * | 781 | * |
626 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
627 | */ | 783 | */ |
628 | int | 784 | static int |
629 | libgnunet_plugin_psycstore_sqlite_fragment_store | 785 | fragment_store (void *cls, |
630 | (void *cls, | 786 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
631 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 787 | const struct GNUNET_MULTICAST_MessageHeader *msg, |
632 | const struct GNUNET_MULTICAST_MessageHeader *message) { | 788 | uint32_t psycstore_flags) |
789 | { | ||
790 | if (msg->fragment_id > INT64_MAX || | ||
791 | msg->fragment_offset > INT64_MAX || | ||
792 | msg->message_id > INT64_MAX || | ||
793 | msg->group_generation > INT64_MAX) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | |||
799 | struct Plugin *plugin = cls; | ||
800 | sqlite3_stmt *stmt = plugin->insert_fragment; | ||
801 | |||
802 | if (GNUNET_OK != channel_key_store (plugin, channel_key)) | ||
803 | return GNUNET_SYSERR; | ||
804 | |||
805 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
806 | sizeof (*channel_key), SQLITE_STATIC) || | ||
807 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, msg->hop_counter ) || | ||
808 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, (const void *) &msg->signature, | ||
809 | sizeof (msg->signature), SQLITE_STATIC) || | ||
810 | SQLITE_OK != sqlite3_bind_blob (stmt, 4, (const void *) &msg->purpose, | ||
811 | sizeof (msg->purpose), SQLITE_STATIC) || | ||
812 | SQLITE_OK != sqlite3_bind_int64 (stmt, 5, msg->fragment_id) || | ||
813 | SQLITE_OK != sqlite3_bind_int64 (stmt, 6, msg->fragment_offset) || | ||
814 | SQLITE_OK != sqlite3_bind_int64 (stmt, 7, msg->message_id) || | ||
815 | SQLITE_OK != sqlite3_bind_int64 (stmt, 8, msg->group_generation) || | ||
816 | SQLITE_OK != sqlite3_bind_int64 (stmt, 9, msg->flags) || | ||
817 | SQLITE_OK != sqlite3_bind_int64 (stmt, 10, psycstore_flags) || | ||
818 | SQLITE_OK != sqlite3_bind_blob (stmt, 11, (const void *) &msg[1], | ||
819 | ntohs (msg->header.size) - sizeof (*msg), | ||
820 | SQLITE_STATIC)) | ||
821 | { | ||
822 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
823 | "insert_fragment (bind)"); | ||
824 | } | ||
825 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
826 | { | ||
827 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
828 | "insert_fragment (step)"); | ||
829 | } | ||
830 | |||
831 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
832 | { | ||
833 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
834 | "insert_fragment (reset)"); | ||
835 | return GNUNET_SYSERR; | ||
836 | } | ||
633 | 837 | ||
838 | return GNUNET_OK; | ||
634 | } | 839 | } |
635 | 840 | ||
636 | /** | 841 | /** |
637 | * Set additional flags for a given message. | 842 | * Set additional flags for a given message. |
638 | * | 843 | * |
844 | * They are OR'd with any existing flags set. | ||
845 | * | ||
846 | * @param plugin Plugin handle. | ||
847 | * @param channel_key Public key of the channel. | ||
639 | * @param message_id ID of the message. | 848 | * @param message_id ID of the message. |
640 | * @param flags Flags to add. | 849 | * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags. |
641 | * | 850 | * |
642 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 851 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
643 | */ | 852 | */ |
644 | int | 853 | static int |
645 | libgnunet_plugin_psycstore_sqlite_fragment_add_flags | 854 | message_add_flags (void *cls, |
646 | (void *cls, | 855 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
647 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 856 | uint64_t message_id, |
648 | uint64_t message_id, | 857 | uint64_t psycstore_flags) |
649 | uint64_t multicast_flags, | 858 | { |
650 | uint64_t psyc_flags) { | 859 | struct Plugin *plugin = cls; |
860 | sqlite3_stmt *stmt = plugin->update_message_flags; | ||
861 | int ret = GNUNET_SYSERR; | ||
862 | |||
863 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, psycstore_flags) || | ||
864 | SQLITE_OK != sqlite3_bind_blob (stmt, 2, channel_key, | ||
865 | sizeof (*channel_key), SQLITE_STATIC) || | ||
866 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, message_id)) | ||
867 | { | ||
868 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
869 | "update_message_flags (bind)"); | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | switch (sqlite3_step (stmt)) | ||
874 | { | ||
875 | case SQLITE_DONE: | ||
876 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
877 | break; | ||
878 | default: | ||
879 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
880 | "update_message_flags (step)"); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
885 | { | ||
886 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
887 | "update_message_flags (reset)"); | ||
888 | return GNUNET_SYSERR; | ||
889 | } | ||
890 | |||
891 | return ret; | ||
892 | } | ||
651 | 893 | ||
894 | static int | ||
895 | fragment_row (sqlite3_stmt *stmt, GNUNET_PSYCSTORE_FragmentCallback cb, | ||
896 | void *cb_cls) | ||
897 | { | ||
898 | int data_size = sqlite3_column_bytes (stmt, 9); | ||
899 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
900 | = GNUNET_malloc (sizeof (*msg) + data_size); | ||
901 | |||
902 | msg->header.size = htons (sizeof (*msg) + data_size); | ||
903 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
904 | msg->hop_counter = (uint32_t) sqlite3_column_int64 (stmt, 0); | ||
905 | memcpy (&msg->signature, | ||
906 | sqlite3_column_blob (stmt, 1), | ||
907 | sqlite3_column_bytes (stmt, 1)); | ||
908 | memcpy (&msg->purpose, | ||
909 | sqlite3_column_blob (stmt, 2), | ||
910 | sqlite3_column_bytes (stmt, 2)); | ||
911 | msg->fragment_id = sqlite3_column_int64 (stmt, 3); | ||
912 | msg->fragment_offset = sqlite3_column_int64 (stmt, 4); | ||
913 | msg->message_id = sqlite3_column_int64 (stmt, 5); | ||
914 | msg->group_generation = sqlite3_column_int64 (stmt, 6); | ||
915 | msg->flags = sqlite3_column_int64 (stmt, 7); | ||
916 | memcpy (&msg[1], sqlite3_column_blob (stmt, 9), data_size); | ||
917 | |||
918 | return cb (cb_cls, (void *) msg, sqlite3_column_int64 (stmt, 8)); | ||
652 | } | 919 | } |
653 | 920 | ||
654 | /** | 921 | /** |
@@ -658,14 +925,49 @@ libgnunet_plugin_psycstore_sqlite_fragment_add_flags | |||
658 | * | 925 | * |
659 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 926 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
660 | */ | 927 | */ |
661 | int | 928 | static int |
662 | libgnunet_plugin_psycstore_sqlite_fragment_get | 929 | fragment_get (void *cls, |
663 | (void *cls, | 930 | const struct |
664 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 931 | GNUNET_CRYPTO_EccPublicKey *channel_key, |
665 | uint64_t fragment_id, | 932 | uint64_t fragment_id, |
666 | GNUNET_PSYCSTORE_FragmentCallback cb, | 933 | GNUNET_PSYCSTORE_FragmentCallback cb, |
667 | void *cb_cls) { | 934 | void *cb_cls) |
935 | { | ||
936 | struct Plugin *plugin = cls; | ||
937 | sqlite3_stmt *stmt = plugin->select_fragment; | ||
938 | int ret = GNUNET_SYSERR; | ||
939 | |||
940 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
941 | sizeof (*channel_key), | ||
942 | SQLITE_STATIC) || | ||
943 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, fragment_id)) | ||
944 | { | ||
945 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
946 | "select_fragment (bind)"); | ||
947 | } | ||
948 | else | ||
949 | { | ||
950 | switch (sqlite3_step (stmt)) | ||
951 | { | ||
952 | case SQLITE_DONE: | ||
953 | ret = GNUNET_NO; | ||
954 | break; | ||
955 | case SQLITE_ROW: | ||
956 | ret = fragment_row (stmt, cb, cb_cls); | ||
957 | break; | ||
958 | default: | ||
959 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
960 | "select_fragment (step)"); | ||
961 | } | ||
962 | } | ||
668 | 963 | ||
964 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
965 | { | ||
966 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
967 | "select_fragment (reset)"); | ||
968 | } | ||
969 | |||
970 | return ret; | ||
669 | } | 971 | } |
670 | 972 | ||
671 | /** | 973 | /** |
@@ -675,14 +977,57 @@ libgnunet_plugin_psycstore_sqlite_fragment_get | |||
675 | * | 977 | * |
676 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 978 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
677 | */ | 979 | */ |
678 | int | 980 | static int |
679 | libgnunet_plugin_psycstore_sqlite_message_get | 981 | message_get (void *cls, |
680 | (void *cls, | 982 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
681 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 983 | uint64_t message_id, |
682 | uint64_t message_id, | 984 | GNUNET_PSYCSTORE_FragmentCallback cb, |
683 | GNUNET_PSYCSTORE_FragmentCallback cb, | 985 | void *cb_cls) |
684 | void *cb_cls) { | 986 | { |
987 | struct Plugin *plugin = cls; | ||
988 | sqlite3_stmt *stmt = plugin->select_message; | ||
989 | int ret = GNUNET_SYSERR; | ||
990 | |||
991 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
992 | sizeof (*channel_key), | ||
993 | SQLITE_STATIC) || | ||
994 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id)) | ||
995 | { | ||
996 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
997 | "select_message (bind)"); | ||
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | int sql_ret; | ||
1002 | do | ||
1003 | { | ||
1004 | sql_ret = sqlite3_step (stmt); | ||
1005 | switch (sql_ret) | ||
1006 | { | ||
1007 | case SQLITE_DONE: | ||
1008 | if (ret != GNUNET_OK) | ||
1009 | ret = GNUNET_NO; | ||
1010 | break; | ||
1011 | case SQLITE_ROW: | ||
1012 | ret = fragment_row (stmt, cb, cb_cls); | ||
1013 | if (ret != GNUNET_YES) | ||
1014 | sql_ret = SQLITE_DONE; | ||
1015 | break; | ||
1016 | default: | ||
1017 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1018 | "select_message (step)"); | ||
1019 | } | ||
1020 | } | ||
1021 | while (sql_ret == SQLITE_ROW); | ||
1022 | } | ||
685 | 1023 | ||
1024 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1025 | { | ||
1026 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1027 | "select_message (reset)"); | ||
1028 | } | ||
1029 | |||
1030 | return ret; | ||
686 | } | 1031 | } |
687 | 1032 | ||
688 | /** | 1033 | /** |
@@ -693,16 +1038,51 @@ libgnunet_plugin_psycstore_sqlite_message_get | |||
693 | * | 1038 | * |
694 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1039 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
695 | */ | 1040 | */ |
696 | int | 1041 | static int |
697 | libgnunet_plugin_psycstore_sqlite_message_get_fragment | 1042 | message_get_fragment (void *cls, |
698 | (void *cls, | 1043 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
699 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1044 | uint64_t message_id, |
700 | uint64_t message_id, | 1045 | uint64_t fragment_offset, |
701 | uint64_t fragment_offset, | 1046 | GNUNET_PSYCSTORE_FragmentCallback cb, |
702 | GNUNET_PSYCSTORE_FragmentCallback cb, | 1047 | void *cb_cls) |
703 | void *cb_cls) | ||
704 | { | 1048 | { |
1049 | struct Plugin *plugin = cls; | ||
1050 | int ret = GNUNET_SYSERR; | ||
1051 | |||
1052 | sqlite3_stmt *stmt = plugin->select_message_fragment; | ||
1053 | |||
1054 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1055 | sizeof (*channel_key), | ||
1056 | SQLITE_STATIC) || | ||
1057 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, message_id) || | ||
1058 | SQLITE_OK != sqlite3_bind_int64 (stmt, 3, fragment_offset)) | ||
1059 | { | ||
1060 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1061 | "select_message_fragment (bind)"); | ||
1062 | } | ||
1063 | else | ||
1064 | { | ||
1065 | switch (sqlite3_step (stmt)) | ||
1066 | { | ||
1067 | case SQLITE_DONE: | ||
1068 | ret = GNUNET_NO; | ||
1069 | break; | ||
1070 | case SQLITE_ROW: | ||
1071 | ret = fragment_row (stmt, cb, cb_cls); | ||
1072 | break; | ||
1073 | default: | ||
1074 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1075 | "select_message_fragment (step)"); | ||
1076 | } | ||
1077 | } | ||
705 | 1078 | ||
1079 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1080 | { | ||
1081 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1082 | "select_message_fragment (reset)"); | ||
1083 | } | ||
1084 | |||
1085 | return ret; | ||
706 | } | 1086 | } |
707 | 1087 | ||
708 | /** | 1088 | /** |
@@ -712,15 +1092,50 @@ libgnunet_plugin_psycstore_sqlite_message_get_fragment | |||
712 | * | 1092 | * |
713 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1093 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
714 | */ | 1094 | */ |
715 | int | 1095 | static int |
716 | libgnunet_plugin_psycstore_sqlite_counters_get_master | 1096 | counters_get_master (void *cls, |
717 | (void *cls, | 1097 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
718 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1098 | uint64_t *fragment_id, |
719 | uint64_t *fragment_id, | 1099 | uint64_t *message_id, |
720 | uint64_t *message_id, | 1100 | uint64_t *group_generation) |
721 | uint64_t *group_generation) | ||
722 | { | 1101 | { |
1102 | struct Plugin *plugin = cls; | ||
1103 | sqlite3_stmt *stmt = plugin->select_counters_master; | ||
1104 | int ret = GNUNET_SYSERR; | ||
1105 | |||
1106 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1107 | sizeof (*channel_key), | ||
1108 | SQLITE_STATIC)) | ||
1109 | { | ||
1110 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1111 | "select_counters_master (bind)"); | ||
1112 | } | ||
1113 | else | ||
1114 | { | ||
1115 | switch (sqlite3_step (stmt)) | ||
1116 | { | ||
1117 | case SQLITE_DONE: | ||
1118 | ret = GNUNET_NO; | ||
1119 | break; | ||
1120 | case SQLITE_ROW: | ||
1121 | *fragment_id = sqlite3_column_int64 (stmt, 0); | ||
1122 | *message_id = sqlite3_column_int64 (stmt, 1); | ||
1123 | *group_generation = sqlite3_column_int64 (stmt, 2); | ||
1124 | ret = GNUNET_OK; | ||
1125 | break; | ||
1126 | default: | ||
1127 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1128 | "select_counters_master (step)"); | ||
1129 | } | ||
1130 | } | ||
723 | 1131 | ||
1132 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1133 | { | ||
1134 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1135 | "select_counters_master (reset)"); | ||
1136 | } | ||
1137 | |||
1138 | return ret; | ||
724 | } | 1139 | } |
725 | 1140 | ||
726 | /** | 1141 | /** |
@@ -730,12 +1145,48 @@ libgnunet_plugin_psycstore_sqlite_counters_get_master | |||
730 | * | 1145 | * |
731 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1146 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
732 | */ | 1147 | */ |
733 | int | 1148 | static int |
734 | libgnunet_plugin_psycstore_sqlite_counters_get_slave | 1149 | counters_get_slave (void *cls, |
735 | (void *cls, | 1150 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
736 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1151 | uint64_t *max_state_msg_id) |
737 | uint64_t *max_state_msg_id) { | 1152 | { |
1153 | struct Plugin *plugin = cls; | ||
1154 | sqlite3_stmt *stmt = plugin->select_counters_slave; | ||
1155 | int ret = GNUNET_SYSERR; | ||
1156 | |||
1157 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1158 | sizeof (*channel_key), | ||
1159 | SQLITE_STATIC) || | ||
1160 | SQLITE_OK != sqlite3_bind_int64 (stmt, 2, | ||
1161 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)) | ||
1162 | { | ||
1163 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1164 | "select_counters_slave (bind)"); | ||
1165 | } | ||
1166 | else | ||
1167 | { | ||
1168 | switch (sqlite3_step (stmt)) | ||
1169 | { | ||
1170 | case SQLITE_DONE: | ||
1171 | ret = GNUNET_NO; | ||
1172 | break; | ||
1173 | case SQLITE_ROW: | ||
1174 | *max_state_msg_id = sqlite3_column_int64 (stmt, 0); | ||
1175 | ret = GNUNET_OK; | ||
1176 | break; | ||
1177 | default: | ||
1178 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1179 | "select_counters_slave (step)"); | ||
1180 | } | ||
1181 | } | ||
738 | 1182 | ||
1183 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1184 | { | ||
1185 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1186 | "select_counters_slave (reset)"); | ||
1187 | } | ||
1188 | |||
1189 | return ret; | ||
739 | } | 1190 | } |
740 | 1191 | ||
741 | /** | 1192 | /** |
@@ -745,35 +1196,174 @@ libgnunet_plugin_psycstore_sqlite_counters_get_slave | |||
745 | * | 1196 | * |
746 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1197 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
747 | */ | 1198 | */ |
748 | int | 1199 | static int |
749 | libgnunet_plugin_psycstore_sqlite_state_set | 1200 | state_set (void *cls, |
750 | (struct GNUNET_PSYCSTORE_Handle *h, | 1201 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
751 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1202 | const char *name, const void *value, size_t value_size) |
752 | const char *name, | 1203 | { |
753 | size_t value_size, | 1204 | struct Plugin *plugin = cls; |
754 | const void *value) { | 1205 | int ret = GNUNET_SYSERR; |
1206 | |||
1207 | sqlite3_stmt *stmt = plugin->insert_state_current; | ||
1208 | |||
1209 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1210 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1211 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC) || | ||
1212 | SQLITE_OK != sqlite3_bind_blob (stmt, 3, value, value_size, | ||
1213 | SQLITE_STATIC)) | ||
1214 | { | ||
1215 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1216 | "insert_state_current (bind)"); | ||
1217 | } | ||
1218 | else | ||
1219 | { | ||
1220 | switch (sqlite3_step (stmt)) | ||
1221 | { | ||
1222 | case SQLITE_DONE: | ||
1223 | ret = sqlite3_total_changes (plugin->dbh) > 0 ? GNUNET_OK : GNUNET_NO; | ||
1224 | break; | ||
1225 | default: | ||
1226 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1227 | "insert_state_current (step)"); | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1232 | { | ||
1233 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1234 | "insert_state_current (reset)"); | ||
1235 | return GNUNET_SYSERR; | ||
1236 | } | ||
1237 | |||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1241 | |||
1242 | /** | ||
1243 | * Reset the state of a channel. | ||
1244 | * | ||
1245 | * @see GNUNET_PSYCSTORE_state_reset() | ||
1246 | * | ||
1247 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1248 | */ | ||
1249 | static int | ||
1250 | state_reset (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1251 | { | ||
1252 | struct Plugin *plugin = cls; | ||
1253 | sqlite3_stmt *stmt = plugin->delete_state; | ||
1254 | |||
1255 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1256 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1257 | { | ||
1258 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1259 | "delete_state (bind)"); | ||
1260 | } | ||
1261 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1262 | { | ||
1263 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1264 | "delete_state (step)"); | ||
1265 | } | ||
1266 | |||
1267 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1268 | { | ||
1269 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1270 | "delete_state (reset)"); | ||
1271 | return GNUNET_SYSERR; | ||
1272 | } | ||
1273 | |||
1274 | return GNUNET_OK; | ||
1275 | } | ||
1276 | |||
1277 | |||
1278 | /** | ||
1279 | * Update signed values of state variables in the state store. | ||
1280 | * | ||
1281 | * @see GNUNET_PSYCSTORE_state_hash_update() | ||
1282 | * | ||
1283 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1284 | */ | ||
1285 | static int | ||
1286 | state_update_signed (void *cls, | ||
1287 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key) | ||
1288 | { | ||
1289 | struct Plugin *plugin = cls; | ||
1290 | sqlite3_stmt *stmt = plugin->update_state_signed; | ||
1291 | |||
1292 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1293 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1294 | { | ||
1295 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1296 | "update_state_signed (bind)"); | ||
1297 | } | ||
1298 | else if (SQLITE_DONE != sqlite3_step (stmt)) | ||
1299 | { | ||
1300 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1301 | "update_state_signed (step)"); | ||
1302 | } | ||
1303 | |||
1304 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1305 | { | ||
1306 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1307 | "update_state_signed (reset)"); | ||
1308 | return GNUNET_SYSERR; | ||
1309 | } | ||
755 | 1310 | ||
1311 | return GNUNET_OK; | ||
756 | } | 1312 | } |
757 | 1313 | ||
1314 | |||
758 | /** | 1315 | /** |
759 | * Retrieve a state variable by name. | 1316 | * Retrieve a state variable by name. |
760 | * | 1317 | * |
761 | * @param name Name of the variable to retrieve. | 1318 | * @see GNUNET_PSYCSTORE_state_get() |
762 | * @param[out] value_size Size of value. | ||
763 | * @param[out] value Returned value. | ||
764 | * | 1319 | * |
765 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1320 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
766 | */ | 1321 | */ |
767 | int | 1322 | static int |
768 | libgnunet_plugin_psycstore_sqlite_state_get | 1323 | state_get (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
769 | (struct GNUNET_PSYCSTORE_Handle *h, | 1324 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) |
770 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1325 | { |
771 | const char *name, | 1326 | struct Plugin *plugin = cls; |
772 | GNUNET_PSYCSTORE_StateCallback cb, | 1327 | int ret = GNUNET_SYSERR; |
773 | void *cb_cls) { | 1328 | |
1329 | sqlite3_stmt *stmt = plugin->select_state_one; | ||
1330 | |||
1331 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1332 | sizeof (*channel_key), | ||
1333 | SQLITE_STATIC) || | ||
1334 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, -1, SQLITE_STATIC)) | ||
1335 | { | ||
1336 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1337 | "select_state_one (bind)"); | ||
1338 | } | ||
1339 | else | ||
1340 | { | ||
1341 | switch (sqlite3_step (stmt)) | ||
1342 | { | ||
1343 | case SQLITE_DONE: | ||
1344 | ret = GNUNET_NO; | ||
1345 | break; | ||
1346 | case SQLITE_ROW: | ||
1347 | ret = cb (cb_cls, name, sqlite3_column_blob (stmt, 0), | ||
1348 | sqlite3_column_bytes (stmt, 0)); | ||
1349 | break; | ||
1350 | default: | ||
1351 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1352 | "select_state_one (step)"); | ||
1353 | } | ||
1354 | } | ||
774 | 1355 | ||
1356 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1357 | { | ||
1358 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1359 | "select_state_one (reset)"); | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | return ret; | ||
775 | } | 1364 | } |
776 | 1365 | ||
1366 | |||
777 | /** | 1367 | /** |
778 | * Retrieve all state variables for a channel with the given prefix. | 1368 | * Retrieve all state variables for a channel with the given prefix. |
779 | * | 1369 | * |
@@ -781,21 +1371,130 @@ libgnunet_plugin_psycstore_sqlite_state_get | |||
781 | * | 1371 | * |
782 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | 1372 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR |
783 | */ | 1373 | */ |
784 | int | 1374 | static int |
785 | libgnunet_plugin_psycstore_sqlite_state_get_all | 1375 | state_get_all (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *channel_key, |
786 | (struct GNUNET_PSYCSTORE_Handle *h, | 1376 | const char *name, GNUNET_PSYCSTORE_StateCallback cb, |
787 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | 1377 | void *cb_cls) |
788 | const char *name, | 1378 | { |
789 | GNUNET_PSYCSTORE_StateCallback cb, | 1379 | struct Plugin *plugin = cls; |
790 | void *cb_cls) { | 1380 | int ret = GNUNET_SYSERR; |
1381 | |||
1382 | sqlite3_stmt *stmt = plugin->select_state_prefix; | ||
1383 | size_t name_len = strlen (name); | ||
1384 | char *name_prefix = GNUNET_malloc (name_len + 2); | ||
1385 | memcpy (name_prefix, name, name_len); | ||
1386 | memcpy (name_prefix + name_len, "_%", 2); | ||
1387 | |||
1388 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1389 | sizeof (*channel_key), SQLITE_STATIC) || | ||
1390 | SQLITE_OK != sqlite3_bind_text (stmt, 2, name, name_len, SQLITE_STATIC) || | ||
1391 | SQLITE_OK != sqlite3_bind_text (stmt, 3, name_prefix, name_len + 2, | ||
1392 | SQLITE_STATIC)) | ||
1393 | { | ||
1394 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1395 | "select_state_prefix (bind)"); | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | int sql_ret; | ||
1400 | do | ||
1401 | { | ||
1402 | sql_ret = sqlite3_step (stmt); | ||
1403 | switch (sql_ret) | ||
1404 | { | ||
1405 | case SQLITE_DONE: | ||
1406 | if (ret != GNUNET_OK) | ||
1407 | ret = GNUNET_NO; | ||
1408 | break; | ||
1409 | case SQLITE_ROW: | ||
1410 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1411 | sqlite3_column_blob (stmt, 1), | ||
1412 | sqlite3_column_bytes (stmt, 1)); | ||
1413 | if (ret != GNUNET_YES) | ||
1414 | sql_ret = SQLITE_DONE; | ||
1415 | break; | ||
1416 | default: | ||
1417 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1418 | "select_state_prefix (step)"); | ||
1419 | } | ||
1420 | } | ||
1421 | while (sql_ret == SQLITE_ROW); | ||
1422 | } | ||
1423 | |||
1424 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1425 | { | ||
1426 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1427 | "select_state_prefix (reset)"); | ||
1428 | } | ||
791 | 1429 | ||
1430 | return ret; | ||
792 | } | 1431 | } |
793 | 1432 | ||
794 | 1433 | ||
795 | /** | 1434 | /** |
1435 | * Retrieve all signed state variables for a channel. | ||
1436 | * | ||
1437 | * @see GNUNET_PSYCSTORE_state_get_signed() | ||
1438 | * | ||
1439 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
1440 | */ | ||
1441 | static int | ||
1442 | state_get_signed (void *cls, | ||
1443 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
1444 | GNUNET_PSYCSTORE_StateCallback cb, void *cb_cls) | ||
1445 | { | ||
1446 | struct Plugin *plugin = cls; | ||
1447 | int ret = GNUNET_SYSERR; | ||
1448 | |||
1449 | sqlite3_stmt *stmt = plugin->select_state_signed; | ||
1450 | |||
1451 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, channel_key, | ||
1452 | sizeof (*channel_key), SQLITE_STATIC)) | ||
1453 | { | ||
1454 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1455 | "select_state_signed (bind)"); | ||
1456 | } | ||
1457 | else | ||
1458 | { | ||
1459 | int sql_ret; | ||
1460 | do | ||
1461 | { | ||
1462 | sql_ret = sqlite3_step (stmt); | ||
1463 | switch (sql_ret) | ||
1464 | { | ||
1465 | case SQLITE_DONE: | ||
1466 | if (ret != GNUNET_OK) | ||
1467 | ret = GNUNET_NO; | ||
1468 | break; | ||
1469 | case SQLITE_ROW: | ||
1470 | ret = cb (cb_cls, (const char *) sqlite3_column_text (stmt, 0), | ||
1471 | sqlite3_column_blob (stmt, 1), | ||
1472 | sqlite3_column_bytes (stmt, 1)); | ||
1473 | if (ret != GNUNET_YES) | ||
1474 | sql_ret = SQLITE_DONE; | ||
1475 | break; | ||
1476 | default: | ||
1477 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1478 | "select_state_signed (step)"); | ||
1479 | } | ||
1480 | } | ||
1481 | while (sql_ret == SQLITE_ROW); | ||
1482 | } | ||
1483 | |||
1484 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
1485 | { | ||
1486 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1487 | "select_state_signed (reset)"); | ||
1488 | } | ||
1489 | |||
1490 | return ret; | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | /** | ||
796 | * Entry point for the plugin. | 1495 | * Entry point for the plugin. |
797 | * | 1496 | * |
798 | * @param cls the "struct GNUNET_PSYCSTORE_PluginEnvironment*" | 1497 | * @param cls The struct GNUNET_CONFIGURATION_Handle. |
799 | * @return NULL on error, otherwise the plugin context | 1498 | * @return NULL on error, otherwise the plugin context |
800 | */ | 1499 | */ |
801 | void * | 1500 | void * |
@@ -816,21 +1515,23 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
816 | } | 1515 | } |
817 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); | 1516 | api = GNUNET_new (struct GNUNET_PSYCSTORE_PluginFunctions); |
818 | api->cls = &plugin; | 1517 | api->cls = &plugin; |
819 | api->membership_store = &libgnunet_plugin_psycstore_sqlite_membership_store; | 1518 | api->membership_store = &membership_store; |
820 | api->membership_test = &libgnunet_plugin_psycstore_sqlite_membership_test; | 1519 | api->membership_test = &membership_test; |
821 | api->fragment_store = &libgnunet_plugin_psycstore_sqlite_fragment_store; | 1520 | api->fragment_store = &fragment_store; |
822 | api->fragment_add_flags = &libgnunet_plugin_psycstore_sqlite_fragment_add_flags; | 1521 | api->message_add_flags = &message_add_flags; |
823 | api->fragment_get = &libgnunet_plugin_psycstore_sqlite_fragment_get; | 1522 | api->fragment_get = &fragment_get; |
824 | api->message_get = &libgnunet_plugin_psycstore_sqlite_message_get; | 1523 | api->message_get = &message_get; |
825 | api->message_get_fragment = &libgnunet_plugin_psycstore_sqlite_message_get_fragment; | 1524 | api->message_get_fragment = &message_get_fragment; |
826 | api->counters_get_master = &libgnunet_plugin_psycstore_sqlite_counters_get_master; | 1525 | api->counters_get_master = &counters_get_master; |
827 | api->counters_get_slave = &libgnunet_plugin_psycstore_sqlite_counters_get_slave; | 1526 | api->counters_get_slave = &counters_get_slave; |
828 | api->state_set = &libgnunet_plugin_psycstore_sqlite_state_set; | 1527 | api->state_set = &state_set; |
829 | api->state_get = &libgnunet_plugin_psycstore_sqlite_state_get; | 1528 | api->state_reset = &state_reset; |
830 | api->state_get_all = &libgnunet_plugin_psycstore_sqlite_state_get_all; | 1529 | api->state_update_signed = &state_update_signed; |
831 | 1530 | api->state_get = &state_get; | |
832 | LOG (GNUNET_ERROR_TYPE_INFO, | 1531 | api->state_get_all = &state_get_all; |
833 | _("Sqlite database running\n")); | 1532 | api->state_get_signed = &state_get_signed; |
1533 | |||
1534 | LOG (GNUNET_ERROR_TYPE_INFO, _("SQLite database running\n")); | ||
834 | return api; | 1535 | return api; |
835 | } | 1536 | } |
836 | 1537 | ||
@@ -838,8 +1539,8 @@ libgnunet_plugin_psycstore_sqlite_init (void *cls) | |||
838 | /** | 1539 | /** |
839 | * Exit point from the plugin. | 1540 | * Exit point from the plugin. |
840 | * | 1541 | * |
841 | * @param cls the plugin context (as returned by "init") | 1542 | * @param cls The plugin context (as returned by "init") |
842 | * @return always NULL | 1543 | * @return Always NULL |
843 | */ | 1544 | */ |
844 | void * | 1545 | void * |
845 | libgnunet_plugin_psycstore_sqlite_done (void *cls) | 1546 | libgnunet_plugin_psycstore_sqlite_done (void *cls) |
@@ -850,8 +1551,7 @@ libgnunet_plugin_psycstore_sqlite_done (void *cls) | |||
850 | database_shutdown (plugin); | 1551 | database_shutdown (plugin); |
851 | plugin->cfg = NULL; | 1552 | plugin->cfg = NULL; |
852 | GNUNET_free (api); | 1553 | GNUNET_free (api); |
853 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1554 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SQLite plugin is finished\n"); |
854 | "sqlite plugin is finished\n"); | ||
855 | return NULL; | 1555 | return NULL; |
856 | } | 1556 | } |
857 | 1557 | ||
diff --git a/src/psycstore/psycstore.conf b/src/psycstore/psycstore.conf index 5b8dfee68..3f86d7b45 100644 --- a/src/psycstore/psycstore.conf +++ b/src/psycstore/psycstore.conf | |||
@@ -2,7 +2,7 @@ | |||
2 | AUTOSTART = YES | 2 | AUTOSTART = YES |
3 | HOME = $SERVICEHOME | 3 | HOME = $SERVICEHOME |
4 | BINARY = gnunet-service-psycstore | 4 | BINARY = gnunet-service-psycstore |
5 | UNIXPATH = /tmp/gnunet-service-psycstore.unix | 5 | UNIXPATH = /tmp/gnunet-service-psycstore.sock |
6 | UNIX_MATCH_UID = NO | 6 | UNIX_MATCH_UID = NO |
7 | UNIX_MATCH_GID = YES | 7 | UNIX_MATCH_GID = YES |
8 | DATABASE = sqlite | 8 | DATABASE = sqlite |
diff --git a/src/psycstore/psycstore.h b/src/psycstore/psycstore.h index f1a1c787a..2e3d66ec5 100644 --- a/src/psycstore/psycstore.h +++ b/src/psycstore/psycstore.h | |||
@@ -35,7 +35,7 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
35 | /** | 35 | /** |
36 | * Answer from service to client about last operation. | 36 | * Answer from service to client about last operation. |
37 | */ | 37 | */ |
38 | struct GNUNET_PSYCSTORE_ResultCodeMessage | 38 | struct ResultCodeMessage |
39 | { | 39 | { |
40 | /** | 40 | /** |
41 | * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE | 41 | * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE |
@@ -52,6 +52,32 @@ struct GNUNET_PSYCSTORE_ResultCodeMessage | |||
52 | 52 | ||
53 | }; | 53 | }; |
54 | 54 | ||
55 | |||
56 | /** | ||
57 | * @see GNUNET_PSYCSTORE_membership_store() | ||
58 | */ | ||
59 | struct MembershipStoreMessage | ||
60 | { | ||
61 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key; | ||
62 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key; | ||
63 | int did_join; | ||
64 | uint64_t announced_at; | ||
65 | uint64_t effective_since; | ||
66 | uint64_t group_generation; | ||
67 | }; | ||
68 | |||
69 | |||
70 | /** | ||
71 | * @see GNUNET_PSYCSTORE_membership_test() | ||
72 | */ | ||
73 | struct MembershipTestMessage | ||
74 | { | ||
75 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key; | ||
76 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key; | ||
77 | uint64_t message_id; | ||
78 | uint64_t group_generation; | ||
79 | }; | ||
80 | |||
55 | GNUNET_NETWORK_STRUCT_END | 81 | GNUNET_NETWORK_STRUCT_END |
56 | 82 | ||
57 | #endif | 83 | #endif |
diff --git a/src/psycstore/psycstore_api.c b/src/psycstore/psycstore_api.c index d8d5134b6..194dcc79e 100644 --- a/src/psycstore/psycstore_api.c +++ b/src/psycstore/psycstore_api.c | |||
@@ -187,7 +187,7 @@ message_handler (void *cls, | |||
187 | { | 187 | { |
188 | struct GNUNET_PSYCSTORE_Handle *h = cls; | 188 | struct GNUNET_PSYCSTORE_Handle *h = cls; |
189 | struct GNUNET_PSYCSTORE_OperationHandle *op; | 189 | struct GNUNET_PSYCSTORE_OperationHandle *op; |
190 | const struct GNUNET_PSYCSTORE_ResultCodeMessage *rcm; | 190 | const struct ResultCodeMessage *rcm; |
191 | const char *str; | 191 | const char *str; |
192 | uint16_t size; | 192 | uint16_t size; |
193 | 193 | ||
@@ -203,22 +203,22 @@ message_handler (void *cls, | |||
203 | switch (ntohs (msg->type)) | 203 | switch (ntohs (msg->type)) |
204 | { | 204 | { |
205 | case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE: | 205 | case GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE: |
206 | if (size < sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) | 206 | if (size < sizeof (struct ResultCodeMessage)) |
207 | { | 207 | { |
208 | GNUNET_break (0); | 208 | GNUNET_break (0); |
209 | reschedule_connect (h); | 209 | reschedule_connect (h); |
210 | return; | 210 | return; |
211 | } | 211 | } |
212 | rcm = (const struct GNUNET_PSYCSTORE_ResultCodeMessage *) msg; | 212 | rcm = (const struct ResultCodeMessage *) msg; |
213 | str = (const char *) &rcm[1]; | 213 | str = (const char *) &rcm[1]; |
214 | if ( (size > sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) && | 214 | if ( (size > sizeof (struct ResultCodeMessage)) && |
215 | ('\0' != str[size - sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage) - 1]) ) | 215 | ('\0' != str[size - sizeof (struct ResultCodeMessage) - 1]) ) |
216 | { | 216 | { |
217 | GNUNET_break (0); | 217 | GNUNET_break (0); |
218 | reschedule_connect (h); | 218 | reschedule_connect (h); |
219 | return; | 219 | return; |
220 | } | 220 | } |
221 | if (size == sizeof (struct GNUNET_PSYCSTORE_ResultCodeMessage)) | 221 | if (size == sizeof (struct ResultCodeMessage)) |
222 | str = NULL; | 222 | str = NULL; |
223 | 223 | ||
224 | op = h->op_head; | 224 | op = h->op_head; |
@@ -341,7 +341,6 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
341 | h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg); | 341 | h->client = GNUNET_CLIENT_connect ("psycstore", h->cfg); |
342 | GNUNET_assert (NULL != h->client); | 342 | GNUNET_assert (NULL != h->client); |
343 | transmit_next (h); | 343 | transmit_next (h); |
344 | GNUNET_assert (NULL != h->th); | ||
345 | } | 344 | } |
346 | 345 | ||
347 | 346 | ||
@@ -399,7 +398,7 @@ GNUNET_PSYCSTORE_disconnect (struct GNUNET_PSYCSTORE_Handle *h) | |||
399 | * was already transmitted, the service may still choose to complete | 398 | * was already transmitted, the service may still choose to complete |
400 | * the operation. | 399 | * the operation. |
401 | * | 400 | * |
402 | * @param op operation to cancel | 401 | * @param op Operation to cancel. |
403 | */ | 402 | */ |
404 | void | 403 | void |
405 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) | 404 | GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) |
@@ -435,4 +434,33 @@ GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op) | |||
435 | } | 434 | } |
436 | 435 | ||
437 | 436 | ||
437 | struct GNUNET_PSYCSTORE_OperationHandle * | ||
438 | GNUNET_PSYCSTORE_membership_store ( | ||
439 | struct GNUNET_PSYCSTORE_Handle *h, | ||
440 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
441 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | ||
442 | int did_join, | ||
443 | uint64_t announced_at, | ||
444 | uint64_t effective_since, | ||
445 | uint64_t group_generation, | ||
446 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
447 | void *rcb_cls) | ||
448 | { | ||
449 | |||
450 | } | ||
451 | |||
452 | |||
453 | struct GNUNET_PSYCSTORE_OperationHandle * | ||
454 | GNUNET_PSYCSTORE_membership_test ( | ||
455 | struct GNUNET_PSYCSTORE_Handle *h, | ||
456 | const struct GNUNET_CRYPTO_EccPublicKey *channel_key, | ||
457 | const struct GNUNET_CRYPTO_EccPublicKey *slave_key, | ||
458 | uint64_t message_id, | ||
459 | uint64_t group_generation, | ||
460 | GNUNET_PSYCSTORE_ResultCallback rcb, | ||
461 | void *rcb_cls) | ||
462 | { | ||
463 | |||
464 | } | ||
465 | |||
438 | /* end of psycstore_api.c */ | 466 | /* end of psycstore_api.c */ |
diff --git a/src/psycstore/test_plugin_psycstore.c b/src/psycstore/test_plugin_psycstore.c new file mode 100644 index 000000000..52a306f07 --- /dev/null +++ b/src/psycstore/test_plugin_psycstore.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /* | ||
21 | * @file psycstore/test_plugin_psycstore.c | ||
22 | * @brief Test for the psycstore plugins | ||
23 | * @author Gabor X Toth | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_psycstore_plugin.h" | ||
30 | #include "gnunet_psycstore_service.h" | ||
31 | #include "gnunet_multicast_service.h" | ||
32 | |||
33 | #define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING | ||
34 | #if DEBUG_PSYCSTORE | ||
35 | # define LOG_LEVEL "DEBUG" | ||
36 | #else | ||
37 | # define LOG_LEVEL "WARNING" | ||
38 | #endif | ||
39 | |||
40 | #define C2ARG(str) str, (sizeof (str) - 1) | ||
41 | |||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__) | ||
43 | |||
44 | #define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, __LINE__); goto FAILURE;} } while (0) | ||
45 | |||
46 | static int ok; | ||
47 | |||
48 | /** | ||
49 | * Name of plugin under test. | ||
50 | */ | ||
51 | static const char *plugin_name; | ||
52 | |||
53 | static struct GNUNET_CRYPTO_EccPrivateKey *channel_key; | ||
54 | static struct GNUNET_CRYPTO_EccPrivateKey *slave_key; | ||
55 | |||
56 | static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key; | ||
57 | static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key; | ||
58 | |||
59 | /** | ||
60 | * Function called when the service shuts down. Unloads our psycstore | ||
61 | * plugin. | ||
62 | * | ||
63 | * @param api api to unload | ||
64 | */ | ||
65 | static void | ||
66 | unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api) | ||
67 | { | ||
68 | char *libname; | ||
69 | |||
70 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
71 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api)); | ||
72 | GNUNET_free (libname); | ||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Load the psycstore plugin. | ||
78 | * | ||
79 | * @param cfg configuration to pass | ||
80 | * @return NULL on error | ||
81 | */ | ||
82 | static struct GNUNET_PSYCSTORE_PluginFunctions * | ||
83 | load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
84 | { | ||
85 | struct GNUNET_PSYCSTORE_PluginFunctions *ret; | ||
86 | char *libname; | ||
87 | |||
88 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' psycstore plugin\n"), | ||
89 | plugin_name); | ||
90 | GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); | ||
91 | if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) | ||
92 | { | ||
93 | FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); | ||
94 | return NULL; | ||
95 | } | ||
96 | GNUNET_free (libname); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | |||
101 | struct FragmentClosure | ||
102 | { | ||
103 | uint8_t n; | ||
104 | uint64_t flags[16]; | ||
105 | struct GNUNET_MULTICAST_MessageHeader *msg[16]; | ||
106 | }; | ||
107 | |||
108 | static int | ||
109 | fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2, | ||
110 | enum GNUNET_PSYCSTORE_MessageFlags flags) | ||
111 | { | ||
112 | struct FragmentClosure *fcls = cls; | ||
113 | struct GNUNET_MULTICAST_MessageHeader *msg1 = fcls->msg[fcls->n]; | ||
114 | uint64_t flags1 = fcls->flags[fcls->n++]; | ||
115 | int ret; | ||
116 | |||
117 | if (flags1 == flags && msg1->header.size == msg2->header.size | ||
118 | && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size))) | ||
119 | { | ||
120 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n", | ||
121 | msg1->fragment_id); | ||
122 | ret = GNUNET_YES; | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n", | ||
127 | msg1->fragment_id); | ||
128 | ret = GNUNET_SYSERR; | ||
129 | } | ||
130 | |||
131 | GNUNET_free (msg2); | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | |||
136 | struct StateClosure { | ||
137 | size_t n; | ||
138 | void *value[16]; | ||
139 | size_t value_size[16]; | ||
140 | }; | ||
141 | |||
142 | static int | ||
143 | state_cb (void *cls, const char *name, const void *value, size_t value_size) | ||
144 | { | ||
145 | struct StateClosure *scls = cls; | ||
146 | const void *val = scls->value[scls->n]; | ||
147 | size_t val_size = scls->value_size[scls->n++]; | ||
148 | |||
149 | return value_size == val_size && 0 == memcmp (value, val, val_size) | ||
150 | ? GNUNET_YES | ||
151 | : GNUNET_SYSERR; | ||
152 | } | ||
153 | |||
154 | |||
155 | static void | ||
156 | run (void *cls, char *const *args, const char *cfgfile, | ||
157 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
158 | { | ||
159 | struct GNUNET_PSYCSTORE_PluginFunctions *db; | ||
160 | |||
161 | ok = 1; | ||
162 | db = load_plugin (cfg); | ||
163 | if (NULL == db) | ||
164 | { | ||
165 | FPRINTF (stderr, | ||
166 | "%s", | ||
167 | "Failed to initialize PSYCstore. " | ||
168 | "Database likely not setup, skipping test.\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | /* Membership */ | ||
173 | |||
174 | channel_key = GNUNET_CRYPTO_ecc_key_create (); | ||
175 | slave_key = GNUNET_CRYPTO_ecc_key_create (); | ||
176 | |||
177 | GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key); | ||
178 | GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key); | ||
179 | |||
180 | ASSERT (GNUNET_OK == db->membership_store(db->cls, &channel_pub_key, | ||
181 | &slave_pub_key, GNUNET_YES, | ||
182 | 4, 2, 1)); | ||
183 | |||
184 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
185 | &slave_pub_key, 4)); | ||
186 | |||
187 | ASSERT (GNUNET_YES == db->membership_test(db->cls, &channel_pub_key, | ||
188 | &slave_pub_key, 2)); | ||
189 | |||
190 | ASSERT (GNUNET_NO == db->membership_test(db->cls, &channel_pub_key, | ||
191 | &slave_pub_key, 1)); | ||
192 | |||
193 | |||
194 | /* Messages */ | ||
195 | |||
196 | struct GNUNET_MULTICAST_MessageHeader *msg | ||
197 | = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key)); | ||
198 | ASSERT (msg != NULL); | ||
199 | |||
200 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); | ||
201 | msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key)); | ||
202 | |||
203 | msg->hop_counter = 9; | ||
204 | msg->fragment_id = INT64_MAX - 1; | ||
205 | msg->fragment_offset = 0; | ||
206 | msg->message_id = INT64_MAX - 2; | ||
207 | msg->group_generation = INT64_MAX - 3; | ||
208 | msg->flags = GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT; | ||
209 | |||
210 | memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key)); | ||
211 | |||
212 | msg->purpose.size = htonl (ntohs (msg->header.size) | ||
213 | - sizeof (msg->header) | ||
214 | - sizeof (msg->hop_counter) | ||
215 | - sizeof (msg->signature)); | ||
216 | msg->purpose.purpose = htonl (234); | ||
217 | GNUNET_CRYPTO_ecc_sign (slave_key, &msg->purpose, &msg->signature); | ||
218 | |||
219 | struct FragmentClosure fcls = { 0 }; | ||
220 | fcls.n = 0; | ||
221 | fcls.msg[0] = msg; | ||
222 | fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE; | ||
223 | |||
224 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg, | ||
225 | fcls.flags[0])); | ||
226 | |||
227 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
228 | msg->fragment_id, | ||
229 | fragment_cb, &fcls)); | ||
230 | ASSERT (fcls.n == 1); | ||
231 | |||
232 | fcls.n = 0; | ||
233 | |||
234 | ASSERT (GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key, | ||
235 | msg->message_id, | ||
236 | msg->fragment_offset, | ||
237 | fragment_cb, &fcls)); | ||
238 | ASSERT (fcls.n == 1); | ||
239 | |||
240 | ASSERT (GNUNET_OK == db->message_add_flags ( | ||
241 | db->cls, &channel_pub_key, msg->message_id, | ||
242 | GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)); | ||
243 | |||
244 | fcls.n = 0; | ||
245 | fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED; | ||
246 | |||
247 | ASSERT (GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, | ||
248 | msg->fragment_id, | ||
249 | fragment_cb, &fcls)); | ||
250 | ASSERT (fcls.n == 1); | ||
251 | |||
252 | struct GNUNET_MULTICAST_MessageHeader *msg1 | ||
253 | = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key)); | ||
254 | |||
255 | memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key)); | ||
256 | |||
257 | msg1->fragment_id++; | ||
258 | msg1->fragment_offset += 32768; | ||
259 | |||
260 | fcls.n = 0; | ||
261 | fcls.msg[1] = msg1; | ||
262 | fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH; | ||
263 | |||
264 | ASSERT (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1, | ||
265 | fcls.flags[1])); | ||
266 | |||
267 | ASSERT (GNUNET_OK == db->message_get (db->cls, &channel_pub_key, | ||
268 | msg->message_id, | ||
269 | fragment_cb, &fcls)); | ||
270 | ASSERT (fcls.n == 2); | ||
271 | |||
272 | uint64_t max_state_msg_id = 0; | ||
273 | ASSERT (GNUNET_OK == db->counters_get_slave (db->cls, &channel_pub_key, | ||
274 | &max_state_msg_id) | ||
275 | && max_state_msg_id == msg->message_id); | ||
276 | |||
277 | uint64_t fragment_id = 0, message_id = 0, group_generation = 0; | ||
278 | ASSERT (GNUNET_OK == db->counters_get_master (db->cls, &channel_pub_key, | ||
279 | &fragment_id, &message_id, | ||
280 | &group_generation) | ||
281 | && fragment_id == msg1->fragment_id | ||
282 | && message_id == msg1->message_id | ||
283 | && group_generation == msg1->group_generation); | ||
284 | |||
285 | |||
286 | /* State */ | ||
287 | |||
288 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo", | ||
289 | C2ARG("one two three"))); | ||
290 | |||
291 | ASSERT (GNUNET_OK == db->state_set (db->cls, &channel_pub_key, "_foo_bar", | ||
292 | slave_key, | ||
293 | sizeof (*slave_key))); | ||
294 | |||
295 | struct StateClosure scls = { 0 }; | ||
296 | scls.n = 0; | ||
297 | scls.value[0] = "one two three"; | ||
298 | scls.value_size[0] = strlen ("one two three"); | ||
299 | |||
300 | ASSERT (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo", | ||
301 | state_cb, &scls)); | ||
302 | ASSERT (scls.n == 1); | ||
303 | |||
304 | scls.n = 0; | ||
305 | scls.value[1] = slave_key; | ||
306 | scls.value_size[1] = sizeof (*slave_key); | ||
307 | |||
308 | ASSERT (GNUNET_OK == db->state_get_all (db->cls, &channel_pub_key, "_foo", | ||
309 | state_cb, &scls)); | ||
310 | ASSERT (scls.n == 2); | ||
311 | |||
312 | scls.n = 0; | ||
313 | ASSERT (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key, | ||
314 | state_cb, &scls)); | ||
315 | ASSERT (scls.n == 0); | ||
316 | |||
317 | ASSERT (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key)); | ||
318 | |||
319 | scls.n = 0; | ||
320 | ASSERT (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key, | ||
321 | state_cb, &scls)); | ||
322 | ASSERT (scls.n == 2); | ||
323 | |||
324 | ok = 0; | ||
325 | |||
326 | FAILURE: | ||
327 | |||
328 | if (NULL != channel_key) | ||
329 | { | ||
330 | GNUNET_free (channel_key); | ||
331 | channel_key = NULL; | ||
332 | } | ||
333 | if (NULL != slave_key) | ||
334 | { | ||
335 | GNUNET_free (slave_key); | ||
336 | slave_key = NULL; | ||
337 | } | ||
338 | |||
339 | unload_plugin (db); | ||
340 | } | ||
341 | |||
342 | |||
343 | int | ||
344 | main (int argc, char *argv[]) | ||
345 | { | ||
346 | char cfg_name[128]; | ||
347 | char *const xargv[] = { | ||
348 | "test-plugin-psycstore", | ||
349 | "-c", cfg_name, | ||
350 | "-L", LOG_LEVEL, | ||
351 | NULL | ||
352 | }; | ||
353 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
354 | GNUNET_GETOPT_OPTION_END | ||
355 | }; | ||
356 | |||
357 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
358 | GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL); | ||
359 | plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); | ||
360 | GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_psycstore_%s.conf", | ||
361 | plugin_name); | ||
362 | GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, | ||
363 | "test-plugin-psycstore", "nohelp", options, &run, NULL); | ||
364 | |||
365 | if (ok != 0) | ||
366 | FPRINTF (stderr, "Missed some testcases: %d\n", ok); | ||
367 | |||
368 | #if ! DEBUG_PSYCSTORE | ||
369 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite"); | ||
370 | #endif | ||
371 | |||
372 | return ok; | ||
373 | } | ||
374 | |||
375 | /* end of test_plugin_psycstore.c */ | ||
diff --git a/src/psycstore/test_plugin_psycstore_sqlite.conf b/src/psycstore/test_plugin_psycstore_sqlite.conf new file mode 100644 index 000000000..7cde6fa4c --- /dev/null +++ b/src/psycstore/test_plugin_psycstore_sqlite.conf | |||
@@ -0,0 +1,2 @@ | |||
1 | [psycstore-sqlite] | ||
2 | FILENAME = /tmp/gnunet-test-plugin-psycstore-sqlite/sqlite.db | ||
diff --git a/src/psycstore/test_psycstore.c b/src/psycstore/test_psycstore.c index 405d1622c..6b9e77180 100644 --- a/src/psycstore/test_psycstore.c +++ b/src/psycstore/test_psycstore.c | |||
@@ -48,13 +48,18 @@ static struct GNUNET_PSYCSTORE_Handle *h; | |||
48 | /** | 48 | /** |
49 | * Handle to PSYCstore operation. | 49 | * Handle to PSYCstore operation. |
50 | */ | 50 | */ |
51 | static struct GNUNET_PSYCSTORE_Operation *op; | 51 | static struct GNUNET_PSYCSTORE_OperationHandle *op; |
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Handle for task for timeout termination. | 54 | * Handle for task for timeout termination. |
55 | */ | 55 | */ |
56 | static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; | 56 | static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; |
57 | 57 | ||
58 | static struct GNUNET_CRYPTO_EccPrivateKey *channel_key; | ||
59 | static struct GNUNET_CRYPTO_EccPrivateKey *slave_key; | ||
60 | |||
61 | static struct GNUNET_CRYPTO_EccPublicKey channel_pub_key; | ||
62 | static struct GNUNET_CRYPTO_EccPublicKey slave_pub_key; | ||
58 | 63 | ||
59 | /** | 64 | /** |
60 | * Clean up all resources used. | 65 | * Clean up all resources used. |
@@ -72,6 +77,16 @@ cleanup () | |||
72 | GNUNET_PSYCSTORE_disconnect (h); | 77 | GNUNET_PSYCSTORE_disconnect (h); |
73 | h = NULL; | 78 | h = NULL; |
74 | } | 79 | } |
80 | if (NULL != channel_key) | ||
81 | { | ||
82 | GNUNET_free (channel_key); | ||
83 | channel_key = NULL; | ||
84 | } | ||
85 | if (NULL != slave_key) | ||
86 | { | ||
87 | GNUNET_free (slave_key); | ||
88 | slave_key = NULL; | ||
89 | } | ||
75 | GNUNET_SCHEDULER_shutdown (); | 90 | GNUNET_SCHEDULER_shutdown (); |
76 | } | 91 | } |
77 | 92 | ||
@@ -119,6 +134,11 @@ end () | |||
119 | &end_normally, NULL); | 134 | &end_normally, NULL); |
120 | } | 135 | } |
121 | 136 | ||
137 | void | ||
138 | membership_store_result (void *cls, int result, const char *err_msg) | ||
139 | { | ||
140 | |||
141 | } | ||
122 | 142 | ||
123 | /** | 143 | /** |
124 | * Main function of the test, run from scheduler. | 144 | * Main function of the test, run from scheduler. |
@@ -136,6 +156,17 @@ run (void *cls, | |||
136 | &endbadly, NULL); | 156 | &endbadly, NULL); |
137 | h = GNUNET_PSYCSTORE_connect (cfg); | 157 | h = GNUNET_PSYCSTORE_connect (cfg); |
138 | GNUNET_assert (NULL != h); | 158 | GNUNET_assert (NULL != h); |
159 | |||
160 | channel_key = GNUNET_CRYPTO_ecc_key_create (); | ||
161 | slave_key = GNUNET_CRYPTO_ecc_key_create (); | ||
162 | |||
163 | GNUNET_CRYPTO_ecc_key_get_public (channel_key, &channel_pub_key); | ||
164 | GNUNET_CRYPTO_ecc_key_get_public (slave_key, &slave_pub_key); | ||
165 | |||
166 | op = GNUNET_PSYCSTORE_membership_store (h, &channel_pub_key, &slave_pub_key, | ||
167 | GNUNET_YES, 2, 2, 1, | ||
168 | &membership_store_result, NULL); | ||
169 | |||
139 | end (); | 170 | end (); |
140 | } | 171 | } |
141 | 172 | ||
diff --git a/src/psycstore/test_psycstore.conf b/src/psycstore/test_psycstore.conf index 1f6d279ab..ea3031524 100644 --- a/src/psycstore/test_psycstore.conf +++ b/src/psycstore/test_psycstore.conf | |||
@@ -3,4 +3,13 @@ DEFAULTSERVICES = psycstore | |||
3 | UNIXPATH = /tmp/test-psycstore-service-arm.sock | 3 | UNIXPATH = /tmp/test-psycstore-service-arm.sock |
4 | 4 | ||
5 | [psycstore] | 5 | [psycstore] |
6 | DBFILE = /tmp/test-psycstore-service.sqlite | 6 | AUTOSTART = YES |
7 | HOME = $SERVICEHOME | ||
8 | BINARY = gnunet-service-psycstore | ||
9 | UNIXPATH = /tmp/test-gnunet-service-psycstore.sock | ||
10 | UNIX_MATCH_UID = NO | ||
11 | UNIX_MATCH_GID = YES | ||
12 | DATABASE = sqlite | ||
13 | |||
14 | [psycstore-sqlite] | ||
15 | FILENAME = $SERVICEHOME/psycstore/sqlite_test.db | ||