diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-23 15:02:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-23 15:02:23 +0000 |
commit | 85c3dbb9ef22d38ec0e24c67a78886859c7809cd (patch) | |
tree | 7925a489eb9dd625835401f8059e2bb9f06f2f87 /src/namestore/plugin_namestore_sqlite.c | |
parent | f2eef75811a8ad78f0dae68d569d0f5c82083064 (diff) | |
download | gnunet-85c3dbb9ef22d38ec0e24c67a78886859c7809cd.tar.gz gnunet-85c3dbb9ef22d38ec0e24c67a78886859c7809cd.zip |
-finishing 1st pass on new plugin
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 349 |
1 files changed, 231 insertions, 118 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 4a40b3db1..1543573e0 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -108,6 +108,35 @@ struct Plugin | |||
108 | 108 | ||
109 | 109 | ||
110 | /** | 110 | /** |
111 | * Internal format of a record in the BLOB in the database. | ||
112 | */ | ||
113 | struct DbRecord | ||
114 | { | ||
115 | |||
116 | /** | ||
117 | * Expiration time for the DNS record. | ||
118 | */ | ||
119 | struct GNUNET_TIME_AbsoluteNBO expiration; | ||
120 | |||
121 | /** | ||
122 | * Number of bytes in 'data', network byte order. | ||
123 | */ | ||
124 | uint32_t data_size; | ||
125 | |||
126 | /** | ||
127 | * Type of the GNS/DNS record, network byte order. | ||
128 | */ | ||
129 | uint32_t record_type; | ||
130 | |||
131 | /** | ||
132 | * Flags for the record, network byte order. | ||
133 | */ | ||
134 | uint32_t flags; | ||
135 | |||
136 | }; | ||
137 | |||
138 | |||
139 | /** | ||
111 | * @brief Prepare a SQL statement | 140 | * @brief Prepare a SQL statement |
112 | * | 141 | * |
113 | * @param dbh handle to the database | 142 | * @param dbh handle to the database |
@@ -257,9 +286,12 @@ database_setup (struct Plugin *plugin) | |||
257 | (sqlite3_exec | 286 | (sqlite3_exec |
258 | (plugin->dbh, | 287 | (plugin->dbh, |
259 | "CREATE TABLE ns090records (" | 288 | "CREATE TABLE ns090records (" |
289 | " zone_key BLOB NOT NULL DEFAULT ''," | ||
260 | " zone_hash BLOB NOT NULL DEFAULT ''," | 290 | " zone_hash BLOB NOT NULL DEFAULT ''," |
291 | " record_count INT NOT NULL DEFAULT 0," | ||
261 | " record_data BLOB NOT NULL DEFAULT ''" | 292 | " record_data BLOB NOT NULL DEFAULT ''" |
262 | " block_expiration_time INT8 NOT NULL DEFAULT 0," | 293 | " block_expiration_time INT8 NOT NULL DEFAULT 0," |
294 | " signature BLOB NOT NULL DEFAULT ''" | ||
263 | " record_name TEXT NOT NULL DEFAULT ''," | 295 | " record_name TEXT NOT NULL DEFAULT ''," |
264 | " record_name_hash BLOB NOT NULL DEFAULT ''," | 296 | " record_name_hash BLOB NOT NULL DEFAULT ''," |
265 | " rvalue INT8 NOT NULL DEFAULT ''" | 297 | " rvalue INT8 NOT NULL DEFAULT ''" |
@@ -274,10 +306,10 @@ database_setup (struct Plugin *plugin) | |||
274 | 306 | ||
275 | create_indices (plugin->dbh); | 307 | create_indices (plugin->dbh); |
276 | 308 | ||
277 | #define ALL "zone_hash, record_name, record_data, block_expiration_time" | 309 | #define ALL "zone_key, record_name, record_count, record_data, block_expiration_time, signature" |
278 | if ((sq_prepare | 310 | if ((sq_prepare |
279 | (plugin->dbh, | 311 | (plugin->dbh, |
280 | "INSERT INTO ns090records (" ALL ", record_name_hash, rvalue) VALUES " | 312 | "INSERT INTO ns090records (" ALL ", zone_hash, record_name_hash, rvalue) VALUES " |
281 | "(?, ?, ?, ?, ?, ?)", | 313 | "(?, ?, ?, ?, ?, ?)", |
282 | &plugin->put_records) != SQLITE_OK) || | 314 | &plugin->put_records) != SQLITE_OK) || |
283 | (sq_prepare | 315 | (sq_prepare |
@@ -368,66 +400,45 @@ database_shutdown (struct Plugin *plugin) | |||
368 | 400 | ||
369 | 401 | ||
370 | /** | 402 | /** |
371 | * Store a record in the datastore. | 403 | * Removes any existing record in the given zone with the same name. |
372 | * | 404 | * |
373 | * @param cls closure (internal context for the plugin) | 405 | * @param cls closure (internal context for the plugin) |
374 | * @param zone hash of the public key of the zone | 406 | * @param zone hash of the public key of the zone |
375 | * @param name name that is being mapped (at most 255 characters long) | 407 | * @param name name to remove (at most 255 characters long) |
376 | * @param record_type type of the record (A, AAAA, PKEY, etc.) | ||
377 | * @param loc location of the signature for the record | ||
378 | * @param expiration expiration time for the content | ||
379 | * @param flags flags for the content | ||
380 | * @param data_size number of bytes in data | ||
381 | * @param data value, semantics depend on 'record_type' (see RFCs for DNS and | ||
382 | * GNS specification for GNS extensions) | ||
383 | * @return GNUNET_OK on success | 408 | * @return GNUNET_OK on success |
384 | */ | 409 | */ |
385 | static int | 410 | static int |
386 | namestore_sqlite_put_records (void *cls, | 411 | namestore_sqlite_remove_records (void *cls, |
387 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, | 412 | const GNUNET_HashCode *zone, |
388 | struct GNUNET_TIME_Absolute expire, | 413 | const char *name) |
389 | const char *name, | ||
390 | unsigned int rd_count, | ||
391 | const struct GNUNET_NAMESTORE_RecordData *rd, | ||
392 | const struct GNUNET_CRYPTO_RsaSignature *signature) | ||
393 | { | 414 | { |
394 | #if 0 | ||
395 | struct Plugin *plugin = cls; | 415 | struct Plugin *plugin = cls; |
396 | int n; | ||
397 | GNUNET_HashCode nh; | 416 | GNUNET_HashCode nh; |
398 | size_t name_len; | 417 | size_t name_len; |
418 | int n; | ||
399 | 419 | ||
400 | name_len = strlen (name); | 420 | name_len = strlen (name); |
401 | GNUNET_CRYPTO_hash (name, name_len, &nh); | 421 | GNUNET_CRYPTO_hash (name, name_len, &nh); |
402 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_record, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | 422 | |
403 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_record, 2, loc->revision)) || | 423 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || |
404 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_record, 3, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | 424 | (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC))) |
405 | (SQLITE_OK != sqlite3_bind_text (plugin->put_record, 4, name, -1, SQLITE_STATIC)) || | ||
406 | (SQLITE_OK != sqlite3_bind_int (plugin->put_record, 5, record_type)) || | ||
407 | (SQLITE_OK != sqlite3_bind_int (plugin->put_record, 6, loc->depth)) || | ||
408 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_record, 7, loc->offset)) || | ||
409 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_record, 8, expiration.abs_value)) || | ||
410 | (SQLITE_OK != sqlite3_bind_int (plugin->put_record, 9, flags)) || | ||
411 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_record, 10, data, data_size, SQLITE_STATIC)) ) | ||
412 | { | 425 | { |
413 | LOG_SQLITE (plugin, | 426 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
414 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
415 | "sqlite3_bind_XXXX"); | 427 | "sqlite3_bind_XXXX"); |
416 | if (SQLITE_OK != sqlite3_reset (plugin->put_record)) | 428 | if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) |
417 | LOG_SQLITE (plugin, | 429 | LOG_SQLITE (plugin, |
418 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 430 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
419 | "sqlite3_reset"); | 431 | "sqlite3_reset"); |
420 | return GNUNET_SYSERR; | 432 | return GNUNET_SYSERR; |
421 | |||
422 | } | 433 | } |
423 | n = sqlite3_step (plugin->put_record); | 434 | n = sqlite3_step (plugin->remove_records); |
424 | if (SQLITE_OK != sqlite3_reset (plugin->put_record)) | 435 | if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) |
425 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 436 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
426 | "sqlite3_reset"); | 437 | "sqlite3_reset"); |
427 | switch (n) | 438 | switch (n) |
428 | { | 439 | { |
429 | case SQLITE_DONE: | 440 | case SQLITE_DONE: |
430 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n"); | 441 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record removed\n"); |
431 | return GNUNET_OK; | 442 | return GNUNET_OK; |
432 | case SQLITE_BUSY: | 443 | case SQLITE_BUSY: |
433 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | 444 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, |
@@ -438,89 +449,124 @@ namestore_sqlite_put_records (void *cls, | |||
438 | "sqlite3_step"); | 449 | "sqlite3_step"); |
439 | return GNUNET_SYSERR; | 450 | return GNUNET_SYSERR; |
440 | } | 451 | } |
441 | #endif | ||
442 | return GNUNET_SYSERR; | ||
443 | } | 452 | } |
444 | 453 | ||
445 | 454 | ||
446 | /** | 455 | /** |
447 | * Store a Merkle tree node in the datastore. | 456 | * Store a record in the datastore. Removes any existing record in the |
457 | * same zone with the same name. | ||
448 | * | 458 | * |
449 | * @param cls closure (internal context for the plugin) | 459 | * @param cls closure (internal context for the plugin) |
450 | * @param zone hash of public key of the zone | 460 | * @param zone_key public key of the zone |
451 | * @param loc location in the B-tree | 461 | * @param expire when does the corresponding block in the DHT expire (until |
452 | * @param ploc parent's location in the B-tree (must have depth = loc.depth + 1), NULL for root | 462 | * when should we never do a DHT lookup for the same name again)? |
453 | * @param num_entries number of entries at this node in the B-tree | 463 | * @param name name that is being mapped (at most 255 characters long) |
454 | * @param entries the 'num_entries' entries to store (hashes over the | 464 | * @param rd_count number of entries in 'rd' array |
455 | * records) | 465 | * @param rd array of records with data to store |
466 | * @param signature signature of the record block, NULL if signature is unavailable (i.e. | ||
467 | * because the user queried for a particular record type only) | ||
456 | * @return GNUNET_OK on success | 468 | * @return GNUNET_OK on success |
457 | */ | 469 | */ |
458 | static int | 470 | static int |
459 | namestore_sqlite_remove_records (void *cls, | 471 | namestore_sqlite_put_records (void *cls, |
460 | const GNUNET_HashCode *zone, | 472 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, |
461 | const char *name) | 473 | struct GNUNET_TIME_Absolute expire, |
474 | const char *name, | ||
475 | unsigned int rd_count, | ||
476 | const struct GNUNET_NAMESTORE_RecordData *rd, | ||
477 | const struct GNUNET_CRYPTO_RsaSignature *signature) | ||
462 | { | 478 | { |
463 | #if 0 | ||
464 | struct Plugin *plugin = cls; | 479 | struct Plugin *plugin = cls; |
465 | int n; | 480 | int n; |
481 | GNUNET_HashCode zone; | ||
482 | GNUNET_HashCode nh; | ||
483 | size_t name_len; | ||
484 | uint64_t rvalue; | ||
485 | size_t data_size; | ||
486 | size_t off; | ||
487 | unsigned int i; | ||
466 | 488 | ||
467 | if ( (loc->revision != ploc->revision) || | 489 | GNUNET_CRYPTO_hash (zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone); |
468 | (loc->depth + 1 != ploc->depth) || | 490 | (void) namestore_sqlite_remove_records (plugin, &zone, name); |
469 | (0 == num_entries)) | 491 | name_len = strlen (name); |
492 | GNUNET_CRYPTO_hash (name, name_len, &nh); | ||
493 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); | ||
494 | data_size = rd_count * sizeof (struct DbRecord); | ||
495 | for (i=0;i<rd_count;i++) | ||
496 | data_size += rd[i].data_size; | ||
497 | if (data_size > 64 * 65536) | ||
470 | { | 498 | { |
471 | GNUNET_break (0); | 499 | GNUNET_break (0); |
472 | return GNUNET_SYSERR; | 500 | return GNUNET_SYSERR; |
473 | } | 501 | } |
474 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_node, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
475 | (SQLITE_OK != sqlite3_bind_int (plugin->put_node, 2, loc->revision)) || | ||
476 | (SQLITE_OK != sqlite3_bind_int (plugin->put_node, 3, loc->depth)) || | ||
477 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_node, 4, loc->offset)) || | ||
478 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_node, 5, ploc->offset)) || | ||
479 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_node, 6, entries, num_entries * sizeof (GNUNET_HashCode), SQLITE_STATIC)) ) | ||
480 | { | 502 | { |
481 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 503 | char data[data_size]; |
482 | "sqlite3_bind_XXXX"); | 504 | struct DbRecord *rec; |
483 | if (SQLITE_OK != sqlite3_reset (plugin->put_node)) | 505 | |
484 | LOG_SQLITE (plugin, | 506 | rec = (struct DbRecord *) data; |
485 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 507 | off = rd_count * sizeof (struct DbRecord); |
486 | "sqlite3_reset"); | 508 | for (i=0;i<rd_count;i++) |
487 | return GNUNET_SYSERR; | 509 | { |
488 | 510 | rec[i].expiration = GNUNET_TIME_absolute_hton (rd[i].expiration); | |
511 | rec[i].data_size = htonl ((uint32_t) rd[i].data_size); | ||
512 | rec[i].record_type = htonl (rd[i].record_type); | ||
513 | rec[i].flags = htonl (rd[i].flags); | ||
514 | memcpy (&data[off], | ||
515 | rd[i].data, | ||
516 | rd[i].data_size); | ||
517 | off += rd[i].data_size; | ||
518 | } | ||
519 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 1, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), SQLITE_STATIC)) || | ||
520 | (SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, SQLITE_STATIC)) || | ||
521 | (SQLITE_OK != sqlite3_bind_int (plugin->put_records, 3, rd_count)) || | ||
522 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || | ||
523 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value)) || | ||
524 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) || | ||
525 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
526 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &nh, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
527 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 9, rvalue)) ) | ||
528 | { | ||
529 | LOG_SQLITE (plugin, | ||
530 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
531 | "sqlite3_bind_XXXX"); | ||
532 | if (SQLITE_OK != sqlite3_reset (plugin->put_records)) | ||
533 | LOG_SQLITE (plugin, | ||
534 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
535 | "sqlite3_reset"); | ||
536 | return GNUNET_SYSERR; | ||
537 | |||
538 | } | ||
539 | n = sqlite3_step (plugin->put_records); | ||
540 | if (SQLITE_OK != sqlite3_reset (plugin->put_records)) | ||
541 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
542 | "sqlite3_reset"); | ||
489 | } | 543 | } |
490 | n = sqlite3_step (plugin->put_node); | ||
491 | if (SQLITE_OK != sqlite3_reset (plugin->put_node)) | ||
492 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
493 | "sqlite3_reset"); | ||
494 | switch (n) | 544 | switch (n) |
495 | { | 545 | { |
496 | case SQLITE_DONE: | 546 | case SQLITE_DONE: |
497 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Node stored\n"); | 547 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n"); |
498 | return GNUNET_OK; | 548 | return GNUNET_OK; |
499 | case SQLITE_BUSY: | 549 | case SQLITE_BUSY: |
500 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | 550 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, |
501 | "sqlite3_step"); | 551 | "sqlite3_step"); |
502 | return GNUNET_NO; | 552 | return GNUNET_NO; |
503 | default: | 553 | default: |
504 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 554 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
505 | "sqlite3_step"); | 555 | "sqlite3_step"); |
506 | return GNUNET_SYSERR; | 556 | return GNUNET_SYSERR; |
507 | } | 557 | } |
508 | #endif | ||
509 | return GNUNET_SYSERR; | ||
510 | } | 558 | } |
511 | 559 | ||
512 | 560 | ||
513 | /** | 561 | /** |
514 | * Iterate over the results for a particular key and zone in the | 562 | * Iterate over the results for a particular key and zone in the |
515 | * datastore. Will only query the latest revision known for the | 563 | * datastore. Will return at most one result to the iterator. |
516 | * zone (as adding a new zone revision will cause the plugin to | ||
517 | * delete all records from previous revisions). | ||
518 | * | 564 | * |
519 | * @param cls closure (internal context for the plugin) | 565 | * @param cls closure (internal context for the plugin) |
520 | * @param zone hash of public key of the zone, NULL to iterate over all zones | 566 | * @param zone hash of public key of the zone, NULL to iterate over all zones |
521 | * @param name_hash hash of name, NULL to iterate over all records of the zone | 567 | * @param name_hash hash of name, NULL to iterate over all records of the zone |
522 | * @param offset offset in the list of all matching records | 568 | * @param offset offset in the list of all matching records |
523 | * @param iter maybe NULL (to just count) | 569 | * @param iter function to call with the result |
524 | * @param iter_cls closure for iter | 570 | * @param iter_cls closure for iter |
525 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error | 571 | * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error |
526 | */ | 572 | */ |
@@ -531,61 +577,128 @@ namestore_sqlite_iterate_records (void *cls, | |||
531 | uint64_t offset, | 577 | uint64_t offset, |
532 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) | 578 | GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) |
533 | { | 579 | { |
534 | #if 0 | ||
535 | struct Plugin *plugin = cls; | 580 | struct Plugin *plugin = cls; |
536 | unsigned int ret; | 581 | sqlite3_stmt *stmt; |
582 | unsigned int boff; | ||
583 | int ret; | ||
537 | int sret; | 584 | int sret; |
538 | struct GNUNET_TIME_Absolute expiration; | 585 | |
539 | uint32_t record_type; | 586 | if (NULL == zone) |
540 | enum GNUNET_NAMESTORE_RecordFlags flags; | 587 | if (NULL == name_hash) |
541 | size_t data_size; | 588 | stmt = plugin->iterate_all; |
542 | const void *data; | 589 | else |
543 | struct GNUNET_NAMESTORE_SignatureLocation loc; | 590 | stmt = plugin->iterate_by_name; |
544 | const char *name; | 591 | else |
545 | 592 | if (NULL == name_hash) | |
546 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->iterate_records, 1, | 593 | stmt = plugin->iterate_by_zone; |
547 | zone, sizeof (GNUNET_HashCode), | 594 | else |
548 | SQLITE_STATIC)) || | 595 | stmt = plugin->iterate_records; |
549 | (SQLITE_OK != sqlite3_bind_blob (plugin->iterate_records, 2, | 596 | |
550 | name_hash, sizeof (GNUNET_HashCode), | 597 | boff = 0; |
551 | SQLITE_STATIC)) ) | 598 | if ( (NULL != zone) && |
599 | (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, | ||
600 | zone, sizeof (GNUNET_HashCode), | ||
601 | SQLITE_STATIC)) ) | ||
602 | { | ||
603 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
604 | "sqlite3_bind_XXXX"); | ||
605 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
606 | LOG_SQLITE (plugin, | ||
607 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
608 | "sqlite3_reset"); | ||
609 | return GNUNET_SYSERR; | ||
610 | } | ||
611 | if ( (NULL != name_hash) && | ||
612 | (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, | ||
613 | name_hash, sizeof (GNUNET_HashCode), | ||
614 | SQLITE_STATIC)) ) | ||
615 | { | ||
616 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
617 | "sqlite3_bind_XXXX"); | ||
618 | if (SQLITE_OK != sqlite3_reset (stmt)) | ||
619 | LOG_SQLITE (plugin, | ||
620 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
621 | "sqlite3_reset"); | ||
622 | return GNUNET_SYSERR; | ||
623 | } | ||
624 | |||
625 | if (SQLITE_OK != sqlite3_bind_int64 (stmt, ++boff, | ||
626 | offset)) | ||
552 | { | 627 | { |
553 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 628 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
554 | "sqlite3_bind_XXXX"); | 629 | "sqlite3_bind_XXXX"); |
555 | if (SQLITE_OK != sqlite3_reset (plugin->iterate_records)) | 630 | if (SQLITE_OK != sqlite3_reset (stmt)) |
556 | LOG_SQLITE (plugin, | 631 | LOG_SQLITE (plugin, |
557 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 632 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
558 | "sqlite3_reset"); | 633 | "sqlite3_reset"); |
559 | return GNUNET_SYSERR; | 634 | return GNUNET_SYSERR; |
560 | } | 635 | } |
561 | ret = 0; | 636 | ret = GNUNET_NO; |
562 | while (SQLITE_ROW == (sret = sqlite3_step (plugin->iterate_records))) | 637 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) |
563 | { | 638 | { |
564 | ret++; | 639 | unsigned int record_count; |
565 | if (NULL == iter) | 640 | size_t data_size; |
566 | continue; /* FIXME: just counting can be done more cheaply... */ | 641 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; |
567 | loc.revision = sqlite3_column_int (plugin->iterate_records, 0); | 642 | const struct GNUNET_CRYPTO_RsaSignature *sig; |
643 | struct GNUNET_TIME_Absolute expiration; | ||
644 | const char *data; | ||
645 | const char *name; | ||
646 | |||
647 | ret = GNUNET_YES; | ||
648 | zone_key = sqlite3_column_blob (plugin->iterate_records, 0); | ||
568 | name = (const char*) sqlite3_column_text (plugin->iterate_records, 1); | 649 | name = (const char*) sqlite3_column_text (plugin->iterate_records, 1); |
569 | record_type = sqlite3_column_int (plugin->iterate_records, 2); | 650 | record_count = sqlite3_column_int (plugin->iterate_records, 2); |
570 | loc.depth = sqlite3_column_int (plugin->iterate_records, 3); | 651 | data_size = sqlite3_column_bytes (plugin->iterate_records, 3); |
571 | loc.offset = sqlite3_column_int64 (plugin->iterate_records, 4); | 652 | data = sqlite3_column_blob (plugin->iterate_records, 3); |
572 | expiration.abs_value = (uint64_t) sqlite3_column_int64 (plugin->iterate_records, 5); | 653 | expiration.abs_value = (uint64_t) sqlite3_column_int64 (plugin->iterate_records, 4); |
573 | flags = (enum GNUNET_NAMESTORE_RecordFlags) sqlite3_column_int (plugin->iterate_records, 6); | 654 | sig = sqlite3_column_blob (plugin->iterate_records, 5); |
574 | data = sqlite3_column_blob (plugin->iterate_records, 7); | 655 | |
575 | data_size = sqlite3_column_bytes (plugin->iterate_records, 7); | 656 | if ( (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) != sqlite3_column_bytes (plugin->iterate_records, 0)) || |
576 | iter (iter_cls, zone, | 657 | (sizeof (struct GNUNET_CRYPTO_RsaSignature) != sqlite3_column_bytes (plugin->iterate_records, 5)) || |
577 | &loc, name, record_type, | 658 | (sizeof (struct DbRecord) * record_count > data_size) ) |
578 | expiration, flags, data_size, data); | 659 | { |
660 | GNUNET_break (0); | ||
661 | ret = GNUNET_SYSERR; | ||
662 | } | ||
663 | else | ||
664 | { | ||
665 | const struct DbRecord *db = (const struct DbRecord*) data; | ||
666 | struct GNUNET_NAMESTORE_RecordData rd[record_count]; | ||
667 | unsigned int i; | ||
668 | size_t off; | ||
669 | |||
670 | off = record_count * sizeof (struct DbRecord); | ||
671 | for (i=0;i<record_count;i++) | ||
672 | { | ||
673 | if (off + db[i].data_size > data_size) | ||
674 | { | ||
675 | GNUNET_break (0); | ||
676 | ret = GNUNET_SYSERR; | ||
677 | record_count = i; | ||
678 | break; | ||
679 | } | ||
680 | rd[i].expiration = GNUNET_TIME_absolute_ntoh (db[i].expiration); | ||
681 | rd[i].data_size = ntohl (db[i].data_size); | ||
682 | rd[i].data = &data[off]; | ||
683 | rd[i].record_type = ntohl (db[i].record_type); | ||
684 | rd[i].flags = ntohl (db[i].flags); | ||
685 | off += rd[i].data_size; | ||
686 | } | ||
687 | iter (iter_cls, zone_key, expiration, name, | ||
688 | record_count, rd, sig); | ||
689 | } | ||
690 | } | ||
691 | else | ||
692 | { | ||
693 | iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); | ||
579 | } | 694 | } |
580 | if (SQLITE_DONE != sret) | 695 | if (SQLITE_DONE != sret) |
581 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); | 696 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); |
582 | if (SQLITE_OK != sqlite3_reset (plugin->iterate_records)) | 697 | if (SQLITE_OK != sqlite3_reset (stmt)) |
583 | LOG_SQLITE (plugin, | 698 | LOG_SQLITE (plugin, |
584 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 699 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
585 | "sqlite3_reset"); | 700 | "sqlite3_reset"); |
586 | return ret; | 701 | return ret; |
587 | #endif | ||
588 | return GNUNET_SYSERR; | ||
589 | } | 702 | } |
590 | 703 | ||
591 | 704 | ||