diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-12 19:09:52 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-12 19:09:52 +0000 |
commit | 5e05019536c0d38bf20f965613636f21ae7c2be6 (patch) | |
tree | eda1dee12e49c010171462d618162d28b21c9c6a /src/namestore/plugin_namestore_sqlite.c | |
parent | 566dfe32be22ed1f071b974be3c4dd8bc5721151 (diff) | |
download | gnunet-5e05019536c0d38bf20f965613636f21ae7c2be6.tar.gz gnunet-5e05019536c0d38bf20f965613636f21ae7c2be6.zip |
-towards namestore support for the new privacy-preserving GNS queries
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 595 |
1 files changed, 310 insertions, 285 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index a7cc03434..3559dc7ce 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -31,14 +31,14 @@ | |||
31 | #include <sqlite3.h> | 31 | #include <sqlite3.h> |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * After how many ms "busy" should a DB operation fail for good? | 34 | * After how many ms "busy" should a DB operation fail for good? A |
35 | * A low value makes sure that we are more responsive to requests | 35 | * low value makes sure that we are more responsive to requests |
36 | * (especially PUTs). A high value guarantees a higher success | 36 | * (especially PUTs). A high value guarantees a higher success rate |
37 | * rate (SELECTs in iterate can take several seconds despite LIMIT=1). | 37 | * (SELECTs in iterate can take several seconds despite LIMIT=1). |
38 | * | 38 | * |
39 | * The default value of 1s should ensure that users do not experience | 39 | * The default value of 1s should ensure that users do not experience |
40 | * huge latencies while at the same time allowing operations to succeed | 40 | * huge latencies while at the same time allowing operations to |
41 | * with reasonable probability. | 41 | * succeed with reasonable probability. |
42 | */ | 42 | */ |
43 | #define BUSY_TIMEOUT_MS 1000 | 43 | #define BUSY_TIMEOUT_MS 1000 |
44 | 44 | ||
@@ -72,45 +72,40 @@ struct Plugin | |||
72 | sqlite3 *dbh; | 72 | sqlite3 *dbh; |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * Precompiled SQL for put record | 75 | * Precompiled SQL for caching a block |
76 | */ | 76 | */ |
77 | sqlite3_stmt *put_records; | 77 | sqlite3_stmt *cache_block; |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * Precompiled SQL for remove record | 80 | * Precompiled SQL for looking up a block |
81 | */ | 81 | */ |
82 | sqlite3_stmt *remove_records; | 82 | sqlite3_stmt *lookup_block; |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * Precompiled SQL for iterate over all records. | 85 | * Precompiled SQL for removing expired blocks |
86 | */ | 86 | */ |
87 | sqlite3_stmt *iterate_all; | 87 | sqlite3_stmt *expire_blocks; |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Precompiled SQL for iterate records with same name. | 90 | * Precompiled SQL to store records. |
91 | */ | 91 | */ |
92 | sqlite3_stmt *iterate_by_name; | 92 | sqlite3_stmt *store_records; |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * Precompiled SQL for iterate records with same zone. | 95 | * Precompiled SQL to deltete existing records. |
96 | */ | 96 | */ |
97 | sqlite3_stmt *iterate_by_zone; | 97 | sqlite3_stmt *delete_records; |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * Precompiled SQL for iterate records with same name and zone. | 100 | * Precompiled SQL for iterate records within a zone. |
101 | */ | 101 | */ |
102 | sqlite3_stmt *iterate_records; | 102 | sqlite3_stmt *iterate_zone; |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Precompiled SQL to get the name for a given zone-value. | 105 | * Precompiled SQL to for reverse lookup based on PKEY. |
106 | */ | 106 | */ |
107 | sqlite3_stmt *zone_to_name; | 107 | sqlite3_stmt *zone_to_name; |
108 | 108 | ||
109 | /** | ||
110 | * Precompiled SQL for delete zone | ||
111 | */ | ||
112 | sqlite3_stmt *delete_zone; | ||
113 | |||
114 | }; | 109 | }; |
115 | 110 | ||
116 | 111 | ||
@@ -147,23 +142,17 @@ create_indices (sqlite3 * dbh) | |||
147 | { | 142 | { |
148 | /* create indices */ | 143 | /* create indices */ |
149 | if ( (SQLITE_OK != | 144 | if ( (SQLITE_OK != |
150 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)", | 145 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_query_hash ON ns096blocks (query,expiration_time)", |
151 | NULL, NULL, NULL)) || | ||
152 | (SQLITE_OK != | ||
153 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON ns091records (zone_hash,zone_delegation)", | ||
154 | NULL, NULL, NULL)) || | ||
155 | (SQLITE_OK != | ||
156 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns091records (zone_hash,rvalue)", | ||
157 | NULL, NULL, NULL)) || | 146 | NULL, NULL, NULL)) || |
158 | (SQLITE_OK != | 147 | (SQLITE_OK != |
159 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records (zone_hash)", | 148 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_block_expiration ON ns096blocks (expiration_time)", |
160 | NULL, NULL, NULL)) || | 149 | NULL, NULL, NULL)) || |
161 | (SQLITE_OK != | 150 | (SQLITE_OK != |
162 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns091records (record_name_hash,rvalue)", | 151 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns096records (zone_private_key,pkey_hash)", |
163 | NULL, NULL, NULL)) || | 152 | NULL, NULL, NULL)) || |
164 | (SQLITE_OK != | 153 | (SQLITE_OK != |
165 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records (rvalue)", | 154 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_iter ON ns096records (zone_private_key,rvalue)", |
166 | NULL, NULL, NULL)) ) | 155 | NULL, NULL, NULL)) ) |
167 | LOG (GNUNET_ERROR_TYPE_ERROR, | 156 | LOG (GNUNET_ERROR_TYPE_ERROR, |
168 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); | 157 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); |
169 | } | 158 | } |
@@ -255,22 +244,38 @@ database_setup (struct Plugin *plugin) | |||
255 | /* Create tables */ | 244 | /* Create tables */ |
256 | CHECK (SQLITE_OK == | 245 | CHECK (SQLITE_OK == |
257 | sq_prepare (plugin->dbh, | 246 | sq_prepare (plugin->dbh, |
258 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns091records'", | 247 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'", |
248 | &stmt)); | ||
249 | if ((sqlite3_step (stmt) == SQLITE_DONE) && | ||
250 | (sqlite3_exec | ||
251 | (plugin->dbh, | ||
252 | "CREATE TABLE ns096blocks (" | ||
253 | " query BLOB NOT NULL DEFAULT ''," | ||
254 | " block BLOB NOT NULL DEFAULT ''," | ||
255 | " expiration_time INT8 NOT NULL DEFAULT 0" | ||
256 | ")", | ||
257 | NULL, NULL, NULL) != SQLITE_OK)) | ||
258 | { | ||
259 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec"); | ||
260 | sqlite3_finalize (stmt); | ||
261 | return GNUNET_SYSERR; | ||
262 | } | ||
263 | sqlite3_finalize (stmt); | ||
264 | |||
265 | CHECK (SQLITE_OK == | ||
266 | sq_prepare (plugin->dbh, | ||
267 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096records'", | ||
259 | &stmt)); | 268 | &stmt)); |
260 | if ((sqlite3_step (stmt) == SQLITE_DONE) && | 269 | if ((sqlite3_step (stmt) == SQLITE_DONE) && |
261 | (sqlite3_exec | 270 | (sqlite3_exec |
262 | (plugin->dbh, | 271 | (plugin->dbh, |
263 | "CREATE TABLE ns091records (" | 272 | "CREATE TABLE ns096records (" |
264 | " zone_key BLOB NOT NULL DEFAULT ''," | 273 | " zone_private_key BLOB NOT NULL DEFAULT ''," |
265 | " zone_delegation BLOB NOT NULL DEFAULT ''," | 274 | " pkey_hash BLOB," |
266 | " zone_hash BLOB NOT NULL DEFAULT ''," | 275 | " rvalue INT8 NOT NULL DEFAULT ''," |
267 | " record_count INT NOT NULL DEFAULT 0," | 276 | " record_count INT NOT NULL DEFAULT 0," |
268 | " record_data BLOB NOT NULL DEFAULT ''," | 277 | " record_data BLOB NOT NULL DEFAULT ''," |
269 | " block_expiration_time INT8 NOT NULL DEFAULT 0," | 278 | " label TEXT NOT NULL DEFAULT ''" |
270 | " signature BLOB NOT NULL DEFAULT ''," | ||
271 | " record_name TEXT NOT NULL DEFAULT ''," | ||
272 | " record_name_hash BLOB NOT NULL DEFAULT ''," | ||
273 | " rvalue INT8 NOT NULL DEFAULT ''" | ||
274 | ")", | 279 | ")", |
275 | NULL, NULL, NULL) != SQLITE_OK)) | 280 | NULL, NULL, NULL) != SQLITE_OK)) |
276 | { | 281 | { |
@@ -284,42 +289,35 @@ database_setup (struct Plugin *plugin) | |||
284 | 289 | ||
285 | if ((sq_prepare | 290 | if ((sq_prepare |
286 | (plugin->dbh, | 291 | (plugin->dbh, |
287 | "INSERT INTO ns091records (zone_key, record_name, record_count, record_data, block_expiration_time, signature, zone_delegation, zone_hash, record_name_hash, rvalue) VALUES " | 292 | "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)", |
288 | "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", | 293 | &plugin->cache_block) != SQLITE_OK) || |
289 | &plugin->put_records) != SQLITE_OK) || | ||
290 | (sq_prepare | 294 | (sq_prepare |
291 | (plugin->dbh, | 295 | (plugin->dbh, |
292 | "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?", | 296 | "DELETE FROM ns096blocks WHERE expiration_time<?", |
293 | &plugin->remove_records) != SQLITE_OK) || | 297 | &plugin->expire_blocks) != SQLITE_OK) || |
294 | (sq_prepare | 298 | (sq_prepare |
295 | (plugin->dbh, | 299 | (plugin->dbh, |
296 | "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" | 300 | "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1", |
297 | " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 301 | &plugin->lookup_block) != SQLITE_OK) || |
298 | &plugin->iterate_records) != SQLITE_OK) || | ||
299 | (sq_prepare | 302 | (sq_prepare |
300 | (plugin->dbh, | 303 | (plugin->dbh, |
301 | "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" | 304 | "INSERT INTO ns096records (zone_private_key, pkey_hash, rvalue, record_count, record_data, label)" |
302 | " FROM ns091records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 305 | " VALUES (?, ?, ?, ?, ?, ?)", |
303 | &plugin->iterate_by_zone) != SQLITE_OK) || | 306 | &plugin->store_records) != SQLITE_OK) || |
304 | (sq_prepare | 307 | (sq_prepare |
305 | (plugin->dbh, | 308 | (plugin->dbh, |
306 | "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" | 309 | "DELETE FROM ns096records WHERE zone_private_key=? AND label=?", |
307 | " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 310 | &plugin->delete_records) != SQLITE_OK) || |
308 | &plugin->iterate_by_name) != SQLITE_OK) || | ||
309 | (sq_prepare | ||
310 | (plugin->dbh, | ||
311 | "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" | ||
312 | " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?", | ||
313 | &plugin->iterate_all) != SQLITE_OK) || | ||
314 | (sq_prepare | 311 | (sq_prepare |
315 | (plugin->dbh, | 312 | (plugin->dbh, |
316 | "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" | 313 | "SELECT record_count,record_data,label" |
317 | " FROM ns091records WHERE zone_hash=? AND zone_delegation=?", | 314 | " FROM ns096records WHERE zone_private_key=? AND pkey_hash=?", |
318 | &plugin->zone_to_name) != SQLITE_OK) || | 315 | &plugin->zone_to_name) != SQLITE_OK) || |
319 | (sq_prepare | 316 | (sq_prepare |
320 | (plugin->dbh, | 317 | (plugin->dbh, |
321 | "DELETE FROM ns091records WHERE zone_hash=?", | 318 | "SELECT record_count,record_data,label" |
322 | &plugin->delete_zone) != SQLITE_OK) ) | 319 | " FROM ns096records WHERE zone_private_key=? ORDER BY rvalue LIMIT 1 OFFSET ?", |
320 | &plugin->iterate_zone) != SQLITE_OK) ) | ||
323 | { | 321 | { |
324 | LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); | 322 | LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); |
325 | return GNUNET_SYSERR; | 323 | return GNUNET_SYSERR; |
@@ -339,22 +337,20 @@ database_shutdown (struct Plugin *plugin) | |||
339 | int result; | 337 | int result; |
340 | sqlite3_stmt *stmt; | 338 | sqlite3_stmt *stmt; |
341 | 339 | ||
342 | if (NULL != plugin->put_records) | 340 | if (NULL != plugin->cache_block) |
343 | sqlite3_finalize (plugin->put_records); | 341 | sqlite3_finalize (plugin->cache_block); |
344 | if (NULL != plugin->remove_records) | 342 | if (NULL != plugin->expire_blocks) |
345 | sqlite3_finalize (plugin->remove_records); | 343 | sqlite3_finalize (plugin->expire_blocks); |
346 | if (NULL != plugin->iterate_records) | 344 | if (NULL != plugin->lookup_block) |
347 | sqlite3_finalize (plugin->iterate_records); | 345 | sqlite3_finalize (plugin->lookup_block); |
348 | if (NULL != plugin->iterate_by_zone) | 346 | if (NULL != plugin->store_records) |
349 | sqlite3_finalize (plugin->iterate_by_zone); | 347 | sqlite3_finalize (plugin->store_records); |
350 | if (NULL != plugin->iterate_by_name) | 348 | if (NULL != plugin->delete_records) |
351 | sqlite3_finalize (plugin->iterate_by_name); | 349 | sqlite3_finalize (plugin->delete_records); |
352 | if (NULL != plugin->iterate_all) | 350 | if (NULL != plugin->iterate_zone) |
353 | sqlite3_finalize (plugin->iterate_all); | 351 | sqlite3_finalize (plugin->iterate_zone); |
354 | if (NULL != plugin->zone_to_name) | 352 | if (NULL != plugin->zone_to_name) |
355 | sqlite3_finalize (plugin->zone_to_name); | 353 | sqlite3_finalize (plugin->zone_to_name); |
356 | if (NULL != plugin->delete_zone) | ||
357 | sqlite3_finalize (plugin->delete_zone); | ||
358 | result = sqlite3_close (plugin->dbh); | 354 | result = sqlite3_close (plugin->dbh); |
359 | if (result == SQLITE_BUSY) | 355 | if (result == SQLITE_BUSY) |
360 | { | 356 | { |
@@ -381,55 +377,179 @@ database_shutdown (struct Plugin *plugin) | |||
381 | 377 | ||
382 | 378 | ||
383 | /** | 379 | /** |
384 | * Removes any existing record in the given zone with the same name. | 380 | * Removes any expired block. |
385 | * | 381 | * |
386 | * @param cls closure (internal context for the plugin) | 382 | * @param plugin the plugin |
387 | * @param zone hash of the public key of the zone | ||
388 | * @param name name to remove (at most 255 characters long) | ||
389 | * @return GNUNET_OK on success | ||
390 | */ | 383 | */ |
391 | static int | 384 | static void |
392 | namestore_sqlite_remove_records (void *cls, | 385 | namestore_sqlite_expire_blocks (struct Plugin *plugin) |
393 | const struct GNUNET_CRYPTO_ShortHashCode *zone, | ||
394 | const char *name) | ||
395 | { | 386 | { |
396 | struct Plugin *plugin = cls; | 387 | struct GNUNET_TIME_Absolute now; |
397 | struct GNUNET_CRYPTO_ShortHashCode nh; | ||
398 | size_t name_len; | ||
399 | int n; | 388 | int n; |
400 | 389 | ||
401 | name_len = strlen (name); | 390 | now = GNUNET_TIME_absolute_get (); |
402 | GNUNET_CRYPTO_short_hash (name, name_len, &nh); | 391 | if (SQLITE_OK != sqlite3_bind_int64 (plugin->expire_blocks, |
403 | 392 | 1, now.abs_value_us)) | |
404 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || | ||
405 | (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC))) | ||
406 | { | 393 | { |
407 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 394 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
408 | "sqlite3_bind_XXXX"); | 395 | "sqlite3_bind_XXXX"); |
409 | if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) | 396 | if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks)) |
410 | LOG_SQLITE (plugin, | 397 | LOG_SQLITE (plugin, |
411 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 398 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
412 | "sqlite3_reset"); | 399 | "sqlite3_reset"); |
413 | return GNUNET_SYSERR; | 400 | return; |
414 | } | 401 | } |
415 | n = sqlite3_step (plugin->remove_records); | 402 | n = sqlite3_step (plugin->expire_blocks); |
416 | if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) | 403 | if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks)) |
417 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 404 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
418 | "sqlite3_reset"); | 405 | "sqlite3_reset"); |
419 | switch (n) | 406 | switch (n) |
420 | { | 407 | { |
421 | case SQLITE_DONE: | 408 | case SQLITE_DONE: |
422 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record removed\n"); | 409 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Records expired\n"); |
423 | return GNUNET_OK; | 410 | return; |
424 | case SQLITE_BUSY: | 411 | case SQLITE_BUSY: |
425 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | 412 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, |
426 | "sqlite3_step"); | 413 | "sqlite3_step"); |
427 | return GNUNET_NO; | 414 | return; |
428 | default: | 415 | default: |
429 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 416 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
430 | "sqlite3_step"); | 417 | "sqlite3_step"); |
418 | return; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
424 | * Cache a block in the datastore. | ||
425 | * | ||
426 | * @param cls closure (internal context for the plugin) | ||
427 | * @param block block to cache | ||
428 | * @return GNUNET_OK on success, else GNUNET_SYSERR | ||
429 | */ | ||
430 | static int | ||
431 | namestore_sqlite_cache_block (void *cls, | ||
432 | const struct GNUNET_NAMESTORE_Block *block) | ||
433 | { | ||
434 | struct Plugin *plugin = cls; | ||
435 | struct GNUNET_HashCode query; | ||
436 | struct GNUNET_TIME_Absolute expiration; | ||
437 | size_t block_size; | ||
438 | int n; | ||
439 | |||
440 | namestore_sqlite_expire_blocks (plugin); | ||
441 | GNUNET_CRYPTO_hash (&block->derived_key, | ||
442 | sizeof (struct GNUNET_CRYPTO_EccPublicKey), | ||
443 | &query); | ||
444 | expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time); | ||
445 | block_size = ntohl (block->purpose.size) + | ||
446 | sizeof (struct GNUNET_CRYPTO_EccPublicKey) + | ||
447 | sizeof (struct GNUNET_CRYPTO_EccSignature); | ||
448 | if (block_size > 64 * 65536) | ||
449 | { | ||
450 | GNUNET_break (0); | ||
451 | return GNUNET_SYSERR; | ||
452 | } | ||
453 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 1, &query, sizeof (struct GNUNET_HashCode), SQLITE_STATIC)) || | ||
454 | (SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 2, block, block_size, SQLITE_STATIC)) || | ||
455 | (SQLITE_OK != sqlite3_bind_int64 (plugin->cache_block, 3, expiration.abs_value_us))) | ||
456 | { | ||
457 | LOG_SQLITE (plugin, | ||
458 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
459 | "sqlite3_bind_XXXX"); | ||
460 | if (SQLITE_OK != sqlite3_reset (plugin->cache_block)) | ||
461 | LOG_SQLITE (plugin, | ||
462 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
463 | "sqlite3_reset"); | ||
464 | return GNUNET_SYSERR; | ||
465 | |||
466 | } | ||
467 | n = sqlite3_step (plugin->cache_block); | ||
468 | if (SQLITE_OK != sqlite3_reset (plugin->cache_block)) | ||
469 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
470 | "sqlite3_reset"); | ||
471 | switch (n) | ||
472 | { | ||
473 | case SQLITE_DONE: | ||
474 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n"); | ||
475 | return GNUNET_OK; | ||
476 | case SQLITE_BUSY: | ||
477 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
478 | "sqlite3_step"); | ||
479 | return GNUNET_NO; | ||
480 | default: | ||
481 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
482 | "sqlite3_step"); | ||
483 | return GNUNET_SYSERR; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | |||
488 | /** | ||
489 | * Get the block for a particular zone and label in the | ||
490 | * datastore. Will return at most one result to the iterator. | ||
491 | * | ||
492 | * @param cls closure (internal context for the plugin) | ||
493 | * @param query hash of public key derived from the zone and the label | ||
494 | * @param iter function to call with the result | ||
495 | * @param iter_cls closure for iter | ||
496 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error | ||
497 | * 'iter' will have been called unless the return value is 'GNUNET_SYSERR' | ||
498 | */ | ||
499 | static int | ||
500 | namestore_sqlite_lookup_block (void *cls, | ||
501 | const struct GNUNET_HashCode *query, | ||
502 | GNUNET_NAMESTORE_BlockCallback iter, void *iter_cls) | ||
503 | { | ||
504 | struct Plugin *plugin = cls; | ||
505 | int ret; | ||
506 | int sret; | ||
507 | size_t block_size; | ||
508 | const struct GNUNET_NAMESTORE_Block *block; | ||
509 | |||
510 | if (SQLITE_OK != sqlite3_bind_blob (plugin->lookup_block, 1, | ||
511 | query, sizeof (struct GNUNET_HashCode), | ||
512 | SQLITE_STATIC)) | ||
513 | { | ||
514 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
515 | "sqlite3_bind_XXXX"); | ||
516 | if (SQLITE_OK != sqlite3_reset (plugin->lookup_block)) | ||
517 | LOG_SQLITE (plugin, | ||
518 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
519 | "sqlite3_reset"); | ||
431 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
521 | } | ||
522 | |||
523 | ret = GNUNET_NO; | ||
524 | if (SQLITE_ROW == (sret = sqlite3_step (plugin->lookup_block))) | ||
525 | { | ||
526 | ret = GNUNET_YES; | ||
527 | block = sqlite3_column_blob (plugin->lookup_block, 0); | ||
528 | block_size = sqlite3_column_bytes (plugin->lookup_block, 0); | ||
529 | if ( (block_size < sizeof (struct GNUNET_NAMESTORE_Block)) || | ||
530 | (ntohl (block->purpose.size) + | ||
531 | sizeof (struct GNUNET_CRYPTO_EccPublicKey) + | ||
532 | sizeof (struct GNUNET_CRYPTO_EccSignature) != block_size) ) | ||
533 | { | ||
534 | GNUNET_break (0); | ||
535 | ret = GNUNET_SYSERR; | ||
536 | } | ||
537 | else | ||
538 | { | ||
539 | iter (iter_cls, block); | ||
540 | } | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | if (SQLITE_DONE != sret) | ||
545 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
546 | iter (iter_cls, NULL); | ||
432 | } | 547 | } |
548 | if (SQLITE_OK != sqlite3_reset (plugin->lookup_block)) | ||
549 | LOG_SQLITE (plugin, | ||
550 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
551 | "sqlite3_reset"); | ||
552 | return ret; | ||
433 | } | 553 | } |
434 | 554 | ||
435 | 555 | ||
@@ -438,47 +558,34 @@ namestore_sqlite_remove_records (void *cls, | |||
438 | * same zone with the same name. | 558 | * same zone with the same name. |
439 | * | 559 | * |
440 | * @param cls closure (internal context for the plugin) | 560 | * @param cls closure (internal context for the plugin) |
441 | * @param zone_key public key of the zone | 561 | * @param zone_key private key of the zone |
442 | * @param expire when does the corresponding block in the DHT expire (until | 562 | * @param label name that is being mapped (at most 255 characters long) |
443 | * when should we never do a DHT lookup for the same name again)? | ||
444 | * @param name name that is being mapped (at most 255 characters long) | ||
445 | * @param rd_count number of entries in 'rd' array | 563 | * @param rd_count number of entries in 'rd' array |
446 | * @param rd array of records with data to store | 564 | * @param rd array of records with data to store |
447 | * @param signature signature of the record block, NULL if signature is unavailable (i.e. | ||
448 | * because the user queried for a particular record type only) | ||
449 | * @return GNUNET_OK on success, else GNUNET_SYSERR | 565 | * @return GNUNET_OK on success, else GNUNET_SYSERR |
450 | */ | 566 | */ |
451 | static int | 567 | static int |
452 | namestore_sqlite_put_records (void *cls, | 568 | namestore_sqlite_store_records (void *cls, |
453 | const struct GNUNET_CRYPTO_EccPublicKey *zone_key, | 569 | const struct GNUNET_CRYPTO_EccPrivateKey *zone_key, |
454 | struct GNUNET_TIME_Absolute expire, | 570 | const char *label, |
455 | const char *name, | 571 | unsigned int rd_count, |
456 | unsigned int rd_count, | 572 | const struct GNUNET_NAMESTORE_RecordData *rd) |
457 | const struct GNUNET_NAMESTORE_RecordData *rd, | ||
458 | const struct GNUNET_CRYPTO_EccSignature *signature) | ||
459 | { | 573 | { |
460 | struct Plugin *plugin = cls; | 574 | struct Plugin *plugin = cls; |
461 | int n; | 575 | int n; |
462 | struct GNUNET_CRYPTO_ShortHashCode zone; | 576 | struct GNUNET_HashCode pkey_hash; |
463 | struct GNUNET_CRYPTO_ShortHashCode zone_delegation; | ||
464 | struct GNUNET_CRYPTO_ShortHashCode nh; | ||
465 | size_t name_len; | ||
466 | uint64_t rvalue; | 577 | uint64_t rvalue; |
467 | size_t data_size; | 578 | size_t data_size; |
468 | unsigned int i; | 579 | unsigned int i; |
469 | 580 | ||
470 | GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_EccPublicKey), &zone); | 581 | memset (&pkey_hash, 0, sizeof (pkey_hash)); |
471 | (void) namestore_sqlite_remove_records (plugin, &zone, name); | ||
472 | name_len = strlen (name); | ||
473 | GNUNET_CRYPTO_short_hash (name, name_len, &nh); | ||
474 | memset (&zone_delegation, 0, sizeof (zone_delegation)); | ||
475 | for (i=0;i<rd_count;i++) | 582 | for (i=0;i<rd_count;i++) |
476 | if (rd[i].record_type == GNUNET_NAMESTORE_TYPE_PKEY) | 583 | if (GNUNET_NAMESTORE_TYPE_PKEY == rd[i].record_type) |
477 | { | 584 | { |
478 | GNUNET_assert (sizeof (struct GNUNET_CRYPTO_ShortHashCode) == rd[i].data_size); | 585 | GNUNET_break (sizeof (struct GNUNET_CRYPTO_EccPublicKey) == rd[i].data_size); |
479 | memcpy (&zone_delegation, | 586 | GNUNET_CRYPTO_hash (rd[i].data, |
480 | rd[i].data, | 587 | rd[i].data_size, |
481 | sizeof (struct GNUNET_CRYPTO_ShortHashCode)); | 588 | &pkey_hash); |
482 | break; | 589 | break; |
483 | } | 590 | } |
484 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | 591 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); |
@@ -497,31 +604,52 @@ namestore_sqlite_put_records (void *cls, | |||
497 | GNUNET_break (0); | 604 | GNUNET_break (0); |
498 | return GNUNET_SYSERR; | 605 | return GNUNET_SYSERR; |
499 | } | 606 | } |
500 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 1, zone_key, sizeof (struct GNUNET_CRYPTO_EccPublicKey), SQLITE_STATIC)) || | 607 | |
501 | (SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, SQLITE_STATIC)) || | 608 | /* First delete 'old' records */ |
502 | (SQLITE_OK != sqlite3_bind_int (plugin->put_records, 3, rd_count)) || | 609 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->delete_records, 1, |
503 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || | 610 | zone_key, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) || |
504 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value_us)) || | 611 | (SQLITE_OK != sqlite3_bind_text (plugin->delete_records, 2, label, -1, SQLITE_STATIC))) |
505 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_EccSignature), SQLITE_STATIC)) || | ||
506 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone_delegation, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || | ||
507 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || | ||
508 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) || | ||
509 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) ) | ||
510 | { | 612 | { |
511 | LOG_SQLITE (plugin, | 613 | LOG_SQLITE (plugin, |
512 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 614 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
513 | "sqlite3_bind_XXXX"); | 615 | "sqlite3_bind_XXXX"); |
514 | if (SQLITE_OK != sqlite3_reset (plugin->put_records)) | 616 | if (SQLITE_OK != sqlite3_reset (plugin->delete_records)) |
515 | LOG_SQLITE (plugin, | 617 | LOG_SQLITE (plugin, |
516 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 618 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
517 | "sqlite3_reset"); | 619 | "sqlite3_reset"); |
518 | return GNUNET_SYSERR; | 620 | return GNUNET_SYSERR; |
519 | 621 | ||
520 | } | 622 | } |
521 | n = sqlite3_step (plugin->put_records); | 623 | n = sqlite3_step (plugin->delete_records); |
522 | if (SQLITE_OK != sqlite3_reset (plugin->put_records)) | 624 | if (SQLITE_OK != sqlite3_reset (plugin->delete_records)) |
523 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 625 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
524 | "sqlite3_reset"); | 626 | "sqlite3_reset"); |
627 | |||
628 | if (0 != rd_count) | ||
629 | { | ||
630 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 1, | ||
631 | zone_key, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) || | ||
632 | (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 2, | ||
633 | &pkey_hash, sizeof (struct GNUNET_HashCode), SQLITE_STATIC)) || | ||
634 | (SQLITE_OK != sqlite3_bind_int64 (plugin->store_records, 3, rvalue)) || | ||
635 | (SQLITE_OK != sqlite3_bind_int (plugin->store_records, 4, rd_count)) || | ||
636 | (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 5, data, data_size, SQLITE_STATIC)) || | ||
637 | (SQLITE_OK != sqlite3_bind_text (plugin->store_records, 6, label, -1, SQLITE_STATIC))) | ||
638 | { | ||
639 | LOG_SQLITE (plugin, | ||
640 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
641 | "sqlite3_bind_XXXX"); | ||
642 | if (SQLITE_OK != sqlite3_reset (plugin->store_records)) | ||
643 | LOG_SQLITE (plugin, | ||
644 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
645 | "sqlite3_reset"); | ||
646 | return GNUNET_SYSERR; | ||
647 | } | ||
648 | n = sqlite3_step (plugin->store_records); | ||
649 | if (SQLITE_OK != sqlite3_reset (plugin->store_records)) | ||
650 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
651 | "sqlite3_reset"); | ||
652 | } | ||
525 | } | 653 | } |
526 | switch (n) | 654 | switch (n) |
527 | { | 655 | { |
@@ -547,6 +675,7 @@ namestore_sqlite_put_records (void *cls, | |||
547 | * | 675 | * |
548 | * @param plugin plugin context | 676 | * @param plugin plugin context |
549 | * @param stmt to run (and then clean up) | 677 | * @param stmt to run (and then clean up) |
678 | * @param zone_key private key of the zone | ||
550 | * @param iter iterator to call with the result | 679 | * @param iter iterator to call with the result |
551 | * @param iter_cls closure for 'iter' | 680 | * @param iter_cls closure for 'iter' |
552 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error | 681 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error |
@@ -554,37 +683,26 @@ namestore_sqlite_put_records (void *cls, | |||
554 | static int | 683 | static int |
555 | get_record_and_call_iterator (struct Plugin *plugin, | 684 | get_record_and_call_iterator (struct Plugin *plugin, |
556 | sqlite3_stmt *stmt, | 685 | sqlite3_stmt *stmt, |
686 | const struct GNUNET_CRYPTO_EccPrivateKey *zone_key, | ||
557 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 687 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) |
558 | { | 688 | { |
559 | int ret; | ||
560 | int sret; | ||
561 | unsigned int record_count; | 689 | unsigned int record_count; |
562 | size_t data_size; | 690 | size_t data_size; |
563 | const struct GNUNET_CRYPTO_EccPublicKey *zone_key; | ||
564 | const struct GNUNET_CRYPTO_EccSignature *sig; | ||
565 | struct GNUNET_TIME_Absolute expiration; | ||
566 | const char *data; | 691 | const char *data; |
567 | const char *name; | 692 | const char *label; |
693 | int ret; | ||
694 | int sret; | ||
568 | 695 | ||
569 | ret = GNUNET_NO; | 696 | ret = GNUNET_NO; |
570 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) | 697 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) |
571 | { | 698 | { |
572 | ret = GNUNET_YES; | 699 | ret = GNUNET_YES; |
573 | zone_key = sqlite3_column_blob (stmt, 0); | 700 | record_count = sqlite3_column_int (stmt, 0); |
574 | name = (const char*) sqlite3_column_text (stmt, 1); | 701 | data_size = sqlite3_column_bytes (stmt, 1); |
575 | record_count = sqlite3_column_int (stmt, 2); | 702 | data = sqlite3_column_blob (stmt, 1); |
576 | data_size = sqlite3_column_bytes (stmt, 3); | 703 | label = (const char*) sqlite3_column_text (stmt, 2); |
577 | data = sqlite3_column_blob (stmt, 3); | 704 | |
578 | expiration.abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4); | 705 | if (record_count > 64 * 1024) |
579 | sig = sqlite3_column_blob (stmt, 5); | ||
580 | |||
581 | if ( (sizeof (struct GNUNET_CRYPTO_EccPublicKey) != sqlite3_column_bytes (stmt, 0)) || | ||
582 | (sizeof (struct GNUNET_CRYPTO_EccSignature) != sqlite3_column_bytes (stmt, 5)) ) | ||
583 | { | ||
584 | GNUNET_break (0); | ||
585 | ret = GNUNET_SYSERR; | ||
586 | } | ||
587 | else if (record_count > 64 * 1024) | ||
588 | { | 706 | { |
589 | /* sanity check, don't stack allocate far too much just | 707 | /* sanity check, don't stack allocate far too much just |
590 | because database might contain a large value here */ | 708 | because database might contain a large value here */ |
@@ -604,8 +722,8 @@ get_record_and_call_iterator (struct Plugin *plugin, | |||
604 | } | 722 | } |
605 | else | 723 | else |
606 | { | 724 | { |
607 | iter (iter_cls, zone_key, expiration, name, | 725 | iter (iter_cls, zone_key, label, |
608 | record_count, rd, sig); | 726 | record_count, rd); |
609 | } | 727 | } |
610 | } | 728 | } |
611 | } | 729 | } |
@@ -613,7 +731,7 @@ get_record_and_call_iterator (struct Plugin *plugin, | |||
613 | { | 731 | { |
614 | if (SQLITE_DONE != sret) | 732 | if (SQLITE_DONE != sret) |
615 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | 733 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); |
616 | iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); | 734 | iter (iter_cls, NULL, NULL, 0, NULL); |
617 | } | 735 | } |
618 | if (SQLITE_OK != sqlite3_reset (stmt)) | 736 | if (SQLITE_OK != sqlite3_reset (stmt)) |
619 | LOG_SQLITE (plugin, | 737 | LOG_SQLITE (plugin, |
@@ -621,15 +739,14 @@ get_record_and_call_iterator (struct Plugin *plugin, | |||
621 | "sqlite3_reset"); | 739 | "sqlite3_reset"); |
622 | return ret; | 740 | return ret; |
623 | } | 741 | } |
624 | 742 | ||
625 | 743 | ||
626 | /** | 744 | /** |
627 | * Iterate over the results for a particular key and zone in the | 745 | * Iterate over the results for a particular key and zone in the |
628 | * datastore. Will return at most one result to the iterator. | 746 | * datastore. Will return at most one result to the iterator. |
629 | * | 747 | * |
630 | * @param cls closure (internal context for the plugin) | 748 | * @param cls closure (internal context for the plugin) |
631 | * @param zone hash of public key of the zone, NULL to iterate over all zones | 749 | * @param zone hash of public key of the zone, NULL to iterate over all zones |
632 | * @param name name as string, NULL to iterate over all records of the zone | ||
633 | * @param offset offset in the list of all matching records | 750 | * @param offset offset in the list of all matching records |
634 | * @param iter function to call with the result | 751 | * @param iter function to call with the result |
635 | * @param iter_cls closure for iter | 752 | * @param iter_cls closure for iter |
@@ -637,55 +754,21 @@ get_record_and_call_iterator (struct Plugin *plugin, | |||
637 | */ | 754 | */ |
638 | static int | 755 | static int |
639 | namestore_sqlite_iterate_records (void *cls, | 756 | namestore_sqlite_iterate_records (void *cls, |
640 | const struct GNUNET_CRYPTO_ShortHashCode *zone, | 757 | const struct GNUNET_CRYPTO_EccPrivateKey *zone, |
641 | const char *name, | ||
642 | uint64_t offset, | 758 | uint64_t offset, |
643 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 759 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) |
644 | { | 760 | { |
645 | struct Plugin *plugin = cls; | 761 | struct Plugin *plugin = cls; |
646 | sqlite3_stmt *stmt; | 762 | sqlite3_stmt *stmt; |
647 | struct GNUNET_CRYPTO_ShortHashCode name_hase; | ||
648 | unsigned int boff; | ||
649 | 763 | ||
650 | if (NULL == zone) | 764 | stmt = plugin->iterate_zone; |
651 | if (NULL == name) | ||
652 | stmt = plugin->iterate_all; | ||
653 | else | ||
654 | { | ||
655 | GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase); | ||
656 | stmt = plugin->iterate_by_name; | ||
657 | } | ||
658 | else | ||
659 | if (NULL == name) | ||
660 | stmt = plugin->iterate_by_zone; | ||
661 | else | ||
662 | { | ||
663 | GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase); | ||
664 | stmt = plugin->iterate_records; | ||
665 | } | ||
666 | 765 | ||
667 | boff = 0; | 766 | if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, |
668 | if ( (NULL != zone) && | 767 | zone, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), |
669 | (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, | 768 | SQLITE_STATIC)) || |
670 | zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), | 769 | (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, |
671 | SQLITE_STATIC)) ) | 770 | offset)) ) |
672 | { | ||
673 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
674 | "sqlite3_bind_XXXX"); | ||
675 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
676 | LOG_SQLITE (plugin, | ||
677 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
678 | "sqlite3_reset"); | ||
679 | return GNUNET_SYSERR; | ||
680 | } | ||
681 | if ( (NULL != name) && | ||
682 | (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, | ||
683 | &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode), | ||
684 | SQLITE_STATIC)) ) | ||
685 | { | 771 | { |
686 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
687 | "ITERATE NAME HASH: `%8s'", | ||
688 | GNUNET_NAMESTORE_short_h2s(&name_hase)); | ||
689 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 772 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
690 | "sqlite3_bind_XXXX"); | 773 | "sqlite3_bind_XXXX"); |
691 | if (SQLITE_OK != sqlite3_reset (stmt)) | 774 | if (SQLITE_OK != sqlite3_reset (stmt)) |
@@ -694,20 +777,7 @@ namestore_sqlite_iterate_records (void *cls, | |||
694 | "sqlite3_reset"); | 777 | "sqlite3_reset"); |
695 | return GNUNET_SYSERR; | 778 | return GNUNET_SYSERR; |
696 | } | 779 | } |
697 | 780 | return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls); | |
698 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, ++boff, | ||
699 | offset)) | ||
700 | { | ||
701 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
702 | "sqlite3_bind_XXXX"); | ||
703 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
704 | LOG_SQLITE (plugin, | ||
705 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
706 | "sqlite3_reset"); | ||
707 | return GNUNET_SYSERR; | ||
708 | } | ||
709 | |||
710 | return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); | ||
711 | } | 781 | } |
712 | 782 | ||
713 | 783 | ||
@@ -716,16 +786,16 @@ namestore_sqlite_iterate_records (void *cls, | |||
716 | * Returns at most one result to the iterator. | 786 | * Returns at most one result to the iterator. |
717 | * | 787 | * |
718 | * @param cls closure (internal context for the plugin) | 788 | * @param cls closure (internal context for the plugin) |
719 | * @param zone hash of public key of the zone to look up in, never NULL | 789 | * @param zone private key of the zone to look up in, never NULL |
720 | * @param value_zone hash of the public key of the target zone (value), never NULL | 790 | * @param value_zone public key of the target zone (value), never NULL |
721 | * @param iter function to call with the result | 791 | * @param iter function to call with the result |
722 | * @param iter_cls closure for iter | 792 | * @param iter_cls closure for iter |
723 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error | 793 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error |
724 | */ | 794 | */ |
725 | static int | 795 | static int |
726 | namestore_sqlite_zone_to_name (void *cls, | 796 | namestore_sqlite_zone_to_name (void *cls, |
727 | const struct GNUNET_CRYPTO_ShortHashCode *zone, | 797 | const struct GNUNET_CRYPTO_EccPrivateKey *zone, |
728 | const struct GNUNET_CRYPTO_ShortHashCode *value_zone, | 798 | const struct GNUNET_CRYPTO_EccPublicKey *value_zone, |
729 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 799 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) |
730 | { | 800 | { |
731 | struct Plugin *plugin = cls; | 801 | struct Plugin *plugin = cls; |
@@ -733,10 +803,10 @@ namestore_sqlite_zone_to_name (void *cls, | |||
733 | 803 | ||
734 | stmt = plugin->zone_to_name; | 804 | stmt = plugin->zone_to_name; |
735 | if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, | 805 | if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, |
736 | zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), | 806 | zone, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), |
737 | SQLITE_STATIC)) || | 807 | SQLITE_STATIC)) || |
738 | (SQLITE_OK != sqlite3_bind_blob (stmt, 2, | 808 | (SQLITE_OK != sqlite3_bind_blob (stmt, 2, |
739 | value_zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), | 809 | value_zone, sizeof (struct GNUNET_CRYPTO_EccPublicKey), |
740 | SQLITE_STATIC)) ) | 810 | SQLITE_STATIC)) ) |
741 | { | 811 | { |
742 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 812 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
@@ -747,52 +817,7 @@ namestore_sqlite_zone_to_name (void *cls, | |||
747 | "sqlite3_reset"); | 817 | "sqlite3_reset"); |
748 | return GNUNET_SYSERR; | 818 | return GNUNET_SYSERR; |
749 | } | 819 | } |
750 | return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); | 820 | return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls); |
751 | } | ||
752 | |||
753 | |||
754 | /** | ||
755 | * Delete an entire zone (all records). Not used in normal operation. | ||
756 | * | ||
757 | * @param cls closure (internal context for the plugin) | ||
758 | * @param zone zone to delete | ||
759 | */ | ||
760 | static void | ||
761 | namestore_sqlite_delete_zone (void *cls, | ||
762 | const struct GNUNET_CRYPTO_ShortHashCode *zone) | ||
763 | { | ||
764 | struct Plugin *plugin = cls; | ||
765 | sqlite3_stmt *stmt = plugin->delete_zone; | ||
766 | int n; | ||
767 | |||
768 | if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) | ||
769 | { | ||
770 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
771 | "sqlite3_bind_XXXX"); | ||
772 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
773 | LOG_SQLITE (plugin, | ||
774 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
775 | "sqlite3_reset"); | ||
776 | return; | ||
777 | } | ||
778 | n = sqlite3_step (stmt); | ||
779 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
780 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
781 | "sqlite3_reset"); | ||
782 | switch (n) | ||
783 | { | ||
784 | case SQLITE_DONE: | ||
785 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Values deleted\n"); | ||
786 | break; | ||
787 | case SQLITE_BUSY: | ||
788 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
789 | "sqlite3_step"); | ||
790 | break; | ||
791 | default: | ||
792 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
793 | "sqlite3_step"); | ||
794 | break; | ||
795 | } | ||
796 | } | 821 | } |
797 | 822 | ||
798 | 823 | ||
@@ -818,13 +843,13 @@ libgnunet_plugin_namestore_sqlite_init (void *cls) | |||
818 | database_shutdown (&plugin); | 843 | database_shutdown (&plugin); |
819 | return NULL; | 844 | return NULL; |
820 | } | 845 | } |
821 | api = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_PluginFunctions)); | 846 | api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions); |
822 | api->cls = &plugin; | 847 | api->cls = &plugin; |
823 | api->put_records = &namestore_sqlite_put_records; | 848 | api->cache_block = &namestore_sqlite_cache_block; |
824 | api->remove_records = &namestore_sqlite_remove_records; | 849 | api->lookup_block = &namestore_sqlite_lookup_block; |
850 | api->store_records = &namestore_sqlite_store_records; | ||
825 | api->iterate_records = &namestore_sqlite_iterate_records; | 851 | api->iterate_records = &namestore_sqlite_iterate_records; |
826 | api->zone_to_name = &namestore_sqlite_zone_to_name; | 852 | api->zone_to_name = &namestore_sqlite_zone_to_name; |
827 | api->delete_zone = &namestore_sqlite_delete_zone; | ||
828 | LOG (GNUNET_ERROR_TYPE_INFO, | 853 | LOG (GNUNET_ERROR_TYPE_INFO, |
829 | _("Sqlite database running\n")); | 854 | _("Sqlite database running\n")); |
830 | return api; | 855 | return api; |