diff options
Diffstat (limited to 'src/namestore')
-rw-r--r-- | src/namestore/Makefile.am | 11 | ||||
-rw-r--r-- | src/namestore/gnunet-namestore.c | 105 | ||||
-rw-r--r-- | src/namestore/gnunet-service-namestore.c | 396 | ||||
-rw-r--r-- | src/namestore/namestore.h | 28 | ||||
-rw-r--r-- | src/namestore/namestore_api.c | 173 | ||||
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 10 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_lookup_nick.c | 4 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_lookup_public.c | 2 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_lookup_shadow.c | 2 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_lookup_shadow_filter.c | 2 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_remove.c | 2 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_remove_not_existing_record.c | 2 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_zone_to_name.c | 10 | ||||
-rwxr-xr-x | src/namestore/test_namestore_delete.sh | 10 | ||||
-rwxr-xr-x | src/namestore/test_plugin_rest_namestore.sh | 10 |
15 files changed, 556 insertions, 211 deletions
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 51708dd67..2441b864a 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am | |||
@@ -39,6 +39,7 @@ if HAVE_SQLITE | |||
39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la | 39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la |
40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ | 40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ |
41 | test_namestore_api_store_sqlite \ | 41 | test_namestore_api_store_sqlite \ |
42 | test_namestore_api_store_locking_sqlite \ | ||
42 | test_namestore_api_store_update_sqlite \ | 43 | test_namestore_api_store_update_sqlite \ |
43 | test_namestore_api_zone_iteration_sqlite \ | 44 | test_namestore_api_zone_iteration_sqlite \ |
44 | test_namestore_api_remove_sqlite \ | 45 | test_namestore_api_remove_sqlite \ |
@@ -249,6 +250,16 @@ test_namestore_api_store_sqlite_LDADD = \ | |||
249 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 250 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
250 | libgnunetnamestore.la | 251 | libgnunetnamestore.la |
251 | 252 | ||
253 | test_namestore_api_store_locking_sqlite_SOURCES = \ | ||
254 | test_namestore_api_store_locking.c | ||
255 | test_namestore_api_store_locking_sqlite_LDADD = \ | ||
256 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
257 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
258 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
259 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
260 | libgnunetnamestore.la | ||
261 | |||
262 | |||
252 | test_namestore_api_store_postgres_SOURCES = \ | 263 | test_namestore_api_store_postgres_SOURCES = \ |
253 | test_namestore_api_store.c | 264 | test_namestore_api_store.c |
254 | test_namestore_api_store_postgres_LDADD = \ | 265 | test_namestore_api_store_postgres_LDADD = \ |
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 852d99608..af40f2dbe 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c | |||
@@ -33,6 +33,12 @@ | |||
33 | #include <gnunet_gns_service.h> | 33 | #include <gnunet_gns_service.h> |
34 | #include <gnunet_namestore_service.h> | 34 | #include <gnunet_namestore_service.h> |
35 | 35 | ||
36 | /** | ||
37 | * The upper bound for the zone iteration interval | ||
38 | * (per record). | ||
39 | */ | ||
40 | #define WARN_RELATIVE_EXPIRATION_LIMIT GNUNET_TIME_relative_multiply ( \ | ||
41 | GNUNET_TIME_UNIT_MINUTES, 15) | ||
36 | 42 | ||
37 | /** | 43 | /** |
38 | * Entry in record set for bulk processing. | 44 | * Entry in record set for bulk processing. |
@@ -430,6 +436,8 @@ display_record (const char *rname, | |||
430 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 436 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && |
431 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) | 437 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) |
432 | continue; | 438 | continue; |
439 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
440 | continue; | ||
433 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) | 441 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) |
434 | continue; | 442 | continue; |
435 | have_record = GNUNET_YES; | 443 | have_record = GNUNET_YES; |
@@ -447,6 +455,8 @@ display_record (const char *rname, | |||
447 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 455 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && |
448 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) | 456 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) |
449 | continue; | 457 | continue; |
458 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
459 | continue; | ||
450 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) | 460 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) |
451 | continue; | 461 | continue; |
452 | typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); | 462 | typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); |
@@ -649,28 +659,6 @@ get_existing_record (void *cls, | |||
649 | { | 659 | { |
650 | switch (rd[i].record_type) | 660 | switch (rd[i].record_type) |
651 | { | 661 | { |
652 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
653 | fprintf ( | ||
654 | stderr, | ||
655 | _ ( | ||
656 | "A %s record exists already under `%s', no other records can be added.\n"), | ||
657 | "CNAME", | ||
658 | rec_name); | ||
659 | ret = 1; | ||
660 | test_finished (); | ||
661 | return; | ||
662 | |||
663 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
664 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
665 | fprintf ( | ||
666 | stderr, | ||
667 | _ ( | ||
668 | "A zone key record exists already under `%s', no other records can be added.\n"), | ||
669 | rec_name); | ||
670 | ret = 1; | ||
671 | test_finished (); | ||
672 | return; | ||
673 | |||
674 | case GNUNET_DNSPARSER_TYPE_SOA: | 662 | case GNUNET_DNSPARSER_TYPE_SOA: |
675 | if (GNUNET_DNSPARSER_TYPE_SOA == type) | 663 | if (GNUNET_DNSPARSER_TYPE_SOA == type) |
676 | { | 664 | { |
@@ -686,51 +674,6 @@ get_existing_record (void *cls, | |||
686 | break; | 674 | break; |
687 | } | 675 | } |
688 | } | 676 | } |
689 | switch (type) | ||
690 | { | ||
691 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
692 | if (0 != rd_count) | ||
693 | { | ||
694 | fprintf (stderr, | ||
695 | _ ( | ||
696 | "Records already exist under `%s', cannot add `%s' record.\n"), | ||
697 | rec_name, | ||
698 | "CNAME"); | ||
699 | ret = 1; | ||
700 | test_finished (); | ||
701 | return; | ||
702 | } | ||
703 | break; | ||
704 | |||
705 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
706 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
707 | if (0 != rd_count) | ||
708 | { | ||
709 | fprintf (stderr, | ||
710 | _ ( | ||
711 | "Records already exist under `%s', cannot add record.\n"), | ||
712 | rec_name); | ||
713 | ret = 1; | ||
714 | test_finished (); | ||
715 | return; | ||
716 | } | ||
717 | break; | ||
718 | |||
719 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | ||
720 | for (unsigned int i = 0; i < rd_count; i++) | ||
721 | if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type) | ||
722 | { | ||
723 | fprintf ( | ||
724 | stderr, | ||
725 | _ ( | ||
726 | "Non-GNS2DNS records already exist under `%s', cannot add GNS2DNS record.\n"), | ||
727 | rec_name); | ||
728 | ret = 1; | ||
729 | test_finished (); | ||
730 | return; | ||
731 | } | ||
732 | break; | ||
733 | } | ||
734 | memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data)); | 677 | memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data)); |
735 | GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data)); | 678 | GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data)); |
736 | rde = &rdn[0]; | 679 | rde = &rdn[0]; |
@@ -929,6 +872,13 @@ parse_expiration (const char *expirationstring, | |||
929 | { | 872 | { |
930 | *etime_is_rel = GNUNET_YES; | 873 | *etime_is_rel = GNUNET_YES; |
931 | *etime = etime_rel.rel_value_us; | 874 | *etime = etime_rel.rel_value_us; |
875 | if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT)) | ||
876 | { | ||
877 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
878 | "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n", | ||
879 | GNUNET_STRINGS_relative_time_to_string ( | ||
880 | WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO)); | ||
881 | } | ||
932 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
933 | "Storing record with relative expiration time of %s\n", | 883 | "Storing record with relative expiration time of %s\n", |
934 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); | 884 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); |
@@ -1212,8 +1162,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1212 | char sname[64]; | 1162 | char sname[64]; |
1213 | struct GNUNET_IDENTITY_PublicKey pkey; | 1163 | struct GNUNET_IDENTITY_PublicKey pkey; |
1214 | 1164 | ||
1215 | memset(sh, 0, 105); | 1165 | memset (sh, 0, 105); |
1216 | memset(sname, 0, 64); | 1166 | memset (sname, 0, 64); |
1217 | 1167 | ||
1218 | if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) || | 1168 | if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) || |
1219 | (GNUNET_OK != | 1169 | (GNUNET_OK != |
@@ -1286,15 +1236,6 @@ identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | |||
1286 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 1236 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
1287 | 1237 | ||
1288 | el = NULL; | 1238 | el = NULL; |
1289 | if ((NULL != name) && (0 != strchr (name, '.'))) | ||
1290 | { | ||
1291 | fprintf (stderr, | ||
1292 | _ ("Label `%s' contains `.' which is not allowed\n"), | ||
1293 | name); | ||
1294 | GNUNET_SCHEDULER_shutdown (); | ||
1295 | ret = -1; | ||
1296 | return; | ||
1297 | } | ||
1298 | 1239 | ||
1299 | if (NULL == ego) | 1240 | if (NULL == ego) |
1300 | { | 1241 | { |
@@ -1705,13 +1646,13 @@ main (int argc, char *const *argv) | |||
1705 | NULL))) | 1646 | NULL))) |
1706 | { | 1647 | { |
1707 | GNUNET_free_nz ((void *) argv); | 1648 | GNUNET_free_nz ((void *) argv); |
1708 | //FIXME | 1649 | // FIXME |
1709 | //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); | 1650 | // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); |
1710 | return lret; | 1651 | return lret; |
1711 | } | 1652 | } |
1712 | GNUNET_free_nz ((void *) argv); | 1653 | GNUNET_free_nz ((void *) argv); |
1713 | //FIXME | 1654 | // FIXME |
1714 | //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); | 1655 | // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); |
1715 | return ret; | 1656 | return ret; |
1716 | } | 1657 | } |
1717 | 1658 | ||
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 9b2d9b6f3..d735822fb 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c | |||
@@ -121,6 +121,23 @@ struct ZoneIteration | |||
121 | int send_end; | 121 | int send_end; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /** | ||
125 | * Lock on a record set | ||
126 | */ | ||
127 | struct RecordsLock | ||
128 | { | ||
129 | /* DLL */ | ||
130 | struct RecordsLock *prev; | ||
131 | |||
132 | /* DLL */ | ||
133 | struct RecordsLock *next; | ||
134 | |||
135 | /* Hash of the locked label */ | ||
136 | struct GNUNET_HashCode label_hash; | ||
137 | |||
138 | /* Client locking the zone */ | ||
139 | struct NamestoreClient *client; | ||
140 | }; | ||
124 | 141 | ||
125 | /** | 142 | /** |
126 | * A namestore client | 143 | * A namestore client |
@@ -394,6 +411,16 @@ static struct StoreActivity *sa_head; | |||
394 | static struct StoreActivity *sa_tail; | 411 | static struct StoreActivity *sa_tail; |
395 | 412 | ||
396 | /** | 413 | /** |
414 | * Head of the DLL of record set locks | ||
415 | */ | ||
416 | static struct RecordsLock *locks_head; | ||
417 | |||
418 | /** | ||
419 | * Tail of the DLL of record set locks | ||
420 | */ | ||
421 | static struct RecordsLock *locks_tail; | ||
422 | |||
423 | /** | ||
397 | * Notification context shared by all monitors. | 424 | * Notification context shared by all monitors. |
398 | */ | 425 | */ |
399 | static struct GNUNET_NotificationContext *monitor_nc; | 426 | static struct GNUNET_NotificationContext *monitor_nc; |
@@ -420,6 +447,7 @@ static void | |||
420 | cleanup_task (void *cls) | 447 | cleanup_task (void *cls) |
421 | { | 448 | { |
422 | struct CacheOperation *cop; | 449 | struct CacheOperation *cop; |
450 | struct RecordsLock *lock; | ||
423 | 451 | ||
424 | (void) cls; | 452 | (void) cls; |
425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); | 453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); |
@@ -431,6 +459,14 @@ cleanup_task (void *cls) | |||
431 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | 459 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); |
432 | GNUNET_free (cop); | 460 | GNUNET_free (cop); |
433 | } | 461 | } |
462 | while (NULL != (lock = locks_head)) | ||
463 | { | ||
464 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
465 | locks_tail, | ||
466 | lock); | ||
467 | GNUNET_free (lock); | ||
468 | } | ||
469 | |||
434 | if (NULL != namecache) | 470 | if (NULL != namecache) |
435 | { | 471 | { |
436 | GNUNET_NAMECACHE_disconnect (namecache); | 472 | GNUNET_NAMECACHE_disconnect (namecache); |
@@ -808,7 +844,8 @@ send_lookup_response (struct NamestoreClient *nc, | |||
808 | * @param rid client's request ID | 844 | * @param rid client's request ID |
809 | */ | 845 | */ |
810 | static void | 846 | static void |
811 | send_store_response (struct NamestoreClient *nc, int res, uint32_t rid) | 847 | send_store_response (struct NamestoreClient *nc, int res, const char*emsg, |
848 | uint32_t rid) | ||
812 | { | 849 | { |
813 | struct GNUNET_MQ_Envelope *env; | 850 | struct GNUNET_MQ_Envelope *env; |
814 | struct RecordStoreResponseMessage *rcr_msg; | 851 | struct RecordStoreResponseMessage *rcr_msg; |
@@ -820,10 +857,17 @@ send_store_response (struct NamestoreClient *nc, int res, uint32_t rid) | |||
820 | "Store requests completed", | 857 | "Store requests completed", |
821 | 1, | 858 | 1, |
822 | GNUNET_NO); | 859 | GNUNET_NO); |
823 | env = GNUNET_MQ_msg (rcr_msg, | 860 | env = GNUNET_MQ_msg_extra (rcr_msg, |
824 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE); | 861 | (NULL != emsg) ? strlen (emsg) + 1 : 0, |
862 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE); | ||
825 | rcr_msg->gns_header.r_id = htonl (rid); | 863 | rcr_msg->gns_header.r_id = htonl (rid); |
826 | rcr_msg->op_result = htonl (res); | 864 | rcr_msg->op_result = htonl (res); |
865 | rcr_msg->reserved = htons (0); | ||
866 | if (NULL != emsg) | ||
867 | { | ||
868 | rcr_msg->emsg_len = htons (strlen (emsg) + 1); | ||
869 | memcpy (&rcr_msg[1], emsg, strlen (emsg) + 1); | ||
870 | } | ||
827 | GNUNET_MQ_send (nc->mq, env); | 871 | GNUNET_MQ_send (nc->mq, env); |
828 | } | 872 | } |
829 | 873 | ||
@@ -874,7 +918,7 @@ finish_cache_operation (void *cls, int32_t success, const char *emsg) | |||
874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); | 918 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); |
875 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | 919 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); |
876 | if (NULL != cop->nc) | 920 | if (NULL != cop->nc) |
877 | send_store_response (cop->nc, success, cop->rid); | 921 | send_store_response (cop->nc, success, emsg, cop->rid); |
878 | if (NULL != (zi = cop->zi)) | 922 | if (NULL != (zi = cop->zi)) |
879 | { | 923 | { |
880 | zi->cache_ops--; | 924 | zi->cache_ops--; |
@@ -910,29 +954,40 @@ refresh_block (struct NamestoreClient *nc, | |||
910 | const struct GNUNET_GNSRECORD_Data *rd) | 954 | const struct GNUNET_GNSRECORD_Data *rd) |
911 | { | 955 | { |
912 | struct GNUNET_GNSRECORD_Block *block; | 956 | struct GNUNET_GNSRECORD_Block *block; |
957 | struct GNUNET_GNSRECORD_Data rd_clean[rd_count]; | ||
913 | struct CacheOperation *cop; | 958 | struct CacheOperation *cop; |
914 | struct GNUNET_IDENTITY_PublicKey pkey; | 959 | struct GNUNET_IDENTITY_PublicKey pkey; |
915 | struct GNUNET_GNSRECORD_Data *nick; | 960 | struct GNUNET_GNSRECORD_Data *nick; |
916 | struct GNUNET_GNSRECORD_Data *res; | 961 | struct GNUNET_GNSRECORD_Data *res; |
917 | unsigned int res_count; | 962 | unsigned int res_count; |
963 | unsigned int rd_count_clean; | ||
918 | struct GNUNET_TIME_Absolute exp_time; | 964 | struct GNUNET_TIME_Absolute exp_time; |
919 | 965 | ||
966 | /** Do not block-cache tombstones */ | ||
967 | rd_count_clean = 0; | ||
968 | for (int i = 0; i < rd_count; i++) | ||
969 | { | ||
970 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
971 | continue; | ||
972 | rd_clean[rd_count_clean++] = rd[i]; | ||
973 | } | ||
974 | |||
920 | nick = get_nick_record (zone_key); | 975 | nick = get_nick_record (zone_key); |
921 | res_count = rd_count; | 976 | res_count = rd_count_clean; |
922 | res = (struct GNUNET_GNSRECORD_Data *) rd; /* fixme: a bit unclean... */ | 977 | res = (struct GNUNET_GNSRECORD_Data *) rd_clean; /* fixme: a bit unclean... */ |
923 | if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) | 978 | if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) |
924 | { | 979 | { |
925 | nick->flags = | 980 | nick->flags = |
926 | (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; | 981 | (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; |
927 | merge_with_nick_records (nick, rd_count, rd, &res_count, &res); | 982 | merge_with_nick_records (nick, rd_count_clean, rd_clean, &res_count, &res); |
928 | } | 983 | } |
929 | if (NULL != nick) | 984 | if (NULL != nick) |
930 | GNUNET_free (nick); | 985 | GNUNET_free (nick); |
931 | if (0 == res_count) | 986 | if (0 == res_count) |
932 | { | 987 | { |
933 | if (NULL != nc) | 988 | if (NULL != nc) |
934 | send_store_response (nc, GNUNET_OK, rid); | 989 | send_store_response (nc, GNUNET_OK, NULL, rid); |
935 | if (rd != res) | 990 | if (rd_clean != res) |
936 | GNUNET_free (res); | 991 | GNUNET_free (res); |
937 | return; /* no data, no need to update cache */ | 992 | return; /* no data, no need to update cache */ |
938 | } | 993 | } |
@@ -943,20 +998,21 @@ refresh_block (struct NamestoreClient *nc, | |||
943 | 1, | 998 | 1, |
944 | GNUNET_NO); | 999 | GNUNET_NO); |
945 | if (NULL != nc) | 1000 | if (NULL != nc) |
946 | send_store_response (nc, GNUNET_OK, rid); | 1001 | send_store_response (nc, GNUNET_OK, NULL, rid); |
947 | if (rd != res) | 1002 | if (rd_clean != res) |
948 | GNUNET_free (res); | 1003 | GNUNET_free (res); |
949 | return; | 1004 | return; |
950 | } | 1005 | } |
951 | exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res); | 1006 | exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res, |
1007 | GNUNET_TIME_UNIT_ZERO_ABS); | ||
952 | if (cache_keys) | 1008 | if (cache_keys) |
953 | GNUNET_assert (GNUNET_OK == | 1009 | GNUNET_assert (GNUNET_OK == |
954 | GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, | 1010 | GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, |
955 | res, res_count, &block)); | 1011 | res, res_count, &block)); |
956 | else | 1012 | else |
957 | GNUNET_assert (GNUNET_OK == | 1013 | GNUNET_assert (GNUNET_OK == |
958 | GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, | 1014 | GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, |
959 | res, res_count, &block)); | 1015 | res, res_count, &block)); |
960 | GNUNET_assert (NULL != block); | 1016 | GNUNET_assert (NULL != block); |
961 | GNUNET_IDENTITY_key_get_public (zone_key, &pkey); | 1017 | GNUNET_IDENTITY_key_get_public (zone_key, &pkey); |
962 | GNUNET_log ( | 1018 | GNUNET_log ( |
@@ -974,7 +1030,7 @@ refresh_block (struct NamestoreClient *nc, | |||
974 | cop->nc = nc; | 1030 | cop->nc = nc; |
975 | cop->zi = zi; | 1031 | cop->zi = zi; |
976 | if (NULL != zi) | 1032 | if (NULL != zi) |
977 | zi->cache_ops++; | 1033 | zi->cache_ops ++; |
978 | cop->rid = rid; | 1034 | cop->rid = rid; |
979 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); | 1035 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); |
980 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, | 1036 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, |
@@ -982,7 +1038,7 @@ refresh_block (struct NamestoreClient *nc, | |||
982 | &finish_cache_operation, | 1038 | &finish_cache_operation, |
983 | cop); | 1039 | cop); |
984 | GNUNET_free (block); | 1040 | GNUNET_free (block); |
985 | if (rd != res) | 1041 | if (rd_clean != res) |
986 | GNUNET_free (res); | 1042 | GNUNET_free (res); |
987 | } | 1043 | } |
988 | 1044 | ||
@@ -1098,6 +1154,7 @@ client_disconnect_cb (void *cls, | |||
1098 | struct NamestoreClient *nc = app_ctx; | 1154 | struct NamestoreClient *nc = app_ctx; |
1099 | struct ZoneIteration *no; | 1155 | struct ZoneIteration *no; |
1100 | struct CacheOperation *cop; | 1156 | struct CacheOperation *cop; |
1157 | struct RecordsLock *lock; | ||
1101 | 1158 | ||
1102 | (void) cls; | 1159 | (void) cls; |
1103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); | 1160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); |
@@ -1148,6 +1205,15 @@ client_disconnect_cb (void *cls, | |||
1148 | for (cop = cop_head; NULL != cop; cop = cop->next) | 1205 | for (cop = cop_head; NULL != cop; cop = cop->next) |
1149 | if (nc == cop->nc) | 1206 | if (nc == cop->nc) |
1150 | cop->nc = NULL; | 1207 | cop->nc = NULL; |
1208 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1209 | { | ||
1210 | if (nc != lock->client) | ||
1211 | continue; | ||
1212 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1213 | locks_tail, | ||
1214 | lock); | ||
1215 | GNUNET_free (lock); | ||
1216 | } | ||
1151 | GNUNET_free (nc); | 1217 | GNUNET_free (nc); |
1152 | } | 1218 | } |
1153 | 1219 | ||
@@ -1341,6 +1407,105 @@ check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1341 | return GNUNET_OK; | 1407 | return GNUNET_OK; |
1342 | } | 1408 | } |
1343 | 1409 | ||
1410 | static void | ||
1411 | calculate_lock_hash (const char *label, | ||
1412 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1413 | struct GNUNET_HashCode *result) | ||
1414 | { | ||
1415 | struct GNUNET_HashContext *hctx; | ||
1416 | |||
1417 | hctx = GNUNET_CRYPTO_hash_context_start (); | ||
1418 | GNUNET_CRYPTO_hash_context_read (hctx, label, strlen (label)); | ||
1419 | GNUNET_CRYPTO_hash_context_read (hctx, zone, | ||
1420 | sizeof (*zone)); | ||
1421 | GNUNET_CRYPTO_hash_context_finish (hctx, result); | ||
1422 | } | ||
1423 | |||
1424 | /** | ||
1425 | * Release a lock on a record set. | ||
1426 | * Does nothing if lock not held. | ||
1427 | * | ||
1428 | * @param label the label of the record set | ||
1429 | * @param zone the zone | ||
1430 | * @param nc the client releasing the lock | ||
1431 | */ | ||
1432 | static void | ||
1433 | NST_label_lock_release (const char *label, | ||
1434 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1435 | const struct NamestoreClient *nc) | ||
1436 | { | ||
1437 | struct GNUNET_HashCode label_hash; | ||
1438 | struct RecordsLock *lock; | ||
1439 | |||
1440 | calculate_lock_hash (label, zone, &label_hash); | ||
1441 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1442 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1443 | break; | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1445 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1446 | if (NULL == lock) | ||
1447 | return; | ||
1448 | if (lock->client != nc) | ||
1449 | { | ||
1450 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1451 | "Lock is held by other client on `%s'\n", label); | ||
1452 | return; | ||
1453 | } | ||
1454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1455 | "Unocking %s\n", GNUNET_h2s (&label_hash)); | ||
1456 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1457 | locks_tail, | ||
1458 | lock); | ||
1459 | GNUNET_free (lock); | ||
1460 | } | ||
1461 | |||
1462 | /** | ||
1463 | * Get/set a lock on a record set. | ||
1464 | * May be called multiple times but will | ||
1465 | * not aquire additional locks. | ||
1466 | * | ||
1467 | * @param the label of the record set | ||
1468 | * @param the zone | ||
1469 | * @param the client doing the locking | ||
1470 | * @return GNUNET_YES if lock retrieved or set already. | ||
1471 | */ | ||
1472 | static enum GNUNET_GenericReturnValue | ||
1473 | NST_label_lock (const char *label, | ||
1474 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1475 | struct NamestoreClient *nc) | ||
1476 | { | ||
1477 | struct GNUNET_HashCode label_hash; | ||
1478 | struct RecordsLock *lock; | ||
1479 | |||
1480 | calculate_lock_hash (label, zone, &label_hash); | ||
1481 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1482 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1483 | break; | ||
1484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1485 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1486 | if (NULL != lock) | ||
1487 | { | ||
1488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1489 | "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes"); | ||
1490 | if (lock->client != nc) | ||
1491 | { | ||
1492 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1493 | "Lock is held by other client on `%s'\n", label); | ||
1494 | return GNUNET_NO; | ||
1495 | } | ||
1496 | return GNUNET_YES; | ||
1497 | } | ||
1498 | lock = GNUNET_new (struct RecordsLock); | ||
1499 | lock->client = nc; | ||
1500 | memcpy (&lock->label_hash, &label_hash, sizeof (label_hash)); | ||
1501 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1502 | "Locking %s\n", GNUNET_h2s (&label_hash)); | ||
1503 | GNUNET_CONTAINER_DLL_insert (locks_head, | ||
1504 | locks_tail, | ||
1505 | lock); | ||
1506 | return GNUNET_YES; | ||
1507 | } | ||
1508 | |||
1344 | 1509 | ||
1345 | /** | 1510 | /** |
1346 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message | 1511 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message |
@@ -1355,13 +1520,14 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1355 | struct GNUNET_MQ_Envelope *env; | 1520 | struct GNUNET_MQ_Envelope *env; |
1356 | struct LabelLookupResponseMessage *llr_msg; | 1521 | struct LabelLookupResponseMessage *llr_msg; |
1357 | struct RecordLookupContext rlc; | 1522 | struct RecordLookupContext rlc; |
1523 | struct RecordsLock *lock; | ||
1524 | struct GNUNET_HashCode label_hash; | ||
1358 | const char *name_tmp; | 1525 | const char *name_tmp; |
1359 | char *res_name; | 1526 | char *res_name; |
1360 | char *conv_name; | 1527 | char *conv_name; |
1361 | uint32_t name_len; | 1528 | uint32_t name_len; |
1362 | int res; | 1529 | int res; |
1363 | 1530 | ||
1364 | name_len = ntohl (ll_msg->label_len); | ||
1365 | name_tmp = (const char *) &ll_msg[1]; | 1531 | name_tmp = (const char *) &ll_msg[1]; |
1366 | GNUNET_SERVICE_client_continue (nc->client); | 1532 | GNUNET_SERVICE_client_continue (nc->client); |
1367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1533 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1377,6 +1543,29 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1377 | GNUNET_SERVICE_client_drop (nc->client); | 1543 | GNUNET_SERVICE_client_drop (nc->client); |
1378 | return; | 1544 | return; |
1379 | } | 1545 | } |
1546 | name_len = strlen (conv_name) + 1; | ||
1547 | if (GNUNET_YES == ntohl (ll_msg->locking)) | ||
1548 | { | ||
1549 | if (GNUNET_NO == NST_label_lock (conv_name, &ll_msg->zone, nc)) | ||
1550 | { | ||
1551 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1552 | "Lock is held by other client on `%s'\n", conv_name); | ||
1553 | env = | ||
1554 | GNUNET_MQ_msg_extra (llr_msg, | ||
1555 | name_len, | ||
1556 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE); | ||
1557 | llr_msg->gns_header.r_id = ll_msg->gns_header.r_id; | ||
1558 | llr_msg->private_key = ll_msg->zone; | ||
1559 | llr_msg->name_len = htons (name_len); | ||
1560 | llr_msg->rd_count = htons (0); | ||
1561 | llr_msg->rd_len = htons (0); | ||
1562 | llr_msg->found = htons (GNUNET_SYSERR); | ||
1563 | GNUNET_memcpy (&llr_msg[1], conv_name, name_len); | ||
1564 | GNUNET_MQ_send (nc->mq, env); | ||
1565 | GNUNET_free (conv_name); | ||
1566 | return; | ||
1567 | } | ||
1568 | } | ||
1380 | rlc.label = conv_name; | 1569 | rlc.label = conv_name; |
1381 | rlc.found = GNUNET_NO; | 1570 | rlc.found = GNUNET_NO; |
1382 | rlc.res_rd_count = 0; | 1571 | rlc.res_rd_count = 0; |
@@ -1388,7 +1577,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1388 | conv_name, | 1577 | conv_name, |
1389 | &lookup_it, | 1578 | &lookup_it, |
1390 | &rlc); | 1579 | &rlc); |
1391 | GNUNET_free (conv_name); | ||
1392 | env = | 1580 | env = |
1393 | GNUNET_MQ_msg_extra (llr_msg, | 1581 | GNUNET_MQ_msg_extra (llr_msg, |
1394 | name_len + rlc.rd_ser_len, | 1582 | name_len + rlc.rd_ser_len, |
@@ -1400,16 +1588,18 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1400 | llr_msg->rd_len = htons (rlc.rd_ser_len); | 1588 | llr_msg->rd_len = htons (rlc.rd_ser_len); |
1401 | res_name = (char *) &llr_msg[1]; | 1589 | res_name = (char *) &llr_msg[1]; |
1402 | if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res)) | 1590 | if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res)) |
1403 | llr_msg->found = ntohs (GNUNET_YES); | 1591 | llr_msg->found = htons (GNUNET_YES); |
1404 | else | 1592 | else |
1405 | llr_msg->found = ntohs (GNUNET_NO); | 1593 | llr_msg->found = htons (GNUNET_NO); |
1406 | GNUNET_memcpy (&llr_msg[1], name_tmp, name_len); | 1594 | GNUNET_memcpy (&llr_msg[1], conv_name, name_len); |
1407 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); | 1595 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); |
1408 | GNUNET_MQ_send (nc->mq, env); | 1596 | GNUNET_MQ_send (nc->mq, env); |
1409 | GNUNET_free (rlc.res_rd); | 1597 | GNUNET_free (rlc.res_rd); |
1598 | GNUNET_free (conv_name); | ||
1410 | } | 1599 | } |
1411 | 1600 | ||
1412 | 1601 | ||
1602 | |||
1413 | /** | 1603 | /** |
1414 | * Checks a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message | 1604 | * Checks a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message |
1415 | * | 1605 | * |
@@ -1452,6 +1642,45 @@ check_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1452 | 1642 | ||
1453 | 1643 | ||
1454 | /** | 1644 | /** |
1645 | * Check if set contains a tombstone, store if necessary | ||
1646 | * | ||
1647 | * @param cls a `struct GNUNET_GNSRECORD_Data **` for storing the nick (if found) | ||
1648 | * @param seq sequence number of the record, MUST NOT BE ZERO | ||
1649 | * @param private_key the private key of the zone (unused) | ||
1650 | * @param label should be #GNUNET_GNS_EMPTY_LABEL_AT | ||
1651 | * @param rd_count number of records in @a rd | ||
1652 | * @param rd records stored under @a label in the zone | ||
1653 | */ | ||
1654 | static void | ||
1655 | get_block_exp_existing (void *cls, | ||
1656 | uint64_t seq, | ||
1657 | const struct | ||
1658 | GNUNET_IDENTITY_PrivateKey *private_key, | ||
1659 | const char *label, | ||
1660 | unsigned int rd_count, | ||
1661 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1662 | { | ||
1663 | struct GNUNET_TIME_Absolute *exp = cls; | ||
1664 | struct GNUNET_GNSRECORD_Data rd_pub[rd_count]; | ||
1665 | unsigned int rd_pub_count; | ||
1666 | char *emsg; | ||
1667 | |||
1668 | if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label, | ||
1669 | rd, | ||
1670 | rd_count, | ||
1671 | rd_pub, | ||
1672 | &rd_pub_count, | ||
1673 | exp, | ||
1674 | &emsg)) | ||
1675 | { | ||
1676 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1677 | "%s\n", emsg); | ||
1678 | GNUNET_free (emsg); | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | |||
1683 | /** | ||
1455 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message | 1684 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message |
1456 | * | 1685 | * |
1457 | * @param cls client sending the message | 1686 | * @param cls client sending the message |
@@ -1470,37 +1699,75 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1470 | unsigned int rd_count; | 1699 | unsigned int rd_count; |
1471 | int res; | 1700 | int res; |
1472 | struct StoreActivity *sa; | 1701 | struct StoreActivity *sa; |
1702 | struct RecordsLock *lock; | ||
1703 | struct GNUNET_HashCode label_hash; | ||
1704 | struct GNUNET_TIME_Absolute existing_block_exp; | ||
1705 | struct GNUNET_TIME_Absolute new_block_exp; | ||
1473 | 1706 | ||
1474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1707 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1475 | "Received NAMESTORE_RECORD_STORE message\n"); | 1708 | "Received NAMESTORE_RECORD_STORE message\n"); |
1709 | existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | ||
1710 | new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | ||
1476 | rid = ntohl (rp_msg->gns_header.r_id); | 1711 | rid = ntohl (rp_msg->gns_header.r_id); |
1477 | name_len = ntohs (rp_msg->name_len); | 1712 | name_len = ntohs (rp_msg->name_len); |
1478 | rd_count = ntohs (rp_msg->rd_count); | 1713 | rd_count = ntohs (rp_msg->rd_count); |
1479 | rd_ser_len = ntohs (rp_msg->rd_len); | 1714 | rd_ser_len = ntohs (rp_msg->rd_len); |
1480 | GNUNET_break (0 == ntohs (rp_msg->reserved)); | ||
1481 | name_tmp = (const char *) &rp_msg[1]; | 1715 | name_tmp = (const char *) &rp_msg[1]; |
1482 | rd_ser = &name_tmp[name_len]; | 1716 | rd_ser = &name_tmp[name_len]; |
1483 | { | 1717 | { |
1484 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; | 1718 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; |
1485 | 1719 | char *emsg; | |
1486 | if (GNUNET_OK != | ||
1487 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd)) | ||
1488 | { | ||
1489 | GNUNET_break (0); | ||
1490 | GNUNET_SERVICE_client_drop (nc->client); | ||
1491 | return; | ||
1492 | } | ||
1493 | 1720 | ||
1494 | /* Extracting and converting private key */ | 1721 | /* Extracting and converting private key */ |
1495 | conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp); | 1722 | conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp); |
1496 | if (NULL == conv_name) | 1723 | if (NULL == conv_name) |
1497 | { | 1724 | { |
1498 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1725 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1499 | "Error converting name `%s'\n", | 1726 | "Error normalizing name `%s'\n", |
1500 | name_tmp); | 1727 | name_tmp); |
1501 | GNUNET_SERVICE_client_drop (nc->client); | 1728 | send_store_response (nc, GNUNET_SYSERR, _ ("Error normalizing name."), |
1729 | rid); | ||
1730 | GNUNET_SERVICE_client_continue (nc->client); | ||
1731 | return; | ||
1732 | } | ||
1733 | |||
1734 | /* Check name for validity */ | ||
1735 | if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg)) | ||
1736 | { | ||
1737 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1738 | "Label invalid: `%s'\n", | ||
1739 | emsg); | ||
1740 | send_store_response (nc, GNUNET_SYSERR, emsg, rid); | ||
1741 | GNUNET_free (emsg); | ||
1742 | GNUNET_free (conv_name); | ||
1743 | GNUNET_SERVICE_client_continue (nc->client); | ||
1744 | return; | ||
1745 | } | ||
1746 | |||
1747 | if (GNUNET_OK != | ||
1748 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd)) | ||
1749 | { | ||
1750 | send_store_response (nc, GNUNET_SYSERR, | ||
1751 | _ ("Error deserializing records."), rid); | ||
1752 | GNUNET_free (conv_name); | ||
1753 | GNUNET_SERVICE_client_continue (nc->client); | ||
1502 | return; | 1754 | return; |
1503 | } | 1755 | } |
1756 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1757 | { | ||
1758 | if (GNUNET_NO == NST_label_lock (conv_name, &rp_msg->private_key, nc)) | ||
1759 | { | ||
1760 | send_store_response (nc, GNUNET_SYSERR, _ ("Record set locked."), rid); | ||
1761 | GNUNET_SERVICE_client_continue (nc->client); | ||
1762 | GNUNET_free (conv_name); | ||
1763 | return; | ||
1764 | } | ||
1765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1766 | "Client has lock on `%s', continuing.\n", conv_name); | ||
1767 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1768 | NST_label_lock_release (conv_name, &rp_msg->private_key, nc); | ||
1769 | } | ||
1770 | |||
1504 | GNUNET_STATISTICS_update (statistics, | 1771 | GNUNET_STATISTICS_update (statistics, |
1505 | "Well-formed store requests received", | 1772 | "Well-formed store requests received", |
1506 | 1, | 1773 | 1, |
@@ -1509,12 +1776,12 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1509 | "Creating %u records for name `%s'\n", | 1776 | "Creating %u records for name `%s'\n", |
1510 | (unsigned int) rd_count, | 1777 | (unsigned int) rd_count, |
1511 | conv_name); | 1778 | conv_name); |
1512 | if ((0 == rd_count) && | 1779 | if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls, |
1513 | (GNUNET_NO == GSN_database->lookup_records (GSN_database->cls, | ||
1514 | &rp_msg->private_key, | 1780 | &rp_msg->private_key, |
1515 | conv_name, | 1781 | conv_name, |
1516 | NULL, | 1782 | &get_block_exp_existing, |
1517 | 0))) | 1783 | &existing_block_exp)) && |
1784 | (rd_count == 0)) | ||
1518 | { | 1785 | { |
1519 | /* This name does not exist, so cannot be removed */ | 1786 | /* This name does not exist, so cannot be removed */ |
1520 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1787 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1525,9 +1792,18 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1525 | else | 1792 | else |
1526 | { | 1793 | { |
1527 | /* remove "NICK" records, unless this is for the | 1794 | /* remove "NICK" records, unless this is for the |
1528 | #GNUNET_GNS_EMPTY_LABEL_AT label */ | 1795 | #GNUNET_GNS_EMPTY_LABEL_AT label |
1796 | We may need one additional record later for tombstone. | ||
1797 | FIXME: Since we must normalize the record set (check for | ||
1798 | consistency etc) we have to iterate the set twice. | ||
1799 | May be inefficient. | ||
1800 | We cannot really move the nick caching into GNSRECORD. | ||
1801 | */ | ||
1529 | struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)]; | 1802 | struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)]; |
1803 | struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1]; | ||
1530 | unsigned int rd_clean_off; | 1804 | unsigned int rd_clean_off; |
1805 | unsigned int rd_nf_count; | ||
1806 | char *emsg; | ||
1531 | int have_nick; | 1807 | int have_nick; |
1532 | 1808 | ||
1533 | rd_clean_off = 0; | 1809 | rd_clean_off = 0; |
@@ -1535,6 +1811,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1535 | for (unsigned int i = 0; i < rd_count; i++) | 1811 | for (unsigned int i = 0; i < rd_count; i++) |
1536 | { | 1812 | { |
1537 | rd_clean[rd_clean_off] = rd[i]; | 1813 | rd_clean[rd_clean_off] = rd[i]; |
1814 | |||
1538 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || | 1815 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || |
1539 | (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) | 1816 | (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) |
1540 | rd_clean_off++; | 1817 | rd_clean_off++; |
@@ -1546,6 +1823,38 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1546 | have_nick = GNUNET_YES; | 1823 | have_nick = GNUNET_YES; |
1547 | } | 1824 | } |
1548 | } | 1825 | } |
1826 | if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (conv_name, | ||
1827 | rd_clean, | ||
1828 | rd_clean_off, | ||
1829 | rd_nf, | ||
1830 | &rd_nf_count, | ||
1831 | &new_block_exp, | ||
1832 | GNUNET_YES, | ||
1833 | &emsg)) | ||
1834 | { | ||
1835 | send_store_response (nc, GNUNET_SYSERR, emsg, rid); | ||
1836 | GNUNET_free (emsg); | ||
1837 | GNUNET_SERVICE_client_continue (nc->client); | ||
1838 | GNUNET_free (conv_name); | ||
1839 | return; | ||
1840 | } | ||
1841 | /* | ||
1842 | * If existing_block_exp is 0, then there was not record set | ||
1843 | * and no tombstone. | ||
1844 | * Otherwise, if the existing block expiration is after the | ||
1845 | * new block expiration would be, we need to add a tombstone | ||
1846 | * or update it. | ||
1847 | */ | ||
1848 | if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp)) | ||
1849 | { | ||
1850 | rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; | ||
1851 | rd_nf[rd_nf_count].expiration_time = | ||
1852 | existing_block_exp.abs_value_us; | ||
1853 | rd_nf[rd_nf_count].data = NULL; | ||
1854 | rd_nf[rd_nf_count].data_size = 0; | ||
1855 | rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE; | ||
1856 | rd_nf_count++; | ||
1857 | } | ||
1549 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && | 1858 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && |
1550 | (GNUNET_NO == have_nick)) | 1859 | (GNUNET_NO == have_nick)) |
1551 | { | 1860 | { |
@@ -1555,19 +1864,18 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1555 | res = GSN_database->store_records (GSN_database->cls, | 1864 | res = GSN_database->store_records (GSN_database->cls, |
1556 | &rp_msg->private_key, | 1865 | &rp_msg->private_key, |
1557 | conv_name, | 1866 | conv_name, |
1558 | rd_clean_off, | 1867 | rd_nf_count, |
1559 | rd_clean); | 1868 | rd_nf); |
1560 | } | 1869 | } |
1561 | 1870 | ||
1562 | if (GNUNET_OK != res) | 1871 | if (GNUNET_OK != res) |
1563 | { | 1872 | { |
1564 | /* store not successful, not need to tell monitors */ | 1873 | /* store not successful, no need to tell monitors */ |
1565 | send_store_response (nc, res, rid); | 1874 | send_store_response (nc, res, _ ("Store failed"), rid); |
1566 | GNUNET_SERVICE_client_continue (nc->client); | 1875 | GNUNET_SERVICE_client_continue (nc->client); |
1567 | GNUNET_free (conv_name); | 1876 | GNUNET_free (conv_name); |
1568 | return; | 1877 | return; |
1569 | } | 1878 | } |
1570 | |||
1571 | sa = GNUNET_malloc (sizeof(struct StoreActivity) | 1879 | sa = GNUNET_malloc (sizeof(struct StoreActivity) |
1572 | + ntohs (rp_msg->gns_header.header.size)); | 1880 | + ntohs (rp_msg->gns_header.header.size)); |
1573 | GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); | 1881 | GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); |
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index fd9a8ed47..0f3ffa837 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h | |||
@@ -68,6 +68,11 @@ struct RecordStoreMessage | |||
68 | struct GNUNET_TIME_AbsoluteNBO expire; | 68 | struct GNUNET_TIME_AbsoluteNBO expire; |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * Unock the label with this request. | ||
72 | */ | ||
73 | uint32_t locking GNUNET_PACKED; | ||
74 | |||
75 | /** | ||
71 | * Name length | 76 | * Name length |
72 | */ | 77 | */ |
73 | uint16_t name_len GNUNET_PACKED; | 78 | uint16_t name_len GNUNET_PACKED; |
@@ -83,7 +88,7 @@ struct RecordStoreMessage | |||
83 | uint16_t rd_count GNUNET_PACKED; | 88 | uint16_t rd_count GNUNET_PACKED; |
84 | 89 | ||
85 | /** | 90 | /** |
86 | * always zero (for alignment) | 91 | * Reserved for alignment. |
87 | */ | 92 | */ |
88 | uint16_t reserved GNUNET_PACKED; | 93 | uint16_t reserved GNUNET_PACKED; |
89 | 94 | ||
@@ -113,6 +118,20 @@ struct RecordStoreResponseMessage | |||
113 | * #GNUNET_SYSERR on failure, #GNUNET_OK on success | 118 | * #GNUNET_SYSERR on failure, #GNUNET_OK on success |
114 | */ | 119 | */ |
115 | int32_t op_result GNUNET_PACKED; | 120 | int32_t op_result GNUNET_PACKED; |
121 | |||
122 | /** | ||
123 | * Error message length | ||
124 | */ | ||
125 | uint16_t emsg_len GNUNET_PACKED; | ||
126 | |||
127 | /** | ||
128 | * Reserved for alignment. | ||
129 | */ | ||
130 | uint16_t reserved GNUNET_PACKED; | ||
131 | |||
132 | /** | ||
133 | * Followed by error message | ||
134 | */ | ||
116 | }; | 135 | }; |
117 | 136 | ||
118 | 137 | ||
@@ -132,6 +151,11 @@ struct LabelLookupMessage | |||
132 | uint32_t label_len GNUNET_PACKED; | 151 | uint32_t label_len GNUNET_PACKED; |
133 | 152 | ||
134 | /** | 153 | /** |
154 | * Lock the label with this lookup | ||
155 | */ | ||
156 | uint32_t locking GNUNET_PACKED; | ||
157 | |||
158 | /** | ||
135 | * The private key of the zone to look up in | 159 | * The private key of the zone to look up in |
136 | */ | 160 | */ |
137 | struct GNUNET_IDENTITY_PrivateKey zone; | 161 | struct GNUNET_IDENTITY_PrivateKey zone; |
@@ -171,7 +195,7 @@ struct LabelLookupResponseMessage | |||
171 | * Was the label found in the database?? | 195 | * Was the label found in the database?? |
172 | * #GNUNET_YES or #GNUNET_NO | 196 | * #GNUNET_YES or #GNUNET_NO |
173 | */ | 197 | */ |
174 | uint16_t found GNUNET_PACKED; | 198 | int16_t found GNUNET_PACKED; |
175 | 199 | ||
176 | /** | 200 | /** |
177 | * The private key of the authority. | 201 | * The private key of the authority. |
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index b24db9b26..a7380bbde 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c | |||
@@ -346,6 +346,44 @@ check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count) | |||
346 | return GNUNET_OK; | 346 | return GNUNET_OK; |
347 | } | 347 | } |
348 | 348 | ||
349 | /** | ||
350 | * Handle an incoming message of type | ||
351 | * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE | ||
352 | * | ||
353 | * @param cls | ||
354 | * @param msg the message we received | ||
355 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
356 | */ | ||
357 | static int | ||
358 | check_record_store_response (void *cls, | ||
359 | const struct RecordStoreResponseMessage *msg) | ||
360 | { | ||
361 | const char *emsg; | ||
362 | size_t msg_len; | ||
363 | size_t emsg_len; | ||
364 | |||
365 | (void) cls; | ||
366 | msg_len = ntohs (msg->gns_header.header.size); | ||
367 | emsg_len = ntohs (msg->emsg_len); | ||
368 | if (0 != ntohs (msg->reserved)) | ||
369 | { | ||
370 | GNUNET_break (0); | ||
371 | return GNUNET_SYSERR; | ||
372 | } | ||
373 | if (msg_len != sizeof(struct RecordStoreResponseMessage) + emsg_len) | ||
374 | { | ||
375 | GNUNET_break (0); | ||
376 | return GNUNET_SYSERR; | ||
377 | } | ||
378 | emsg = (const char *) &msg[1]; | ||
379 | if ((0 != emsg_len) && ('\0' != emsg[emsg_len - 1])) | ||
380 | { | ||
381 | GNUNET_break (0); | ||
382 | return GNUNET_SYSERR; | ||
383 | } | ||
384 | return GNUNET_OK; | ||
385 | } | ||
386 | |||
349 | 387 | ||
350 | /** | 388 | /** |
351 | * Handle an incoming message of type | 389 | * Handle an incoming message of type |
@@ -364,19 +402,16 @@ handle_record_store_response (void *cls, | |||
364 | const char *emsg; | 402 | const char *emsg; |
365 | 403 | ||
366 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); | 404 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); |
405 | emsg = (const char *) &msg[1]; | ||
367 | res = ntohl (msg->op_result); | 406 | res = ntohl (msg->op_result); |
368 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 407 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
369 | "Received RECORD_STORE_RESPONSE with result %d\n", | 408 | "Received RECORD_STORE_RESPONSE with result %d\n", |
370 | res); | 409 | res); |
371 | /* TODO: add actual error message from namestore to response... */ | ||
372 | if (GNUNET_SYSERR == res) | ||
373 | emsg = _ ("Namestore failed to store record\n"); | ||
374 | else | ||
375 | emsg = NULL; | ||
376 | if (NULL == qe) | 410 | if (NULL == qe) |
377 | return; | 411 | return; |
378 | if (NULL != qe->cont) | 412 | if (NULL != qe->cont) |
379 | qe->cont (qe->cont_cls, res, emsg); | 413 | qe->cont (qe->cont_cls, res, |
414 | (GNUNET_OK == res) ? NULL : emsg); | ||
380 | free_qe (qe); | 415 | free_qe (qe); |
381 | } | 416 | } |
382 | 417 | ||
@@ -444,8 +479,10 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
444 | size_t name_len; | 479 | size_t name_len; |
445 | size_t rd_len; | 480 | size_t rd_len; |
446 | unsigned int rd_count; | 481 | unsigned int rd_count; |
482 | int16_t found = (int16_t) ntohs (msg->found); | ||
447 | 483 | ||
448 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT\n"); | 484 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n", |
485 | found); | ||
449 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); | 486 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); |
450 | if (NULL == qe) | 487 | if (NULL == qe) |
451 | return; | 488 | return; |
@@ -453,7 +490,7 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
453 | rd_count = ntohs (msg->rd_count); | 490 | rd_count = ntohs (msg->rd_count); |
454 | name_len = ntohs (msg->name_len); | 491 | name_len = ntohs (msg->name_len); |
455 | name = (const char *) &msg[1]; | 492 | name = (const char *) &msg[1]; |
456 | if (GNUNET_NO == ntohs (msg->found)) | 493 | if (GNUNET_NO == found) |
457 | { | 494 | { |
458 | /* label was not in namestore */ | 495 | /* label was not in namestore */ |
459 | if (NULL != qe->proc) | 496 | if (NULL != qe->proc) |
@@ -461,6 +498,13 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
461 | free_qe (qe); | 498 | free_qe (qe); |
462 | return; | 499 | return; |
463 | } | 500 | } |
501 | if (GNUNET_SYSERR == found) | ||
502 | { | ||
503 | if (NULL != qe->error_cb) | ||
504 | qe->error_cb (qe->error_cb_cls); | ||
505 | free_qe (qe); | ||
506 | return; | ||
507 | } | ||
464 | 508 | ||
465 | rd_tmp = &name[name_len]; | 509 | rd_tmp = &name[name_len]; |
466 | { | 510 | { |
@@ -775,7 +819,7 @@ static void | |||
775 | reconnect (struct GNUNET_NAMESTORE_Handle *h) | 819 | reconnect (struct GNUNET_NAMESTORE_Handle *h) |
776 | { | 820 | { |
777 | struct GNUNET_MQ_MessageHandler handlers[] = | 821 | struct GNUNET_MQ_MessageHandler handlers[] = |
778 | { GNUNET_MQ_hd_fixed_size (record_store_response, | 822 | { GNUNET_MQ_hd_var_size (record_store_response, |
779 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, | 823 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, |
780 | struct RecordStoreResponseMessage, | 824 | struct RecordStoreResponseMessage, |
781 | h), | 825 | h), |
@@ -969,30 +1013,16 @@ warn_delay (void *cls) | |||
969 | GNUNET_NAMESTORE_cancel (qe); | 1013 | GNUNET_NAMESTORE_cancel (qe); |
970 | } | 1014 | } |
971 | 1015 | ||
972 | |||
973 | /** | ||
974 | * Store an item in the namestore. If the item is already present, | ||
975 | * it is replaced with the new record. Use an empty array to | ||
976 | * remove all records under the given name. | ||
977 | * | ||
978 | * @param h handle to the namestore | ||
979 | * @param pkey private key of the zone | ||
980 | * @param label name that is being mapped (at most 255 characters long) | ||
981 | * @param rd_count number of records in the @a rd array | ||
982 | * @param rd array of records with data to store | ||
983 | * @param cont continuation to call when done | ||
984 | * @param cont_cls closure for @a cont | ||
985 | * @return handle to abort the request | ||
986 | */ | ||
987 | struct GNUNET_NAMESTORE_QueueEntry * | 1016 | struct GNUNET_NAMESTORE_QueueEntry * |
988 | GNUNET_NAMESTORE_records_store ( | 1017 | records_store_ ( |
989 | struct GNUNET_NAMESTORE_Handle *h, | 1018 | struct GNUNET_NAMESTORE_Handle *h, |
990 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1019 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
991 | const char *label, | 1020 | const char *label, |
992 | unsigned int rd_count, | 1021 | unsigned int rd_count, |
993 | const struct GNUNET_GNSRECORD_Data *rd, | 1022 | const struct GNUNET_GNSRECORD_Data *rd, |
994 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | 1023 | GNUNET_NAMESTORE_ContinuationWithStatus cont, |
995 | void *cont_cls) | 1024 | void *cont_cls, |
1025 | int locking) | ||
996 | { | 1026 | { |
997 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1027 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
998 | struct GNUNET_MQ_Envelope *env; | 1028 | struct GNUNET_MQ_Envelope *env; |
@@ -1037,8 +1067,9 @@ GNUNET_NAMESTORE_records_store ( | |||
1037 | msg->name_len = htons (name_len); | 1067 | msg->name_len = htons (name_len); |
1038 | msg->rd_count = htons (rd_count); | 1068 | msg->rd_count = htons (rd_count); |
1039 | msg->rd_len = htons (rd_ser_len); | 1069 | msg->rd_len = htons (rd_ser_len); |
1040 | msg->reserved = htons (0); | 1070 | msg->reserved = ntohs(0); |
1041 | msg->private_key = *pkey; | 1071 | msg->private_key = *pkey; |
1072 | msg->locking = htonl (locking); | ||
1042 | 1073 | ||
1043 | name_tmp = (char *) &msg[1]; | 1074 | name_tmp = (char *) &msg[1]; |
1044 | GNUNET_memcpy (name_tmp, label, name_len); | 1075 | GNUNET_memcpy (name_tmp, label, name_len); |
@@ -1070,28 +1101,45 @@ GNUNET_NAMESTORE_records_store ( | |||
1070 | return qe; | 1101 | return qe; |
1071 | } | 1102 | } |
1072 | 1103 | ||
1104 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1105 | GNUNET_NAMESTORE_records_store ( | ||
1106 | struct GNUNET_NAMESTORE_Handle *h, | ||
1107 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1108 | const char *label, | ||
1109 | unsigned int rd_count, | ||
1110 | const struct GNUNET_GNSRECORD_Data *rd, | ||
1111 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
1112 | void *cont_cls) | ||
1113 | { | ||
1114 | return records_store_ (h, pkey, label, | ||
1115 | rd_count, rd, cont, cont_cls, GNUNET_NO); | ||
1116 | } | ||
1117 | |||
1118 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1119 | GNUNET_NAMESTORE_records_commit ( | ||
1120 | struct GNUNET_NAMESTORE_Handle *h, | ||
1121 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1122 | const char *label, | ||
1123 | unsigned int rd_count, | ||
1124 | const struct GNUNET_GNSRECORD_Data *rd, | ||
1125 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
1126 | void *cont_cls) | ||
1127 | { | ||
1128 | return records_store_ (h, pkey, label, | ||
1129 | rd_count, rd, cont, cont_cls, GNUNET_YES); | ||
1130 | } | ||
1131 | |||
1073 | 1132 | ||
1074 | /** | ||
1075 | * Lookup an item in the namestore. | ||
1076 | * | ||
1077 | * @param h handle to the namestore | ||
1078 | * @param pkey private key of the zone | ||
1079 | * @param label name that is being mapped (at most 255 characters long) | ||
1080 | * @param error_cb function to call on error (i.e. disconnect) | ||
1081 | * @param error_cb_cls closure for @a error_cb | ||
1082 | * @param rm function to call with the result (with 0 records if we don't have that label) | ||
1083 | * @param rm_cls closure for @a rm | ||
1084 | * @return handle to abort the request | ||
1085 | */ | ||
1086 | struct GNUNET_NAMESTORE_QueueEntry * | 1133 | struct GNUNET_NAMESTORE_QueueEntry * |
1087 | GNUNET_NAMESTORE_records_lookup ( | 1134 | records_lookup_ ( |
1088 | struct GNUNET_NAMESTORE_Handle *h, | 1135 | struct GNUNET_NAMESTORE_Handle *h, |
1089 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1136 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1090 | const char *label, | 1137 | const char *label, |
1091 | GNUNET_SCHEDULER_TaskCallback error_cb, | 1138 | GNUNET_SCHEDULER_TaskCallback error_cb, |
1092 | void *error_cb_cls, | 1139 | void *error_cb_cls, |
1093 | GNUNET_NAMESTORE_RecordMonitor rm, | 1140 | GNUNET_NAMESTORE_RecordMonitor rm, |
1094 | void *rm_cls) | 1141 | void *rm_cls, |
1142 | int locking) | ||
1095 | { | 1143 | { |
1096 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1144 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
1097 | struct GNUNET_MQ_Envelope *env; | 1145 | struct GNUNET_MQ_Envelope *env; |
@@ -1119,6 +1167,7 @@ GNUNET_NAMESTORE_records_lookup ( | |||
1119 | msg->gns_header.r_id = htonl (qe->op_id); | 1167 | msg->gns_header.r_id = htonl (qe->op_id); |
1120 | msg->zone = *pkey; | 1168 | msg->zone = *pkey; |
1121 | msg->label_len = htonl (label_len); | 1169 | msg->label_len = htonl (label_len); |
1170 | msg->locking = htonl (locking); | ||
1122 | GNUNET_memcpy (&msg[1], label, label_len); | 1171 | GNUNET_memcpy (&msg[1], label, label_len); |
1123 | if (NULL == h->mq) | 1172 | if (NULL == h->mq) |
1124 | qe->env = env; | 1173 | qe->env = env; |
@@ -1127,22 +1176,34 @@ GNUNET_NAMESTORE_records_lookup ( | |||
1127 | return qe; | 1176 | return qe; |
1128 | } | 1177 | } |
1129 | 1178 | ||
1179 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1180 | GNUNET_NAMESTORE_records_lookup ( | ||
1181 | struct GNUNET_NAMESTORE_Handle *h, | ||
1182 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1183 | const char *label, | ||
1184 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1185 | void *error_cb_cls, | ||
1186 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
1187 | void *rm_cls) | ||
1188 | { | ||
1189 | return records_lookup_ (h, pkey, label, | ||
1190 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_NO); | ||
1191 | } | ||
1192 | |||
1193 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1194 | GNUNET_NAMESTORE_records_open ( | ||
1195 | struct GNUNET_NAMESTORE_Handle *h, | ||
1196 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1197 | const char *label, | ||
1198 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1199 | void *error_cb_cls, | ||
1200 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
1201 | void *rm_cls) | ||
1202 | { | ||
1203 | return records_lookup_ (h, pkey, label, | ||
1204 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_YES); | ||
1205 | } | ||
1130 | 1206 | ||
1131 | /** | ||
1132 | * Look for an existing PKEY delegation record for a given public key. | ||
1133 | * Returns at most one result to the processor. | ||
1134 | * | ||
1135 | * @param h handle to the namestore | ||
1136 | * @param zone public key of the zone to look up in, never NULL | ||
1137 | * @param value_zone public key of the target zone (value), never NULL | ||
1138 | * @param error_cb function to call on error (i.e. disconnect) | ||
1139 | * @param error_cb_cls closure for @a error_cb | ||
1140 | * @param proc function to call on the matching records, or with | ||
1141 | * NULL (rd_count == 0) if there are no matching records | ||
1142 | * @param proc_cls closure for @a proc | ||
1143 | * @return a handle that can be used to | ||
1144 | * cancel | ||
1145 | */ | ||
1146 | struct GNUNET_NAMESTORE_QueueEntry * | 1207 | struct GNUNET_NAMESTORE_QueueEntry * |
1147 | GNUNET_NAMESTORE_zone_to_name ( | 1208 | GNUNET_NAMESTORE_zone_to_name ( |
1148 | struct GNUNET_NAMESTORE_Handle *h, | 1209 | struct GNUNET_NAMESTORE_Handle *h, |
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 7cb9b7ed0..0b3aac84f 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -329,6 +329,11 @@ namestore_sqlite_store_records (void *cls, | |||
329 | 0, | 329 | 0, |
330 | sizeof(pkey)); | 330 | sizeof(pkey)); |
331 | for (unsigned int i = 0; i < rd_count; i++) | 331 | for (unsigned int i = 0; i < rd_count; i++) |
332 | { | ||
333 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
334 | "Checking if `%d' is zonekey type\n", | ||
335 | rd[i].record_type); | ||
336 | |||
332 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) | 337 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) |
333 | { | 338 | { |
334 | GNUNET_break (GNUNET_YES == | 339 | GNUNET_break (GNUNET_YES == |
@@ -336,8 +341,13 @@ namestore_sqlite_store_records (void *cls, | |||
336 | rd[i].data_size, | 341 | rd[i].data_size, |
337 | rd[i].record_type, | 342 | rd[i].record_type, |
338 | &pkey)); | 343 | &pkey)); |
344 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
345 | "Storing delegation zone record value `%s'\n", | ||
346 | GNUNET_GNSRECORD_z2s (&pkey)); | ||
347 | |||
339 | break; | 348 | break; |
340 | } | 349 | } |
350 | } | ||
341 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 351 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
342 | UINT64_MAX); | 352 | UINT64_MAX); |
343 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, | 353 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
diff --git a/src/namestore/test_namestore_api_lookup_nick.c b/src/namestore/test_namestore_api_lookup_nick.c index 6ce969c9b..7decf39f8 100644 --- a/src/namestore/test_namestore_api_lookup_nick.c +++ b/src/namestore/test_namestore_api_lookup_nick.c | |||
@@ -262,12 +262,12 @@ nick_cont (void *cls, int32_t success, const char *emsg) | |||
262 | "Nick added : %s\n", | 262 | "Nick added : %s\n", |
263 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); | 263 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); |
264 | 264 | ||
265 | rd_orig.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; | 265 | rd_orig.expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; |
266 | rd_orig.record_type = TEST_RECORD_TYPE; | 266 | rd_orig.record_type = TEST_RECORD_TYPE; |
267 | rd_orig.data_size = TEST_RECORD_DATALEN; | 267 | rd_orig.data_size = TEST_RECORD_DATALEN; |
268 | record_data = GNUNET_malloc (TEST_RECORD_DATALEN); | 268 | record_data = GNUNET_malloc (TEST_RECORD_DATALEN); |
269 | rd_orig.data = record_data; | 269 | rd_orig.data = record_data; |
270 | rd_orig.flags = 0; | 270 | rd_orig.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
271 | memset ((char *) rd_orig.data, 'a', TEST_RECORD_DATALEN); | 271 | memset ((char *) rd_orig.data, 'a', TEST_RECORD_DATALEN); |
272 | 272 | ||
273 | nsqe = GNUNET_NAMESTORE_records_store (nsh, &privkey, | 273 | nsqe = GNUNET_NAMESTORE_records_store (nsh, &privkey, |
diff --git a/src/namestore/test_namestore_api_lookup_public.c b/src/namestore/test_namestore_api_lookup_public.c index 5e3e7bbd8..cd69b96ef 100644 --- a/src/namestore/test_namestore_api_lookup_public.c +++ b/src/namestore/test_namestore_api_lookup_public.c | |||
@@ -188,7 +188,7 @@ run (void *cls, | |||
188 | struct GNUNET_TESTING_Peer *peer) | 188 | struct GNUNET_TESTING_Peer *peer) |
189 | { | 189 | { |
190 | struct GNUNET_GNSRECORD_Data rd; | 190 | struct GNUNET_GNSRECORD_Data rd; |
191 | const char *name = "dummy.dummy.gnunet"; | 191 | const char *name = "dummy"; |
192 | 192 | ||
193 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 193 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
194 | &endbadly, | 194 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_lookup_shadow.c b/src/namestore/test_namestore_api_lookup_shadow.c index 79fa4c9c6..8f47d1280 100644 --- a/src/namestore/test_namestore_api_lookup_shadow.c +++ b/src/namestore/test_namestore_api_lookup_shadow.c | |||
@@ -223,7 +223,7 @@ run (void *cls, | |||
223 | struct GNUNET_TESTING_Peer *peer) | 223 | struct GNUNET_TESTING_Peer *peer) |
224 | { | 224 | { |
225 | struct GNUNET_GNSRECORD_Data rd; | 225 | struct GNUNET_GNSRECORD_Data rd; |
226 | const char *name = "dummy.dummy.gnunet"; | 226 | const char *name = "dummy"; |
227 | 227 | ||
228 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 228 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
229 | &endbadly, | 229 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_lookup_shadow_filter.c b/src/namestore/test_namestore_api_lookup_shadow_filter.c index 4fc197750..0bcd130f9 100644 --- a/src/namestore/test_namestore_api_lookup_shadow_filter.c +++ b/src/namestore/test_namestore_api_lookup_shadow_filter.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT | 33 | #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT |
34 | 34 | ||
35 | #define TEST_NAME "dummy.dummy.gnunet" | 35 | #define TEST_NAME "gnunet" |
36 | #define TEST_RECORD_DATALEN 123 | 36 | #define TEST_RECORD_DATALEN 123 |
37 | #define TEST_RECORD_DATA 'a' | 37 | #define TEST_RECORD_DATA 'a' |
38 | #define TEST_SHADOW_RECORD_DATA 'b' | 38 | #define TEST_SHADOW_RECORD_DATA 'b' |
diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c index b6254e531..e8124c595 100644 --- a/src/namestore/test_namestore_api_remove.c +++ b/src/namestore/test_namestore_api_remove.c | |||
@@ -153,7 +153,7 @@ run (void *cls, | |||
153 | struct GNUNET_TESTING_Peer *peer) | 153 | struct GNUNET_TESTING_Peer *peer) |
154 | { | 154 | { |
155 | struct GNUNET_GNSRECORD_Data rd; | 155 | struct GNUNET_GNSRECORD_Data rd; |
156 | const char *name = "dummy.dummy.gnunet"; | 156 | const char *name = "dummy"; |
157 | 157 | ||
158 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 158 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
159 | &endbadly, | 159 | &endbadly, |
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 e66992909..958ea4bf2 100644 --- a/src/namestore/test_namestore_api_remove_not_existing_record.c +++ b/src/namestore/test_namestore_api_remove_not_existing_record.c | |||
@@ -127,7 +127,7 @@ run (void *cls, | |||
127 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 127 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
128 | struct GNUNET_TESTING_Peer *peer) | 128 | struct GNUNET_TESTING_Peer *peer) |
129 | { | 129 | { |
130 | const char *name = "dummy.dummy.gnunet"; | 130 | const char *name = "dummy"; |
131 | 131 | ||
132 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 132 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
133 | &endbadly, | 133 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c index 3fd10e4a1..1e2f8248b 100644 --- a/src/namestore/test_namestore_api_zone_to_name.c +++ b/src/namestore/test_namestore_api_zone_to_name.c | |||
@@ -216,11 +216,11 @@ run (void *cls, | |||
216 | { | 216 | { |
217 | struct GNUNET_GNSRECORD_Data rd; | 217 | struct GNUNET_GNSRECORD_Data rd; |
218 | 218 | ||
219 | rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; | 219 | rd.expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; |
220 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | 220 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; |
221 | rd.data_size = GNUNET_IDENTITY_key_get_length (&s_zone_value); | 221 | rd.data_size = sizeof (s_zone_value.ecdsa_key); |
222 | rd.data = &s_zone_value; | 222 | rd.data = &s_zone_value.ecdsa_key; |
223 | rd.flags = 0; | 223 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
224 | 224 | ||
225 | nsh = GNUNET_NAMESTORE_connect (cfg); | 225 | nsh = GNUNET_NAMESTORE_connect (cfg); |
226 | GNUNET_break (NULL != nsh); | 226 | GNUNET_break (NULL != nsh); |
@@ -230,7 +230,7 @@ run (void *cls, | |||
230 | 1, | 230 | 1, |
231 | &rd, | 231 | &rd, |
232 | &put_cont, | 232 | &put_cont, |
233 | NULL); | 233 | s_name); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/src/namestore/test_namestore_delete.sh b/src/namestore/test_namestore_delete.sh index 44ea1e66c..b861a4bc0 100755 --- a/src/namestore/test_namestore_delete.sh +++ b/src/namestore/test_namestore_delete.sh | |||
@@ -61,15 +61,7 @@ for LINE in $OUTPUT ; | |||
61 | stop_peer | 61 | stop_peer |
62 | 62 | ||
63 | 63 | ||
64 | if [ $FOUND_NAME = false -a $FOUND_IP != false ] | 64 | if [ $FOUND_IP = true ] |
65 | then | ||
66 | echo "PASS: Delete name in namestore" | ||
67 | exit 0 | ||
68 | elif [ $FOUND_NAME = true ] | ||
69 | then | ||
70 | echo "FAIL: Delete name in namestore: name returned" | ||
71 | exit 1 | ||
72 | elif [ $FOUND_IP = true ] | ||
73 | then | 65 | then |
74 | echo "FAIL: Delete name in namestore: IP returned" | 66 | echo "FAIL: Delete name in namestore: IP returned" |
75 | exit 1 | 67 | exit 1 |
diff --git a/src/namestore/test_plugin_rest_namestore.sh b/src/namestore/test_plugin_rest_namestore.sh index 8a45cebf5..50b3c8c12 100755 --- a/src/namestore/test_plugin_rest_namestore.sh +++ b/src/namestore/test_plugin_rest_namestore.sh | |||
@@ -78,15 +78,16 @@ curl_delete () { | |||
78 | 78 | ||
79 | TEST_ID="test" | 79 | TEST_ID="test" |
80 | gnunet-arm -s -c test_namestore_api.conf | 80 | gnunet-arm -s -c test_namestore_api.conf |
81 | gnunet-arm -i rest -c test_namestore_api.conf | ||
82 | #Test GET | 81 | #Test GET |
83 | gnunet-identity -C $TEST_ID -c test_namestore_api.conf | 82 | gnunet-identity -C $TEST_ID -c test_namestore_api.conf |
84 | test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" | 83 | test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" |
85 | name=$TEST_ID | 84 | name=$TEST_ID |
86 | public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" | 85 | public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" |
87 | echo "$name $public" | 86 | echo "$name $public" |
88 | valgrind gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | 87 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf |
89 | #curl_get "${namestore_link}" "HTTP/1.1 200 OK" | 88 | sleep 1 |
89 | gnunet-arm -i rest -c test_namestore_api.conf | ||
90 | sleep 1 | ||
90 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" | 91 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" |
91 | curl_get "${namestore_link}/$public" "error" | 92 | curl_get "${namestore_link}/$public" "error" |
92 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf | 93 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf |
@@ -128,9 +129,6 @@ gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/ | |||
128 | #Test DELETE | 129 | #Test DELETE |
129 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | 130 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf |
130 | curl_delete "${namestore_link}/$name/test_entry" "HTTP/1.1 204" | 131 | curl_delete "${namestore_link}/$name/test_entry" "HTTP/1.1 204" |
131 | curl_delete "${namestore_link}/$name/test_entry" "error" | ||
132 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | ||
133 | curl_delete "${namestore_link}/$public/test_entry" "error" | ||
134 | 132 | ||
135 | gnunet-arm -e -c test_namestore_api.conf | 133 | gnunet-arm -e -c test_namestore_api.conf |
136 | exit 0; | 134 | exit 0; |