aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-service-namestore.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-06-29 15:55:08 +0000
committerChristian Grothoff <christian@grothoff.org>2012-06-29 15:55:08 +0000
commit20bef67d7b8a216bd2ebaafb30dbb19770e549c2 (patch)
tree8470bed089ee511e844b726aa0a3171b54aa76fe /src/namestore/gnunet-service-namestore.c
parentb510c934e38ef0eb4ea959af5be94f4490ddb667 (diff)
downloadgnunet-20bef67d7b8a216bd2ebaafb30dbb19770e549c2.tar.gz
gnunet-20bef67d7b8a216bd2ebaafb30dbb19770e549c2.zip
-more fixes to namestore
Diffstat (limited to 'src/namestore/gnunet-service-namestore.c')
-rw-r--r--src/namestore/gnunet-service-namestore.c240
1 files changed, 146 insertions, 94 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index b8714f08d..a03f70d2a 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -24,8 +24,8 @@
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_getopt_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_service_lib.h" 28#include "gnunet_dnsparser_lib.h"
29#include "gnunet_namestore_service.h" 29#include "gnunet_namestore_service.h"
30#include "gnunet_namestore_plugin.h" 30#include "gnunet_namestore_plugin.h"
31#include "gnunet_signatures.h" 31#include "gnunet_signatures.h"
@@ -553,6 +553,7 @@ handle_lookup_name_it (void *cls,
553 struct GNUNET_NAMESTORE_CryptoContainer *cc; 553 struct GNUNET_NAMESTORE_CryptoContainer *cc;
554 struct GNUNET_CRYPTO_RsaSignature *signature_new; 554 struct GNUNET_CRYPTO_RsaSignature *signature_new;
555 struct GNUNET_TIME_Absolute e; 555 struct GNUNET_TIME_Absolute e;
556 struct GNUNET_TIME_Relative re;
556 struct GNUNET_CRYPTO_ShortHashCode zone_key_hash; 557 struct GNUNET_CRYPTO_ShortHashCode zone_key_hash;
557 struct GNUNET_HashCode long_hash; 558 struct GNUNET_HashCode long_hash;
558 char *rd_tmp; 559 char *rd_tmp;
@@ -563,79 +564,139 @@ handle_lookup_name_it (void *cls,
563 int copied_elements; 564 int copied_elements;
564 int contains_signature; 565 int contains_signature;
565 int authoritative; 566 int authoritative;
566 int c; 567 int rd_modified;
568 unsigned int c;
569
570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
571 "Found %u records under name `%s'\n",
572 rd_count,
573 name);
574 authoritative = GNUNET_NO;
575 signature_new = NULL;
576 cc = NULL;
577 if (NULL != zone_key)
578 {
579 GNUNET_CRYPTO_short_hash (zone_key,
580 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
581 &zone_key_hash);
582 GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash);
583 if (NULL != (cc = GNUNET_CONTAINER_multihashmap_get (zonekeys, &long_hash)))
584 {
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "Am authoritative for zone `%s'\n",
587 GNUNET_short_h2s (&zone_key_hash));
588 authoritative = GNUNET_YES;
589 }
590 }
567 591
568 name_len = (NULL == name) ? 0 : strlen(name) + 1;
569 copied_elements = 0; 592 copied_elements = 0;
593 rd_modified = GNUNET_NO;
570 rd_selected = NULL; 594 rd_selected = NULL;
571 /* count records to copy */ 595 /* count records to copy */
572 if (0 != lnc->record_type) 596 for (c = 0; c < rd_count; c++)
597 {
598 if ( (GNUNET_YES == authoritative) &&
599 (GNUNET_YES ==
600 GNUNET_NAMESTORE_is_expired (&rd[c]) ) )
601 {
602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
603 "Skipping expired record\n");
604 continue;
605 }
606 if ( (GNUNET_NAMESTORE_TYPE_ANY == lnc->record_type) ||
607 (rd[c].record_type == lnc->record_type) )
608 copied_elements++; /* found matching record */
609 else
610 {
611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
612 "Skipping non-mtaching record\n");
613 rd_modified = GNUNET_YES;
614 }
615 }
616 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
617 "Found %u records with type %u for name `%s' in zone `%s'\n",
618 copied_elements,
619 lnc->record_type,
620 lnc->name,
621 GNUNET_short_h2s(lnc->zone));
622 if (copied_elements > 0)
573 { 623 {
574 /* special record type needed */ 624 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData));
625 copied_elements = 0;
575 for (c = 0; c < rd_count; c++) 626 for (c = 0; c < rd_count; c++)
576 if (rd[c].record_type == lnc->record_type)
577 copied_elements++; /* found matching record */
578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
579 "Found %u records with type %u for name `%s' in zone `%s'\n",
580 copied_elements,
581 lnc->record_type,
582 lnc->name,
583 GNUNET_short_h2s(lnc->zone));
584 if (copied_elements > 0)
585 { 627 {
586 rd_selected = GNUNET_malloc (copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); 628 if ( (GNUNET_YES == authoritative) &&
587 copied_elements = 0; 629 (GNUNET_YES ==
588 for (c = 0; c < rd_count; c++) 630 GNUNET_NAMESTORE_is_expired (&rd[c])) )
631 continue;
632 if ( (GNUNET_NAMESTORE_TYPE_ANY == lnc->record_type) ||
633 (rd[c].record_type == lnc->record_type) )
589 { 634 {
590 if (rd[c].record_type == lnc->record_type) 635 if (0 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
591 { 636 {
592 /* found matching record */ 637 GNUNET_break (GNUNET_YES == authoritative);
593 rd_selected[copied_elements] = rd[c]; /* shallow copy! */ 638 rd_modified = GNUNET_YES;
594 copied_elements++; 639 re.rel_value = rd[c].expiration_time;
640 e = GNUNET_TIME_relative_to_absolute (re);
595 } 641 }
642 else
643 {
644 e.abs_value = rd[c].expiration_time;
645 }
646 /* found matching record, copy and convert flags to public format */
647 rd_selected[copied_elements] = rd[c]; /* shallow copy! */
648 rd_selected[copied_elements].expiration_time = e.abs_value;
649 if (0 != (rd_selected[copied_elements].flags &
650 (GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION | GNUNET_NAMESTORE_RF_AUTHORITY)))
651 {
652 rd_selected[copied_elements].flags &= ~ (GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION |
653 GNUNET_NAMESTORE_RF_AUTHORITY);
654 rd_modified = GNUNET_YES;
655 }
656 copied_elements++;
657 }
658 else
659 {
660 rd_modified = GNUNET_YES;
596 } 661 }
597 } 662 }
598 } 663 }
599 else 664 else
600 { 665 rd_selected = NULL;
601 copied_elements = rd_count; 666
602 rd_selected = (struct GNUNET_NAMESTORE_RecordData *) rd;
603 }
604 // FIXME: need to adjust 'rd' from relative to absolute times!
605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
606 "Found %u records for name `%s' in zone `%s'\n", 668 "Found %u matching records for name `%s' in zone `%s'\n",
607 copied_elements, 669 copied_elements,
608 lnc->name, 670 lnc->name,
609 GNUNET_short_h2s (lnc->zone)); 671 GNUNET_short_h2s (lnc->zone));
610 672 contains_signature = GNUNET_NO;
611 if ((copied_elements == rd_count) && (NULL != signature)) 673 if (copied_elements > 0)
612 contains_signature = GNUNET_YES; /* returning all records, so include signature */
613 else
614 contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */
615
616 authoritative = GNUNET_NO;
617 signature_new = NULL;
618 if ((NULL != zone_key) && (copied_elements == rd_count))
619 { 674 {
620 GNUNET_CRYPTO_short_hash (zone_key, 675 if (GNUNET_YES == authoritative)
621 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
622 &zone_key_hash);
623 GNUNET_CRYPTO_short_hash_double (&zone_key_hash, &long_hash);
624 if (NULL != (cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash)))
625 { 676 {
677 GNUNET_assert (NULL != cc);
626 e = get_block_expiration_time (rd_count, rd); 678 e = get_block_expiration_time (rd_count, rd);
627 signature_new = GNUNET_NAMESTORE_create_signature (cc->privkey, e, name, rd, rd_count); 679 signature_new = GNUNET_NAMESTORE_create_signature (cc->privkey, e, name, rd_selected, copied_elements);
628 GNUNET_assert (NULL != signature_new); 680 GNUNET_assert (NULL != signature_new);
629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
630 "Creating signature for name `%s' with %u records in zone `%s'\n", 682 "Creating signature for name `%s' with %u records in zone `%s'\n",
631 name, 683 name,
632 copied_elements, 684 copied_elements,
633 GNUNET_short_h2s(&zone_key_hash)); 685 GNUNET_short_h2s(&zone_key_hash));
634 authoritative = GNUNET_YES; 686 }
687 else
688 {
689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
690 "Not authoritative, records modified is %d, have sig is %d\n",
691 rd_modified,
692 NULL != signature);
693 if ((GNUNET_NO == rd_modified) && (NULL != signature))
694 contains_signature = GNUNET_YES; /* returning all records, so include signature */
635 } 695 }
636 } 696 }
637 697
638 rd_ser_len = GNUNET_NAMESTORE_records_get_size (copied_elements, rd_selected); 698 rd_ser_len = GNUNET_NAMESTORE_records_get_size (copied_elements, rd_selected);
699 name_len = (NULL == name) ? 0 : strlen(name) + 1;
639 r_size = sizeof (struct LookupNameResponseMessage) + 700 r_size = sizeof (struct LookupNameResponseMessage) +
640 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + 701 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
641 name_len + 702 name_len +
@@ -656,13 +717,12 @@ handle_lookup_name_it (void *cls,
656 memcpy (name_tmp, name, name_len); 717 memcpy (name_tmp, name, name_len);
657 rd_tmp = &name_tmp[name_len]; 718 rd_tmp = &name_tmp[name_len];
658 GNUNET_NAMESTORE_records_serialize (copied_elements, rd_selected, rd_ser_len, rd_tmp); 719 GNUNET_NAMESTORE_records_serialize (copied_elements, rd_selected, rd_ser_len, rd_tmp);
659
660 if (rd_selected != rd) 720 if (rd_selected != rd)
661 GNUNET_free_non_null (rd_selected); 721 GNUNET_free_non_null (rd_selected);
662
663 if (NULL != zone_key) 722 if (NULL != zone_key)
664 lnr_msg->public_key = *zone_key; 723 lnr_msg->public_key = *zone_key;
665 if (GNUNET_YES == authoritative) 724 if ( (GNUNET_YES == authoritative) &&
725 (copied_elements > 0) )
666 { 726 {
667 /* use new created signature */ 727 /* use new created signature */
668 lnr_msg->contains_sig = htons (GNUNET_YES); 728 lnr_msg->contains_sig = htons (GNUNET_YES);
@@ -957,35 +1017,31 @@ handle_create_record_it (void *cls,
957 update = GNUNET_NO; 1017 update = GNUNET_NO;
958 for (c = 0; c < rd_count; c++) 1018 for (c = 0; c < rd_count; c++)
959 { 1019 {
960 if (crc->rd->record_type != rd[c].record_type) 1020 if ( (crc->rd->record_type != rd[c].record_type) ||
1021 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
1022 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) )
961 continue; /* no match */ 1023 continue; /* no match */
962 if ( (GNUNET_NAMESTORE_TYPE_PKEY == crc->rd->record_type) || 1024 if ( (GNUNET_NAMESTORE_TYPE_PKEY == crc->rd->record_type) ||
963 (GNUNET_NAMESTORE_TYPE_PSEU == crc->rd->record_type) ) 1025 (GNUNET_NAMESTORE_TYPE_PSEU == crc->rd->record_type) ||
1026 (GNUNET_DNSPARSER_TYPE_CNAME == crc->rd->record_type) )
964 { 1027 {
965 /* Update unique PKEY or PSEU */ 1028 /* Update unique PKEY, PSEU or CNAME record; for these
966 /* FIXME: should we do this test here? Is this not something 1029 record types, only one can be active at any time */
967 that should be handled closer to the UI? If not, what
968 about othrer 'unique' record types like CNAME? */
969 exist = c; 1030 exist = c;
970 if ( (crc->rd->data_size != rd[c].data_size) || 1031 if ( (crc->rd->data_size != rd[c].data_size) ||
971 (0 != memcmp (crc->rd->data, rd[c].data, rd[c].data_size)) || 1032 (0 != memcmp (crc->rd->data, rd[c].data, rd[c].data_size)) ||
972 (crc->rd->expiration_time != rd[c].expiration_time) || 1033 (crc->rd->expiration_time != rd[c].expiration_time) )
973 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
974 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) )
975 update = GNUNET_YES; 1034 update = GNUNET_YES;
976 break; 1035 break;
977 } 1036 }
978 if ( (crc->rd->data_size == rd[c].data_size) && 1037 if ( (crc->rd->data_size == rd[c].data_size) &&
979 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size))) 1038 (0 == memcmp (crc->rd->data, rd[c].data, rd[c].data_size)))
980 { 1039 {
981 /* FIXME: again, do we need to handle this special case here? */
982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
983 "Found matching existing record for `%s'; only updating expiration date!\n", 1041 "Found matching existing record for `%s'; only updating expiration date!\n",
984 crc->name); 1042 crc->name);
985 exist = c; 1043 exist = c;
986 if ( (crc->rd->expiration_time != rd[c].expiration_time) && 1044 if (crc->rd->expiration_time != rd[c].expiration_time)
987 ((crc->rd->flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)
988 == (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION) ) )
989 update = GNUNET_YES; 1045 update = GNUNET_YES;
990 break; 1046 break;
991 } 1047 }
@@ -1682,7 +1738,7 @@ zone_iteraterate_proc (void *cls,
1682 { 1738 {
1683 // FIXME: new expiration flags need additional special treatment here! 1739 // FIXME: new expiration flags need additional special treatment here!
1684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1685 "Record %i has flags: 0x%x must have 0x%x \n", 1741 "Record %i has flags: 0x%x must have 0x%x\n",
1686 c, rd[c].flags, 1742 c, rd[c].flags,
1687 proc->zi->must_have_flags); 1743 proc->zi->must_have_flags);
1688 include = GNUNET_YES; 1744 include = GNUNET_YES;
@@ -1719,43 +1775,39 @@ zone_iteraterate_proc (void *cls,
1719 "Included %u of %u records\n", 1775 "Included %u of %u records\n",
1720 rd_count_filtered, rd_count); 1776 rd_count_filtered, rd_count);
1721 1777
1722 /* compute / obtain signature */ 1778 signature = NULL;
1723 GNUNET_CRYPTO_short_hash (zone_key, 1779 if (rd_count_filtered > 0)
1724 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1725 &zone_hash);
1726 GNUNET_CRYPTO_short_hash_double (&zone_hash, &long_hash);
1727 if (NULL != (cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash)))
1728 {
1729 expire = get_block_expiration_time (rd_count_filtered, rd_filtered);
1730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1731 "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1732 name, GNUNET_short_h2s(&zone_hash),
1733 rd_count_filtered,
1734 (unsigned long long) expire.abs_value);
1735 new_signature = GNUNET_NAMESTORE_create_signature (cc->privkey, expire, name,
1736 rd_filtered, rd_count_filtered);
1737 GNUNET_assert (NULL != signature);
1738 signature = new_signature;
1739 }
1740 else if (rd_count_filtered == rd_count)
1741 { 1780 {
1742 if (NULL != signature) 1781 /* compute / obtain signature */
1782 GNUNET_CRYPTO_short_hash (zone_key,
1783 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1784 &zone_hash);
1785 GNUNET_CRYPTO_short_hash_double (&zone_hash, &long_hash);
1786 if (NULL != (cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash)))
1743 { 1787 {
1744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1788 expire = get_block_expiration_time (rd_count_filtered, rd_filtered);
1745 "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n", 1789 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1746 name, GNUNET_short_h2s (&zone_hash), rd_count_filtered, 1790 "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1791 name, GNUNET_short_h2s(&zone_hash),
1792 rd_count_filtered,
1747 (unsigned long long) expire.abs_value); 1793 (unsigned long long) expire.abs_value);
1748 return; 1794 new_signature = GNUNET_NAMESTORE_create_signature (cc->privkey, expire, name,
1749 } 1795 rd_filtered, rd_count_filtered);
1750 } 1796 GNUNET_assert (NULL != new_signature);
1751 else 1797 signature = new_signature;
1752 { 1798 }
1753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1799 else if (rd_count_filtered == rd_count)
1754 "No signature provided for `%s'\n", 1800 {
1755 name); 1801 if (NULL != signature)
1756 signature = NULL; 1802 {
1803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1804 "Using provided signature for `%s' in zone `%s' with %u records and expiration %llu\n",
1805 name, GNUNET_short_h2s (&zone_hash), rd_count_filtered,
1806 (unsigned long long) expire.abs_value);
1807 return;
1808 }
1809 }
1757 } 1810 }
1758
1759 if (GNUNET_YES == proc->zi->has_zone) 1811 if (GNUNET_YES == proc->zi->has_zone)
1760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1761 "Sending name `%s' for iteration over zone `%s'\n", 1813 "Sending name `%s' for iteration over zone `%s'\n",