aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_sqlite.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-02-23 15:02:23 +0000
committerChristian Grothoff <christian@grothoff.org>2012-02-23 15:02:23 +0000
commit85c3dbb9ef22d38ec0e24c67a78886859c7809cd (patch)
tree7925a489eb9dd625835401f8059e2bb9f06f2f87 /src/namestore/plugin_namestore_sqlite.c
parentf2eef75811a8ad78f0dae68d569d0f5c82083064 (diff)
downloadgnunet-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.c349
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 */
113struct 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 */
385static int 410static int
386namestore_sqlite_put_records (void *cls, 411namestore_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 */
458static int 470static int
459namestore_sqlite_remove_records (void *cls, 471namestore_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