aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-06-30 19:21:05 +0000
committerChristian Grothoff <christian@grothoff.org>2013-06-30 19:21:05 +0000
commit17de5c9d798109f55059190c886609ba377e4eb6 (patch)
tree07f2b4241f433b18baf02d5bf189307ad2308166 /src
parentfd87b25438487e1215c68bdb9f1bcac2d7012bc2 (diff)
downloadgnunet-17de5c9d798109f55059190c886609ba377e4eb6.tar.gz
gnunet-17de5c9d798109f55059190c886609ba377e4eb6.zip
-towards implementing improved namestore API
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_namestore_service.h86
-rw-r--r--src/include/gnunet_protocols.h10
-rw-r--r--src/namestore/Makefile.am9
-rw-r--r--src/namestore/gnunet-namestore.c295
-rw-r--r--src/namestore/gnunet-service-namestore.c571
-rw-r--r--src/namestore/namestore.h151
-rw-r--r--src/namestore/namestore_api.c205
-rw-r--r--src/namestore/namestore_api_common.c (renamed from src/namestore/namestore_common.c)2
-rw-r--r--src/namestore/namestore_api_monitor.c79
-rw-r--r--src/namestore/plugin_namestore_sqlite.c2
-rw-r--r--src/namestore/test_namestore_api_create.c14
-rw-r--r--src/namestore/test_namestore_api_create_update.c14
-rw-r--r--src/namestore/test_namestore_api_remove.c6
-rw-r--r--src/namestore/test_namestore_api_remove_not_existing_record.c13
-rw-r--r--src/namestore/test_namestore_api_zone_iteration.c8
-rw-r--r--src/namestore/test_namestore_api_zone_iteration_specific_zone.c15
-rw-r--r--src/namestore/test_namestore_api_zone_iteration_stop.c6
-rw-r--r--src/namestore/test_namestore_api_zone_to_name.c2
18 files changed, 456 insertions, 1032 deletions
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h
index 418813734..a1c5d6437 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -371,6 +371,17 @@ GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
371 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls); 371 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls);
372 372
373 373
374/**
375 * Cancel a namestore operation. The final callback from the
376 * operation must not have been done yet. Must be called on any
377 * namestore operation that has not yet completed prior to calling
378 * 'GNUNET_NAMESTORE_disconnect'.
379 *
380 * @param qe operation to cancel
381 */
382void
383GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe);
384
374 385
375/** 386/**
376 * Starts a new zone iteration (used to periodically PUT all of our 387 * Starts a new zone iteration (used to periodically PUT all of our
@@ -447,7 +458,13 @@ struct GNUNET_NAMESTORE_ZoneMonitor;
447 * Function called whenever the records for a given name changed. 458 * Function called whenever the records for a given name changed.
448 * 459 *
449 * @param cls closure 460 * @param cls closure
450 * @param was_removed GNUNET_NO if the record was added, GNUNET_YES if it was removed 461 * @param was_removed GNUNET_NO if the record was added, GNUNET_YES if it was removed,
462 * GNUNET_SYSERR if the communication with the namestore broke down
463 * (and thus all entries should be 'cleared' until the communication
464 * can be re-established, at which point the monitor will
465 * re-add all records that are (still) in the namestore after
466 * the reconnect); if this value is SYSERR, all other arguments
467 * will be 0/NULL.
451 * @param freshness when does the corresponding block in the DHT expire (until 468 * @param freshness when does the corresponding block in the DHT expire (until
452 * when should we never do a DHT lookup for the same name again)?; 469 * when should we never do a DHT lookup for the same name again)?;
453 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore, 470 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
@@ -495,18 +512,6 @@ void
495GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm); 512GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm);
496 513
497 514
498/**
499 * Cancel a namestore operation. The final callback from the
500 * operation must not have been done yet. Must be called on any
501 * namestore operation that has not yet completed prior to calling
502 * 'GNUNET_NAMESTORE_disconnect'.
503 *
504 * @param qe operation to cancel
505 */
506void
507GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe);
508
509
510/* convenience APIs for serializing / deserializing GNS records */ 515/* convenience APIs for serializing / deserializing GNS records */
511 516
512/** 517/**
@@ -620,6 +625,61 @@ int
620GNUNET_NAMESTORE_is_expired (const struct GNUNET_NAMESTORE_RecordData *rd); 625GNUNET_NAMESTORE_is_expired (const struct GNUNET_NAMESTORE_RecordData *rd);
621 626
622 627
628/**
629 * Convert a UTF-8 string to UTF-8 lowercase
630 * @param src source string
631 * @return converted result
632 */
633char *
634GNUNET_NAMESTORE_normalize_string (const char *src);
635
636
637/**
638 * Convert a short hash to a string (for printing debug messages).
639 * This is one of the very few calls in the entire API that is
640 * NOT reentrant!
641 *
642 * @param hc the short hash code
643 * @return string form; will be overwritten by next call to GNUNET_h2s.
644 */
645const char *
646GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc);
647
648
649/**
650 * Sign name and records
651 *
652 * @param key the private key
653 * @param expire block expiration
654 * @param name the name
655 * @param rd record data
656 * @param rd_count number of records
657 *
658 * @return the signature
659 */
660struct GNUNET_CRYPTO_EccSignature *
661GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key,
662 struct GNUNET_TIME_Absolute expire,
663 const char *name,
664 const struct GNUNET_NAMESTORE_RecordData *rd,
665 unsigned int rd_count);
666
667
668/**
669 * Compares if two records are equal
670 *
671 * @param a Record a
672 * @param b Record b
673 *
674 * @return GNUNET_YES or GNUNET_NO
675 */
676int
677GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a,
678 const struct GNUNET_NAMESTORE_RecordData *b);
679
680
681
682
623#if 0 /* keep Emacsens' auto-indent happy */ 683#if 0 /* keep Emacsens' auto-indent happy */
624{ 684{
625#endif 685#endif
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 74dd5af1f..f2193fe84 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1452,16 +1452,6 @@ extern "C"
1452#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436 1452#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436
1453 1453
1454/** 1454/**
1455 * Client to service: remove record(s)
1456 */
1457#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE 437
1458
1459/**
1460 * Service to client: result of removal request.
1461 */
1462#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE 438
1463
1464/**
1465 * Client to service: "reverse" lookup for zone name based on zone key 1455 * Client to service: "reverse" lookup for zone name based on zone key
1466 */ 1456 */
1467#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439 1457#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index df16e04bd..b920c43c4 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -64,7 +64,10 @@ lib_LTLIBRARIES = \
64 libgnunetnamestore.la 64 libgnunetnamestore.la
65 65
66libgnunetnamestore_la_SOURCES = \ 66libgnunetnamestore_la_SOURCES = \
67 namestore_api.c namestore_common.c namestore.h 67 namestore_api.c \
68 namestore_api_monitor.c \
69 namestore_api_common.c \
70 namestore.h
68libgnunetnamestore_la_LIBADD = \ 71libgnunetnamestore_la_LIBADD = \
69 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 72 $(top_builddir)/src/statistics/libgnunetstatistics.la \
70 $(top_builddir)/src/util/libgnunetutil.la \ 73 $(top_builddir)/src/util/libgnunetutil.la \
@@ -111,7 +114,7 @@ plugin_LTLIBRARIES = \
111 $(POSTGRES_PLUGIN) 114 $(POSTGRES_PLUGIN)
112 115
113libgnunet_plugin_namestore_sqlite_la_SOURCES = \ 116libgnunet_plugin_namestore_sqlite_la_SOURCES = \
114 plugin_namestore_sqlite.c namestore_common.c 117 plugin_namestore_sqlite.c
115libgnunet_plugin_namestore_sqlite_la_LIBADD = \ 118libgnunet_plugin_namestore_sqlite_la_LIBADD = \
116 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 119 $(top_builddir)/src/namestore/libgnunetnamestore.la \
117 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 120 $(top_builddir)/src/statistics/libgnunetstatistics.la \
@@ -126,7 +129,7 @@ libgnunet_plugin_namestore_sqlite_la_DEPENDENCIES = \
126 129
127 130
128libgnunet_plugin_namestore_postgres_la_SOURCES = \ 131libgnunet_plugin_namestore_postgres_la_SOURCES = \
129 plugin_namestore_postgres.c namestore_common.c 132 plugin_namestore_postgres.c
130libgnunet_plugin_namestore_postgres_la_LIBADD = \ 133libgnunet_plugin_namestore_postgres_la_LIBADD = \
131 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 134 $(top_builddir)/src/namestore/libgnunetnamestore.la \
132 $(top_builddir)/src/postgres/libgnunetpostgres.la \ 135 $(top_builddir)/src/postgres/libgnunetpostgres.la \
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index 20452eb8c..c43b18593 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -133,6 +133,36 @@ static char *expirationstring;
133 */ 133 */
134static int ret; 134static int ret;
135 135
136/**
137 * Type string converted to DNS type value.
138 */
139static uint32_t type;
140
141/**
142 * Value in binary format.
143 */
144static void *data;
145
146/**
147 * Number of bytes in 'data'.
148 */
149static size_t data_size;
150
151/**
152 * Expirationstring converted to relative time.
153 */
154static struct GNUNET_TIME_Relative etime_rel;
155
156/**
157 * Expirationstring converted to absolute time.
158 */
159static struct GNUNET_TIME_Absolute etime_abs;
160
161/**
162 * Is expiration time relative or absolute time?
163 */
164static int etime_is_rel = GNUNET_SYSERR;
165
136 166
137/** 167/**
138 * Task run on shutdown. Cleans up everything. 168 * Task run on shutdown. Cleans up everything.
@@ -328,6 +358,69 @@ display_record (void *cls,
328 358
329 359
330/** 360/**
361 * We're storing a record; this function is given the existing record
362 * so that we can merge the information.
363 *
364 * @param cls closure, unused
365 * @param zone_key public key of the zone
366 * @param freshness when does the corresponding block in the DHT expire (until
367 * when should we never do a DHT lookup for the same name again)?;
368 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
369 * or the expiration time of the block in the namestore (even if there are zero
370 * records matching the desired record type)
371 * @param name name that is being mapped (at most 255 characters long)
372 * @param rd_count number of entries in 'rd' array
373 * @param rd array of records with data to store
374 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
375 * because the user queried for a particular record type only)
376 */
377static void
378get_existing_record (void *cls,
379 const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *zone_key,
380 struct GNUNET_TIME_Absolute freshness,
381 const char *name,
382 unsigned int rd_count,
383 const struct GNUNET_NAMESTORE_RecordData *rd,
384 const struct GNUNET_CRYPTO_EccSignature *signature)
385{
386 struct GNUNET_NAMESTORE_RecordData rdn[rd_count + 1];
387 struct GNUNET_NAMESTORE_RecordData *rde;
388
389 add_qe = NULL;
390 memset (rdn, 0, sizeof (struct GNUNET_NAMESTORE_RecordData));
391 memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
392 /* FIXME: should add some logic to overwrite records if there
393 can only be one record of a particular type, and to check
394 if the combination of records is valid to begin with... */
395 rde = &rdn[0];
396 rde->data = data;
397 rde->data_size = data_size;
398 rde->record_type = type;
399 if (GNUNET_YES == etime_is_rel)
400 {
401 rde->expiration_time = etime_rel.rel_value;
402 rde->flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
403 }
404 else if (GNUNET_NO == etime_is_rel)
405 {
406 rde->expiration_time = etime_abs.abs_value;
407 }
408 if (1 != nonauthority)
409 rde->flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
410 if (1 != public)
411 rde->flags |= GNUNET_NAMESTORE_RF_PRIVATE;
412
413 add_qe = GNUNET_NAMESTORE_record_put_by_authority (ns,
414 zone_pkey,
415 name,
416 rd_count + 1,
417 rde,
418 &add_continuation,
419 &add_qe);
420}
421
422
423/**
331 * Function called with the result of the ECC key generation. 424 * Function called with the result of the ECC key generation.
332 * 425 *
333 * @param cls our configuration 426 * @param cls our configuration
@@ -341,12 +434,6 @@ key_generation_cb (void *cls,
341{ 434{
342 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 435 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
343 struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pub; 436 struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pub;
344 uint32_t type;
345 void *data = NULL;
346 size_t data_size = 0;
347 struct GNUNET_TIME_Relative etime_rel;
348 struct GNUNET_TIME_Absolute etime_abs;
349 int etime_is_rel = GNUNET_SYSERR;
350 struct GNUNET_NAMESTORE_RecordData rd; 437 struct GNUNET_NAMESTORE_RecordData rd;
351 438
352 keygen = NULL; 439 keygen = NULL;
@@ -385,138 +472,97 @@ key_generation_cb (void *cls,
385 } 472 }
386 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 473 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
387 &do_shutdown, NULL); 474 &do_shutdown, NULL);
388 if (NULL == typestring) 475 if (add)
389 type = 0;
390 else
391 type = GNUNET_NAMESTORE_typename_to_number (typestring);
392 if (UINT32_MAX == type)
393 {
394 fprintf (stderr, _("Unsupported type `%s'\n"), typestring);
395 GNUNET_SCHEDULER_shutdown ();
396 ret = 1;
397 return;
398 }
399 if ((NULL == typestring) && (add | del))
400 {
401 fprintf (stderr,
402 _("Missing option `%s' for operation `%s'\n"),
403 "-t", _("add/del"));
404 GNUNET_SCHEDULER_shutdown ();
405 ret = 1;
406 return;
407 }
408 if (NULL != value)
409 {
410 if (GNUNET_OK !=
411 GNUNET_NAMESTORE_string_to_value (type,
412 value,
413 &data,
414 &data_size))
415 {
416 fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
417 value,
418 typestring);
419 GNUNET_SCHEDULER_shutdown ();
420 ret = 1;
421 return;
422 }
423 } else if (add | del)
424 {
425 fprintf (stderr,
426 _("Missing option `%s' for operation `%s'\n"),
427 "-V", _("add/del"));
428 ret = 1;
429 GNUNET_SCHEDULER_shutdown ();
430 return;
431 }
432 if (NULL != expirationstring)
433 { 476 {
434 if (0 == strcmp (expirationstring, "never")) 477 if (NULL == name)
435 { 478 {
436 etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS; 479 fprintf (stderr,
437 etime_is_rel = GNUNET_NO; 480 _("Missing option `%s' for operation `%s'\n"),
481 "-n", _("add"));
482 GNUNET_SCHEDULER_shutdown ();
483 ret = 1;
484 return;
438 } 485 }
439 else if (GNUNET_OK == 486 if (NULL == typestring)
440 GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
441 &etime_rel))
442 { 487 {
443 etime_is_rel = GNUNET_YES; 488 fprintf (stderr,
489 _("Missing option `%s' for operation `%s'\n"),
490 "-t", _("add"));
491 GNUNET_SCHEDULER_shutdown ();
492 ret = 1;
493 return;
444 } 494 }
445 else if (GNUNET_OK == 495 type = GNUNET_NAMESTORE_typename_to_number (typestring);
446 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, 496 if (UINT32_MAX == type)
447 &etime_abs))
448 { 497 {
449 etime_is_rel = GNUNET_NO; 498 fprintf (stderr, _("Unsupported type `%s'\n"), typestring);
499 GNUNET_SCHEDULER_shutdown ();
500 ret = 1;
501 return;
450 } 502 }
451 else 503 if (NULL == value)
452 { 504 {
453 fprintf (stderr, 505 fprintf (stderr,
454 _("Invalid time format `%s'\n"), 506 _("Missing option `%s' for operation `%s'\n"),
455 expirationstring); 507 "-V", _("add"));
508 ret = 1;
456 GNUNET_SCHEDULER_shutdown (); 509 GNUNET_SCHEDULER_shutdown ();
457 ret = 1;
458 return; 510 return;
459 } 511 }
460 if (etime_is_rel && del) 512 if (GNUNET_OK !=
513 GNUNET_NAMESTORE_string_to_value (type,
514 value,
515 &data,
516 &data_size))
461 { 517 {
462 fprintf (stderr, 518 fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"),
463 _("Deletion requires either absolute time, or no time at all. Got relative time `%s' instead.\n"), 519 value,
464 expirationstring); 520 typestring);
465 GNUNET_SCHEDULER_shutdown (); 521 GNUNET_SCHEDULER_shutdown ();
466 ret = 1; 522 ret = 1;
467 return; 523 return;
468 } 524 }
469 } 525 if (NULL == expirationstring)
470 else if (add)
471 {
472 fprintf (stderr,
473 _("Missing option `%s' for operation `%s'\n"),
474 "-e", _("add"));
475 GNUNET_SCHEDULER_shutdown ();
476 ret = 1;
477 return;
478 }
479 memset (&rd, 0, sizeof (rd));
480 if (add)
481 {
482 if (NULL == name)
483 { 526 {
484 fprintf (stderr, 527 fprintf (stderr,
485 _("Missing option `%s' for operation `%s'\n"), 528 _("Missing option `%s' for operation `%s'\n"),
486 "-n", _("add")); 529 "-e", _("add"));
487 GNUNET_SCHEDULER_shutdown (); 530 GNUNET_SCHEDULER_shutdown ();
488 ret = 1; 531 ret = 1;
489 return; 532 return;
490 } 533 }
491 rd.data = data; 534 if (0 == strcmp (expirationstring, "never"))
492 rd.data_size = data_size;
493 rd.record_type = type;
494 if (GNUNET_YES == etime_is_rel)
495 { 535 {
496 rd.expiration_time = etime_rel.rel_value; 536 etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS;
497 rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION; 537 etime_is_rel = GNUNET_NO;
538 }
539 else if (GNUNET_OK ==
540 GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
541 &etime_rel))
542 {
543 etime_is_rel = GNUNET_YES;
544 }
545 else if (GNUNET_OK ==
546 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
547 &etime_abs))
548 {
549 etime_is_rel = GNUNET_NO;
498 } 550 }
499 else if (GNUNET_NO == etime_is_rel)
500 rd.expiration_time = etime_abs.abs_value;
501 else 551 else
502 { 552 {
503 fprintf (stderr, 553 fprintf (stderr,
504 _("No valid expiration time for operation `%s'\n"), 554 _("Invalid time format `%s'\n"),
505 _("add")); 555 expirationstring);
506 GNUNET_SCHEDULER_shutdown (); 556 GNUNET_SCHEDULER_shutdown ();
507 ret = 1; 557 ret = 1;
508 return; 558 return;
509 } 559 }
510 if (1 != nonauthority) 560 add_qe = GNUNET_NAMESTORE_lookup_record (ns,
511 rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY; 561 &zone,
512 if (1 != public) 562 name,
513 rd.flags |= GNUNET_NAMESTORE_RF_PRIVATE; 563 0,
514 add_qe = GNUNET_NAMESTORE_record_create (ns, 564 &get_existing_record,
515 zone_pkey, 565 NULL);
516 name,
517 &rd,
518 &add_continuation,
519 &add_qe);
520 } 566 }
521 if (del) 567 if (del)
522 { 568 {
@@ -529,19 +575,12 @@ key_generation_cb (void *cls,
529 ret = 1; 575 ret = 1;
530 return; 576 return;
531 } 577 }
532 rd.data = data; 578 del_qe = GNUNET_NAMESTORE_record_put_by_authority (ns,
533 rd.data_size = data_size; 579 zone_pkey,
534 rd.record_type = type; 580 name,
535 rd.expiration_time = 0; 581 0, NULL,
536 if (!etime_is_rel) 582 &del_continuation,
537 rd.expiration_time = etime_abs.abs_value; 583 NULL);
538 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
539 del_qe = GNUNET_NAMESTORE_record_remove (ns,
540 zone_pkey,
541 name,
542 &rd,
543 &del_continuation,
544 NULL);
545 } 584 }
546 if (list) 585 if (list)
547 { 586 {
@@ -580,6 +619,7 @@ key_generation_cb (void *cls,
580 ret = 1; 619 ret = 1;
581 return; 620 return;
582 } 621 }
622 memset (&rd, 0, sizeof (rd));
583 rd.data = &sc; 623 rd.data = &sc;
584 rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); 624 rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
585 rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY; 625 rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY;
@@ -594,16 +634,15 @@ key_generation_cb (void *cls,
594 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value; 634 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value;
595 if (1 != nonauthority) 635 if (1 != nonauthority)
596 rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY; 636 rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
597 637 add_qe_uri = GNUNET_NAMESTORE_record_put_by_authority (ns,
598 add_qe_uri = GNUNET_NAMESTORE_record_create (ns, 638 zone_pkey,
599 zone_pkey, 639 name,
600 name, 640 1,
601 &rd, 641 &rd,
602 &add_continuation, 642 &add_continuation,
603 &add_qe_uri); 643 &add_qe_uri);
604 } 644 }
605 GNUNET_free_non_null (data); 645 GNUNET_free_non_null (data);
606
607} 646}
608 647
609 648
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 9c8fbae7b..b71893d5d 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors) 3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,6 +22,7 @@
22 * @file namestore/gnunet-service-namestore.c 22 * @file namestore/gnunet-service-namestore.c
23 * @brief namestore for the GNUnet naming system 23 * @brief namestore for the GNUnet naming system
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 * @author Christian Grothoff
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -250,7 +251,7 @@ write_key_to_file (const char *filename,
250 { 251 {
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
252 "File zone `%s' containing this key already exists\n", 253 "File zone `%s' containing this key already exists\n",
253 GNUNET_short_h2s (&zone)); 254 GNUNET_NAMESTORE_short_h2s (&zone));
254 return GNUNET_OK; 255 return GNUNET_OK;
255 } 256 }
256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -279,7 +280,7 @@ write_key_to_file (const char *filename,
279 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); 280 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 "Stored zonekey for zone `%s' in file `%s'\n", 282 "Stored zonekey for zone `%s' in file `%s'\n",
282 GNUNET_short_h2s(&c->zone), c->filename); 283 GNUNET_NAMESTORE_short_h2s(&c->zone), c->filename);
283 return GNUNET_OK; 284 return GNUNET_OK;
284} 285}
285 286
@@ -305,7 +306,7 @@ zone_to_disk_it (void *cls,
305 GNUNET_asprintf(&c->filename, 306 GNUNET_asprintf(&c->filename,
306 "%s/%s.zkey", 307 "%s/%s.zkey",
307 zonefile_directory, 308 zonefile_directory,
308 GNUNET_short_h2s (&c->zone)); 309 GNUNET_NAMESTORE_short_h2s (&c->zone));
309 (void) write_key_to_file(c->filename, c); 310 (void) write_key_to_file(c->filename, c);
310 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value)); 311 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value));
311 GNUNET_CRYPTO_ecc_key_free (c->privkey); 312 GNUNET_CRYPTO_ecc_key_free (c->privkey);
@@ -343,7 +344,7 @@ learn_private_key (struct GNUNET_CRYPTO_EccPrivateKey *pkey)
343 } 344 }
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
345 "Received new private key for zone `%s'\n", 346 "Received new private key for zone `%s'\n",
346 GNUNET_short_h2s(&pubkey_hash)); 347 GNUNET_NAMESTORE_short_h2s(&pubkey_hash));
347 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer)); 348 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
348 cc->privkey = pkey; 349 cc->privkey = pkey;
349 cc->zone = pubkey_hash; 350 cc->zone = pubkey_hash;
@@ -611,7 +612,7 @@ handle_lookup_name_it (void *cls,
611 { 612 {
612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 613 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
613 "Am authoritative for zone `%s'\n", 614 "Am authoritative for zone `%s'\n",
614 GNUNET_short_h2s (&zone_key_hash)); 615 GNUNET_NAMESTORE_short_h2s (&zone_key_hash));
615 authoritative = GNUNET_YES; 616 authoritative = GNUNET_YES;
616 } 617 }
617 } 618 }
@@ -645,7 +646,7 @@ handle_lookup_name_it (void *cls,
645 copied_elements, 646 copied_elements,
646 lnc->record_type, 647 lnc->record_type,
647 lnc->name, 648 lnc->name,
648 GNUNET_short_h2s(lnc->zone)); 649 GNUNET_NAMESTORE_short_h2s(lnc->zone));
649 if (copied_elements > 0) 650 if (copied_elements > 0)
650 { 651 {
651 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); 652 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
@@ -695,7 +696,7 @@ handle_lookup_name_it (void *cls,
695 "Found %u matching records for name `%s' in zone `%s'\n", 696 "Found %u matching records for name `%s' in zone `%s'\n",
696 copied_elements, 697 copied_elements,
697 lnc->name, 698 lnc->name,
698 GNUNET_short_h2s (lnc->zone)); 699 GNUNET_NAMESTORE_short_h2s (lnc->zone));
699 contains_signature = GNUNET_NO; 700 contains_signature = GNUNET_NO;
700 if (copied_elements > 0) 701 if (copied_elements > 0)
701 { 702 {
@@ -709,7 +710,7 @@ handle_lookup_name_it (void *cls,
709 "Creating signature for name `%s' with %u records in zone `%s'\n", 710 "Creating signature for name `%s' with %u records in zone `%s'\n",
710 name, 711 name,
711 copied_elements, 712 copied_elements,
712 GNUNET_short_h2s(&zone_key_hash)); 713 GNUNET_NAMESTORE_short_h2s(&zone_key_hash));
713 } 714 }
714 else 715 else
715 { 716 {
@@ -828,12 +829,12 @@ handle_lookup_name (void *cls,
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
829 "Looking up all records for name `%s' in zone `%s'\n", 830 "Looking up all records for name `%s' in zone `%s'\n",
830 name, 831 name,
831 GNUNET_short_h2s(&ln_msg->zone)); 832 GNUNET_NAMESTORE_short_h2s(&ln_msg->zone));
832 else 833 else
833 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
834 "Looking up records with type %u for name `%s' in zone `%s'\n", 835 "Looking up records with type %u for name `%s' in zone `%s'\n",
835 type, name, 836 type, name,
836 GNUNET_short_h2s(&ln_msg->zone)); 837 GNUNET_NAMESTORE_short_h2s(&ln_msg->zone));
837 838
838 conv_name = GNUNET_NAMESTORE_normalize_string (name); 839 conv_name = GNUNET_NAMESTORE_normalize_string (name);
839 if (NULL == conv_name) 840 if (NULL == conv_name)
@@ -964,7 +965,7 @@ handle_record_put (void *cls,
964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
965 "Putting %u records under name `%s' in zone `%s'\n", 966 "Putting %u records under name `%s' in zone `%s'\n",
966 rd_count, conv_name, 967 rd_count, conv_name,
967 GNUNET_short_h2s (&zone_hash)); 968 GNUNET_NAMESTORE_short_h2s (&zone_hash));
968 res = GSN_database->put_records(GSN_database->cls, 969 res = GSN_database->put_records(GSN_database->cls,
969 &rp_msg->public_key, 970 &rp_msg->public_key,
970 expire, 971 expire,
@@ -992,156 +993,6 @@ handle_record_put (void *cls,
992 993
993 994
994/** 995/**
995 * Context for record create operations passed from 'handle_record_create' to
996 * 'handle_create_record_it' as closure
997 */
998struct CreateRecordContext
999{
1000 /**
1001 * Record data
1002 */
1003 const struct GNUNET_NAMESTORE_RecordData *rd;
1004
1005 /**
1006 * Zone's public key
1007 */
1008 struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pubkey;
1009
1010 /**
1011 * Name for the record to create
1012 */
1013 const char *name;
1014
1015 /**
1016 * Record expiration time
1017 */
1018 struct GNUNET_TIME_Absolute expire;
1019
1020 /**
1021 * result returned from 'handle_create_record_it'
1022 * GNUNET_SYSERR: failed to create the record
1023 * GNUNET_NO: we updated an existing record or identical entry existed
1024 * GNUNET_YES : we created a new record
1025 */
1026 int res;
1027};
1028
1029
1030/**
1031 * A 'GNUNET_NAMESTORE_RecordIterator' for record create operations
1032 * in handle_record_create
1033 *
1034 * @param cls a 'struct CreateRecordContext *' with information about the request
1035 * @param pubkey zone key of the zone
1036 * @param expire expiration time
1037 * @param name name
1038 * @param rd_count number of records
1039 * @param rd array of records
1040 * @param signature signature
1041 */
1042static void
1043handle_create_record_it (void *cls,
1044 const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pubkey,
1045 struct GNUNET_TIME_Absolute expire,
1046 const char *name,
1047 unsigned int rd_count,
1048 const struct GNUNET_NAMESTORE_RecordData *rd,
1049 const struct GNUNET_CRYPTO_EccSignature *signature)
1050{
1051 static struct GNUNET_CRYPTO_EccSignature dummy_signature;
1052 struct CreateRecordContext *crc = cls;
1053 struct GNUNET_NAMESTORE_RecordData *rd_new;
1054 struct GNUNET_TIME_Absolute block_expiration;
1055 int exist;
1056 int update;
1057 unsigned int c;
1058 unsigned int rd_count_new;
1059
1060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1061 "Found %u existing records for `%s'\n",
1062 rd_count, crc->name);
1063 exist = -1;
1064 update = GNUNET_NO;
1065 for (c = 0; c < rd_count; c++)
1066 {
1067 if ( (crc->rd->record_type != rd[c].record_type) ||
1068 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
1069 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) )
1070 continue; /* no match */
1071 if ( (GNUNET_NAMESTORE_TYPE_PKEY == crc->rd->record_type) ||
1072 (GNUNET_NAMESTORE_TYPE_PSEU == crc->rd->record_type) ||
1073 (GNUNET_DNSPARSER_TYPE_CNAME == crc->rd->record_type) )
1074 {
1075 /* Update unique PKEY, PSEU or CNAME record; for these
1076 record types, only one can be active at any time */
1077 exist = c;
1078 if ( (crc->rd->data_size != rd[c].data_size) ||
1079 (0 != memcmp (crc->rd->data, rd[c].data, rd[c].data_size)) ||
1080 (crc->rd->expiration_time != rd[c].expiration_time) )
1081 update = GNUNET_YES;
1082 break;
1083 }
1084 if ( (crc->rd->data_size == rd[c].data_size) &&
1085 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
1086 {
1087 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1088 "Found matching existing record for `%s'; only updating expiration date!\n",
1089 crc->name);
1090 exist = c;
1091 if (crc->rd->expiration_time != rd[c].expiration_time)
1092 update = GNUNET_YES;
1093 break;
1094 }
1095 }
1096
1097 if ( (-1 != exist) &&
1098 (GNUNET_NO == update) )
1099 {
1100 /* Exact same record already exists */
1101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1102 "Matching record for %s' exists, no change required!\n",
1103 crc->name);
1104 crc->res = GNUNET_NO; /* identical record existed */
1105 return;
1106 }
1107 if (-1 == exist)
1108 {
1109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1110 "No existing record for name `%s'!\n",
1111 crc->name);
1112 rd_count_new = rd_count + 1;
1113 rd_new = GNUNET_malloc (rd_count_new * sizeof (struct GNUNET_NAMESTORE_RecordData));
1114 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
1115 rd_new[rd_count] = *(crc->rd);
1116 }
1117 else
1118 {
1119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1120 "Updating existing records for `%s'!\n",
1121 crc->name);
1122 rd_count_new = rd_count;
1123 rd_new = GNUNET_malloc (rd_count_new * sizeof (struct GNUNET_NAMESTORE_RecordData));
1124 memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
1125 rd_new[exist] = *(crc->rd);
1126 }
1127 block_expiration = GNUNET_TIME_absolute_max (crc->expire, expire);
1128 if (GNUNET_OK !=
1129 GSN_database->put_records (GSN_database->cls,
1130 &crc->pubkey,
1131 block_expiration,
1132 crc->name,
1133 rd_count_new, rd_new,
1134 &dummy_signature))
1135 crc->res = GNUNET_SYSERR; /* error */
1136 else if (GNUNET_YES == update)
1137 crc->res = GNUNET_NO; /* update */
1138 else
1139 crc->res = GNUNET_YES; /* created new record */
1140 GNUNET_free (rd_new);
1141}
1142
1143
1144/**
1145 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE' message 996 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE' message
1146 * 997 *
1147 * @param cls unused 998 * @param cls unused
@@ -1153,9 +1004,9 @@ handle_record_create (void *cls,
1153 struct GNUNET_SERVER_Client *client, 1004 struct GNUNET_SERVER_Client *client,
1154 const struct GNUNET_MessageHeader *message) 1005 const struct GNUNET_MessageHeader *message)
1155{ 1006{
1007 static struct GNUNET_CRYPTO_EccSignature dummy_signature;
1156 struct GNUNET_NAMESTORE_Client *nc; 1008 struct GNUNET_NAMESTORE_Client *nc;
1157 const struct RecordCreateMessage *rp_msg; 1009 const struct RecordCreateMessage *rp_msg;
1158 struct CreateRecordContext crc;
1159 struct GNUNET_CRYPTO_EccPrivateKey *pkey; 1010 struct GNUNET_CRYPTO_EccPrivateKey *pkey;
1160 struct RecordCreateResponseMessage rcr_msg; 1011 struct RecordCreateResponseMessage rcr_msg;
1161 size_t name_len; 1012 size_t name_len;
@@ -1170,8 +1021,8 @@ handle_record_create (void *cls,
1170 const char *rd_ser; 1021 const char *rd_ser;
1171 unsigned int rd_count; 1022 unsigned int rd_count;
1172 int res; 1023 int res;
1173 struct GNUNET_NAMESTORE_RecordData rd;
1174 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash; 1024 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1025 struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pubkey;
1175 1026
1176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1177 "Received `%s' message\n", "NAMESTORE_RECORD_CREATE"); 1028 "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
@@ -1195,7 +1046,7 @@ handle_record_create (void *cls,
1195 rd_ser_len = ntohs (rp_msg->rd_len); 1046 rd_ser_len = ntohs (rp_msg->rd_len);
1196 key_len = ntohs (rp_msg->pkey_len); 1047 key_len = ntohs (rp_msg->pkey_len);
1197 msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len; 1048 msg_size_exp = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
1198 if ( (msg_size != msg_size_exp) || (1 != rd_count) ) 1049 if (msg_size != msg_size_exp)
1199 { 1050 {
1200 GNUNET_break (0); 1051 GNUNET_break (0);
1201 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1052 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -1223,56 +1074,59 @@ handle_record_create (void *cls,
1223 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1074 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1224 return; 1075 return;
1225 } 1076 }
1226 if (GNUNET_OK !=
1227 GNUNET_NAMESTORE_records_deserialize (rd_ser_len, rd_ser, rd_count, &rd))
1228 { 1077 {
1229 GNUNET_break (0); 1078 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
1230 GNUNET_CRYPTO_ecc_key_free (pkey);
1231 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1232 return;
1233 }
1234 1079
1235 /* Extracting and converting private key */ 1080 if (GNUNET_OK !=
1236 GNUNET_CRYPTO_ecc_key_get_public (pkey, &crc.pubkey); 1081 GNUNET_NAMESTORE_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1237 GNUNET_CRYPTO_short_hash (&crc.pubkey, 1082 {
1238 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), 1083 GNUNET_break (0);
1239 &pubkey_hash); 1084 GNUNET_CRYPTO_ecc_key_free (pkey);
1240 learn_private_key (pkey); 1085 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1086 return;
1087 }
1241 1088
1242 conv_name = GNUNET_NAMESTORE_normalize_string(name_tmp); 1089 /* Extracting and converting private key */
1243 if (NULL == conv_name) 1090 GNUNET_CRYPTO_ecc_key_get_public (pkey, &pubkey);
1244 { 1091 GNUNET_CRYPTO_short_hash (&pubkey,
1092 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded),
1093 &pubkey_hash);
1094 learn_private_key (pkey);
1095 conv_name = GNUNET_NAMESTORE_normalize_string (name_tmp);
1096 if (NULL == conv_name)
1097 {
1245 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1098 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1246 "Error converting name `%s'\n", name_tmp); 1099 "Error converting name `%s'\n", name_tmp);
1100 GNUNET_CRYPTO_ecc_key_free (pkey);
1101 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1247 return; 1102 return;
1103 }
1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1105 "Creating %u records for name `%s' in zone `%s'\n",
1106 (unsigned int) rd_count,
1107 conv_name,
1108 GNUNET_NAMESTORE_short_h2s (&pubkey_hash));
1109 if (0 == rd_count)
1110 res = GSN_database->remove_records (GSN_database->cls,
1111 &pubkey_hash,
1112 conv_name);
1113 else
1114 res = GSN_database->put_records (GSN_database->cls,
1115 &pubkey,
1116 GNUNET_TIME_absolute_ntoh(rp_msg->expire),
1117 conv_name,
1118 rd_count, rd,
1119 &dummy_signature);
1120 GNUNET_free (conv_name);
1248 } 1121 }
1249 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1122
1250 "Creating record for name `%s' in zone `%s'\n",
1251 conv_name, GNUNET_short_h2s(&pubkey_hash));
1252 crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
1253 crc.res = GNUNET_SYSERR;
1254 crc.rd = &rd;
1255 crc.name = conv_name;
1256
1257 /* Get existing records for name */
1258 res = GSN_database->iterate_records (GSN_database->cls, &pubkey_hash, conv_name, 0,
1259 &handle_create_record_it, &crc);
1260 GNUNET_free (conv_name);
1261 if (res != GNUNET_SYSERR)
1262 res = GNUNET_OK;
1263
1264 /* Send response */ 1123 /* Send response */
1265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1266 "Sending `%s' message\n", "RECORD_CREATE_RESPONSE"); 1125 "Sending `%s' message\n", "RECORD_CREATE_RESPONSE");
1267 rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE); 1126 rcr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE);
1268 rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage)); 1127 rcr_msg.gns_header.header.size = htons (sizeof (struct RecordCreateResponseMessage));
1269 rcr_msg.gns_header.r_id = htonl (rid); 1128 rcr_msg.gns_header.r_id = htonl (rid);
1270 if ((GNUNET_OK == res) && (crc.res == GNUNET_YES)) 1129 rcr_msg.op_result = htonl (res);
1271 rcr_msg.op_result = htonl (GNUNET_YES);
1272 else if ((GNUNET_OK == res) && (crc.res == GNUNET_NO))
1273 rcr_msg.op_result = htonl (GNUNET_NO);
1274 else
1275 rcr_msg.op_result = htonl (GNUNET_SYSERR);
1276 GNUNET_SERVER_notification_context_unicast (snc, nc->client, 1130 GNUNET_SERVER_notification_context_unicast (snc, nc->client,
1277 &rcr_msg.gns_header.header, 1131 &rcr_msg.gns_header.header,
1278 GNUNET_NO); 1132 GNUNET_NO);
@@ -1281,305 +1135,6 @@ handle_record_create (void *cls,
1281 1135
1282 1136
1283/** 1137/**
1284 * Context for record remove operations passed from 'handle_record_remove' to
1285 * 'handle_record_remove_it' as closure
1286 */
1287struct RemoveRecordContext
1288{
1289 /**
1290 * Record to remove
1291 */
1292 const struct GNUNET_NAMESTORE_RecordData *rd;
1293
1294 /**
1295 * See RECORD_REMOVE_RESULT_*-codes. Set by 'handle_record_remove_it'
1296 * to the result of the operation.
1297 */
1298 int32_t op_res;
1299};
1300
1301
1302/**
1303 * We are to remove a record (or all records for a given name). This function
1304 * will be called with the existing records (if there are any) and is to then
1305 * compute what to keep and trigger the necessary changes.
1306 *
1307 * @param cls the 'struct RecordRemoveContext' with information about what to remove
1308 * @param zone_key public key of the zone
1309 * @param expire when does the corresponding block in the DHT expire (until
1310 * when should we never do a DHT lookup for the same name again)?
1311 * @param name name that is being mapped (at most 255 characters long)
1312 * @param rd_count number of entries in 'rd' array
1313 * @param rd array of records with data to store
1314 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
1315 * because the user queried for a particular record type only)
1316 */
1317static void
1318handle_record_remove_it (void *cls,
1319 const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *zone_key,
1320 struct GNUNET_TIME_Absolute expire,
1321 const char *name,
1322 unsigned int rd_count,
1323 const struct GNUNET_NAMESTORE_RecordData *rd,
1324 const struct GNUNET_CRYPTO_EccSignature *signature)
1325{
1326 static struct GNUNET_CRYPTO_EccSignature dummy_signature;
1327 struct RemoveRecordContext *rrc = cls;
1328 unsigned int c;
1329 int found;
1330 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1331
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1333 "Name `%s 'currently has %u records\n",
1334 name, rd_count);
1335 if (0 == rd_count)
1336 {
1337 /* Could not find record to remove */
1338 rrc->op_res = RECORD_REMOVE_RESULT_NO_RECORDS;
1339 return;
1340 }
1341 /* Find record to remove */
1342 found = -1;
1343 for (c = 0; c < rd_count; c++)
1344 {
1345 if (GNUNET_YES !=
1346 GNUNET_NAMESTORE_records_cmp (&rd[c],
1347 rrc->rd))
1348 continue;
1349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found record to remove!\n", rd_count);
1350 found = c;
1351 break;
1352 }
1353 if (-1 == found)
1354 {
1355 /* Could not find record to remove */
1356 rrc->op_res = RECORD_REMOVE_RESULT_RECORD_NOT_FOUND;
1357 return;
1358 }
1359 if (1 == rd_count)
1360 {
1361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1362 "No records left for name `%s', removing name\n",
1363 name);
1364 GNUNET_CRYPTO_short_hash (zone_key,
1365 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded),
1366 &pubkey_hash);
1367 if (GNUNET_OK !=
1368 GSN_database->remove_records (GSN_database->cls,
1369 &pubkey_hash,
1370 name))
1371 {
1372 /* Could not remove records from database */
1373 rrc->op_res = RECORD_REMOVE_RESULT_FAILED_TO_REMOVE;
1374 return;
1375 }
1376 rrc->op_res = RECORD_REMOVE_RESULT_SUCCESS;
1377 return;
1378 }
1379
1380 {
1381 struct GNUNET_NAMESTORE_RecordData rd_new[rd_count - 1];
1382 unsigned int c2 = 0;
1383
1384 for (c = 0; c < rd_count; c++)
1385 {
1386 if (c == found)
1387 continue;
1388 rd_new[c2++] = rd[c];
1389 }
1390 if (GNUNET_OK !=
1391 GSN_database->put_records(GSN_database->cls,
1392 zone_key,
1393 expire,
1394 name,
1395 rd_count - 1, rd_new,
1396 &dummy_signature))
1397 {
1398 /* Could not put records into database */
1399 rrc->op_res = RECORD_REMOVE_RESULT_FAILED_TO_PUT_UPDATE;
1400 return;
1401 }
1402 }
1403 rrc->op_res = RECORD_REMOVE_RESULT_SUCCESS;
1404}
1405
1406
1407/**
1408 * Handles a 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE' message
1409 *
1410 * @param cls unused
1411 * @param client GNUNET_SERVER_Client sending the message
1412 * @param message message of type 'struct RecordRemoveMessage'
1413 */
1414static void
1415handle_record_remove (void *cls,
1416 struct GNUNET_SERVER_Client *client,
1417 const struct GNUNET_MessageHeader *message)
1418{
1419 struct GNUNET_NAMESTORE_Client *nc;
1420 const struct RecordRemoveMessage *rr_msg;
1421 struct RecordRemoveResponseMessage rrr_msg;
1422 struct GNUNET_CRYPTO_EccPrivateKey *pkey;
1423 struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pub;
1424 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
1425 struct GNUNET_NAMESTORE_RecordData rd;
1426 const char *pkey_tmp;
1427 const char *name_tmp;
1428 const char *rd_ser;
1429 char * conv_name;
1430 size_t key_len;
1431 size_t name_len;
1432 size_t rd_ser_len;
1433 size_t msg_size;
1434 size_t msg_size_exp;
1435 uint32_t rd_count;
1436 uint32_t rid;
1437 struct RemoveRecordContext rrc;
1438 int res;
1439 uint64_t off;
1440
1441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1442 "Received `%s' message\n",
1443 "NAMESTORE_RECORD_REMOVE");
1444 if (ntohs (message->size) < sizeof (struct RecordRemoveMessage))
1445 {
1446 GNUNET_break (0);
1447 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1448 return;
1449 }
1450 if (NULL == (nc = client_lookup(client)))
1451 {
1452 GNUNET_break (0);
1453 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1454 return;
1455 }
1456 rr_msg = (const struct RecordRemoveMessage *) message;
1457 rid = ntohl (rr_msg->gns_header.r_id);
1458 name_len = ntohs (rr_msg->name_len);
1459 rd_ser_len = ntohs (rr_msg->rd_len);
1460 rd_count = ntohs (rr_msg->rd_count);
1461 key_len = ntohs (rr_msg->pkey_len);
1462 msg_size = ntohs (message->size);
1463 if ((name_len >= MAX_NAME_LEN) || (0 == name_len) || (1 < rd_count) )
1464 {
1465 GNUNET_break (0);
1466 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1467 return;
1468 }
1469 msg_size_exp = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
1470 if (msg_size != msg_size_exp)
1471 {
1472 GNUNET_break (0);
1473 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1474 return;
1475 }
1476 pkey_tmp = (const char *) &rr_msg[1];
1477 name_tmp = &pkey_tmp[key_len];
1478 rd_ser = &name_tmp[name_len];
1479 if ('\0' != name_tmp[name_len -1])
1480 {
1481 GNUNET_break (0);
1482 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1483 return;
1484 }
1485 if (NULL == (pkey = GNUNET_CRYPTO_ecc_decode_key (pkey_tmp, key_len,
1486 GNUNET_NO)))
1487 {
1488 GNUNET_break (0);
1489 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1490 return;
1491 }
1492 GNUNET_CRYPTO_ecc_key_get_public (pkey, &pub);
1493 GNUNET_CRYPTO_short_hash (&pub,
1494 sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded),
1495 &pubkey_hash);
1496 learn_private_key (pkey);
1497 if (GNUNET_OK !=
1498 GNUNET_NAMESTORE_records_deserialize (rd_ser_len, rd_ser, rd_count, &rd))
1499 {
1500 GNUNET_break (0);
1501 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1502 return;
1503 }
1504
1505 conv_name = GNUNET_NAMESTORE_normalize_string(name_tmp);
1506 if (NULL == conv_name)
1507 {
1508 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1509 "Error converting name `%s'\n", name_tmp);
1510 return;
1511 }
1512
1513 if (0 == rd_count)
1514 {
1515 /* remove the whole name and all records */
1516 res = GSN_database->remove_records (GSN_database->cls,
1517 &pubkey_hash,
1518 conv_name);
1519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1520 "Removing name `%s': %s\n",
1521 conv_name, (GNUNET_OK == res) ? "OK" : "FAILED");
1522 if (GNUNET_OK != res)
1523 /* Could not remove entry from database */
1524 res = RECORD_REMOVE_RESULT_FAILED_TO_PUT_UPDATE;
1525 else
1526 res = RECORD_REMOVE_RESULT_SUCCESS;
1527 }
1528 else
1529 {
1530 /* remove a single record */
1531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1532 "Removing record for name `%s' in zone `%s'\n", conv_name,
1533 GNUNET_short_h2s (&pubkey_hash));
1534 rrc.rd = &rd;
1535 rrc.op_res = RECORD_REMOVE_RESULT_RECORD_NOT_FOUND;
1536 off = 0;
1537 res = GNUNET_OK;
1538 while ( (RECORD_REMOVE_RESULT_RECORD_NOT_FOUND == rrc.op_res) &&
1539 (GNUNET_OK == res) )
1540 {
1541 res = GSN_database->iterate_records (GSN_database->cls,
1542 &pubkey_hash,
1543 conv_name,
1544 off++,
1545 &handle_record_remove_it, &rrc);
1546 }
1547 switch (res)
1548 {
1549 case GNUNET_OK:
1550 res = rrc.op_res;
1551 break;
1552 case GNUNET_NO:
1553 GNUNET_break (RECORD_REMOVE_RESULT_NO_RECORDS == rrc.op_res);
1554 res = RECORD_REMOVE_RESULT_NO_RECORDS;
1555 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1556 _("Failed to find record to remove\n"));
1557 break;
1558 case GNUNET_SYSERR:
1559 res = RECORD_REMOVE_RESULT_FAILED_ACCESS_DATABASE;
1560 break;
1561 default:
1562 GNUNET_break (0);
1563 res = RECORD_REMOVE_RESULT_FAILED_INTERNAL_ERROR;
1564 break;
1565 }
1566 }
1567 GNUNET_free (conv_name);
1568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1569 "Sending `%s' message\n",
1570 "RECORD_REMOVE_RESPONSE");
1571 rrr_msg.gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE);
1572 rrr_msg.gns_header.header.size = htons (sizeof (struct RecordRemoveResponseMessage));
1573 rrr_msg.gns_header.r_id = htonl (rid);
1574 rrr_msg.op_result = htonl (res);
1575 GNUNET_SERVER_notification_context_unicast (snc, nc->client,
1576 &rrr_msg.gns_header.header,
1577 GNUNET_NO);
1578 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1579}
1580
1581
1582/**
1583 * Context for record remove operations passed from 'handle_zone_to_name' to 1138 * Context for record remove operations passed from 'handle_zone_to_name' to
1584 * 'handle_zone_to_name_it' as closure 1139 * 'handle_zone_to_name_it' as closure
1585 */ 1140 */
@@ -1891,7 +1446,7 @@ zone_iteraterate_proc (void *cls,
1891 expire = get_block_expiration_time (rd_count_filtered, rd_filtered); 1446 expire = get_block_expiration_time (rd_count_filtered, rd_filtered);
1892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1893 "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n", 1448 "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1894 name, GNUNET_short_h2s(&zone_hash), 1449 name, GNUNET_NAMESTORE_short_h2s(&zone_hash),
1895 rd_count_filtered, 1450 rd_count_filtered,
1896 (unsigned long long) expire.abs_value); 1451 (unsigned long long) expire.abs_value);
1897 new_signature = GNUNET_NAMESTORE_create_signature (cc->privkey, expire, name, 1452 new_signature = GNUNET_NAMESTORE_create_signature (cc->privkey, expire, name,
@@ -1905,7 +1460,7 @@ zone_iteraterate_proc (void *cls,
1905 { 1460 {
1906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1907 "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n", 1462 "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1908 name, GNUNET_short_h2s (&zone_hash), rd_count_filtered, 1463 name, GNUNET_NAMESTORE_short_h2s (&zone_hash), rd_count_filtered,
1909 (unsigned long long) expire.abs_value); 1464 (unsigned long long) expire.abs_value);
1910 return; 1465 return;
1911 } 1466 }
@@ -1922,7 +1477,7 @@ zone_iteraterate_proc (void *cls,
1922 if (GNUNET_YES == proc->zi->has_zone) 1477 if (GNUNET_YES == proc->zi->has_zone)
1923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1924 "Sending name `%s' for iteration over zone `%s'\n", 1479 "Sending name `%s' for iteration over zone `%s'\n",
1925 name, GNUNET_short_h2s(&proc->zi->zone)); 1480 name, GNUNET_NAMESTORE_short_h2s(&proc->zi->zone));
1926 else 1481 else
1927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1928 "Sending name `%s' for iteration over all zones\n", 1483 "Sending name `%s' for iteration over all zones\n",
@@ -2000,7 +1555,7 @@ run_zone_iteration_round (struct GNUNET_NAMESTORE_ZoneIteration *zi)
2000 if (GNUNET_YES == zi->has_zone) 1555 if (GNUNET_YES == zi->has_zone)
2001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2002 "No more results for zone `%s'\n", 1557 "No more results for zone `%s'\n",
2003 GNUNET_short_h2s(&zi->zone)); 1558 GNUNET_NAMESTORE_short_h2s(&zi->zone));
2004 else 1559 else
2005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2006 "No more results for all zones\n"); 1561 "No more results for all zones\n");
@@ -2058,7 +1613,7 @@ handle_iteration_start (void *cls,
2058 else 1613 else
2059 { 1614 {
2060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2061 "Starting to iterate over zone `%s'\n", GNUNET_short_h2s (&zis_msg->zone)); 1616 "Starting to iterate over zone `%s'\n", GNUNET_NAMESTORE_short_h2s (&zis_msg->zone));
2062 zi->zone = zis_msg->zone; 1617 zi->zone = zis_msg->zone;
2063 zi->has_zone = GNUNET_YES; 1618 zi->has_zone = GNUNET_YES;
2064 } 1619 }
@@ -2109,7 +1664,7 @@ handle_iteration_stop (void *cls,
2109 if (GNUNET_YES == zi->has_zone) 1664 if (GNUNET_YES == zi->has_zone)
2110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2111 "Stopped zone iteration for zone `%s'\n", 1666 "Stopped zone iteration for zone `%s'\n",
2112 GNUNET_short_h2s (&zi->zone)); 1667 GNUNET_NAMESTORE_short_h2s (&zi->zone));
2113 else 1668 else
2114 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2115 "Stopped zone iteration over all zones\n"); 1670 "Stopped zone iteration over all zones\n");
@@ -2233,8 +1788,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
2233 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0}, 1788 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0},
2234 {&handle_record_create, NULL, 1789 {&handle_record_create, NULL,
2235 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0}, 1790 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE, 0},
2236 {&handle_record_remove, NULL,
2237 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE, 0},
2238 {&handle_zone_to_name, NULL, 1791 {&handle_zone_to_name, NULL,
2239 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, sizeof (struct ZoneToNameMessage) }, 1792 GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, sizeof (struct ZoneToNameMessage) },
2240 {&handle_iteration_start, NULL, 1793 {&handle_iteration_start, NULL,
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index b0d3ffad0..0c1ec9be3 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -31,59 +31,9 @@
31 */ 31 */
32#define MAX_NAME_LEN 256 32#define MAX_NAME_LEN 256
33 33
34/** 34GNUNET_NETWORK_STRUCT_BEGIN
35 * Convert a UTF-8 string to UTF-8 lowercase
36 * @param src source string
37 * @return converted result
38 */
39char *
40GNUNET_NAMESTORE_normalize_string (const char *src);
41
42/**
43 * Convert a short hash to a string (for printing debug messages).
44 * This is one of the very few calls in the entire API that is
45 * NOT reentrant!
46 *
47 * @param hc the short hash code
48 * @return string form; will be overwritten by next call to GNUNET_h2s.
49 */
50const char *
51GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc);
52
53
54/**
55 * Sign name and records
56 *
57 * @param key the private key
58 * @param expire block expiration
59 * @param name the name
60 * @param rd record data
61 * @param rd_count number of records
62 *
63 * @return the signature
64 */
65struct GNUNET_CRYPTO_EccSignature *
66GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key,
67 struct GNUNET_TIME_Absolute expire,
68 const char *name,
69 const struct GNUNET_NAMESTORE_RecordData *rd,
70 unsigned int rd_count);
71
72
73/**
74 * Compares if two records are equal
75 *
76 * @param a Record a
77 * @param b Record b
78 *
79 * @return GNUNET_YES or GNUNET_NO
80 */
81int
82GNUNET_NAMESTORE_records_cmp (const struct GNUNET_NAMESTORE_RecordData *a,
83 const struct GNUNET_NAMESTORE_RecordData *b);
84 35
85 36
86GNUNET_NETWORK_STRUCT_BEGIN
87/** 37/**
88 * A GNS record serialized for network transmission. 38 * A GNS record serialized for network transmission.
89 * 39 *
@@ -352,105 +302,6 @@ struct RecordCreateResponseMessage
352 302
353 303
354/** 304/**
355 * Remove a record from the namestore
356 * Memory layout:
357 */
358struct RecordRemoveMessage
359{
360 /**
361 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE
362 */
363 struct GNUNET_NAMESTORE_Header gns_header;
364
365 /**
366 * Name length
367 */
368 uint16_t name_len;
369
370 /**
371 * Length of serialized rd data
372 */
373 uint16_t rd_len;
374
375 /**
376 * Number of records contained
377 */
378 uint16_t rd_count;
379
380 /**
381 * Length of private key
382 */
383 uint16_t pkey_len;
384
385 /* followed by:
386 * GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded private key with length pkey_len
387 * name with length name_len
388 * serialized record data with length rd_len
389 * */
390};
391
392
393/**
394 * Removal of the record succeeded.
395 */
396#define RECORD_REMOVE_RESULT_SUCCESS 0
397
398/**
399 * There are NO records for the given name.
400 */
401#define RECORD_REMOVE_RESULT_NO_RECORDS 1
402
403/**
404 * The specific record that was to be removed was
405 * not found.
406 */
407#define RECORD_REMOVE_RESULT_RECORD_NOT_FOUND 2
408
409/**
410 * Internal error, failed to sign the remaining records.
411 * (Note: not used?)
412 */
413#define RECORD_REMOVE_RESULT_FAILED_TO_SIGN 3
414
415/**
416 * Internal error, failed to store the updated record set
417 */
418#define RECORD_REMOVE_RESULT_FAILED_TO_PUT_UPDATE 4
419
420/**
421 * Internal error, failed to remove records from database
422 */
423#define RECORD_REMOVE_RESULT_FAILED_TO_REMOVE 5
424
425/**
426 * Internal error, failed to access database
427 */
428#define RECORD_REMOVE_RESULT_FAILED_ACCESS_DATABASE 6
429
430/**
431 * Internal error, failed to access database
432 */
433#define RECORD_REMOVE_RESULT_FAILED_INTERNAL_ERROR 7
434
435
436/**
437 * Remove a record from the namestore response
438 */
439struct RecordRemoveResponseMessage
440{
441 /**
442 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE
443 */
444 struct GNUNET_NAMESTORE_Header gns_header;
445
446 /**
447 * Result code (see RECORD_REMOVE_RESULT_*). In network byte order.
448 */
449 int32_t op_result;
450};
451
452
453/**
454 * Lookup a name for a zone hash 305 * Lookup a name for a zone hash
455 */ 306 */
456struct ZoneToNameMessage 307struct ZoneToNameMessage
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 7a7c3eabb..97d34aa24 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) 3 (C) 2010-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -378,71 +378,6 @@ handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
378 378
379 379
380/** 380/**
381 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE'
382 *
383 * @param qe the respective entry in the message queue
384 * @param msg the message we received
385 * @param size the message size
386 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client
387 */
388static int
389handle_record_remove_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
390 const struct RecordRemoveResponseMessage* msg,
391 size_t size)
392{
393 int ret;
394 const char *emsg;
395
396 /* Operation done, remove */
397 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
398 "RECORD_REMOVE_RESPONSE");
399 switch (ntohl (msg->op_result))
400 {
401 case RECORD_REMOVE_RESULT_SUCCESS:
402 ret = GNUNET_OK;
403 emsg = NULL;
404 break;
405 case RECORD_REMOVE_RESULT_NO_RECORDS:
406 ret = GNUNET_NO;
407 emsg = NULL;
408 break;
409 case RECORD_REMOVE_RESULT_RECORD_NOT_FOUND:
410 ret = GNUNET_NO;
411 emsg = NULL;
412 break;
413 case RECORD_REMOVE_RESULT_FAILED_TO_SIGN:
414 ret = GNUNET_SYSERR;
415 emsg = _("Failed to create new signature");
416 break;
417 case RECORD_REMOVE_RESULT_FAILED_TO_PUT_UPDATE:
418 ret = GNUNET_SYSERR;
419 emsg = _("Failed to put new set of records in database");
420 break;
421 case RECORD_REMOVE_RESULT_FAILED_TO_REMOVE:
422 ret = GNUNET_SYSERR;
423 emsg = _("Failed to remove records from database");
424 break;
425 case RECORD_REMOVE_RESULT_FAILED_ACCESS_DATABASE:
426 ret = GNUNET_SYSERR;
427 emsg = _("Failed to access database");
428 break;
429 case RECORD_REMOVE_RESULT_FAILED_INTERNAL_ERROR:
430 ret = GNUNET_SYSERR;
431 emsg = _("unknown internal error in namestore");
432 break;
433 default:
434 GNUNET_break (0);
435 if (NULL != qe->cont)
436 qe->cont (qe->cont_cls, GNUNET_SYSERR, _("Protocol error"));
437 return GNUNET_NO;
438 }
439 if (NULL != qe->cont)
440 qe->cont (qe->cont_cls, ret, emsg);
441 return GNUNET_OK;
442}
443
444
445/**
446 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE' 381 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE'
447 * 382 *
448 * @param qe the respective entry in the message queue 383 * @param qe the respective entry in the message queue
@@ -554,13 +489,6 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
554 return GNUNET_SYSERR; 489 return GNUNET_SYSERR;
555 } 490 }
556 return handle_record_create_response (qe, (const struct RecordCreateResponseMessage *) msg, size); 491 return handle_record_create_response (qe, (const struct RecordCreateResponseMessage *) msg, size);
557 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE:
558 if (size != sizeof (struct RecordRemoveResponseMessage))
559 {
560 GNUNET_break (0);
561 return GNUNET_SYSERR;
562 }
563 return handle_record_remove_response (qe, (const struct RecordRemoveResponseMessage *) msg, size);
564 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE: 492 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
565 if (size < sizeof (struct ZoneToNameResponseMessage)) 493 if (size < sizeof (struct ZoneToNameResponseMessage))
566 { 494 {
@@ -1142,18 +1070,20 @@ GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKeyBinary
1142 * @param h handle to the namestore 1070 * @param h handle to the namestore
1143 * @param pkey private key of the zone 1071 * @param pkey private key of the zone
1144 * @param name name that is being mapped (at most 255 characters long) 1072 * @param name name that is being mapped (at most 255 characters long)
1073 * @param rd_count number of records in 'rd' array
1145 * @param rd record data to store 1074 * @param rd record data to store
1146 * @param cont continuation to call when done 1075 * @param cont continuation to call when done
1147 * @param cont_cls closure for cont 1076 * @param cont_cls closure for cont
1148 * @return handle to abort the request 1077 * @return handle to abort the request
1149 */ 1078 */
1150struct GNUNET_NAMESTORE_QueueEntry * 1079struct GNUNET_NAMESTORE_QueueEntry *
1151GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h, 1080GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
1152 const struct GNUNET_CRYPTO_EccPrivateKey *pkey, 1081 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
1153 const char *name, 1082 const char *name,
1154 const struct GNUNET_NAMESTORE_RecordData *rd, 1083 unsigned int rd_count,
1155 GNUNET_NAMESTORE_ContinuationWithStatus cont, 1084 const struct GNUNET_NAMESTORE_RecordData *rd,
1156 void *cont_cls) 1085 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1086 void *cont_cls)
1157{ 1087{
1158 struct GNUNET_NAMESTORE_QueueEntry *qe; 1088 struct GNUNET_NAMESTORE_QueueEntry *qe;
1159 struct PendingMessage *pe; 1089 struct PendingMessage *pe;
@@ -1171,19 +1101,14 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
1171 GNUNET_assert (NULL != h); 1101 GNUNET_assert (NULL != h);
1172 GNUNET_assert (NULL != pkey); 1102 GNUNET_assert (NULL != pkey);
1173 GNUNET_assert (NULL != name); 1103 GNUNET_assert (NULL != name);
1174 GNUNET_assert (NULL != rd);
1175 LOG (GNUNET_ERROR_TYPE_DEBUG,
1176 "Creating record of type %u under name `%s'\n",
1177 rd->record_type,
1178 name);
1179 name_len = strlen(name) + 1; 1104 name_len = strlen(name) + 1;
1180 if (name_len > MAX_NAME_LEN) 1105 if (name_len > MAX_NAME_LEN)
1181 { 1106 {
1182 GNUNET_break (0); 1107 GNUNET_break (0);
1183 return NULL; 1108 return NULL;
1184 } 1109 }
1185 rid = get_op_id(h); 1110 rid = get_op_id (h);
1186 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); 1111 qe = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1187 qe->nsh = h; 1112 qe->nsh = h;
1188 qe->cont = cont; 1113 qe->cont = cont;
1189 qe->cont_cls = cont_cls; 1114 qe->cont_cls = cont_cls;
@@ -1195,9 +1120,9 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
1195 1120
1196 /* setup msg */ 1121 /* setup msg */
1197 key_len = ntohs (pkey_enc->size); 1122 key_len = ntohs (pkey_enc->size);
1198 rd_ser_len = GNUNET_NAMESTORE_records_get_size(1, rd); 1123 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1199 msg_size = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len; 1124 msg_size = sizeof (struct RecordCreateMessage) + key_len + name_len + rd_ser_len;
1200 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); 1125 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1201 pe->size = msg_size; 1126 pe->size = msg_size;
1202 pe->is_init = GNUNET_NO; 1127 pe->is_init = GNUNET_NO;
1203 msg = (struct RecordCreateMessage *) &pe[1]; 1128 msg = (struct RecordCreateMessage *) &pe[1];
@@ -1205,114 +1130,21 @@ GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
1205 msg->gns_header.header.size = htons (msg_size); 1130 msg->gns_header.header.size = htons (msg_size);
1206 msg->gns_header.r_id = htonl (rid); 1131 msg->gns_header.r_id = htonl (rid);
1207 msg->name_len = htons (name_len); 1132 msg->name_len = htons (name_len);
1208 msg->rd_count = htons (1);
1209 msg->rd_len = htons (rd_ser_len);
1210 msg->pkey_len = htons (key_len);
1211 msg->expire = GNUNET_TIME_absolute_hton(GNUNET_TIME_UNIT_FOREVER_ABS);
1212 pkey_tmp = (char *) &msg[1];
1213 memcpy (pkey_tmp, pkey_enc, key_len);
1214 name_tmp = &pkey_tmp[key_len];
1215 memcpy (name_tmp, name, name_len);
1216 rd_ser = &name_tmp[name_len];
1217 GNUNET_NAMESTORE_records_serialize(1, rd, rd_ser_len, rd_ser);
1218
1219 GNUNET_free (pkey_enc);
1220
1221 LOG (GNUNET_ERROR_TYPE_DEBUG,
1222 "Sending `%s' message for name `%s' with size %u\n",
1223 "NAMESTORE_RECORD_CREATE", name, msg_size);
1224 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1225 do_transmit(h);
1226 return qe;
1227}
1228
1229
1230/**
1231 * Explicitly remove some content from the database. The
1232 * "cont"inuation will be called with status "GNUNET_OK" if content
1233 * was removed, "GNUNET_NO" if no matching entry was found and
1234 * "GNUNET_SYSERR" on all other types of errors.
1235 * This API is used by the authority of a zone.
1236 *
1237 * @param h handle to the namestore
1238 * @param pkey private key of the zone
1239 * @param name name that is being mapped (at most 255 characters long)
1240 * @param rd record data, remove specific record, NULL to remove the name and all records
1241 * @param cont continuation to call when done
1242 * @param cont_cls closure for cont
1243 * @return handle to abort the request
1244 */
1245struct GNUNET_NAMESTORE_QueueEntry *
1246GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
1247 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
1248 const char *name,
1249 const struct GNUNET_NAMESTORE_RecordData *rd,
1250 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1251 void *cont_cls)
1252{
1253 struct GNUNET_NAMESTORE_QueueEntry *qe;
1254 struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded *pkey_enc;
1255 struct PendingMessage *pe;
1256 struct RecordRemoveMessage * msg;
1257 char *pkey_tmp;
1258 char *rd_ser;
1259 char *name_tmp;
1260 size_t rd_ser_len;
1261 size_t msg_size;
1262 size_t name_len;
1263 size_t key_len;
1264 uint32_t rid;
1265 uint16_t rd_count;
1266
1267 GNUNET_assert (NULL != h);
1268 if (NULL != rd)
1269 LOG (GNUNET_ERROR_TYPE_DEBUG,
1270 "Removing record of type %u under name `%s'\n",
1271 rd->record_type,
1272 name);
1273 else
1274 LOG (GNUNET_ERROR_TYPE_DEBUG,
1275 "Removing all records under name `%s'\n",
1276 name);
1277 rid = get_op_id(h);
1278 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
1279 qe->nsh = h;
1280 qe->cont = cont;
1281 qe->cont_cls = cont_cls;
1282 qe->op_id = rid;
1283 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1284
1285 pkey_enc = GNUNET_CRYPTO_ecc_encode_key (pkey);
1286 GNUNET_assert (NULL != pkey_enc);
1287 key_len = ntohs (pkey_enc->size);
1288
1289 rd_count = (NULL == rd) ? 0 : 1;
1290 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1291 name_len = strlen (name) + 1;
1292 msg_size = sizeof (struct RecordRemoveMessage) + key_len + name_len + rd_ser_len;
1293 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1294 pe->size = msg_size;
1295 pe->is_init = GNUNET_NO;
1296 msg = (struct RecordRemoveMessage *) &pe[1];
1297 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE);
1298 msg->gns_header.header.size = htons (msg_size);
1299 msg->gns_header.r_id = htonl (rid);
1300 msg->name_len = htons (name_len);
1301 msg->rd_len = htons (rd_ser_len);
1302 msg->rd_count = htons (rd_count); 1133 msg->rd_count = htons (rd_count);
1134 msg->rd_len = htons (rd_ser_len);
1303 msg->pkey_len = htons (key_len); 1135 msg->pkey_len = htons (key_len);
1136 msg->expire = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1304 pkey_tmp = (char *) &msg[1]; 1137 pkey_tmp = (char *) &msg[1];
1305 memcpy (pkey_tmp, pkey_enc, key_len); 1138 memcpy (pkey_tmp, pkey_enc, key_len);
1306 name_tmp = &pkey_tmp[key_len]; 1139 name_tmp = &pkey_tmp[key_len];
1307 memcpy (name_tmp, name, name_len); 1140 memcpy (name_tmp, name, name_len);
1308 rd_ser = &name_tmp[name_len]; 1141 rd_ser = &name_tmp[name_len];
1309 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser); 1142 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser);
1310
1311 GNUNET_free (pkey_enc); 1143 GNUNET_free (pkey_enc);
1312 1144
1313 LOG (GNUNET_ERROR_TYPE_DEBUG, 1145 LOG (GNUNET_ERROR_TYPE_DEBUG,
1314 "Sending `%s' message for name `%s' with size %u\n", 1146 "Sending `%s' message for name `%s' with size %u\n",
1315 "NAMESTORE_RECORD_REMOVE", name, msg_size); 1147 "NAMESTORE_RECORD_CREATE", name, msg_size);
1316 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1148 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1317 do_transmit(h); 1149 do_transmit(h);
1318 return qe; 1150 return qe;
@@ -1507,7 +1339,7 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1507 { 1339 {
1508 LOG (GNUNET_ERROR_TYPE_DEBUG, 1340 LOG (GNUNET_ERROR_TYPE_DEBUG,
1509 "Sending `%s' message for zone `%s'\n", 1341 "Sending `%s' message for zone `%s'\n",
1510 "ZONE_ITERATION_START", GNUNET_short_h2s(zone)); 1342 "ZONE_ITERATION_START", GNUNET_NAMESTORE_short_h2s(zone));
1511 msg->zone = *zone; 1343 msg->zone = *zone;
1512 } 1344 }
1513 else 1345 else
@@ -1582,7 +1414,7 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1582 msg->gns_header.r_id = htonl (it->op_id); 1414 msg->gns_header.r_id = htonl (it->op_id);
1583 if (GNUNET_YES == it->has_zone) 1415 if (GNUNET_YES == it->has_zone)
1584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1585 "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_short_h2s(&it->zone)); 1417 "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_NAMESTORE_short_h2s(&it->zone));
1586 else 1418 else
1587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1588 "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP"); 1420 "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");
@@ -1608,4 +1440,5 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
1608 GNUNET_free(qe); 1440 GNUNET_free(qe);
1609} 1441}
1610 1442
1443
1611/* end of namestore_api.c */ 1444/* end of namestore_api.c */
diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_api_common.c
index 826eae504..ab2506611 100644
--- a/src/namestore/namestore_common.c
+++ b/src/namestore/namestore_api_common.c
@@ -96,7 +96,7 @@ GNUNET_NAMESTORE_normalize_string (const char *src)
96 * @return string form; will be overwritten by next call to GNUNET_h2s. 96 * @return string form; will be overwritten by next call to GNUNET_h2s.
97 */ 97 */
98const char * 98const char *
99GNUNET_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc) 99GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc)
100{ 100{
101 static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret; 101 static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret;
102 102
diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c
new file mode 100644
index 000000000..4c242d17d
--- /dev/null
+++ b/src/namestore/namestore_api_monitor.c
@@ -0,0 +1,79 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file namestore/namestore_api_monitor.c
23 * @brief API to monitor changes in the NAMESTORE
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_crypto_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_dnsparser_lib.h"
32#include "gnunet_arm_service.h"
33#include "gnunet_signatures.h"
34#include "gnunet_namestore_service.h"
35#include "namestore.h"
36
37
38
39/**
40 * Handle for a monitoring activity.
41 */
42struct GNUNET_NAMESTORE_ZoneMonitor
43{
44};
45
46
47/**
48 * Begin monitoring a zone for changes. Will first call the 'monitor' function
49 * on all existing records in the selected zone(s) and then call it whenever
50 * a record changes.
51 *
52 * @param cfg configuration to use to connect to namestore
53 * @param zone zone to monitor, NULL for all zones
54 * @param monitor function to call on zone changes
55 * @param monitor_cls closure for 'monitor'
56 * @return handle to stop monitoring
57 */
58struct GNUNET_NAMESTORE_ZoneMonitor *
59GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
60 const struct GNUNET_CRYPTO_ShortHashCode *zone,
61 GNUNET_NAMESTORE_RecordMonitor monitor,
62 void *monitor_cls)
63{
64 GNUNET_break (0);
65 return NULL;
66}
67
68
69/**
70 * Stop monitoring a zone for changes.
71 *
72 * @param zm handle to the monitor activity to stop
73 */
74void
75GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
76{
77}
78
79/* end of namestore_api_monitor.c */
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index f0b801d1e..806debae4 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -683,7 +683,7 @@ namestore_sqlite_iterate_records (void *cls,
683 &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode), 683 &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
684 SQLITE_STATIC)) ) 684 SQLITE_STATIC)) )
685 { 685 {
686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ITERATE NAME HASH: `%8s'", GNUNET_short_h2s(&name_hase)); 686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ITERATE NAME HASH: `%8s'", GNUNET_NAMESTORE_short_h2s(&name_hase));
687 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 687 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
688 "sqlite3_bind_XXXX"); 688 "sqlite3_bind_XXXX");
689 if (SQLITE_OK != sqlite3_reset (stmt)) 689 if (SQLITE_OK != sqlite3_reset (stmt))
diff --git a/src/namestore/test_namestore_api_create.c b/src/namestore/test_namestore_api_create.c
index 6db832149..0510a6c4b 100644
--- a/src/namestore/test_namestore_api_create.c
+++ b/src/namestore/test_namestore_api_create.c
@@ -254,7 +254,7 @@ name_lookup_initial_proc (void *cls,
254 254
255 for (c = 0; c < RECORDS; c++) 255 for (c = 0; c < RECORDS; c++)
256 { 256 {
257 if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp(&rd[c], &s_first_record[c])) 257 if (GNUNET_NO == GNUNET_NAMESTORE_records_cmp (&rd[c], &s_first_record[c]))
258 { 258 {
259 GNUNET_break (0); 259 GNUNET_break (0);
260 failed = GNUNET_YES; 260 failed = GNUNET_YES;
@@ -280,7 +280,7 @@ name_lookup_initial_proc (void *cls,
280 res = 1; 280 res = 1;
281 281
282 /* create a second record */ 282 /* create a second record */
283 s_second_record = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN); 283 s_second_record = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_RecordData) + TEST_CREATE_RECORD_DATALEN);
284 s_second_record->expiration_time = UINT64_MAX; 284 s_second_record->expiration_time = UINT64_MAX;
285 s_second_record->record_type = TEST_CREATE_RECORD_TYPE; 285 s_second_record->record_type = TEST_CREATE_RECORD_TYPE;
286 s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY; 286 s_second_record->flags = GNUNET_NAMESTORE_RF_AUTHORITY;
@@ -288,7 +288,9 @@ name_lookup_initial_proc (void *cls,
288 s_second_record->data_size = TEST_CREATE_RECORD_DATALEN; 288 s_second_record->data_size = TEST_CREATE_RECORD_DATALEN;
289 memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN); 289 memset ((char *) s_second_record->data, TEST_CREATE_RECORD_DATA, TEST_CREATE_RECORD_DATALEN);
290 290
291 GNUNET_NAMESTORE_record_create (nsh, privkey, name, s_second_record, &create_second_cont, name); 291 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, name,
292 1, s_second_record,
293 &create_second_cont, name);
292 294
293 } 295 }
294 else 296 else
@@ -375,7 +377,7 @@ run (void *cls,
375 /* create random zone hash */ 377 /* create random zone hash */
376 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone); 378 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone);
377 379
378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); 380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_NAMESTORE_short_h2s (&s_zone));
379 nsh = GNUNET_NAMESTORE_connect (cfg); 381 nsh = GNUNET_NAMESTORE_connect (cfg);
380 GNUNET_break (NULL != nsh); 382 GNUNET_break (NULL != nsh);
381 383
@@ -383,7 +385,9 @@ run (void *cls,
383 GNUNET_break (s_name != NULL); 385 GNUNET_break (s_name != NULL);
384 386
385 /* create initial record */ 387 /* create initial record */
386 GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name); 388 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name,
389 1, s_first_record,
390 &create_first_cont, s_name);
387} 391}
388 392
389 393
diff --git a/src/namestore/test_namestore_api_create_update.c b/src/namestore/test_namestore_api_create_update.c
index 5df7c4934..2d18af89e 100644
--- a/src/namestore/test_namestore_api_create_update.c
+++ b/src/namestore/test_namestore_api_create_update.c
@@ -141,7 +141,9 @@ create_identical_cont (void *cls, int32_t success, const char *emsg)
141 { 141 {
142 res = 0; 142 res = 0;
143 s_first_record->expiration_time = GNUNET_TIME_absolute_get ().abs_value; 143 s_first_record->expiration_time = GNUNET_TIME_absolute_get ().abs_value;
144 GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_updated_cont, s_name); 144 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name,
145 1, s_first_record,
146 &create_updated_cont, s_name);
145 } 147 }
146 else 148 else
147 { 149 {
@@ -162,7 +164,9 @@ create_first_cont (void *cls, int32_t success, const char *emsg)
162 { 164 {
163 res = 0; 165 res = 0;
164 /* check if record was created correct */ 166 /* check if record was created correct */
165 GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_identical_cont, s_name); 167 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name,
168 1, s_first_record,
169 &create_identical_cont, s_name);
166 } 170 }
167 else 171 else
168 { 172 {
@@ -228,7 +232,7 @@ run (void *cls,
228 /* create random zone hash */ 232 /* create random zone hash */
229 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone); 233 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone);
230 234
231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); 235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_NAMESTORE_short_h2s (&s_zone));
232 nsh = GNUNET_NAMESTORE_connect (cfg); 236 nsh = GNUNET_NAMESTORE_connect (cfg);
233 GNUNET_break (NULL != nsh); 237 GNUNET_break (NULL != nsh);
234 238
@@ -236,7 +240,9 @@ run (void *cls,
236 GNUNET_break (s_name != NULL); 240 GNUNET_break (s_name != NULL);
237 241
238 /* create initial record */ 242 /* create initial record */
239 GNUNET_NAMESTORE_record_create (nsh, privkey, s_name, s_first_record, &create_first_cont, s_name); 243 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name,
244 1, s_first_record,
245 &create_first_cont, s_name);
240} 246}
241 247
242 248
diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c
index 265a93b81..b40a935fd 100644
--- a/src/namestore/test_namestore_api_remove.c
+++ b/src/namestore/test_namestore_api_remove.c
@@ -204,7 +204,9 @@ put_cont (void *cls, int32_t success, const char *emsg)
204 res = 0; 204 res = 0;
205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name); 205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name);
206 206
207 GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &s_rd[0], &remove_cont, name); 207 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, name,
208 0, NULL,
209 &remove_cont, name);
208 } 210 }
209 else 211 else
210 { 212 {
@@ -275,7 +277,7 @@ run (void *cls,
275 /* create random zone hash */ 277 /* create random zone hash */
276 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone); 278 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone);
277 279
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_short_h2s (&s_zone)); 280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_NAMESTORE_short_h2s (&s_zone));
279 nsh = GNUNET_NAMESTORE_connect (cfg); 281 nsh = GNUNET_NAMESTORE_connect (cfg);
280 GNUNET_break (NULL != nsh); 282 GNUNET_break (NULL != nsh);
281 GNUNET_break (s_rd != NULL); 283 GNUNET_break (s_rd != NULL);
diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c
index 16586240a..c31ea8d0b 100644
--- a/src/namestore/test_namestore_api_remove_not_existing_record.c
+++ b/src/namestore/test_namestore_api_remove_not_existing_record.c
@@ -136,16 +136,9 @@ put_cont (void *cls, int32_t success, const char *emsg)
136 { 136 {
137 res = 0; 137 res = 0;
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing non existing record for `%s'\n", name); 138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing non existing record for `%s'\n", name);
139 139 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, name,
140 struct GNUNET_NAMESTORE_RecordData rd; 140 0, NULL,
141 char data[TEST_REMOVE_RECORD_DATALEN]; 141 &remove_cont, name);
142
143 rd.expiration_time = GNUNET_TIME_absolute_get().abs_value;
144 rd.record_type = TEST_REMOVE_RECORD_TYPE;
145 rd.data_size = TEST_REMOVE_RECORD_DATALEN;
146 rd.data = &data;
147
148 GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &rd, &remove_cont, name);
149 } 142 }
150 else 143 else
151 { 144 {
diff --git a/src/namestore/test_namestore_api_zone_iteration.c b/src/namestore/test_namestore_api_zone_iteration.c
index 48ac35f71..71afc359c 100644
--- a/src/namestore/test_namestore_api_zone_iteration.c
+++ b/src/namestore/test_namestore_api_zone_iteration.c
@@ -410,7 +410,9 @@ empty_zone_proc (void *cls,
410 s_rd_1 = create_record(1); 410 s_rd_1 = create_record(1);
411 et.abs_value = s_rd_1->expiration_time; 411 et.abs_value = s_rd_1->expiration_time;
412 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1); 412 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1);
413 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); 413 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_1,
414 1, s_rd_1,
415 &put_cont, NULL);
414 416
415 417
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); 418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
@@ -419,7 +421,9 @@ empty_zone_proc (void *cls,
419 421
420 et.abs_value = s_rd_2->expiration_time; 422 et.abs_value = s_rd_2->expiration_time;
421 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1); 423 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1);
422 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); 424 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_2,
425 1, s_rd_2,
426 &put_cont, NULL);
423 427
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); 428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
425 /* name in different zone */ 429 /* name in different zone */
diff --git a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c
index 53457cdaa..86871120c 100644
--- a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c
+++ b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c
@@ -182,7 +182,7 @@ zone_proc (void *cls,
182 const struct GNUNET_CRYPTO_EccSignature *signature) 182 const struct GNUNET_CRYPTO_EccSignature *signature)
183{ 183{
184 int failed = GNUNET_NO; 184 int failed = GNUNET_NO;
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_short_h2s (&zone)); 185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for zone `%s'\n", GNUNET_NAMESTORE_short_h2s (&zone));
186 if ((zone_key == NULL) && (name == NULL)) 186 if ((zone_key == NULL) && (name == NULL))
187 { 187 {
188 GNUNET_break (2 == returned_records); 188 GNUNET_break (2 == returned_records);
@@ -285,7 +285,7 @@ put_cont (void *cls, int32_t success, const char *emsg)
285 res = 1; 285 res = 1;
286 returned_records = 0; 286 returned_records = 0;
287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over zone `%s'\n", 287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All records created, starting iteration over zone `%s'\n",
288 GNUNET_short_h2s(&zone)); 288 GNUNET_NAMESTORE_short_h2s(&zone));
289 zi = GNUNET_NAMESTORE_zone_iteration_start(nsh, 289 zi = GNUNET_NAMESTORE_zone_iteration_start(nsh,
290 &zone, 290 &zone,
291 GNUNET_NAMESTORE_RF_NONE, 291 GNUNET_NAMESTORE_RF_NONE,
@@ -356,14 +356,18 @@ run (void *cls,
356 s_rd_1 = create_record(1); 356 s_rd_1 = create_record(1);
357 et.abs_value = s_rd_1[0].expiration_time; 357 et.abs_value = s_rd_1[0].expiration_time;
358 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1); 358 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1);
359 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); 359 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_1,
360 1, s_rd_1,
361 &put_cont, NULL);
360 362
361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); 363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
362 GNUNET_asprintf(&s_name_2, "dummy2"); 364 GNUNET_asprintf(&s_name_2, "dummy2");
363 s_rd_2 = create_record(1); 365 s_rd_2 = create_record(1);
364 et.abs_value = s_rd_2[0].expiration_time; 366 et.abs_value = s_rd_2[0].expiration_time;
365 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1); 367 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1);
366 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); 368 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_2,
369 1, s_rd_2,
370 &put_cont, NULL);
367 371
368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); 372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
369 /* name in different zone */ 373 /* name in different zone */
@@ -371,7 +375,8 @@ run (void *cls,
371 s_rd_3 = create_record(1); 375 s_rd_3 = create_record(1);
372 et.abs_value = s_rd_3[0].expiration_time; 376 et.abs_value = s_rd_3[0].expiration_time;
373 sig_3 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_3, s_rd_3, 1); 377 sig_3 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_3, s_rd_3, 1);
374 GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3, GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL); 378 GNUNET_NAMESTORE_record_put (nsh, &pubkey2, s_name_3,
379 GNUNET_TIME_UNIT_FOREVER_ABS, 1, s_rd_3, sig_3, &put_cont, NULL);
375} 380}
376 381
377 382
diff --git a/src/namestore/test_namestore_api_zone_iteration_stop.c b/src/namestore/test_namestore_api_zone_iteration_stop.c
index 666e09ee8..9c1829e91 100644
--- a/src/namestore/test_namestore_api_zone_iteration_stop.c
+++ b/src/namestore/test_namestore_api_zone_iteration_stop.c
@@ -407,7 +407,8 @@ run (void *cls,
407 s_rd_1 = create_record(1); 407 s_rd_1 = create_record(1);
408 et.abs_value = s_rd_1[0].expiration_time; 408 et.abs_value = s_rd_1[0].expiration_time;
409 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1); 409 sig_1 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_1, s_rd_1, 1);
410 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_1, s_rd_1, &put_cont, NULL); 410 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_1,
411 1, s_rd_1, &put_cont, NULL);
411 412
412 413
413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n"); 414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 2 \n");
@@ -416,7 +417,8 @@ run (void *cls,
416 417
417 et.abs_value = s_rd_2[0].expiration_time; 418 et.abs_value = s_rd_2[0].expiration_time;
418 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1); 419 sig_2 = GNUNET_NAMESTORE_create_signature(privkey, et, s_name_2, s_rd_2, 1);
419 GNUNET_NAMESTORE_record_create(nsh, privkey, s_name_2, s_rd_2, &put_cont, NULL); 420 GNUNET_NAMESTORE_record_put_by_authority (nsh, privkey, s_name_2,
421 1, s_rd_2, &put_cont, NULL);
420 422
421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); 423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n");
422 /* name in different zone */ 424 /* name in different zone */
diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c
index 2734ebae8..f0b712eb9 100644
--- a/src/namestore/test_namestore_api_zone_to_name.c
+++ b/src/namestore/test_namestore_api_zone_to_name.c
@@ -184,7 +184,7 @@ run (void *cls,
184 /* zone hash */ 184 /* zone hash */
185 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone); 185 GNUNET_CRYPTO_short_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), &s_zone);
186 GNUNET_CRYPTO_short_hash (s_name, strlen (s_name) + 1, &s_zone_value); 186 GNUNET_CRYPTO_short_hash (s_name, strlen (s_name) + 1, &s_zone_value);
187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using PKEY `%s' \n", GNUNET_short_h2s (&s_zone_value)); 187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using PKEY `%s' \n", GNUNET_NAMESTORE_short_h2s (&s_zone_value));
188 188
189 struct GNUNET_NAMESTORE_RecordData rd; 189 struct GNUNET_NAMESTORE_RecordData rd;
190 rd.expiration_time = GNUNET_TIME_absolute_get().abs_value; 190 rd.expiration_time = GNUNET_TIME_absolute_get().abs_value;