diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-03-05 00:59:24 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-03-05 00:59:24 +0000 |
commit | 3023629d236c50dff73e8c5c74fc6d4bc004e906 (patch) | |
tree | 2505522f26d9e0f1124829805462f3e7d43495b1 /src/namestore/plugin_namestore_sqlite.c | |
parent | 1f4ed20322b5f78db7dec530753d00a32fd03761 (diff) | |
download | gnunet-3023629d236c50dff73e8c5c74fc6d4bc004e906.tar.gz gnunet-3023629d236c50dff73e8c5c74fc6d4bc004e906.zip |
-implementing zone_to_name
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 170 |
1 files changed, 148 insertions, 22 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 3d511a6e4..5dc52bcfc 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -101,6 +101,11 @@ struct Plugin | |||
101 | sqlite3_stmt *iterate_records; | 101 | sqlite3_stmt *iterate_records; |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * Precompiled SQL to get the name for a given zone-value. | ||
105 | */ | ||
106 | sqlite3_stmt *zone_to_name; | ||
107 | |||
108 | /** | ||
104 | * Precompiled SQL for delete zone | 109 | * Precompiled SQL for delete zone |
105 | */ | 110 | */ |
106 | sqlite3_stmt *delete_zone; | 111 | sqlite3_stmt *delete_zone; |
@@ -141,19 +146,22 @@ create_indices (sqlite3 * dbh) | |||
141 | { | 146 | { |
142 | /* create indices */ | 147 | /* create indices */ |
143 | if ( (SQLITE_OK != | 148 | if ( (SQLITE_OK != |
144 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns090records (zone_hash,record_name_hash,rvalue)", | 149 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)", |
145 | NULL, NULL, NULL)) || | 150 | NULL, NULL, NULL)) || |
146 | (SQLITE_OK != | 151 | (SQLITE_OK != |
147 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns090records (zone_hash,rvalue)", | 152 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON ns091records (zone_hash,zone_delegation)", |
148 | NULL, NULL, NULL)) || | 153 | NULL, NULL, NULL)) || |
149 | (SQLITE_OK != | 154 | (SQLITE_OK != |
150 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns090records (zone_hash)", | 155 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns091records (zone_hash,rvalue)", |
151 | NULL, NULL, NULL)) || | 156 | NULL, NULL, NULL)) || |
152 | (SQLITE_OK != | 157 | (SQLITE_OK != |
153 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns090records (record_name_hash,rvalue)", | 158 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records (zone_hash)", |
154 | NULL, NULL, NULL)) || | 159 | NULL, NULL, NULL)) || |
155 | (SQLITE_OK != | 160 | (SQLITE_OK != |
156 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns090records (rvalue)", | 161 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns091records (record_name_hash,rvalue)", |
162 | NULL, NULL, NULL)) || | ||
163 | (SQLITE_OK != | ||
164 | sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records (rvalue)", | ||
157 | NULL, NULL, NULL)) ) | 165 | NULL, NULL, NULL)) ) |
158 | LOG (GNUNET_ERROR_TYPE_ERROR, | 166 | LOG (GNUNET_ERROR_TYPE_ERROR, |
159 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); | 167 | "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); |
@@ -252,13 +260,14 @@ database_setup (struct Plugin *plugin) | |||
252 | /* Create tables */ | 260 | /* Create tables */ |
253 | CHECK (SQLITE_OK == | 261 | CHECK (SQLITE_OK == |
254 | sq_prepare (plugin->dbh, | 262 | sq_prepare (plugin->dbh, |
255 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns090records'", | 263 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns091records'", |
256 | &stmt)); | 264 | &stmt)); |
257 | if ((sqlite3_step (stmt) == SQLITE_DONE) && | 265 | if ((sqlite3_step (stmt) == SQLITE_DONE) && |
258 | (sqlite3_exec | 266 | (sqlite3_exec |
259 | (plugin->dbh, | 267 | (plugin->dbh, |
260 | "CREATE TABLE ns090records (" | 268 | "CREATE TABLE ns091records (" |
261 | " zone_key BLOB NOT NULL DEFAULT ''," | 269 | " zone_key BLOB NOT NULL DEFAULT ''," |
270 | " zone_delegation BLOB NOT NULL DEFAULT ''," | ||
262 | " zone_hash BLOB NOT NULL DEFAULT ''," | 271 | " zone_hash BLOB NOT NULL DEFAULT ''," |
263 | " record_count INT NOT NULL DEFAULT 0," | 272 | " record_count INT NOT NULL DEFAULT 0," |
264 | " record_data BLOB NOT NULL DEFAULT ''," | 273 | " record_data BLOB NOT NULL DEFAULT ''," |
@@ -281,36 +290,41 @@ database_setup (struct Plugin *plugin) | |||
281 | #define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature" | 290 | #define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature" |
282 | if ((sq_prepare | 291 | if ((sq_prepare |
283 | (plugin->dbh, | 292 | (plugin->dbh, |
284 | "INSERT INTO ns090records (" ALL ", zone_hash, record_name_hash, rvalue) VALUES " | 293 | "INSERT INTO ns091records (" ALL ", zone_delegation, zone_hash, record_name_hash, rvalue) VALUES " |
285 | "(?, ?, ?, ?, ?, ?, ?, ?, ?)", | 294 | "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", |
286 | &plugin->put_records) != SQLITE_OK) || | 295 | &plugin->put_records) != SQLITE_OK) || |
287 | (sq_prepare | 296 | (sq_prepare |
288 | (plugin->dbh, | 297 | (plugin->dbh, |
289 | "DELETE FROM ns090records WHERE zone_hash=? AND record_name_hash=?", | 298 | "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?", |
290 | &plugin->remove_records) != SQLITE_OK) || | 299 | &plugin->remove_records) != SQLITE_OK) || |
291 | (sq_prepare | 300 | (sq_prepare |
292 | (plugin->dbh, | 301 | (plugin->dbh, |
293 | "SELECT " ALL | 302 | "SELECT " ALL |
294 | " FROM ns090records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 303 | " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", |
295 | &plugin->iterate_records) != SQLITE_OK) || | 304 | &plugin->iterate_records) != SQLITE_OK) || |
296 | (sq_prepare | 305 | (sq_prepare |
297 | (plugin->dbh, | 306 | (plugin->dbh, |
298 | "SELECT " ALL | 307 | "SELECT " ALL |
299 | " FROM ns090records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 308 | " FROM ns091records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", |
300 | &plugin->iterate_by_zone) != SQLITE_OK) || | 309 | &plugin->iterate_by_zone) != SQLITE_OK) || |
301 | (sq_prepare | 310 | (sq_prepare |
302 | (plugin->dbh, | 311 | (plugin->dbh, |
303 | "SELECT " ALL | 312 | "SELECT " ALL |
304 | " FROM ns090records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", | 313 | " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", |
305 | &plugin->iterate_by_name) != SQLITE_OK) || | 314 | &plugin->iterate_by_name) != SQLITE_OK) || |
306 | (sq_prepare | 315 | (sq_prepare |
307 | (plugin->dbh, | 316 | (plugin->dbh, |
308 | "SELECT " ALL | 317 | "SELECT " ALL |
309 | " FROM ns090records ORDER BY rvalue LIMIT 1 OFFSET ?", | 318 | " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?", |
310 | &plugin->iterate_all) != SQLITE_OK) || | 319 | &plugin->iterate_all) != SQLITE_OK) || |
311 | (sq_prepare | 320 | (sq_prepare |
321 | (plugin->dbh, | ||
322 | "SELECT " ALL | ||
323 | " FROM ns091records WHERE zone_hash=? AND zone_delegation=?", | ||
324 | &plugin->zone_to_name) != SQLITE_OK) || | ||
325 | (sq_prepare | ||
312 | (plugin->dbh, | 326 | (plugin->dbh, |
313 | "DELETE FROM ns090records WHERE zone_hash=?", | 327 | "DELETE FROM ns091records WHERE zone_hash=?", |
314 | &plugin->delete_zone) != SQLITE_OK) ) | 328 | &plugin->delete_zone) != SQLITE_OK) ) |
315 | { | 329 | { |
316 | LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); | 330 | LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); |
@@ -338,12 +352,14 @@ database_shutdown (struct Plugin *plugin) | |||
338 | sqlite3_finalize (plugin->remove_records); | 352 | sqlite3_finalize (plugin->remove_records); |
339 | if (NULL != plugin->iterate_records) | 353 | if (NULL != plugin->iterate_records) |
340 | sqlite3_finalize (plugin->iterate_records); | 354 | sqlite3_finalize (plugin->iterate_records); |
341 | if (NULL != plugin->iterate_records) | 355 | if (NULL != plugin->iterate_by_zone) |
342 | sqlite3_finalize (plugin->iterate_by_zone); | 356 | sqlite3_finalize (plugin->iterate_by_zone); |
343 | if (NULL != plugin->iterate_records) | 357 | if (NULL != plugin->iterate_by_name) |
344 | sqlite3_finalize (plugin->iterate_by_name); | 358 | sqlite3_finalize (plugin->iterate_by_name); |
345 | if (NULL != plugin->iterate_records) | 359 | if (NULL != plugin->iterate_all) |
346 | sqlite3_finalize (plugin->iterate_all); | 360 | sqlite3_finalize (plugin->iterate_all); |
361 | if (NULL != plugin->zone_to_name) | ||
362 | sqlite3_finalize (plugin->zone_to_name); | ||
347 | if (NULL != plugin->delete_zone) | 363 | if (NULL != plugin->delete_zone) |
348 | sqlite3_finalize (plugin->delete_zone); | 364 | sqlite3_finalize (plugin->delete_zone); |
349 | result = sqlite3_close (plugin->dbh); | 365 | result = sqlite3_close (plugin->dbh); |
@@ -451,16 +467,27 @@ namestore_sqlite_put_records (void *cls, | |||
451 | struct Plugin *plugin = cls; | 467 | struct Plugin *plugin = cls; |
452 | int n; | 468 | int n; |
453 | GNUNET_HashCode zone; | 469 | GNUNET_HashCode zone; |
470 | GNUNET_HashCode zone_delegation; | ||
454 | GNUNET_HashCode nh; | 471 | GNUNET_HashCode nh; |
455 | size_t name_len; | 472 | size_t name_len; |
456 | uint64_t rvalue; | 473 | uint64_t rvalue; |
457 | size_t data_size; | 474 | size_t data_size; |
475 | unsigned int i; | ||
458 | 476 | ||
459 | GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); | 477 | GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); |
460 | (void) namestore_sqlite_remove_records (plugin, &zone, name); | 478 | (void) namestore_sqlite_remove_records (plugin, &zone, name); |
461 | name_len = strlen (name); | 479 | name_len = strlen (name); |
462 | GNUNET_CRYPTO_hash (name, name_len, &nh); | 480 | GNUNET_CRYPTO_hash (name, name_len, &nh); |
463 | 481 | memset (&zone_delegation, 0, sizeof (zone_delegation)); | |
482 | for (i=0;i<rd_count;i++) | ||
483 | if (rd->record_type == GNUNET_GNS_TYPE_PKEY) | ||
484 | { | ||
485 | GNUNET_assert (sizeof (GNUNET_HashCode) == rd->data_size); | ||
486 | memcpy (&zone_delegation, | ||
487 | rd->data, | ||
488 | sizeof (GNUNET_HashCode)); | ||
489 | break; | ||
490 | } | ||
464 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | 491 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); |
465 | data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd); | 492 | data_size = GNUNET_NAMESTORE_records_get_size (rd_count, rd); |
466 | if (data_size > 64 * 65536) | 493 | if (data_size > 64 * 65536) |
@@ -483,9 +510,10 @@ namestore_sqlite_put_records (void *cls, | |||
483 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || | 510 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || |
484 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value)) || | 511 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value)) || |
485 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) || | 512 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) || |
486 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | 513 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone_delegation, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || |
487 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | 514 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || |
488 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 9, rvalue)) ) | 515 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || |
516 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) ) | ||
489 | { | 517 | { |
490 | LOG_SQLITE (plugin, | 518 | LOG_SQLITE (plugin, |
491 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 519 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
@@ -662,6 +690,103 @@ namestore_sqlite_iterate_records (void *cls, | |||
662 | 690 | ||
663 | 691 | ||
664 | /** | 692 | /** |
693 | * Look for an existing PKEY delegation record for a given public key. | ||
694 | * Returns at most one result to the iterator. | ||
695 | * | ||
696 | * @param cls closure (internal context for the plugin) | ||
697 | * @param zone hash of public key of the zone to look up in, never NULL | ||
698 | * @param value_zone hash of the public key of the target zone (value), never NULL | ||
699 | * @param iter function to call with the result | ||
700 | * @param iter_cls closure for iter | ||
701 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error | ||
702 | */ | ||
703 | static int | ||
704 | namestore_sqlite_zone_to_name (void *cls, | ||
705 | const GNUNET_HashCode *zone, | ||
706 | const GNUNET_HashCode *value_zone, | ||
707 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | ||
708 | { | ||
709 | struct Plugin *plugin = cls; | ||
710 | sqlite3_stmt *stmt; | ||
711 | int ret; | ||
712 | int sret; | ||
713 | |||
714 | stmt = plugin->zone_to_name; | ||
715 | if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, | ||
716 | zone, sizeof (GNUNET_HashCode), | ||
717 | SQLITE_STATIC)) || | ||
718 | (SQLITE_OK != sqlite3_bind_blob (stmt, 2, | ||
719 | value_zone, sizeof (GNUNET_HashCode), | ||
720 | SQLITE_STATIC)) ) | ||
721 | { | ||
722 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
723 | "sqlite3_bind_XXXX"); | ||
724 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
725 | LOG_SQLITE (plugin, | ||
726 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
727 | "sqlite3_reset"); | ||
728 | return GNUNET_SYSERR; | ||
729 | } | ||
730 | ret = GNUNET_NO; | ||
731 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) | ||
732 | { | ||
733 | unsigned int record_count; | ||
734 | size_t data_size; | ||
735 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; | ||
736 | const struct GNUNET_CRYPTO_RsaSignature *sig; | ||
737 | struct GNUNET_TIME_Absolute expiration; | ||
738 | const char *data; | ||
739 | const char *name; | ||
740 | |||
741 | ret = GNUNET_YES; | ||
742 | zone_key = sqlite3_column_blob (stmt, 0); | ||
743 | name = (const char*) sqlite3_column_text (stmt, 1); | ||
744 | record_count = sqlite3_column_int (stmt, 2); | ||
745 | data_size = sqlite3_column_bytes (stmt, 3); | ||
746 | data = sqlite3_column_blob (stmt, 3); | ||
747 | expiration.abs_value = (uint64_t) sqlite3_column_int64 (stmt, 4); | ||
748 | sig = sqlite3_column_blob (stmt, 5); | ||
749 | |||
750 | if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (stmt, 0)) || | ||
751 | (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (stmt, 5)) ) | ||
752 | { | ||
753 | GNUNET_break (0); | ||
754 | ret = GNUNET_SYSERR; | ||
755 | } | ||
756 | else | ||
757 | { | ||
758 | struct GNUNET_NAMESTORE_RecordData rd[record_count]; | ||
759 | |||
760 | if (GNUNET_OK != | ||
761 | GNUNET_NAMESTORE_records_deserialize (data_size, data, | ||
762 | record_count, rd)) | ||
763 | { | ||
764 | GNUNET_break (0); | ||
765 | ret = GNUNET_SYSERR; | ||
766 | record_count = 0; | ||
767 | } | ||
768 | else | ||
769 | { | ||
770 | iter (iter_cls, zone_key, expiration, name, | ||
771 | record_count, rd, sig); | ||
772 | } | ||
773 | } | ||
774 | } | ||
775 | else | ||
776 | { | ||
777 | if (SQLITE_DONE != sret) | ||
778 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | ||
779 | iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); | ||
780 | } | ||
781 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
782 | LOG_SQLITE (plugin, | ||
783 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
784 | "sqlite3_reset"); | ||
785 | return ret; | ||
786 | } | ||
787 | |||
788 | |||
789 | /** | ||
665 | * Delete an entire zone (all records). Not used in normal operation. | 790 | * Delete an entire zone (all records). Not used in normal operation. |
666 | * | 791 | * |
667 | * @param cls closure (internal context for the plugin) | 792 | * @param cls closure (internal context for the plugin) |
@@ -733,6 +858,7 @@ libgnunet_plugin_namestore_sqlite_init (void *cls) | |||
733 | api->put_records = &namestore_sqlite_put_records; | 858 | api->put_records = &namestore_sqlite_put_records; |
734 | api->remove_records = &namestore_sqlite_remove_records; | 859 | api->remove_records = &namestore_sqlite_remove_records; |
735 | api->iterate_records = &namestore_sqlite_iterate_records; | 860 | api->iterate_records = &namestore_sqlite_iterate_records; |
861 | api->zone_to_name = &namestore_sqlite_zone_to_name; | ||
736 | api->delete_zone = &namestore_sqlite_delete_zone; | 862 | api->delete_zone = &namestore_sqlite_delete_zone; |
737 | LOG (GNUNET_ERROR_TYPE_INFO, | 863 | LOG (GNUNET_ERROR_TYPE_INFO, |
738 | _("Sqlite database running\n")); | 864 | _("Sqlite database running\n")); |