diff options
author | t3sserakt <t3ss@posteo.de> | 2022-01-06 15:32:56 +0100 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2022-01-06 15:34:01 +0100 |
commit | 85697ed9ad40cdeffc642ccd6d63811cbd91c9b1 (patch) | |
tree | 003058a75af2e861f9a70d633292c3d40c1b5a1e /src | |
parent | d65ae53a5abf9388a0cc6a27e705af331fa5069e (diff) | |
parent | f59876f79b520f174161a40928ddbba1fab87215 (diff) | |
download | gnunet-85697ed9ad40cdeffc642ccd6d63811cbd91c9b1.tar.gz gnunet-85697ed9ad40cdeffc642ccd6d63811cbd91c9b1.zip |
Merge branch 'master' of ssh://git.gnunet.org/gnunet
Diffstat (limited to 'src')
95 files changed, 5464 insertions, 4296 deletions
diff --git a/src/abd/Makefile.am b/src/abd/Makefile.am index 304469e22..ae9248b43 100644 --- a/src/abd/Makefile.am +++ b/src/abd/Makefile.am | |||
@@ -3,7 +3,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include | |||
3 | 3 | ||
4 | EXTRA_DIST = \ | 4 | EXTRA_DIST = \ |
5 | test_abd_defaults.conf \ | 5 | test_abd_defaults.conf \ |
6 | test_abd_lookup.conf | 6 | test_abd_lookup.conf \ |
7 | $(check_SCRIPTS) \ | ||
8 | $(pkgdata_DATA) | ||
7 | 9 | ||
8 | 10 | ||
9 | if USE_COVERAGE | 11 | if USE_COVERAGE |
@@ -51,6 +53,7 @@ libgnunet_plugin_gnsrecord_abd_la_SOURCES = \ | |||
51 | libgnunet_plugin_gnsrecord_abd_la_LIBADD = \ | 53 | libgnunet_plugin_gnsrecord_abd_la_LIBADD = \ |
52 | libgnunetabd.la \ | 54 | libgnunetabd.la \ |
53 | $(top_builddir)/src/util/libgnunetutil.la \ | 55 | $(top_builddir)/src/util/libgnunetutil.la \ |
56 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
54 | $(LTLIBINTL) | 57 | $(LTLIBINTL) |
55 | libgnunet_plugin_gnsrecord_abd_la_LDFLAGS = \ | 58 | libgnunet_plugin_gnsrecord_abd_la_LDFLAGS = \ |
56 | $(GN_PLUGIN_LDFLAGS) | 59 | $(GN_PLUGIN_LDFLAGS) |
@@ -64,6 +67,7 @@ gnunet_service_abd_LDADD = \ | |||
64 | $(top_builddir)/src/util/libgnunetutil.la \ | 67 | $(top_builddir)/src/util/libgnunetutil.la \ |
65 | $(top_builddir)/src/gns/libgnunetgns.la \ | 68 | $(top_builddir)/src/gns/libgnunetgns.la \ |
66 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 69 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
70 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
67 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 71 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
68 | $(GN_LIBINTL) | 72 | $(GN_LIBINTL) |
69 | 73 | ||
diff --git a/src/abd/abd_serialization.c b/src/abd/abd_serialization.c index 4c219d791..2ed24ff2f 100644 --- a/src/abd/abd_serialization.c +++ b/src/abd/abd_serialization.c | |||
@@ -191,8 +191,8 @@ GNUNET_ABD_delegates_serialize ( | |||
191 | off = 0; | 191 | off = 0; |
192 | for (i = 0; i < c_count; i++) | 192 | for (i = 0; i < c_count; i++) |
193 | { | 193 | { |
194 | // c_rec.subject_attribute_len = htonl ((uint32_t) cd[i].subject_attribute_len); | 194 | c_rec.subject_attribute_len = htonl (cd[i].subject_attribute_len); |
195 | c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len); | 195 | c_rec.issuer_attribute_len = htonl (cd[i].issuer_attribute_len); |
196 | c_rec.issuer_key = cd[i].issuer_key; | 196 | c_rec.issuer_key = cd[i].issuer_key; |
197 | c_rec.subject_key = cd[i].subject_key; | 197 | c_rec.subject_key = cd[i].subject_key; |
198 | c_rec.signature = cd[i].signature; | 198 | c_rec.signature = cd[i].signature; |
diff --git a/src/abd/delegate_misc.c b/src/abd/delegate_misc.c index d67b40088..0c5520d52 100644 --- a/src/abd/delegate_misc.c +++ b/src/abd/delegate_misc.c | |||
@@ -143,10 +143,20 @@ GNUNET_ABD_delegate_from_string (const char *s) | |||
143 | } | 143 | } |
144 | tmp_str[attr_len - 1] = '\0'; | 144 | tmp_str[attr_len - 1] = '\0'; |
145 | 145 | ||
146 | GNUNET_IDENTITY_public_key_from_string (subject_pkey, | 146 | if (GNUNET_SYSERR == |
147 | &dele->subject_key); | 147 | GNUNET_IDENTITY_public_key_from_string (subject_pkey, |
148 | GNUNET_IDENTITY_public_key_from_string (issuer_pkey, | 148 | &dele->subject_key)) |
149 | &dele->issuer_key); | 149 | { |
150 | GNUNET_free (dele); | ||
151 | return NULL; | ||
152 | } | ||
153 | if (GNUNET_SYSERR == | ||
154 | GNUNET_IDENTITY_public_key_from_string (issuer_pkey, | ||
155 | &dele->issuer_key)) | ||
156 | { | ||
157 | GNUNET_free (dele); | ||
158 | return NULL; | ||
159 | } | ||
150 | GNUNET_assert (sizeof (struct GNUNET_IDENTITY_Signature) == | 160 | GNUNET_assert (sizeof (struct GNUNET_IDENTITY_Signature) == |
151 | GNUNET_STRINGS_base64_decode (signature, | 161 | GNUNET_STRINGS_base64_decode (signature, |
152 | strlen (signature), | 162 | strlen (signature), |
diff --git a/src/abd/gnunet-abd.c b/src/abd/gnunet-abd.c index 17671273c..cf3733abd 100644 --- a/src/abd/gnunet-abd.c +++ b/src/abd/gnunet-abd.c | |||
@@ -544,6 +544,10 @@ static void | |||
544 | store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | 544 | store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) |
545 | { | 545 | { |
546 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 546 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
547 | struct GNUNET_ABD_Delegate *cred; | ||
548 | struct GNUNET_IDENTITY_PublicKey zone_pubkey; | ||
549 | char *subject_pubkey_str; | ||
550 | char *zone_pubkey_str; | ||
547 | 551 | ||
548 | el = NULL; | 552 | el = NULL; |
549 | 553 | ||
@@ -562,17 +566,23 @@ store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | |||
562 | if (GNUNET_GNSRECORD_TYPE_DELEGATE == type) | 566 | if (GNUNET_GNSRECORD_TYPE_DELEGATE == type) |
563 | { | 567 | { |
564 | // Parse import | 568 | // Parse import |
565 | struct GNUNET_ABD_Delegate *cred; | ||
566 | cred = GNUNET_ABD_delegate_from_string (import); | 569 | cred = GNUNET_ABD_delegate_from_string (import); |
567 | 570 | ||
571 | if (NULL == cred) | ||
572 | { | ||
573 | fprintf (stderr, | ||
574 | "%s is not a valid credential\n", import); | ||
575 | GNUNET_SCHEDULER_shutdown(); | ||
576 | return; | ||
577 | } | ||
578 | |||
568 | // Get import subject public key string | 579 | // Get import subject public key string |
569 | char *subject_pubkey_str = | 580 | subject_pubkey_str = |
570 | GNUNET_IDENTITY_public_key_to_string (&cred->subject_key); | 581 | GNUNET_IDENTITY_public_key_to_string (&cred->subject_key); |
571 | 582 | ||
572 | // Get zone public key string | 583 | // Get zone public key string |
573 | struct GNUNET_IDENTITY_PublicKey zone_pubkey; | ||
574 | GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey); | 584 | GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey); |
575 | char *zone_pubkey_str = | 585 | zone_pubkey_str = |
576 | GNUNET_IDENTITY_public_key_to_string (&zone_pubkey); | 586 | GNUNET_IDENTITY_public_key_to_string (&zone_pubkey); |
577 | 587 | ||
578 | // Check if the subject key in the signed import matches the zone's key it is issued to | 588 | // Check if the subject key in the signed import matches the zone's key it is issued to |
@@ -580,6 +590,7 @@ store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | |||
580 | { | 590 | { |
581 | fprintf (stderr, | 591 | fprintf (stderr, |
582 | "Import signed delegate does not match this ego's public key.\n"); | 592 | "Import signed delegate does not match this ego's public key.\n"); |
593 | GNUNET_free (cred); | ||
583 | GNUNET_SCHEDULER_shutdown (); | 594 | GNUNET_SCHEDULER_shutdown (); |
584 | return; | 595 | return; |
585 | } | 596 | } |
@@ -691,6 +702,13 @@ sign_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | |||
691 | // work on keys | 702 | // work on keys |
692 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego); | 703 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego); |
693 | 704 | ||
705 | if (NULL == subject_pubkey_str) | ||
706 | { | ||
707 | fprintf (stderr, | ||
708 | "Subject pubkey not given\n"); | ||
709 | GNUNET_SCHEDULER_shutdown (); | ||
710 | return; | ||
711 | } | ||
694 | if (GNUNET_OK != | 712 | if (GNUNET_OK != |
695 | GNUNET_IDENTITY_public_key_from_string (subject_pubkey_str, | 713 | GNUNET_IDENTITY_public_key_from_string (subject_pubkey_str, |
696 | &subject_pkey)) | 714 | &subject_pkey)) |
diff --git a/src/abd/gnunet-service-abd.c b/src/abd/gnunet-service-abd.c index 3f9f2f924..407d5bdc3 100644 --- a/src/abd/gnunet-service-abd.c +++ b/src/abd/gnunet-service-abd.c | |||
@@ -512,6 +512,8 @@ send_intermediate_response (struct VerifyRequestHandle *vrh, struct | |||
512 | size, | 512 | size, |
513 | (char *) &rmsg[1])); | 513 | (char *) &rmsg[1])); |
514 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env); | 514 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (vrh->client), env); |
515 | |||
516 | GNUNET_free (dd); | ||
515 | } | 517 | } |
516 | 518 | ||
517 | 519 | ||
@@ -740,12 +742,13 @@ forward_resolution (void *cls, | |||
740 | uint32_t rd_count, | 742 | uint32_t rd_count, |
741 | const struct GNUNET_GNSRECORD_Data *rd) | 743 | const struct GNUNET_GNSRECORD_Data *rd) |
742 | { | 744 | { |
743 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count); | ||
744 | |||
745 | struct VerifyRequestHandle *vrh; | 745 | struct VerifyRequestHandle *vrh; |
746 | struct DelegationSetQueueEntry *current_set; | 746 | struct DelegationSetQueueEntry *current_set; |
747 | struct DelegationSetQueueEntry *ds_entry; | 747 | struct DelegationSetQueueEntry *ds_entry; |
748 | struct DelegationQueueEntry *dq_entry; | 748 | struct DelegationQueueEntry *dq_entry; |
749 | struct GNUNET_ABD_Delegate *del; | ||
750 | |||
751 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %d entries.\n", rd_count); | ||
749 | 752 | ||
750 | current_set = cls; | 753 | current_set = cls; |
751 | // set handle to NULL (as el = NULL) | 754 | // set handle to NULL (as el = NULL) |
@@ -760,9 +763,11 @@ forward_resolution (void *cls, | |||
760 | continue; | 763 | continue; |
761 | 764 | ||
762 | // Start deserialize into Delegate | 765 | // Start deserialize into Delegate |
763 | struct GNUNET_ABD_Delegate *del; | ||
764 | del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size); | 766 | del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size); |
765 | 767 | ||
768 | if (NULL == del) | ||
769 | continue; | ||
770 | |||
766 | // Start: Create DQ Entry | 771 | // Start: Create DQ Entry |
767 | dq_entry = GNUNET_new (struct DelegationQueueEntry); | 772 | dq_entry = GNUNET_new (struct DelegationQueueEntry); |
768 | // AND delegations are not possible, only 1 solution | 773 | // AND delegations are not possible, only 1 solution |
@@ -834,6 +839,7 @@ forward_resolution (void *cls, | |||
834 | GNUNET_IDENTITY_public_key_to_string ( | 839 | GNUNET_IDENTITY_public_key_to_string ( |
835 | &del->subject_key), | 840 | &del->subject_key), |
836 | del->subject_attribute); | 841 | del->subject_attribute); |
842 | GNUNET_free (del); | ||
837 | continue; | 843 | continue; |
838 | } | 844 | } |
839 | else | 845 | else |
@@ -910,6 +916,7 @@ forward_resolution (void *cls, | |||
910 | } | 916 | } |
911 | 917 | ||
912 | send_lookup_response (vrh); | 918 | send_lookup_response (vrh); |
919 | GNUNET_free (del); | ||
913 | return; | 920 | return; |
914 | } | 921 | } |
915 | } | 922 | } |
@@ -936,6 +943,7 @@ forward_resolution (void *cls, | |||
936 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
937 | "Forward: Found match with above!\n"); | 944 | "Forward: Found match with above!\n"); |
938 | 945 | ||
946 | GNUNET_free (del); | ||
939 | // one node on the path still needs solutions: return | 947 | // one node on the path still needs solutions: return |
940 | if (GNUNET_NO == | 948 | if (GNUNET_NO == |
941 | handle_bidirectional_match (ds_entry, del_entry, vrh)) | 949 | handle_bidirectional_match (ds_entry, del_entry, vrh)) |
@@ -965,6 +973,7 @@ forward_resolution (void *cls, | |||
965 | GNUNET_GNS_LO_DEFAULT, | 973 | GNUNET_GNS_LO_DEFAULT, |
966 | &forward_resolution, | 974 | &forward_resolution, |
967 | ds_entry); | 975 | ds_entry); |
976 | GNUNET_free (del); | ||
968 | } | 977 | } |
969 | 978 | ||
970 | if (0 == vrh->pending_lookups) | 979 | if (0 == vrh->pending_lookups) |
@@ -1586,34 +1595,29 @@ handle_delegate_collection_cb (void *cls, | |||
1586 | const struct GNUNET_GNSRECORD_Data *rd) | 1595 | const struct GNUNET_GNSRECORD_Data *rd) |
1587 | { | 1596 | { |
1588 | struct VerifyRequestHandle *vrh = cls; | 1597 | struct VerifyRequestHandle *vrh = cls; |
1589 | struct GNUNET_ABD_Delegate *del; | ||
1590 | struct DelegateRecordEntry *del_entry; | 1598 | struct DelegateRecordEntry *del_entry; |
1591 | int cred_record_count; | ||
1592 | cred_record_count = 0; | ||
1593 | vrh->dele_qe = NULL; | 1599 | vrh->dele_qe = NULL; |
1594 | 1600 | ||
1595 | for (uint32_t i = 0; i < rd_count; i++) | 1601 | for (uint32_t i = 0; i < rd_count; i++) |
1596 | { | 1602 | { |
1597 | if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) | 1603 | if (GNUNET_GNSRECORD_TYPE_DELEGATE != rd[i].record_type) |
1598 | continue; | 1604 | continue; |
1599 | cred_record_count++; | ||
1600 | del = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size); | ||
1601 | if (NULL == del) | ||
1602 | { | ||
1603 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n"); | ||
1604 | continue; | ||
1605 | } | ||
1606 | // only add the entries that are explicitly marked as private | 1605 | // only add the entries that are explicitly marked as private |
1607 | // and therefore symbolize the end of a chain | 1606 | // and therefore symbolize the end of a chain |
1608 | if (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE) | 1607 | if (0 == (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) |
1608 | continue; | ||
1609 | del_entry = GNUNET_new (struct DelegateRecordEntry); | ||
1610 | del_entry->delegate = GNUNET_ABD_delegate_deserialize (rd[i].data, rd[i].data_size); | ||
1611 | if (NULL == del_entry->delegate) | ||
1609 | { | 1612 | { |
1610 | del_entry = GNUNET_new (struct DelegateRecordEntry); | 1613 | GNUNET_free (del_entry); |
1611 | del_entry->delegate = del; | 1614 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid delegate found\n"); |
1612 | GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, | 1615 | continue; |
1613 | vrh->del_chain_tail, | ||
1614 | del_entry); | ||
1615 | vrh->del_chain_size++; | ||
1616 | } | 1616 | } |
1617 | GNUNET_CONTAINER_DLL_insert_tail (vrh->del_chain_head, | ||
1618 | vrh->del_chain_tail, | ||
1619 | del_entry); | ||
1620 | vrh->del_chain_size++; | ||
1617 | } | 1621 | } |
1618 | 1622 | ||
1619 | delegate_collection_finished (vrh); | 1623 | delegate_collection_finished (vrh); |
diff --git a/src/abd/plugin_gnsrecord_abd.c b/src/abd/plugin_gnsrecord_abd.c index 24cf6a3aa..7b2f4af5b 100644 --- a/src/abd/plugin_gnsrecord_abd.c +++ b/src/abd/plugin_gnsrecord_abd.c | |||
@@ -207,8 +207,13 @@ abd_string_to_value (void *cls, | |||
207 | matches = sscanf (token, "%s %s", subject_pkey, attr_str); | 207 | matches = sscanf (token, "%s %s", subject_pkey, attr_str); |
208 | 208 | ||
209 | // sets the public key for the set entry | 209 | // sets the public key for the set entry |
210 | GNUNET_IDENTITY_public_key_from_string (subject_pkey, | 210 | if (GNUNET_SYSERR == |
211 | &set[i].subject_key); | 211 | GNUNET_IDENTITY_public_key_from_string (subject_pkey, |
212 | &set[i].subject_key)) | ||
213 | { | ||
214 | GNUNET_free (tmp_str); | ||
215 | return GNUNET_SYSERR; | ||
216 | } | ||
212 | 217 | ||
213 | // If not just key, also set subject attribute (Not A.a <- B but A.a <- B.b) | 218 | // If not just key, also set subject attribute (Not A.a <- B but A.a <- B.b) |
214 | if (2 == matches) | 219 | if (2 == matches) |
@@ -252,7 +257,7 @@ abd_string_to_value (void *cls, | |||
252 | cred = GNUNET_ABD_delegate_from_string (s); | 257 | cred = GNUNET_ABD_delegate_from_string (s); |
253 | 258 | ||
254 | *data_size = GNUNET_ABD_delegate_serialize (cred, (char **) data); | 259 | *data_size = GNUNET_ABD_delegate_serialize (cred, (char **) data); |
255 | 260 | GNUNET_free (cred); | |
256 | return GNUNET_OK; | 261 | return GNUNET_OK; |
257 | } | 262 | } |
258 | default: | 263 | default: |
diff --git a/src/block/block.c b/src/block/block.c index 975c0f747..5824946f7 100644 --- a/src/block/block.c +++ b/src/block/block.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010, 2017 GNUnet e.V. | 3 | Copyright (C) 2010, 2017, 2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -70,13 +70,6 @@ struct GNUNET_BLOCK_Context | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | 72 | ||
73 | /** | ||
74 | * Mingle hash with the mingle_number to produce different bits. | ||
75 | * | ||
76 | * @param in original hash code | ||
77 | * @param mingle_number number for hash permutation | ||
78 | * @param hc where to store the result. | ||
79 | */ | ||
80 | void | 73 | void |
81 | GNUNET_BLOCK_mingle_hash (const struct GNUNET_HashCode *in, | 74 | GNUNET_BLOCK_mingle_hash (const struct GNUNET_HashCode *in, |
82 | uint32_t mingle_number, | 75 | uint32_t mingle_number, |
@@ -121,12 +114,6 @@ add_plugin (void *cls, | |||
121 | } | 114 | } |
122 | 115 | ||
123 | 116 | ||
124 | /** | ||
125 | * Create a block context. Loads the block plugins. | ||
126 | * | ||
127 | * @param cfg configuration to use | ||
128 | * @return NULL on error | ||
129 | */ | ||
130 | struct GNUNET_BLOCK_Context * | 117 | struct GNUNET_BLOCK_Context * |
131 | GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg) | 118 | GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg) |
132 | { | 119 | { |
@@ -143,11 +130,6 @@ GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
143 | } | 130 | } |
144 | 131 | ||
145 | 132 | ||
146 | /** | ||
147 | * Destroy the block context. | ||
148 | * | ||
149 | * @param ctx context to destroy | ||
150 | */ | ||
151 | void | 133 | void |
152 | GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx) | 134 | GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx) |
153 | { | 135 | { |
@@ -167,17 +149,7 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx) | |||
167 | } | 149 | } |
168 | 150 | ||
169 | 151 | ||
170 | /** | 152 | enum GNUNET_GenericReturnValue |
171 | * Serialize state of a block group. | ||
172 | * | ||
173 | * @param bg group to serialize | ||
174 | * @param[out] nonce set to the nonce of the @a bg | ||
175 | * @param[out] raw_data set to the serialized state | ||
176 | * @param[out] raw_data_size set to the number of bytes in @a raw_data | ||
177 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not | ||
178 | * supported, #GNUNET_SYSERR on error | ||
179 | */ | ||
180 | int | ||
181 | GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, | 153 | GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, |
182 | uint32_t *nonce, | 154 | uint32_t *nonce, |
183 | void **raw_data, | 155 | void **raw_data, |
@@ -197,11 +169,6 @@ GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, | |||
197 | } | 169 | } |
198 | 170 | ||
199 | 171 | ||
200 | /** | ||
201 | * Destroy resources used by a block group. | ||
202 | * | ||
203 | * @param bg group to destroy, NULL is allowed | ||
204 | */ | ||
205 | void | 172 | void |
206 | GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg) | 173 | GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg) |
207 | { | 174 | { |
@@ -211,23 +178,11 @@ GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg) | |||
211 | } | 178 | } |
212 | 179 | ||
213 | 180 | ||
214 | /** | 181 | enum GNUNET_GenericReturnValue |
215 | * Try merging two block groups. Afterwards, @a bg1 should remain | ||
216 | * valid and contain the rules from both @a bg1 and @bg2, and | ||
217 | * @a bg2 should be destroyed (as part of this call). The latter | ||
218 | * should happen even if merging is not supported. | ||
219 | * | ||
220 | * @param[in,out] bg1 first group to merge, is updated | ||
221 | * @param bg2 second group to merge, is destroyed | ||
222 | * @return #GNUNET_OK on success, | ||
223 | * #GNUNET_NO if merge failed due to different nonce | ||
224 | * #GNUNET_SYSERR if merging is not supported | ||
225 | */ | ||
226 | int | ||
227 | GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1, | 182 | GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1, |
228 | struct GNUNET_BLOCK_Group *bg2) | 183 | struct GNUNET_BLOCK_Group *bg2) |
229 | { | 184 | { |
230 | int ret; | 185 | enum GNUNET_GenericReturnValue ret; |
231 | 186 | ||
232 | if (NULL == bg2) | 187 | if (NULL == bg2) |
233 | return GNUNET_OK; | 188 | return GNUNET_OK; |
@@ -257,35 +212,18 @@ static struct GNUNET_BLOCK_PluginFunctions * | |||
257 | find_plugin (struct GNUNET_BLOCK_Context *ctx, | 212 | find_plugin (struct GNUNET_BLOCK_Context *ctx, |
258 | enum GNUNET_BLOCK_Type type) | 213 | enum GNUNET_BLOCK_Type type) |
259 | { | 214 | { |
260 | struct Plugin *plugin; | ||
261 | unsigned int j; | ||
262 | |||
263 | for (unsigned i = 0; i < ctx->num_plugins; i++) | 215 | for (unsigned i = 0; i < ctx->num_plugins; i++) |
264 | { | 216 | { |
265 | plugin = ctx->plugins[i]; | 217 | struct Plugin *plugin = ctx->plugins[i]; |
266 | j = 0; | 218 | |
267 | while (0 != (plugin->api->types[j])) | 219 | for (unsigned int j = 0; 0 != plugin->api->types[j]; j++) |
268 | { | ||
269 | if (type == plugin->api->types[j]) | 220 | if (type == plugin->api->types[j]) |
270 | return plugin->api; | 221 | return plugin->api; |
271 | j++; | ||
272 | } | ||
273 | } | 222 | } |
274 | return NULL; | 223 | return NULL; |
275 | } | 224 | } |
276 | 225 | ||
277 | 226 | ||
278 | /** | ||
279 | * Create a new block group. | ||
280 | * | ||
281 | * @param ctx block context in which the block group is created | ||
282 | * @param type type of the block for which we are creating the group | ||
283 | * @param nonce random value used to seed the group creation | ||
284 | * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh | ||
285 | * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh | ||
286 | * @return block group handle, NULL if block groups are not supported | ||
287 | * by this @a type of block (this is not an error) | ||
288 | */ | ||
289 | struct GNUNET_BLOCK_Group * | 227 | struct GNUNET_BLOCK_Group * |
290 | GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, | 228 | GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, |
291 | enum GNUNET_BLOCK_Type type, | 229 | enum GNUNET_BLOCK_Type type, |
@@ -317,24 +255,6 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, | |||
317 | } | 255 | } |
318 | 256 | ||
319 | 257 | ||
320 | /** | ||
321 | * Function called to validate a reply or a request. For | ||
322 | * request evaluation, simply pass "NULL" for the reply_block. | ||
323 | * Note that it is assumed that the reply has already been | ||
324 | * matched to the key (and signatures checked) as it would | ||
325 | * be done with the "get_key" function. | ||
326 | * | ||
327 | * @param ctx block contxt | ||
328 | * @param type block type | ||
329 | * @param block block group to use | ||
330 | * @param eo control flags | ||
331 | * @param query original query (hash) | ||
332 | * @param xquery extended query data (can be NULL, depending on type) | ||
333 | * @param xquery_size number of bytes in @a xquery | ||
334 | * @param reply_block response to validate | ||
335 | * @param reply_block_size number of bytes in @a reply_block | ||
336 | * @return characterization of result | ||
337 | */ | ||
338 | enum GNUNET_BLOCK_EvaluationResult | 258 | enum GNUNET_BLOCK_EvaluationResult |
339 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | 259 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, |
340 | enum GNUNET_BLOCK_Type type, | 260 | enum GNUNET_BLOCK_Type type, |
@@ -364,18 +284,7 @@ GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | |||
364 | } | 284 | } |
365 | 285 | ||
366 | 286 | ||
367 | /** | 287 | enum GNUNET_GenericReturnValue |
368 | * Function called to obtain the key for a block. | ||
369 | * | ||
370 | * @param ctx block context | ||
371 | * @param type block type | ||
372 | * @param block block to get the key for | ||
373 | * @param block_size number of bytes in @a block | ||
374 | * @param key set to the key (query) for the given block | ||
375 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | ||
376 | * (or if extracting a key from a block of this type does not work) | ||
377 | */ | ||
378 | int | ||
379 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | 288 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, |
380 | enum GNUNET_BLOCK_Type type, | 289 | enum GNUNET_BLOCK_Type type, |
381 | const void *block, | 290 | const void *block, |
@@ -385,8 +294,8 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | |||
385 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, | 294 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, |
386 | type); | 295 | type); |
387 | 296 | ||
388 | if (plugin == NULL) | 297 | if (NULL == plugin) |
389 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 298 | return GNUNET_SYSERR; |
390 | return plugin->get_key (plugin->cls, | 299 | return plugin->get_key (plugin->cls, |
391 | type, | 300 | type, |
392 | block, | 301 | block, |
@@ -395,18 +304,73 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | |||
395 | } | 304 | } |
396 | 305 | ||
397 | 306 | ||
398 | /** | 307 | enum GNUNET_GenericReturnValue |
399 | * Update block group to filter out the given results. Note that the | 308 | GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, |
400 | * use of a hash for seen results implies that the caller magically | 309 | enum GNUNET_BLOCK_Type type, |
401 | * knows how the specific block engine hashes for filtering | 310 | const struct GNUNET_HashCode *query, |
402 | * duplicates, so this API may not always apply. | 311 | const void *xquery, |
403 | * | 312 | size_t xquery_size) |
404 | * @param bf_mutator mutation value to use | 313 | { |
405 | * @param seen_results results already seen | 314 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, |
406 | * @param seen_results_count number of entries in @a seen_results | 315 | type); |
407 | * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success | 316 | |
408 | */ | 317 | if (NULL == plugin) |
409 | int | 318 | return GNUNET_SYSERR; |
319 | return plugin->check_query (plugin->cls, | ||
320 | type, | ||
321 | query, | ||
322 | xquery, | ||
323 | xquery_size); | ||
324 | } | ||
325 | |||
326 | |||
327 | enum GNUNET_GenericReturnValue | ||
328 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | ||
329 | enum GNUNET_BLOCK_Type type, | ||
330 | const struct GNUNET_HashCode *query, | ||
331 | const void *block, | ||
332 | size_t block_size) | ||
333 | { | ||
334 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, | ||
335 | type); | ||
336 | |||
337 | if (NULL == plugin) | ||
338 | return GNUNET_SYSERR; | ||
339 | return plugin->check_block (plugin->cls, | ||
340 | type, | ||
341 | query, | ||
342 | block, | ||
343 | block_size); | ||
344 | } | ||
345 | |||
346 | |||
347 | enum GNUNET_BLOCK_ReplyEvaluationResult | ||
348 | GNUNET_BLOCK_check_reply (struct GNUNET_BLOCK_Context *ctx, | ||
349 | enum GNUNET_BLOCK_Type type, | ||
350 | struct GNUNET_BLOCK_Group *group, | ||
351 | const struct GNUNET_HashCode *query, | ||
352 | const void *xquery, | ||
353 | size_t xquery_size, | ||
354 | const void *reply_block, | ||
355 | size_t reply_block_size) | ||
356 | { | ||
357 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, | ||
358 | type); | ||
359 | |||
360 | if (NULL == plugin) | ||
361 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
362 | return plugin->check_reply (plugin->cls, | ||
363 | type, | ||
364 | group, | ||
365 | query, | ||
366 | xquery, | ||
367 | xquery_size, | ||
368 | reply_block, | ||
369 | reply_block_size); | ||
370 | } | ||
371 | |||
372 | |||
373 | enum GNUNET_GenericReturnValue | ||
410 | GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, | 374 | GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, |
411 | const struct GNUNET_HashCode *seen_results, | 375 | const struct GNUNET_HashCode *seen_results, |
412 | unsigned int seen_results_count) | 376 | unsigned int seen_results_count) |
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c index ecd46e364..13d9adfda 100644 --- a/src/block/plugin_block_template.c +++ b/src/block/plugin_block_template.c | |||
@@ -135,6 +135,80 @@ block_plugin_template_evaluate (void *cls, | |||
135 | 135 | ||
136 | 136 | ||
137 | /** | 137 | /** |
138 | * Function called to validate a query. | ||
139 | * | ||
140 | * @param cls closure | ||
141 | * @param ctx block context | ||
142 | * @param type block type | ||
143 | * @param query original query (hash) | ||
144 | * @param xquery extrended query data (can be NULL, depending on type) | ||
145 | * @param xquery_size number of bytes in @a xquery | ||
146 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
147 | */ | ||
148 | static enum GNUNET_GenericReturnValue | ||
149 | block_plugin_template_check_query (void *cls, | ||
150 | enum GNUNET_BLOCK_Type type, | ||
151 | const struct GNUNET_HashCode *query, | ||
152 | const void *xquery, | ||
153 | size_t xquery_size) | ||
154 | { | ||
155 | return GNUNET_OK; | ||
156 | } | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Function called to validate a block for storage. | ||
161 | * | ||
162 | * @param cls closure | ||
163 | * @param type block type | ||
164 | * @param query key for the block (hash), must match exactly | ||
165 | * @param block block data to validate | ||
166 | * @param block_size number of bytes in @a block | ||
167 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
168 | */ | ||
169 | static enum GNUNET_GenericReturnValue | ||
170 | block_plugin_template_check_block (void *cls, | ||
171 | enum GNUNET_BLOCK_Type type, | ||
172 | const struct GNUNET_HashCode *query, | ||
173 | const void *block, | ||
174 | size_t block_size) | ||
175 | { | ||
176 | return GNUNET_OK; | ||
177 | } | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Function called to validate a reply to a request. Note that it is assumed | ||
182 | * that the reply has already been matched to the key (and signatures checked) | ||
183 | * as it would be done with the GetKeyFunction and the | ||
184 | * BlockEvaluationFunction. | ||
185 | * | ||
186 | * @param cls closure | ||
187 | * @param type block type | ||
188 | * @param group which block group to use for evaluation | ||
189 | * @param query original query (hash) | ||
190 | * @param xquery extrended query data (can be NULL, depending on type) | ||
191 | * @param xquery_size number of bytes in @a xquery | ||
192 | * @param reply_block response to validate | ||
193 | * @param reply_block_size number of bytes in @a reply_block | ||
194 | * @return characterization of result | ||
195 | */ | ||
196 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
197 | block_plugin_template_check_reply ( | ||
198 | void *cls, | ||
199 | enum GNUNET_BLOCK_Type type, | ||
200 | struct GNUNET_BLOCK_Group *group, | ||
201 | const struct GNUNET_HashCode *query, | ||
202 | const void *xquery, | ||
203 | size_t xquery_size, | ||
204 | const void *reply_block, | ||
205 | size_t reply_block_size) | ||
206 | { | ||
207 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
208 | } | ||
209 | |||
210 | |||
211 | /** | ||
138 | * Function called to obtain the key for a block. | 212 | * Function called to obtain the key for a block. |
139 | * | 213 | * |
140 | * @param cls closure | 214 | * @param cls closure |
@@ -145,7 +219,7 @@ block_plugin_template_evaluate (void *cls, | |||
145 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 219 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
146 | * (or if extracting a key from a block of this type does not work) | 220 | * (or if extracting a key from a block of this type does not work) |
147 | */ | 221 | */ |
148 | static int | 222 | static enum GNUNET_GenericReturnValue |
149 | block_plugin_template_get_key (void *cls, | 223 | block_plugin_template_get_key (void *cls, |
150 | enum GNUNET_BLOCK_Type type, | 224 | enum GNUNET_BLOCK_Type type, |
151 | const void *block, | 225 | const void *block, |
@@ -164,8 +238,8 @@ block_plugin_template_get_key (void *cls, | |||
164 | void * | 238 | void * |
165 | libgnunet_plugin_block_template_init (void *cls) | 239 | libgnunet_plugin_block_template_init (void *cls) |
166 | { | 240 | { |
167 | static enum GNUNET_BLOCK_Type types[] = { | 241 | static const enum GNUNET_BLOCK_Type types[] = { |
168 | /* FIXME: insert supported block types here */ | 242 | /* NOTE: insert supported block types here */ |
169 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 243 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
170 | }; | 244 | }; |
171 | struct GNUNET_BLOCK_PluginFunctions *api; | 245 | struct GNUNET_BLOCK_PluginFunctions *api; |
@@ -173,6 +247,9 @@ libgnunet_plugin_block_template_init (void *cls) | |||
173 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 247 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
174 | api->evaluate = &block_plugin_template_evaluate; | 248 | api->evaluate = &block_plugin_template_evaluate; |
175 | api->get_key = &block_plugin_template_get_key; | 249 | api->get_key = &block_plugin_template_get_key; |
250 | api->check_query = &block_plugin_template_check_query; | ||
251 | api->check_block = &block_plugin_template_check_block; | ||
252 | api->check_reply = &block_plugin_template_check_reply; | ||
176 | api->create_group = &block_plugin_template_create_group; | 253 | api->create_group = &block_plugin_template_create_group; |
177 | api->types = types; | 254 | api->types = types; |
178 | return api; | 255 | return api; |
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c index 45d54d339..fd643c4dc 100644 --- a/src/block/plugin_block_test.c +++ b/src/block/plugin_block_test.c | |||
@@ -143,6 +143,108 @@ block_plugin_test_evaluate (void *cls, | |||
143 | 143 | ||
144 | 144 | ||
145 | /** | 145 | /** |
146 | * Function called to validate a query. | ||
147 | * | ||
148 | * @param cls closure | ||
149 | * @param ctx block context | ||
150 | * @param type block type | ||
151 | * @param query original query (hash) | ||
152 | * @param xquery extrended query data (can be NULL, depending on type) | ||
153 | * @param xquery_size number of bytes in @a xquery | ||
154 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
155 | */ | ||
156 | static enum GNUNET_GenericReturnValue | ||
157 | block_plugin_test_check_query (void *cls, | ||
158 | enum GNUNET_BLOCK_Type type, | ||
159 | const struct GNUNET_HashCode *query, | ||
160 | const void *xquery, | ||
161 | size_t xquery_size) | ||
162 | { | ||
163 | if (GNUNET_BLOCK_TYPE_TEST != type) | ||
164 | { | ||
165 | GNUNET_break (0); | ||
166 | return GNUNET_SYSERR; | ||
167 | } | ||
168 | if (0 != xquery_size) | ||
169 | { | ||
170 | GNUNET_break_op (0); | ||
171 | return GNUNET_SYSERR; | ||
172 | } | ||
173 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
174 | } | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Function called to validate a block for storage. | ||
179 | * | ||
180 | * @param cls closure | ||
181 | * @param type block type | ||
182 | * @param query key for the block (hash), must match exactly | ||
183 | * @param block block data to validate | ||
184 | * @param block_size number of bytes in @a block | ||
185 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
186 | */ | ||
187 | static enum GNUNET_GenericReturnValue | ||
188 | block_plugin_test_check_block (void *cls, | ||
189 | enum GNUNET_BLOCK_Type type, | ||
190 | const struct GNUNET_HashCode *query, | ||
191 | const void *block, | ||
192 | size_t block_size) | ||
193 | { | ||
194 | if (GNUNET_BLOCK_TYPE_TEST != type) | ||
195 | { | ||
196 | GNUNET_break (0); | ||
197 | return GNUNET_SYSERR; | ||
198 | } | ||
199 | return GNUNET_OK; | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * Function called to validate a reply to a request. Note that it is assumed | ||
205 | * that the reply has already been matched to the key (and signatures checked) | ||
206 | * as it would be done with the GetKeyFunction and the | ||
207 | * BlockEvaluationFunction. | ||
208 | * | ||
209 | * @param cls closure | ||
210 | * @param type block type | ||
211 | * @param group which block group to use for evaluation | ||
212 | * @param query original query (hash) | ||
213 | * @param xquery extrended query data (can be NULL, depending on type) | ||
214 | * @param xquery_size number of bytes in @a xquery | ||
215 | * @param reply_block response to validate | ||
216 | * @param reply_block_size number of bytes in @a reply_block | ||
217 | * @return characterization of result | ||
218 | */ | ||
219 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
220 | block_plugin_test_check_reply (void *cls, | ||
221 | enum GNUNET_BLOCK_Type type, | ||
222 | struct GNUNET_BLOCK_Group *group, | ||
223 | const struct GNUNET_HashCode *query, | ||
224 | const void *xquery, | ||
225 | size_t xquery_size, | ||
226 | const void *reply_block, | ||
227 | size_t reply_block_size) | ||
228 | { | ||
229 | struct GNUNET_HashCode chash; | ||
230 | |||
231 | if (GNUNET_BLOCK_TYPE_TEST != type) | ||
232 | { | ||
233 | GNUNET_break (0); | ||
234 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
235 | } | ||
236 | GNUNET_CRYPTO_hash (reply_block, | ||
237 | reply_block_size, | ||
238 | &chash); | ||
239 | if (GNUNET_YES == | ||
240 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
241 | &chash)) | ||
242 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
243 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
244 | } | ||
245 | |||
246 | |||
247 | /** | ||
146 | * Function called to obtain the key for a block. | 248 | * Function called to obtain the key for a block. |
147 | * | 249 | * |
148 | * @param cls closure | 250 | * @param cls closure |
@@ -153,7 +255,7 @@ block_plugin_test_evaluate (void *cls, | |||
153 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 255 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
154 | * (or if extracting a key from a block of this type does not work) | 256 | * (or if extracting a key from a block of this type does not work) |
155 | */ | 257 | */ |
156 | static int | 258 | static enum GNUNET_GenericReturnValue |
157 | block_plugin_test_get_key (void *cls, | 259 | block_plugin_test_get_key (void *cls, |
158 | enum GNUNET_BLOCK_Type type, | 260 | enum GNUNET_BLOCK_Type type, |
159 | const void *block, | 261 | const void *block, |
@@ -175,7 +277,7 @@ block_plugin_test_get_key (void *cls, | |||
175 | void * | 277 | void * |
176 | libgnunet_plugin_block_test_init (void *cls) | 278 | libgnunet_plugin_block_test_init (void *cls) |
177 | { | 279 | { |
178 | static enum GNUNET_BLOCK_Type types[] = { | 280 | static const enum GNUNET_BLOCK_Type types[] = { |
179 | GNUNET_BLOCK_TYPE_TEST, | 281 | GNUNET_BLOCK_TYPE_TEST, |
180 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 282 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
181 | }; | 283 | }; |
@@ -184,6 +286,9 @@ libgnunet_plugin_block_test_init (void *cls) | |||
184 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 286 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
185 | api->evaluate = &block_plugin_test_evaluate; | 287 | api->evaluate = &block_plugin_test_evaluate; |
186 | api->get_key = &block_plugin_test_get_key; | 288 | api->get_key = &block_plugin_test_get_key; |
289 | api->check_query = &block_plugin_test_check_query; | ||
290 | api->check_block = &block_plugin_test_check_block; | ||
291 | api->check_reply = &block_plugin_test_check_reply; | ||
187 | api->create_group = &block_plugin_test_create_group; | 292 | api->create_group = &block_plugin_test_create_group; |
188 | api->types = types; | 293 | api->types = types; |
189 | return api; | 294 | return api; |
diff --git a/src/consensus/plugin_block_consensus.c b/src/consensus/plugin_block_consensus.c index cdac12ed5..67309bc79 100644 --- a/src/consensus/plugin_block_consensus.c +++ b/src/consensus/plugin_block_consensus.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2017 GNUnet e.V. | 3 | Copyright (C) 2017, 2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -80,6 +80,109 @@ block_plugin_consensus_evaluate (void *cls, | |||
80 | 80 | ||
81 | 81 | ||
82 | /** | 82 | /** |
83 | * Function called to validate a query. | ||
84 | * | ||
85 | * @param cls closure | ||
86 | * @param ctx block context | ||
87 | * @param type block type | ||
88 | * @param query original query (hash) | ||
89 | * @param xquery extrended query data (can be NULL, depending on type) | ||
90 | * @param xquery_size number of bytes in @a xquery | ||
91 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
92 | */ | ||
93 | static enum GNUNET_GenericReturnValue | ||
94 | block_plugin_consensus_check_query (void *cls, | ||
95 | enum GNUNET_BLOCK_Type type, | ||
96 | const struct GNUNET_HashCode *query, | ||
97 | const void *xquery, | ||
98 | size_t xquery_size) | ||
99 | { | ||
100 | /* consensus does not use queries/DHT */ | ||
101 | GNUNET_break (0); | ||
102 | return GNUNET_SYSERR; | ||
103 | } | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Function called to validate a block for storage. | ||
108 | * | ||
109 | * @param cls closure | ||
110 | * @param type block type | ||
111 | * @param query key for the block (hash), must match exactly | ||
112 | * @param block block data to validate | ||
113 | * @param block_size number of bytes in @a block | ||
114 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
115 | */ | ||
116 | static enum GNUNET_GenericReturnValue | ||
117 | block_plugin_consensus_check_block (void *cls, | ||
118 | enum GNUNET_BLOCK_Type type, | ||
119 | const struct GNUNET_HashCode *query, | ||
120 | const void *block, | ||
121 | size_t block_size) | ||
122 | { | ||
123 | struct GNUNET_BLOCK_Context *ctx = cls; | ||
124 | const struct ConsensusElement *ce = block; | ||
125 | |||
126 | if (block_size < sizeof(*ce)) | ||
127 | return GNUNET_NO; | ||
128 | if ( (0 != ce->marker) || | ||
129 | (0 == ce->payload_type) ) | ||
130 | return GNUNET_OK; | ||
131 | return GNUNET_BLOCK_check_block (ctx, | ||
132 | ntohl (ce->payload_type), | ||
133 | query, | ||
134 | &ce[1], | ||
135 | block_size - sizeof(*ce)); | ||
136 | } | ||
137 | |||
138 | |||
139 | /** | ||
140 | * Function called to validate a reply to a request. Note that it is assumed | ||
141 | * that the reply has already been matched to the key (and signatures checked) | ||
142 | * as it would be done with the GetKeyFunction and the | ||
143 | * BlockEvaluationFunction. | ||
144 | * | ||
145 | * @param cls closure | ||
146 | * @param type block type | ||
147 | * @param group which block group to use for evaluation | ||
148 | * @param query original query (hash) | ||
149 | * @param xquery extrended query data (can be NULL, depending on type) | ||
150 | * @param xquery_size number of bytes in @a xquery | ||
151 | * @param reply_block response to validate | ||
152 | * @param reply_block_size number of bytes in @a reply_block | ||
153 | * @return characterization of result | ||
154 | */ | ||
155 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
156 | block_plugin_consensus_check_reply ( | ||
157 | void *cls, | ||
158 | enum GNUNET_BLOCK_Type type, | ||
159 | struct GNUNET_BLOCK_Group *group, | ||
160 | const struct GNUNET_HashCode *query, | ||
161 | const void *xquery, | ||
162 | size_t xquery_size, | ||
163 | const void *reply_block, | ||
164 | size_t reply_block_size) | ||
165 | { | ||
166 | struct GNUNET_BLOCK_Context *ctx = cls; | ||
167 | const struct ConsensusElement *ce = reply_block; | ||
168 | |||
169 | if (reply_block_size < sizeof(struct ConsensusElement)) | ||
170 | return GNUNET_NO; | ||
171 | if ( (0 != ce->marker) || | ||
172 | (0 == ce->payload_type) ) | ||
173 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
174 | return GNUNET_BLOCK_check_reply (ctx, | ||
175 | ntohl (ce->payload_type), | ||
176 | group, | ||
177 | query, | ||
178 | xquery, | ||
179 | xquery_size, | ||
180 | &ce[1], | ||
181 | reply_block_size - sizeof(*ce)); | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
83 | * Function called to obtain the key for a block. | 186 | * Function called to obtain the key for a block. |
84 | * | 187 | * |
85 | * @param cls closure | 188 | * @param cls closure |
@@ -90,7 +193,7 @@ block_plugin_consensus_evaluate (void *cls, | |||
90 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 193 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
91 | * (or if extracting a key from a block of this type does not work) | 194 | * (or if extracting a key from a block of this type does not work) |
92 | */ | 195 | */ |
93 | static int | 196 | static enum GNUNET_GenericReturnValue |
94 | block_plugin_consensus_get_key (void *cls, | 197 | block_plugin_consensus_get_key (void *cls, |
95 | enum GNUNET_BLOCK_Type type, | 198 | enum GNUNET_BLOCK_Type type, |
96 | const void *block, | 199 | const void *block, |
@@ -107,15 +210,20 @@ block_plugin_consensus_get_key (void *cls, | |||
107 | void * | 210 | void * |
108 | libgnunet_plugin_block_consensus_init (void *cls) | 211 | libgnunet_plugin_block_consensus_init (void *cls) |
109 | { | 212 | { |
110 | static enum GNUNET_BLOCK_Type types[] = { | 213 | static const enum GNUNET_BLOCK_Type types[] = { |
111 | GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT, | 214 | GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT, |
112 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 215 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
113 | }; | 216 | }; |
217 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
114 | struct GNUNET_BLOCK_PluginFunctions *api; | 218 | struct GNUNET_BLOCK_PluginFunctions *api; |
115 | 219 | ||
116 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 220 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
221 | api->cls = GNUNET_BLOCK_context_create (cfg); | ||
117 | api->evaluate = &block_plugin_consensus_evaluate; | 222 | api->evaluate = &block_plugin_consensus_evaluate; |
118 | api->get_key = &block_plugin_consensus_get_key; | 223 | api->get_key = &block_plugin_consensus_get_key; |
224 | api->check_query = &block_plugin_consensus_check_query; | ||
225 | api->check_block = &block_plugin_consensus_check_block; | ||
226 | api->check_reply = &block_plugin_consensus_check_reply; | ||
119 | api->types = types; | 227 | api->types = types; |
120 | return api; | 228 | return api; |
121 | } | 229 | } |
@@ -128,7 +236,9 @@ void * | |||
128 | libgnunet_plugin_block_consensus_done (void *cls) | 236 | libgnunet_plugin_block_consensus_done (void *cls) |
129 | { | 237 | { |
130 | struct GNUNET_BLOCK_PluginFunctions *api = cls; | 238 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
239 | struct GNUNET_BLOCK_Context *bc = api->cls; | ||
131 | 240 | ||
241 | GNUNET_BLOCK_context_destroy (bc); | ||
132 | GNUNET_free (api); | 242 | GNUNET_free (api); |
133 | return NULL; | 243 | return NULL; |
134 | } | 244 | } |
diff --git a/src/curl/curl.c b/src/curl/curl.c index 684610101..e45612e94 100644 --- a/src/curl/curl.c +++ b/src/curl/curl.c | |||
@@ -201,14 +201,6 @@ struct GNUNET_CURL_Context | |||
201 | }; | 201 | }; |
202 | 202 | ||
203 | 203 | ||
204 | /** | ||
205 | * Force use of the provided username and password | ||
206 | * for client authentication for all operations performed | ||
207 | * with @a ctx. | ||
208 | * | ||
209 | * @param ctx context to set authentication data for | ||
210 | * @param userpass string with "$USERNAME:$PASSWORD" | ||
211 | */ | ||
212 | void | 204 | void |
213 | GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx, | 205 | GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx, |
214 | const char *userpass) | 206 | const char *userpass) |
@@ -219,21 +211,6 @@ GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx, | |||
219 | } | 211 | } |
220 | 212 | ||
221 | 213 | ||
222 | /** | ||
223 | * Force use of the provided TLS client certificate | ||
224 | * for client authentication for all operations performed | ||
225 | * with @a ctx. | ||
226 | * | ||
227 | * Note that if the provided information is incorrect, | ||
228 | * the earliest operation that could fail is | ||
229 | * #GNUNET_CURL_job_add() or #GNUNET_CURL_job_add2()! | ||
230 | * | ||
231 | * @param ctx context to set authentication data for | ||
232 | * @param certtype type of the certificate | ||
233 | * @param certfile file with the certificate | ||
234 | * @param keyfile file with the private key | ||
235 | * @param keypass passphrase to decrypt @a keyfile (or NULL) | ||
236 | */ | ||
237 | void | 214 | void |
238 | GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx, | 215 | GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx, |
239 | const char *certtype, | 216 | const char *certtype, |
@@ -256,14 +233,6 @@ GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx, | |||
256 | } | 233 | } |
257 | 234 | ||
258 | 235 | ||
259 | /** | ||
260 | * Initialise this library. This function should be called before using any of | ||
261 | * the following functions. | ||
262 | * | ||
263 | * @param cb function to call when rescheduling is required | ||
264 | * @param cb_cls closure for @a cb | ||
265 | * @return library context | ||
266 | */ | ||
267 | struct GNUNET_CURL_Context * | 236 | struct GNUNET_CURL_Context * |
268 | GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, | 237 | GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, |
269 | void *cb_cls) | 238 | void *cb_cls) |
@@ -299,12 +268,6 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, | |||
299 | } | 268 | } |
300 | 269 | ||
301 | 270 | ||
302 | /** | ||
303 | * Enable sending the async scope ID as a header. | ||
304 | * | ||
305 | * @param ctx the context to enable this for | ||
306 | * @param header_name name of the header to send. | ||
307 | */ | ||
308 | void | 271 | void |
309 | GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, | 272 | GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, |
310 | const char *header_name) | 273 | const char *header_name) |
@@ -313,15 +276,6 @@ GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, | |||
313 | } | 276 | } |
314 | 277 | ||
315 | 278 | ||
316 | /** | ||
317 | * Return #GNUNET_YES if given a valid scope ID and | ||
318 | * #GNUNET_NO otherwise. See #setup_job_headers, | ||
319 | * logic related to | ||
320 | * #GNUNET_CURL_enable_async_scope_header() for the | ||
321 | * code that generates such a @a scope_id. | ||
322 | * | ||
323 | * @returns #GNUNET_YES iff given a valid scope ID | ||
324 | */ | ||
325 | int | 279 | int |
326 | GNUNET_CURL_is_valid_scope_id (const char *scope_id) | 280 | GNUNET_CURL_is_valid_scope_id (const char *scope_id) |
327 | { | 281 | { |
@@ -447,7 +401,9 @@ setup_job (CURL *eh, | |||
447 | struct GNUNET_CURL_Job *job; | 401 | struct GNUNET_CURL_Job *job; |
448 | 402 | ||
449 | if (CURLE_OK != | 403 | if (CURLE_OK != |
450 | curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers)) | 404 | curl_easy_setopt (eh, |
405 | CURLOPT_HTTPHEADER, | ||
406 | all_headers)) | ||
451 | { | 407 | { |
452 | GNUNET_break (0); | 408 | GNUNET_break (0); |
453 | curl_slist_free_all (all_headers); | 409 | curl_slist_free_all (all_headers); |
@@ -491,12 +447,6 @@ setup_job (CURL *eh, | |||
491 | } | 447 | } |
492 | 448 | ||
493 | 449 | ||
494 | /** | ||
495 | * Add @a extra_headers to the HTTP headers for @a job. | ||
496 | * | ||
497 | * @param[in,out] job the job to modify | ||
498 | * @param extra_headers headers to append | ||
499 | */ | ||
500 | void | 450 | void |
501 | GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job, | 451 | GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job, |
502 | const struct curl_slist *extra_headers) | 452 | const struct curl_slist *extra_headers) |
@@ -515,21 +465,6 @@ GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job, | |||
515 | } | 465 | } |
516 | 466 | ||
517 | 467 | ||
518 | /** | ||
519 | * Schedule a CURL request to be executed and call the given @a jcc | ||
520 | * upon its completion. Note that the context will make use of the | ||
521 | * CURLOPT_PRIVATE facility of the CURL @a eh. Used to download | ||
522 | * resources that are NOT in JSON. The raw body will be returned. | ||
523 | * | ||
524 | * @param ctx context to execute the job in | ||
525 | * @param eh curl easy handle for the request, will | ||
526 | * be executed AND cleaned up | ||
527 | * @param job_headers extra headers to add for this request | ||
528 | * @param max_reply_size largest acceptable response body | ||
529 | * @param jcc callback to invoke upon completion | ||
530 | * @param jcc_cls closure for @a jcc | ||
531 | * @return NULL on error (in this case, @eh is still released!) | ||
532 | */ | ||
533 | struct GNUNET_CURL_Job * | 468 | struct GNUNET_CURL_Job * |
534 | GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx, | 469 | GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx, |
535 | CURL *eh, | 470 | CURL *eh, |
@@ -554,25 +489,6 @@ GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx, | |||
554 | } | 489 | } |
555 | 490 | ||
556 | 491 | ||
557 | /** | ||
558 | * Schedule a CURL request to be executed and call the given @a jcc | ||
559 | * upon its completion. Note that the context will make use of the | ||
560 | * CURLOPT_PRIVATE facility of the CURL @a eh. | ||
561 | * | ||
562 | * This function modifies the CURL handle to add the | ||
563 | * "Content-Type: application/json" header if @a add_json is set. | ||
564 | * | ||
565 | * @param ctx context to execute the job in | ||
566 | * @param eh curl easy handle for the request, will be executed AND | ||
567 | * cleaned up. NOTE: the handle should _never_ have gotten | ||
568 | * any headers list, as that would then be overridden by | ||
569 | * @a jcc. Therefore, always pass custom headers as the | ||
570 | * @a job_headers parameter. | ||
571 | * @param job_headers extra headers to add for this request | ||
572 | * @param jcc callback to invoke upon completion | ||
573 | * @param jcc_cls closure for @a jcc | ||
574 | * @return NULL on error (in this case, @eh is still released!) | ||
575 | */ | ||
576 | struct GNUNET_CURL_Job * | 492 | struct GNUNET_CURL_Job * |
577 | GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, | 493 | GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, |
578 | CURL *eh, | 494 | CURL *eh, |
@@ -624,21 +540,6 @@ GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, | |||
624 | } | 540 | } |
625 | 541 | ||
626 | 542 | ||
627 | /** | ||
628 | * Schedule a CURL request to be executed and call the given @a jcc | ||
629 | * upon its completion. Note that the context will make use of the | ||
630 | * CURLOPT_PRIVATE facility of the CURL @a eh. | ||
631 | * | ||
632 | * This function modifies the CURL handle to add the | ||
633 | * "Content-Type: application/json" header. | ||
634 | * | ||
635 | * @param ctx context to execute the job in | ||
636 | * @param eh curl easy handle for the request, will | ||
637 | * be executed AND cleaned up | ||
638 | * @param jcc callback to invoke upon completion | ||
639 | * @param jcc_cls closure for @a jcc | ||
640 | * @return NULL on error (in this case, @eh is still released!) | ||
641 | */ | ||
642 | struct GNUNET_CURL_Job * | 543 | struct GNUNET_CURL_Job * |
643 | GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx, | 544 | GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx, |
644 | CURL *eh, | 545 | CURL *eh, |
@@ -661,18 +562,6 @@ GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx, | |||
661 | } | 562 | } |
662 | 563 | ||
663 | 564 | ||
664 | /** | ||
665 | * Schedule a CURL request to be executed and call the given @a jcc | ||
666 | * upon its completion. Note that the context will make use of the | ||
667 | * CURLOPT_PRIVATE facility of the CURL @a eh. | ||
668 | * | ||
669 | * @param ctx context to execute the job in | ||
670 | * @param eh curl easy handle for the request, will | ||
671 | * be executed AND cleaned up | ||
672 | * @param jcc callback to invoke upon completion | ||
673 | * @param jcc_cls closure for @a jcc | ||
674 | * @return NULL on error (in this case, @eh is still released!) | ||
675 | */ | ||
676 | struct GNUNET_CURL_Job * | 565 | struct GNUNET_CURL_Job * |
677 | GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, | 566 | GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, |
678 | CURL *eh, | 567 | CURL *eh, |
@@ -687,12 +576,6 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, | |||
687 | } | 576 | } |
688 | 577 | ||
689 | 578 | ||
690 | /** | ||
691 | * Cancel a job. Must only be called before the job completion | ||
692 | * callback is called for the respective job. | ||
693 | * | ||
694 | * @param job job to cancel | ||
695 | */ | ||
696 | void | 579 | void |
697 | GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job) | 580 | GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job) |
698 | { | 581 | { |
@@ -746,24 +629,6 @@ is_json (const char *ct) | |||
746 | } | 629 | } |
747 | 630 | ||
748 | 631 | ||
749 | /** | ||
750 | * Obtain information about the final result about the | ||
751 | * HTTP download. If the download was successful, parses | ||
752 | * the JSON in the @a db and returns it. Also returns | ||
753 | * the HTTP @a response_code. If the download failed, | ||
754 | * the return value is NULL. The response code is set | ||
755 | * in any case, on download errors to zero. | ||
756 | * | ||
757 | * Calling this function also cleans up @a db. | ||
758 | * | ||
759 | * @param db download buffer | ||
760 | * @param eh CURL handle (to get the response code) | ||
761 | * @param[out] response_code set to the HTTP response code | ||
762 | * (or zero if we aborted the download, for example | ||
763 | * because the response was too big, or if | ||
764 | * the JSON we received was malformed). | ||
765 | * @return NULL if downloading a JSON reply failed. | ||
766 | */ | ||
767 | void * | 632 | void * |
768 | GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db, | 633 | GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db, |
769 | CURL *eh, | 634 | CURL *eh, |
@@ -838,13 +703,6 @@ GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db, | |||
838 | } | 703 | } |
839 | 704 | ||
840 | 705 | ||
841 | /** | ||
842 | * Add custom request header. | ||
843 | * | ||
844 | * @param ctx cURL context. | ||
845 | * @param header header string; will be given to the context AS IS. | ||
846 | * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. | ||
847 | */ | ||
848 | enum GNUNET_GenericReturnValue | 706 | enum GNUNET_GenericReturnValue |
849 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, | 707 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, |
850 | const char *header) | 708 | const char *header) |
@@ -858,14 +716,6 @@ GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, | |||
858 | } | 716 | } |
859 | 717 | ||
860 | 718 | ||
861 | /** | ||
862 | * Run the main event loop for the HTTP interaction. | ||
863 | * | ||
864 | * @param ctx the library context | ||
865 | * @param rp parses the raw response returned from | ||
866 | * the Web server. | ||
867 | * @param rc cleans/frees the response | ||
868 | */ | ||
869 | void | 719 | void |
870 | GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, | 720 | GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, |
871 | GNUNET_CURL_RawParser rp, | 721 | GNUNET_CURL_RawParser rp, |
@@ -920,11 +770,6 @@ GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, | |||
920 | } | 770 | } |
921 | 771 | ||
922 | 772 | ||
923 | /** | ||
924 | * Run the main event loop for the HTTP interaction. | ||
925 | * | ||
926 | * @param ctx the library context | ||
927 | */ | ||
928 | void | 773 | void |
929 | GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) | 774 | GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) |
930 | { | 775 | { |
@@ -934,34 +779,6 @@ GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx) | |||
934 | } | 779 | } |
935 | 780 | ||
936 | 781 | ||
937 | /** | ||
938 | * Obtain the information for a select() call to wait until | ||
939 | * #GNUNET_CURL_perform() is ready again. Note that calling | ||
940 | * any other GNUNET_CURL-API may also imply that the library | ||
941 | * is again ready for #GNUNET_CURL_perform(). | ||
942 | * | ||
943 | * Basically, a client should use this API to prepare for select(), | ||
944 | * then block on select(), then call #GNUNET_CURL_perform() and then | ||
945 | * start again until the work with the context is done. | ||
946 | * | ||
947 | * This function will NOT zero out the sets and assumes that @a max_fd | ||
948 | * and @a timeout are already set to minimal applicable values. It is | ||
949 | * safe to give this API FD-sets and @a max_fd and @a timeout that are | ||
950 | * already initialized to some other descriptors that need to go into | ||
951 | * the select() call. | ||
952 | * | ||
953 | * @param ctx context to get the event loop information for | ||
954 | * @param read_fd_set will be set for any pending read operations | ||
955 | * @param write_fd_set will be set for any pending write operations | ||
956 | * @param except_fd_set is here because curl_multi_fdset() has this argument | ||
957 | * @param max_fd set to the highest FD included in any set; | ||
958 | * if the existing sets have no FDs in it, the initial | ||
959 | * value should be "-1". (Note that `max_fd + 1` will need | ||
960 | * to be passed to select().) | ||
961 | * @param timeout set to the timeout in milliseconds (!); -1 means | ||
962 | * no timeout (NULL, blocking forever is OK), 0 means to | ||
963 | * proceed immediately with #GNUNET_CURL_perform(). | ||
964 | */ | ||
965 | void | 782 | void |
966 | GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, | 783 | GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, |
967 | fd_set *read_fd_set, | 784 | fd_set *read_fd_set, |
@@ -995,13 +812,6 @@ GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, | |||
995 | } | 812 | } |
996 | 813 | ||
997 | 814 | ||
998 | /** | ||
999 | * Cleanup library initialisation resources. This function should be called | ||
1000 | * after using this library to cleanup the resources occupied during library's | ||
1001 | * initialisation. | ||
1002 | * | ||
1003 | * @param ctx the library context | ||
1004 | */ | ||
1005 | void | 815 | void |
1006 | GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx) | 816 | GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx) |
1007 | { | 817 | { |
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c index 331a9b784..8b665e705 100644 --- a/src/datacache/datacache.c +++ b/src/datacache/datacache.c | |||
@@ -101,7 +101,9 @@ struct GNUNET_DATACACHE_Handle | |||
101 | * @param size number of bytes that were made available | 101 | * @param size number of bytes that were made available |
102 | */ | 102 | */ |
103 | static void | 103 | static void |
104 | env_delete_notify (void *cls, const struct GNUNET_HashCode *key, size_t size) | 104 | env_delete_notify (void *cls, |
105 | const struct GNUNET_HashCode *key, | ||
106 | size_t size) | ||
105 | { | 107 | { |
106 | struct GNUNET_DATACACHE_Handle *h = cls; | 108 | struct GNUNET_DATACACHE_Handle *h = cls; |
107 | 109 | ||
@@ -122,13 +124,6 @@ env_delete_notify (void *cls, const struct GNUNET_HashCode *key, size_t size) | |||
122 | } | 124 | } |
123 | 125 | ||
124 | 126 | ||
125 | /** | ||
126 | * Create a data cache. | ||
127 | * | ||
128 | * @param cfg configuration to use | ||
129 | * @param section section in the configuration that contains our options | ||
130 | * @return handle to use to access the service | ||
131 | */ | ||
132 | struct GNUNET_DATACACHE_Handle * | 127 | struct GNUNET_DATACACHE_Handle * |
133 | GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | 128 | GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, |
134 | const char *section) | 129 | const char *section) |
@@ -193,9 +188,9 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
193 | ret->lib_name = libname; | 188 | ret->lib_name = libname; |
194 | /* Load the plugin within GNUnet's default context */ | 189 | /* Load the plugin within GNUnet's default context */ |
195 | pd = GNUNET_OS_project_data_get (); | 190 | pd = GNUNET_OS_project_data_get (); |
196 | GNUNET_OS_init(GNUNET_OS_project_data_default ()); | 191 | GNUNET_OS_init (GNUNET_OS_project_data_default ()); |
197 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); | 192 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); |
198 | GNUNET_OS_init(pd); | 193 | GNUNET_OS_init (pd); |
199 | if (NULL == ret->api) | 194 | if (NULL == ret->api) |
200 | { | 195 | { |
201 | /* Try to load the plugin within the application's context | 196 | /* Try to load the plugin within the application's context |
@@ -215,11 +210,6 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
215 | } | 210 | } |
216 | 211 | ||
217 | 212 | ||
218 | /** | ||
219 | * Destroy a data cache (and free associated resources). | ||
220 | * | ||
221 | * @param h handle to the datastore | ||
222 | */ | ||
223 | void | 213 | void |
224 | GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | 214 | GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) |
225 | { | 215 | { |
@@ -244,21 +234,7 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | |||
244 | } | 234 | } |
245 | 235 | ||
246 | 236 | ||
247 | /** | 237 | enum GNUNET_GenericReturnValue |
248 | * Store an item in the datastore. | ||
249 | * | ||
250 | * @param h handle to the datacache | ||
251 | * @param key key to store data under | ||
252 | * @param xor_distance distance of @a key to our PID | ||
253 | * @param data_size number of bytes in @a data | ||
254 | * @param data data to store | ||
255 | * @param type type of the value | ||
256 | * @param discard_time when to discard the value in any case | ||
257 | * @param path_info_len number of entries in @a path_info | ||
258 | * @param path_info a path through the network | ||
259 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if duplicate | ||
260 | */ | ||
261 | int | ||
262 | GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | 238 | GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, |
263 | const struct GNUNET_HashCode *key, | 239 | const struct GNUNET_HashCode *key, |
264 | uint32_t xor_distance, | 240 | uint32_t xor_distance, |
@@ -310,17 +286,6 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | |||
310 | } | 286 | } |
311 | 287 | ||
312 | 288 | ||
313 | /** | ||
314 | * Iterate over the results for a particular key | ||
315 | * in the datacache. | ||
316 | * | ||
317 | * @param h handle to the datacache | ||
318 | * @param key what to look up | ||
319 | * @param type entries of which type are relevant? | ||
320 | * @param iter maybe NULL (to just count) | ||
321 | * @param iter_cls closure for @a iter | ||
322 | * @return the number of results found | ||
323 | */ | ||
324 | unsigned int | 289 | unsigned int |
325 | GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | 290 | GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, |
326 | const struct GNUNET_HashCode *key, | 291 | const struct GNUNET_HashCode *key, |
@@ -352,42 +317,6 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
352 | } | 317 | } |
353 | 318 | ||
354 | 319 | ||
355 | /** | ||
356 | * Obtain a random element from the datacache. | ||
357 | * | ||
358 | * @param h handle to the datacache | ||
359 | * @param iter maybe NULL (to just count) | ||
360 | * @param iter_cls closure for @a iter | ||
361 | * @return the number of results found (zero or 1) | ||
362 | */ | ||
363 | unsigned int | ||
364 | GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h, | ||
365 | GNUNET_DATACACHE_Iterator iter, | ||
366 | void *iter_cls) | ||
367 | { | ||
368 | GNUNET_STATISTICS_update (h->stats, | ||
369 | gettext_noop ( | ||
370 | "# requests for random value received"), | ||
371 | 1, | ||
372 | GNUNET_NO); | ||
373 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for random value\n"); | ||
374 | return h->api->get_random (h->api->cls, iter, iter_cls); | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Iterate over the results that are "close" to a particular key in | ||
380 | * the datacache. "close" is defined as numerically larger than @a | ||
381 | * key (when interpreted as a circular address space), with small | ||
382 | * distance. | ||
383 | * | ||
384 | * @param h handle to the datacache | ||
385 | * @param key area of the keyspace to look into | ||
386 | * @param num_results number of results that should be returned to @a iter | ||
387 | * @param iter maybe NULL (to just count) | ||
388 | * @param iter_cls closure for @a iter | ||
389 | * @return the number of results found | ||
390 | */ | ||
391 | unsigned int | 320 | unsigned int |
392 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, | 321 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, |
393 | const struct GNUNET_HashCode *key, | 322 | const struct GNUNET_HashCode *key, |
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c index 074437e7d..20d18458d 100644 --- a/src/datacache/plugin_datacache_heap.c +++ b/src/datacache/plugin_datacache_heap.c | |||
@@ -402,33 +402,6 @@ heap_plugin_del (void *cls) | |||
402 | 402 | ||
403 | 403 | ||
404 | /** | 404 | /** |
405 | * Return a random value from the datastore. | ||
406 | * | ||
407 | * @param cls closure (our `struct Plugin`) | ||
408 | * @param iter maybe NULL (to just count) | ||
409 | * @param iter_cls closure for @a iter | ||
410 | * @return the number of results found | ||
411 | */ | ||
412 | static unsigned int | ||
413 | heap_plugin_get_random (void *cls, | ||
414 | GNUNET_DATACACHE_Iterator iter, | ||
415 | void *iter_cls) | ||
416 | { | ||
417 | struct Plugin *plugin = cls; | ||
418 | struct GetContext get_ctx; | ||
419 | |||
420 | get_ctx.type = GNUNET_BLOCK_TYPE_ANY; | ||
421 | get_ctx.iter = iter; | ||
422 | get_ctx.iter_cls = iter_cls; | ||
423 | get_ctx.cnt = 0; | ||
424 | GNUNET_CONTAINER_multihashmap_get_random (plugin->map, | ||
425 | &get_cb, | ||
426 | &get_ctx); | ||
427 | return get_ctx.cnt; | ||
428 | } | ||
429 | |||
430 | |||
431 | /** | ||
432 | * Closure for #find_closest(). | 405 | * Closure for #find_closest(). |
433 | */ | 406 | */ |
434 | struct GetClosestContext | 407 | struct GetClosestContext |
@@ -548,7 +521,6 @@ libgnunet_plugin_datacache_heap_init (void *cls) | |||
548 | api->get = &heap_plugin_get; | 521 | api->get = &heap_plugin_get; |
549 | api->put = &heap_plugin_put; | 522 | api->put = &heap_plugin_put; |
550 | api->del = &heap_plugin_del; | 523 | api->del = &heap_plugin_del; |
551 | api->get_random = &heap_plugin_get_random; | ||
552 | api->get_closest = &heap_plugin_get_closest; | 524 | api->get_closest = &heap_plugin_get_closest; |
553 | LOG (GNUNET_ERROR_TYPE_INFO, | 525 | LOG (GNUNET_ERROR_TYPE_INFO, |
554 | _ ("Heap datacache running\n")); | 526 | _ ("Heap datacache running\n")); |
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 6613ae928..070619137 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c | |||
@@ -67,7 +67,8 @@ static int | |||
67 | init_connection (struct Plugin *plugin) | 67 | init_connection (struct Plugin *plugin) |
68 | { | 68 | { |
69 | struct GNUNET_PQ_ExecuteStatement es[] = { | 69 | struct GNUNET_PQ_ExecuteStatement es[] = { |
70 | GNUNET_PQ_make_try_execute ("CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn011dc_oid_seq"), | 70 | GNUNET_PQ_make_try_execute ( |
71 | "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn011dc_oid_seq"), | ||
71 | GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" | 72 | GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" |
72 | " oid OID NOT NULL DEFAULT nextval('gn011dc_oid_seq')," | 73 | " oid OID NOT NULL DEFAULT nextval('gn011dc_oid_seq')," |
73 | " type INTEGER NOT NULL," | 74 | " type INTEGER NOT NULL," |
@@ -107,11 +108,6 @@ init_connection (struct Plugin *plugin) | |||
107 | "SELECT length(value) AS len,oid,key FROM gn011dc" | 108 | "SELECT length(value) AS len,oid,key FROM gn011dc" |
108 | " ORDER BY prox ASC, discard_time ASC LIMIT 1", | 109 | " ORDER BY prox ASC, discard_time ASC LIMIT 1", |
109 | 0), | 110 | 0), |
110 | GNUNET_PQ_make_prepare ("get_random", | ||
111 | "SELECT discard_time,type,value,path,key FROM gn011dc" | ||
112 | " WHERE discard_time >= $1" | ||
113 | " ORDER BY key ASC LIMIT 1 OFFSET $2", | ||
114 | 2), | ||
115 | GNUNET_PQ_make_prepare ("get_closest", | 111 | GNUNET_PQ_make_prepare ("get_closest", |
116 | "SELECT discard_time,type,value,path,key FROM gn011dc " | 112 | "SELECT discard_time,type,value,path,key FROM gn011dc " |
117 | "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", | 113 | "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", |
@@ -410,96 +406,6 @@ postgres_plugin_del (void *cls) | |||
410 | 406 | ||
411 | 407 | ||
412 | /** | 408 | /** |
413 | * Obtain a random key-value pair from the datacache. | ||
414 | * | ||
415 | * @param cls closure (our `struct Plugin`) | ||
416 | * @param iter maybe NULL (to just count) | ||
417 | * @param iter_cls closure for @a iter | ||
418 | * @return the number of results found, zero (datacache empty) or one | ||
419 | */ | ||
420 | static unsigned int | ||
421 | postgres_plugin_get_random (void *cls, | ||
422 | GNUNET_DATACACHE_Iterator iter, | ||
423 | void *iter_cls) | ||
424 | { | ||
425 | struct Plugin *plugin = cls; | ||
426 | uint32_t off; | ||
427 | struct GNUNET_TIME_Absolute now = { 0 }; | ||
428 | struct GNUNET_TIME_Absolute expiration_time; | ||
429 | size_t data_size; | ||
430 | void *data; | ||
431 | size_t path_len; | ||
432 | struct GNUNET_PeerIdentity *path; | ||
433 | struct GNUNET_HashCode key; | ||
434 | uint32_t type; | ||
435 | enum GNUNET_DB_QueryStatus res; | ||
436 | struct GNUNET_PQ_QueryParam params[] = { | ||
437 | GNUNET_PQ_query_param_absolute_time (&now), | ||
438 | GNUNET_PQ_query_param_uint32 (&off), | ||
439 | GNUNET_PQ_query_param_end | ||
440 | }; | ||
441 | struct GNUNET_PQ_ResultSpec rs[] = { | ||
442 | GNUNET_PQ_result_spec_absolute_time ("discard_time", | ||
443 | &expiration_time), | ||
444 | GNUNET_PQ_result_spec_uint32 ("type", | ||
445 | &type), | ||
446 | GNUNET_PQ_result_spec_variable_size ("value", | ||
447 | &data, | ||
448 | &data_size), | ||
449 | GNUNET_PQ_result_spec_variable_size ("path", | ||
450 | (void **) &path, | ||
451 | &path_len), | ||
452 | GNUNET_PQ_result_spec_auto_from_type ("key", | ||
453 | &key), | ||
454 | GNUNET_PQ_result_spec_end | ||
455 | }; | ||
456 | |||
457 | if (0 == plugin->num_items) | ||
458 | return 0; | ||
459 | if (NULL == iter) | ||
460 | return 1; | ||
461 | now = GNUNET_TIME_absolute_get (); | ||
462 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
463 | plugin->num_items); | ||
464 | res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, | ||
465 | "get_random", | ||
466 | params, | ||
467 | rs); | ||
468 | if (0 > res) | ||
469 | { | ||
470 | GNUNET_break (0); | ||
471 | return 0; | ||
472 | } | ||
473 | if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == res) | ||
474 | { | ||
475 | GNUNET_break (0); | ||
476 | return 0; | ||
477 | } | ||
478 | if (0 != (path_len % sizeof(struct GNUNET_PeerIdentity))) | ||
479 | { | ||
480 | GNUNET_break (0); | ||
481 | path_len = 0; | ||
482 | } | ||
483 | path_len %= sizeof(struct GNUNET_PeerIdentity); | ||
484 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
485 | "Found random value with key %s of size %u bytes and type %u in database\n", | ||
486 | GNUNET_h2s (&key), | ||
487 | (unsigned int) data_size, | ||
488 | (unsigned int) type); | ||
489 | (void) iter (iter_cls, | ||
490 | &key, | ||
491 | data_size, | ||
492 | data, | ||
493 | (enum GNUNET_BLOCK_Type) type, | ||
494 | expiration_time, | ||
495 | path_len, | ||
496 | path); | ||
497 | GNUNET_PQ_cleanup_result (rs); | ||
498 | return 1; | ||
499 | } | ||
500 | |||
501 | |||
502 | /** | ||
503 | * Closure for #extract_result_cb. | 409 | * Closure for #extract_result_cb. |
504 | */ | 410 | */ |
505 | struct ExtractResultContext | 411 | struct ExtractResultContext |
@@ -681,7 +587,6 @@ libgnunet_plugin_datacache_postgres_init (void *cls) | |||
681 | api->get = &postgres_plugin_get; | 587 | api->get = &postgres_plugin_get; |
682 | api->put = &postgres_plugin_put; | 588 | api->put = &postgres_plugin_put; |
683 | api->del = &postgres_plugin_del; | 589 | api->del = &postgres_plugin_del; |
684 | api->get_random = &postgres_plugin_get_random; | ||
685 | api->get_closest = &postgres_plugin_get_closest; | 590 | api->get_closest = &postgres_plugin_get_closest; |
686 | LOG (GNUNET_ERROR_TYPE_INFO, | 591 | LOG (GNUNET_ERROR_TYPE_INFO, |
687 | "Postgres datacache running\n"); | 592 | "Postgres datacache running\n"); |
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c index 66ff9e82c..0c894556b 100644 --- a/src/datacache/plugin_datacache_sqlite.c +++ b/src/datacache/plugin_datacache_sqlite.c | |||
@@ -92,11 +92,6 @@ struct Plugin | |||
92 | sqlite3_stmt *del_stmt; | 92 | sqlite3_stmt *del_stmt; |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * Prepared statement for #sqlite_plugin_get_random. | ||
96 | */ | ||
97 | sqlite3_stmt *get_random_stmt; | ||
98 | |||
99 | /** | ||
100 | * Prepared statement for #sqlite_plugin_get_closest. | 95 | * Prepared statement for #sqlite_plugin_get_closest. |
101 | */ | 96 | */ |
102 | sqlite3_stmt *get_closest_stmt; | 97 | sqlite3_stmt *get_closest_stmt; |
@@ -452,85 +447,6 @@ sqlite_plugin_del (void *cls) | |||
452 | 447 | ||
453 | 448 | ||
454 | /** | 449 | /** |
455 | * Obtain a random key-value pair from the datacache. | ||
456 | * | ||
457 | * @param cls closure (our `struct Plugin`) | ||
458 | * @param iter maybe NULL (to just count) | ||
459 | * @param iter_cls closure for @a iter | ||
460 | * @return the number of results found, zero (datacache empty) or one | ||
461 | */ | ||
462 | static unsigned int | ||
463 | sqlite_plugin_get_random (void *cls, | ||
464 | GNUNET_DATACACHE_Iterator iter, | ||
465 | void *iter_cls) | ||
466 | { | ||
467 | struct Plugin *plugin = cls; | ||
468 | struct GNUNET_TIME_Absolute exp; | ||
469 | size_t size; | ||
470 | void *dat; | ||
471 | uint32_t off = 0; | ||
472 | size_t psize; | ||
473 | uint32_t type; | ||
474 | struct GNUNET_PeerIdentity *path; | ||
475 | struct GNUNET_HashCode key; | ||
476 | struct GNUNET_SQ_QueryParam params[] = { GNUNET_SQ_query_param_uint32 (&off), | ||
477 | GNUNET_SQ_query_param_end }; | ||
478 | struct GNUNET_SQ_ResultSpec rs[] = | ||
479 | { GNUNET_SQ_result_spec_variable_size (&dat, &size), | ||
480 | GNUNET_SQ_result_spec_absolute_time (&exp), | ||
481 | GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), | ||
482 | GNUNET_SQ_result_spec_auto_from_type (&key), | ||
483 | GNUNET_SQ_result_spec_uint32 (&type), | ||
484 | GNUNET_SQ_result_spec_end }; | ||
485 | |||
486 | if (0 == plugin->num_items) | ||
487 | return 0; | ||
488 | if (NULL == iter) | ||
489 | return 1; | ||
490 | off = | ||
491 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items); | ||
492 | if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_random_stmt, params)) | ||
493 | { | ||
494 | return 0; | ||
495 | } | ||
496 | if (SQLITE_ROW != sqlite3_step (plugin->get_random_stmt)) | ||
497 | { | ||
498 | GNUNET_break (0); | ||
499 | GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt); | ||
500 | return 0; | ||
501 | } | ||
502 | if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_random_stmt, rs)) | ||
503 | { | ||
504 | GNUNET_break (0); | ||
505 | GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt); | ||
506 | return 0; | ||
507 | } | ||
508 | if (0 != psize % sizeof(struct GNUNET_PeerIdentity)) | ||
509 | { | ||
510 | GNUNET_break (0); | ||
511 | psize = 0; | ||
512 | path = NULL; | ||
513 | } | ||
514 | psize /= sizeof(struct GNUNET_PeerIdentity); | ||
515 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
516 | "Found %u-byte result with key %s when processing GET-RANDOM\n", | ||
517 | (unsigned int) size, | ||
518 | GNUNET_h2s (&key)); | ||
519 | (void) iter (iter_cls, | ||
520 | &key, | ||
521 | size, | ||
522 | dat, | ||
523 | (enum GNUNET_BLOCK_Type) type, | ||
524 | exp, | ||
525 | psize, | ||
526 | path); | ||
527 | GNUNET_SQ_cleanup_result (rs); | ||
528 | GNUNET_SQ_reset (plugin->dbh, plugin->get_random_stmt); | ||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | |||
533 | /** | ||
534 | * Iterate over the results that are "close" to a particular key in | 450 | * Iterate over the results that are "close" to a particular key in |
535 | * the datacache. "close" is defined as numerically larger than @a | 451 | * the datacache. "close" is defined as numerically larger than @a |
536 | * key (when interpreted as a circular address space), with small | 452 | * key (when interpreted as a circular address space), with small |
@@ -714,10 +630,6 @@ libgnunet_plugin_datacache_sqlite_init (void *cls) | |||
714 | (SQLITE_OK != sq_prepare (plugin->dbh, | 630 | (SQLITE_OK != sq_prepare (plugin->dbh, |
715 | "DELETE FROM ds091 WHERE _ROWID_=?", | 631 | "DELETE FROM ds091 WHERE _ROWID_=?", |
716 | &plugin->del_stmt)) || | 632 | &plugin->del_stmt)) || |
717 | (SQLITE_OK != sq_prepare (plugin->dbh, | ||
718 | "SELECT value,expire,path,key,type FROM ds091 " | ||
719 | "ORDER BY key LIMIT 1 OFFSET ?", | ||
720 | &plugin->get_random_stmt)) || | ||
721 | (SQLITE_OK != | 633 | (SQLITE_OK != |
722 | sq_prepare (plugin->dbh, | 634 | sq_prepare (plugin->dbh, |
723 | "SELECT value,expire,path,type,key FROM ds091 " | 635 | "SELECT value,expire,path,type,key FROM ds091 " |
@@ -737,7 +649,6 @@ libgnunet_plugin_datacache_sqlite_init (void *cls) | |||
737 | api->get = &sqlite_plugin_get; | 649 | api->get = &sqlite_plugin_get; |
738 | api->put = &sqlite_plugin_put; | 650 | api->put = &sqlite_plugin_put; |
739 | api->del = &sqlite_plugin_del; | 651 | api->del = &sqlite_plugin_del; |
740 | api->get_random = &sqlite_plugin_get_random; | ||
741 | api->get_closest = &sqlite_plugin_get_closest; | 652 | api->get_closest = &sqlite_plugin_get_closest; |
742 | LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n"); | 653 | LOG (GNUNET_ERROR_TYPE_INFO, "Sqlite datacache running\n"); |
743 | return api; | 654 | return api; |
@@ -772,7 +683,6 @@ libgnunet_plugin_datacache_sqlite_done (void *cls) | |||
772 | sqlite3_finalize (plugin->del_select_stmt); | 683 | sqlite3_finalize (plugin->del_select_stmt); |
773 | sqlite3_finalize (plugin->del_expired_stmt); | 684 | sqlite3_finalize (plugin->del_expired_stmt); |
774 | sqlite3_finalize (plugin->del_stmt); | 685 | sqlite3_finalize (plugin->del_stmt); |
775 | sqlite3_finalize (plugin->get_random_stmt); | ||
776 | sqlite3_finalize (plugin->get_closest_stmt); | 686 | sqlite3_finalize (plugin->get_closest_stmt); |
777 | result = sqlite3_close (plugin->dbh); | 687 | result = sqlite3_close (plugin->dbh); |
778 | #if SQLITE_VERSION_NUMBER >= 3007000 | 688 | #if SQLITE_VERSION_NUMBER >= 3007000 |
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c index 329bfd9a4..09279f55c 100644 --- a/src/datacache/plugin_datacache_template.c +++ b/src/datacache/plugin_datacache_template.c | |||
@@ -109,24 +109,6 @@ template_plugin_del (void *cls) | |||
109 | 109 | ||
110 | 110 | ||
111 | /** | 111 | /** |
112 | * Return a random value from the datastore. | ||
113 | * | ||
114 | * @param cls closure (internal context for the plugin) | ||
115 | * @param iter maybe NULL (to just count) | ||
116 | * @param iter_cls closure for @a iter | ||
117 | * @return the number of results found (zero or one) | ||
118 | */ | ||
119 | static unsigned int | ||
120 | template_plugin_get_random (void *cls, | ||
121 | GNUNET_DATACACHE_Iterator iter, | ||
122 | void *iter_cls) | ||
123 | { | ||
124 | GNUNET_break (0); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Iterate over the results that are "close" to a particular key in | 112 | * Iterate over the results that are "close" to a particular key in |
131 | * the datacache. "close" is defined as numerically larger than @a | 113 | * the datacache. "close" is defined as numerically larger than @a |
132 | * key (when interpreted as a circular address space), with small | 114 | * key (when interpreted as a circular address space), with small |
@@ -171,7 +153,6 @@ libgnunet_plugin_datacache_template_init (void *cls) | |||
171 | api->get = &template_plugin_get; | 153 | api->get = &template_plugin_get; |
172 | api->put = &template_plugin_put; | 154 | api->put = &template_plugin_put; |
173 | api->del = &template_plugin_del; | 155 | api->del = &template_plugin_del; |
174 | api->get_random = &template_plugin_get_random; | ||
175 | api->get_closest = &template_plugin_get_closest; | 156 | api->get_closest = &template_plugin_get_closest; |
176 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 157 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
177 | "template", | 158 | "template", |
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 97888ce03..498a7b3e6 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c | |||
@@ -599,7 +599,8 @@ handle_reserve (void *cls, const struct ReserveMessage *msg) | |||
599 | * message happens, the insertion request could be blocked | 599 | * message happens, the insertion request could be blocked |
600 | * by less-important content from migration because it is | 600 | * by less-important content from migration because it is |
601 | * larger than 1/8th of the overall available space, and | 601 | * larger than 1/8th of the overall available space, and |
602 | * we only reserve 1/8th for "fresh" insertions */GNUNET_log ( | 602 | * we only reserve 1/8th for "fresh" insertions */ |
603 | GNUNET_log ( | ||
603 | GNUNET_ERROR_TYPE_WARNING, | 604 | GNUNET_ERROR_TYPE_WARNING, |
604 | _ ( | 605 | _ ( |
605 | "The requested amount (%llu bytes) is larger than the cache size (%llu bytes)\n"), | 606 | "The requested amount (%llu bytes) is larger than the cache size (%llu bytes)\n"), |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 96399cb5a..727f1a1f6 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -1048,8 +1048,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph) | |||
1048 | 1048 | ||
1049 | 1049 | ||
1050 | /** | 1050 | /** |
1051 | * Perform an asynchronous GET operation on the DHT identified. See | 1051 | * Perform an asynchronous GET operation on the DHT identified. |
1052 | * also #GNUNET_BLOCK_evaluate. | ||
1053 | * | 1052 | * |
1054 | * @param handle handle to the DHT service | 1053 | * @param handle handle to the DHT service |
1055 | * @param type expected type of the response object | 1054 | * @param type expected type of the response object |
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index 6741efb4e..e9b1ff63a 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h | |||
@@ -26,10 +26,10 @@ | |||
26 | #ifndef GNUNET_SERVICE_DHT_H | 26 | #ifndef GNUNET_SERVICE_DHT_H |
27 | #define GNUNET_SERVICE_DHT_H | 27 | #define GNUNET_SERVICE_DHT_H |
28 | 28 | ||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet-service-dht_datacache.h" |
30 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_service.h" | 31 | #include "gnunet_transport_service.h" |
32 | #include "gnunet_block_lib.h" | 32 | |
33 | 33 | ||
34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | 34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING |
35 | 35 | ||
@@ -64,26 +64,16 @@ extern struct GNUNET_MessageHeader *GDS_my_hello; | |||
64 | * matches any of our pending queries, forward it to the respective | 64 | * matches any of our pending queries, forward it to the respective |
65 | * client(s). | 65 | * client(s). |
66 | * | 66 | * |
67 | * @param expiration when will the reply expire | 67 | * @param bd block details |
68 | * @param key the query this reply is for | 68 | * @param query_hash hash of the original query, might not match key in @a bd |
69 | * @param get_path_length number of peers in @a get_path | 69 | * @param get_path_length number of entries in @a get_path |
70 | * @param get_path path the reply took on get | 70 | * @param get_path path the reply has taken |
71 | * @param put_path_length number of peers in @a put_path | ||
72 | * @param put_path path the reply took on put | ||
73 | * @param type type of the reply | ||
74 | * @param data_size number of bytes in @a data | ||
75 | * @param data application payload data | ||
76 | */ | 71 | */ |
77 | void | 72 | void |
78 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | 73 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
79 | const struct GNUNET_HashCode *key, | 74 | const struct GNUNET_HashCode *query_hash, |
80 | unsigned int get_path_length, | 75 | unsigned int get_path_length, |
81 | const struct GNUNET_PeerIdentity *get_path, | 76 | const struct GNUNET_PeerIdentity *get_path); |
82 | unsigned int put_path_length, | ||
83 | const struct GNUNET_PeerIdentity *put_path, | ||
84 | enum GNUNET_BLOCK_Type type, | ||
85 | size_t data_size, | ||
86 | const void *data); | ||
87 | 77 | ||
88 | 78 | ||
89 | /** | 79 | /** |
@@ -99,7 +89,7 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | |||
99 | * @param key Key of the requested data. | 89 | * @param key Key of the requested data. |
100 | */ | 90 | */ |
101 | void | 91 | void |
102 | GDS_CLIENTS_process_get (uint32_t options, | 92 | GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options, |
103 | enum GNUNET_BLOCK_Type type, | 93 | enum GNUNET_BLOCK_Type type, |
104 | uint32_t hop_count, | 94 | uint32_t hop_count, |
105 | uint32_t desired_replication_level, | 95 | uint32_t desired_replication_level, |
@@ -112,53 +102,30 @@ GDS_CLIENTS_process_get (uint32_t options, | |||
112 | * Check if some client is monitoring GET RESP messages and notify | 102 | * Check if some client is monitoring GET RESP messages and notify |
113 | * them in that case. | 103 | * them in that case. |
114 | * | 104 | * |
115 | * @param type The type of data in the result. | 105 | * @param bd block details |
116 | * @param get_path Peers on GET path (or NULL if not recorded). | 106 | * @param get_path Peers on GET path (or NULL if not recorded). |
117 | * @param get_path_length number of entries in @a get_path. | 107 | * @param get_path_length number of entries in @a get_path. |
118 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
119 | * @param put_path_length number of entries in @a get_path. | ||
120 | * @param exp Expiration time of the data. | ||
121 | * @param key Key of the @a data. | ||
122 | * @param data Pointer to the result data. | ||
123 | * @param size Number of bytes in @a data. | ||
124 | */ | 108 | */ |
125 | void | 109 | void |
126 | GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | 110 | GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, |
127 | const struct GNUNET_PeerIdentity *get_path, | 111 | const struct GNUNET_PeerIdentity *get_path, |
128 | unsigned int get_path_length, | 112 | unsigned int get_path_length); |
129 | const struct GNUNET_PeerIdentity *put_path, | ||
130 | unsigned int put_path_length, | ||
131 | struct GNUNET_TIME_Absolute exp, | ||
132 | const struct GNUNET_HashCode *key, | ||
133 | const void *data, | ||
134 | size_t size); | ||
135 | 113 | ||
136 | 114 | ||
137 | /** | 115 | /** |
138 | * Check if some client is monitoring PUT messages and notify | 116 | * Check if some client is monitoring PUT messages and notify |
139 | * them in that case. | 117 | * them in that case. The @a path should include our own |
118 | * peer ID (if recorded). | ||
140 | * | 119 | * |
141 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | 120 | * @param options routing options to apply |
142 | * @param type The type of data in the request. | 121 | * @param bd details about the block |
143 | * @param hop_count Hop count so far. | 122 | * @param hop_count Hop count so far. |
144 | * @param path_length number of entries in path (or 0 if not recorded). | ||
145 | * @param path peers on the PUT path (or NULL if not recorded). | ||
146 | * @param desired_replication_level Desired replication level. | 123 | * @param desired_replication_level Desired replication level. |
147 | * @param exp Expiration time of the data. | ||
148 | * @param key Key under which data is to be stored. | ||
149 | * @param data Pointer to the data carried. | ||
150 | * @param size Number of bytes in data. | ||
151 | */ | 124 | */ |
152 | void | 125 | void |
153 | GDS_CLIENTS_process_put (uint32_t options, | 126 | GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, |
154 | enum GNUNET_BLOCK_Type type, | 127 | const struct GDS_DATACACHE_BlockData *bd, |
155 | uint32_t hop_count, | 128 | uint32_t hop_count, |
156 | uint32_t desired_replication_level, | 129 | uint32_t desired_replication_level); |
157 | unsigned int path_length, | ||
158 | const struct GNUNET_PeerIdentity *path, | ||
159 | struct GNUNET_TIME_Absolute exp, | ||
160 | const struct GNUNET_HashCode *key, | ||
161 | const void *data, | ||
162 | size_t size); | ||
163 | 130 | ||
164 | #endif | 131 | #endif |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index cfcb25336..245130dbc 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011, 2016, 2017 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2016, 2017, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -83,7 +83,7 @@ struct ClientQueryRecord | |||
83 | const void *xquery; | 83 | const void *xquery; |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * Replies we have already seen for this request. | 86 | * Array of (hashes of) replies we have already seen for this request. |
87 | */ | 87 | */ |
88 | struct GNUNET_HashCode *seen_replies; | 88 | struct GNUNET_HashCode *seen_replies; |
89 | 89 | ||
@@ -114,7 +114,7 @@ struct ClientQueryRecord | |||
114 | size_t xquery_size; | 114 | size_t xquery_size; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * Number of entries in 'seen_replies'. | 117 | * Number of entries in @e seen_replies. |
118 | */ | 118 | */ |
119 | unsigned int seen_replies_count; | 119 | unsigned int seen_replies_count; |
120 | 120 | ||
@@ -126,7 +126,7 @@ struct ClientQueryRecord | |||
126 | /** | 126 | /** |
127 | * Any message options for this request | 127 | * Any message options for this request |
128 | */ | 128 | */ |
129 | uint32_t msg_options; | 129 | enum GNUNET_DHT_RouteOption msg_options; |
130 | 130 | ||
131 | /** | 131 | /** |
132 | * The type for the data for the GET request. | 132 | * The type for the data for the GET request. |
@@ -151,14 +151,19 @@ struct ClientMonitorRecord | |||
151 | struct ClientMonitorRecord *prev; | 151 | struct ClientMonitorRecord *prev; |
152 | 152 | ||
153 | /** | 153 | /** |
154 | * Type of blocks that are of interest | 154 | * Client to notify of these requests. |
155 | */ | 155 | */ |
156 | enum GNUNET_BLOCK_Type type; | 156 | struct ClientHandle *ch; |
157 | |||
158 | /** | ||
159 | * Key of data of interest. All bits zero for 'all'. | ||
160 | */ | ||
161 | struct GNUNET_HashCode key; | ||
157 | 162 | ||
158 | /** | 163 | /** |
159 | * Key of data of interest, NULL for all. | 164 | * Type of blocks that are of interest |
160 | */ | 165 | */ |
161 | struct GNUNET_HashCode *key; | 166 | enum GNUNET_BLOCK_Type type; |
162 | 167 | ||
163 | /** | 168 | /** |
164 | * Flag whether to notify about GET messages. | 169 | * Flag whether to notify about GET messages. |
@@ -175,10 +180,6 @@ struct ClientMonitorRecord | |||
175 | */ | 180 | */ |
176 | uint16_t put; | 181 | uint16_t put; |
177 | 182 | ||
178 | /** | ||
179 | * Client to notify of these requests. | ||
180 | */ | ||
181 | struct ClientHandle *ch; | ||
182 | }; | 183 | }; |
183 | 184 | ||
184 | 185 | ||
@@ -210,6 +211,7 @@ struct ClientHandle | |||
210 | struct GNUNET_MQ_Handle *mq; | 211 | struct GNUNET_MQ_Handle *mq; |
211 | }; | 212 | }; |
212 | 213 | ||
214 | |||
213 | /** | 215 | /** |
214 | * Our handle to the BLOCK library. | 216 | * Our handle to the BLOCK library. |
215 | */ | 217 | */ |
@@ -262,7 +264,7 @@ static struct GNUNET_SCHEDULER_Task *retry_task; | |||
262 | * @param record record to remove | 264 | * @param record record to remove |
263 | */ | 265 | */ |
264 | static void | 266 | static void |
265 | remove_client_record (struct ClientQueryRecord *record) | 267 | remove_client_query_record (struct ClientQueryRecord *record) |
266 | { | 268 | { |
267 | struct ClientHandle *ch = record->ch; | 269 | struct ClientHandle *ch = record->ch; |
268 | 270 | ||
@@ -298,6 +300,7 @@ client_connect_cb (void *cls, | |||
298 | { | 300 | { |
299 | struct ClientHandle *ch; | 301 | struct ClientHandle *ch; |
300 | 302 | ||
303 | (void) cls; | ||
301 | ch = GNUNET_new (struct ClientHandle); | 304 | ch = GNUNET_new (struct ClientHandle); |
302 | ch->client = client; | 305 | ch->client = client; |
303 | ch->mq = mq; | 306 | ch->mq = mq; |
@@ -319,34 +322,35 @@ client_disconnect_cb (void *cls, | |||
319 | void *app_ctx) | 322 | void *app_ctx) |
320 | { | 323 | { |
321 | struct ClientHandle *ch = app_ctx; | 324 | struct ClientHandle *ch = app_ctx; |
322 | struct ClientQueryRecord *cqr; | ||
323 | struct ClientMonitorRecord *monitor; | ||
324 | 325 | ||
326 | (void) cls; | ||
327 | (void) client; | ||
325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
326 | "Local client %p disconnects\n", | 329 | "Local client %p disconnects\n", |
327 | ch); | 330 | ch); |
328 | monitor = monitor_head; | ||
329 | while (NULL != monitor) | ||
330 | { | 331 | { |
331 | if (monitor->ch == ch) | 332 | struct ClientMonitorRecord *next; |
332 | { | ||
333 | struct ClientMonitorRecord *next; | ||
334 | 333 | ||
334 | for (struct ClientMonitorRecord *monitor = monitor_head; | ||
335 | NULL != monitor; | ||
336 | monitor = next) | ||
337 | { | ||
335 | next = monitor->next; | 338 | next = monitor->next; |
336 | GNUNET_free (monitor->key); | 339 | if (monitor->ch != ch) |
340 | continue; | ||
337 | GNUNET_CONTAINER_DLL_remove (monitor_head, | 341 | GNUNET_CONTAINER_DLL_remove (monitor_head, |
338 | monitor_tail, | 342 | monitor_tail, |
339 | monitor); | 343 | monitor); |
340 | GNUNET_free (monitor); | 344 | GNUNET_free (monitor); |
341 | monitor = next; | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | monitor = monitor->next; | ||
346 | } | 345 | } |
347 | } | 346 | } |
348 | while (NULL != (cqr = ch->cqr_head)) | 347 | |
349 | remove_client_record (cqr); | 348 | { |
349 | struct ClientQueryRecord *cqr; | ||
350 | |||
351 | while (NULL != (cqr = ch->cqr_head)) | ||
352 | remove_client_query_record (cqr); | ||
353 | } | ||
350 | GNUNET_free (ch); | 354 | GNUNET_free (ch); |
351 | } | 355 | } |
352 | 356 | ||
@@ -355,6 +359,8 @@ client_disconnect_cb (void *cls, | |||
355 | * Route the given request via the DHT. This includes updating | 359 | * Route the given request via the DHT. This includes updating |
356 | * the bloom filter and retransmission times, building the P2P | 360 | * the bloom filter and retransmission times, building the P2P |
357 | * message and initiating the routing operation. | 361 | * message and initiating the routing operation. |
362 | * | ||
363 | * @param cqr request to transmit | ||
358 | */ | 364 | */ |
359 | static void | 365 | static void |
360 | transmit_request (struct ClientQueryRecord *cqr) | 366 | transmit_request (struct ClientQueryRecord *cqr) |
@@ -363,8 +369,7 @@ transmit_request (struct ClientQueryRecord *cqr) | |||
363 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 369 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; |
364 | 370 | ||
365 | GNUNET_STATISTICS_update (GDS_stats, | 371 | GNUNET_STATISTICS_update (GDS_stats, |
366 | gettext_noop ( | 372 | "# GET requests from clients injected", |
367 | "# GET requests from clients injected"), | ||
368 | 1, | 373 | 1, |
369 | GNUNET_NO); | 374 | GNUNET_NO); |
370 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | 375 | bg = GNUNET_BLOCK_group_create (GDS_block_context, |
@@ -372,8 +377,8 @@ transmit_request (struct ClientQueryRecord *cqr) | |||
372 | GNUNET_CRYPTO_random_u32 ( | 377 | GNUNET_CRYPTO_random_u32 ( |
373 | GNUNET_CRYPTO_QUALITY_WEAK, | 378 | GNUNET_CRYPTO_QUALITY_WEAK, |
374 | UINT32_MAX), | 379 | UINT32_MAX), |
375 | NULL, | 380 | NULL, /* raw data */ |
376 | 0, | 381 | 0, /* raw data size */ |
377 | "seen-set-size", | 382 | "seen-set-size", |
378 | cqr->seen_replies_count, | 383 | cqr->seen_replies_count, |
379 | NULL); | 384 | NULL); |
@@ -401,8 +406,8 @@ transmit_request (struct ClientQueryRecord *cqr) | |||
401 | GNUNET_BLOCK_group_destroy (bg); | 406 | GNUNET_BLOCK_group_destroy (bg); |
402 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | 407 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); |
403 | 408 | ||
404 | /* exponential back-off for retries. | 409 | /* Exponential back-off for retries. |
405 | * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ | 410 | * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ |
406 | cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); | 411 | cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); |
407 | cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); | 412 | cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); |
408 | } | 413 | } |
@@ -419,14 +424,13 @@ static void | |||
419 | transmit_next_request_task (void *cls) | 424 | transmit_next_request_task (void *cls) |
420 | { | 425 | { |
421 | struct ClientQueryRecord *cqr; | 426 | struct ClientQueryRecord *cqr; |
422 | struct GNUNET_TIME_Relative delay; | ||
423 | 427 | ||
428 | (void) cls; | ||
424 | retry_task = NULL; | 429 | retry_task = NULL; |
425 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) | 430 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) |
426 | { | 431 | { |
427 | cqr->hnode = NULL; | 432 | cqr->hnode = NULL; |
428 | delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); | 433 | if (! GNUNET_TIME_absolute_is_past (cqr->retry_time)) |
429 | if (delay.rel_value_us > 0) | ||
430 | { | 434 | { |
431 | cqr->hnode | 435 | cqr->hnode |
432 | = GNUNET_CONTAINER_heap_insert (retry_heap, | 436 | = GNUNET_CONTAINER_heap_insert (retry_heap, |
@@ -454,11 +458,18 @@ transmit_next_request_task (void *cls) | |||
454 | * @param dht_msg the actual message received | 458 | * @param dht_msg the actual message received |
455 | * @return #GNUNET_OK (always) | 459 | * @return #GNUNET_OK (always) |
456 | */ | 460 | */ |
457 | static int | 461 | static enum GNUNET_GenericReturnValue |
458 | check_dht_local_put (void *cls, | 462 | check_dht_local_put (void *cls, |
459 | const struct GNUNET_DHT_ClientPutMessage *dht_msg) | 463 | const struct GNUNET_DHT_ClientPutMessage *dht_msg) |
460 | { | 464 | { |
461 | /* always well-formed */ | 465 | uint32_t replication_level = ntohl (dht_msg->desired_replication_level); |
466 | |||
467 | (void) cls; | ||
468 | if (replication_level > GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL) | ||
469 | { | ||
470 | GNUNET_break_op (0); | ||
471 | return GNUNET_SYSERR; | ||
472 | } | ||
462 | return GNUNET_OK; | 473 | return GNUNET_OK; |
463 | } | 474 | } |
464 | 475 | ||
@@ -474,125 +485,108 @@ handle_dht_local_put (void *cls, | |||
474 | const struct GNUNET_DHT_ClientPutMessage *dht_msg) | 485 | const struct GNUNET_DHT_ClientPutMessage *dht_msg) |
475 | { | 486 | { |
476 | struct ClientHandle *ch = cls; | 487 | struct ClientHandle *ch = cls; |
477 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 488 | uint16_t size = ntohs (dht_msg->header.size); |
478 | uint16_t size; | 489 | enum GNUNET_DHT_RouteOption options |
490 | = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options); | ||
491 | uint32_t replication_level | ||
492 | = ntohl (dht_msg->desired_replication_level); | ||
493 | struct GDS_DATACACHE_BlockData bd = { | ||
494 | .key = dht_msg->key, | ||
495 | .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | ||
496 | .data = &dht_msg[1], | ||
497 | .data_size = size - sizeof (*dht_msg), | ||
498 | .type = ntohl (dht_msg->type) | ||
499 | }; | ||
479 | 500 | ||
480 | size = ntohs (dht_msg->header.size); | 501 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
502 | "Handling local PUT of %lu-bytes for query %s of type %u\n", | ||
503 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), | ||
504 | GNUNET_h2s (&dht_msg->key), | ||
505 | (unsigned int) bd.type); | ||
481 | GNUNET_STATISTICS_update (GDS_stats, | 506 | GNUNET_STATISTICS_update (GDS_stats, |
482 | gettext_noop ( | 507 | "# PUT requests received from clients", |
483 | "# PUT requests received from clients"), | ||
484 | 1, | 508 | 1, |
485 | GNUNET_NO); | 509 | GNUNET_NO); |
486 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 510 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
487 | "CLIENT-PUT %s\n", | 511 | "CLIENT-PUT %s\n", |
488 | GNUNET_h2s_full (&dht_msg->key)); | 512 | GNUNET_h2s_full (&dht_msg->key)); |
489 | /* give to local clients */ | 513 | /* give to local clients */ |
490 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 514 | GDS_CLIENTS_handle_reply (&bd, |
491 | "Handling local PUT of %lu-bytes for query %s\n", | 515 | &bd.key, |
492 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), | 516 | 0, NULL /* get path */); |
493 | GNUNET_h2s (&dht_msg->key)); | 517 | |
494 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | 518 | { |
495 | &dht_msg->key, | 519 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; |
496 | 0, | 520 | |
497 | NULL, | 521 | peer_bf |
498 | 0, | 522 | = GNUNET_CONTAINER_bloomfilter_init (NULL, |
499 | NULL, | 523 | DHT_BLOOM_SIZE, |
500 | ntohl (dht_msg->type), | 524 | GNUNET_CONSTANTS_BLOOMFILTER_K); |
501 | size - sizeof(struct GNUNET_DHT_ClientPutMessage), | 525 | /* store locally */ |
502 | &dht_msg[1]); | 526 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
503 | /* store locally */ | 527 | (GDS_am_closest_peer (&dht_msg->key, |
504 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | 528 | peer_bf))) |
505 | &dht_msg->key, | 529 | GDS_DATACACHE_handle_put (&bd); |
506 | 0, | 530 | /* route to other peers */ |
507 | NULL, | 531 | if (GNUNET_OK != |
508 | ntohl (dht_msg->type), | 532 | GDS_NEIGHBOURS_handle_put (&bd, |
509 | size - sizeof(struct GNUNET_DHT_ClientPutMessage), | 533 | options, |
510 | &dht_msg[1]); | 534 | replication_level, |
511 | /* route to other peers */ | 535 | 0 /* hop count */, |
512 | peer_bf | 536 | peer_bf)) |
513 | = GNUNET_CONTAINER_bloomfilter_init (NULL, | 537 | { |
514 | DHT_BLOOM_SIZE, | 538 | GNUNET_STATISTICS_update (GDS_stats, |
515 | GNUNET_CONSTANTS_BLOOMFILTER_K); | 539 | "# Local PUT requests not routed", |
516 | GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type), | 540 | 1, |
517 | ntohl (dht_msg->options), | 541 | GNUNET_NO); |
518 | ntohl (dht_msg->desired_replication_level), | 542 | } |
519 | GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | 543 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); |
520 | 0 /* hop count */, | 544 | } |
521 | peer_bf, | 545 | GDS_CLIENTS_process_put ( |
522 | &dht_msg->key, | 546 | options, |
523 | 0, | 547 | &bd, |
524 | NULL, | 548 | 0, /* hop count */ |
525 | &dht_msg[1], | 549 | replication_level); |
526 | size - sizeof(struct GNUNET_DHT_ClientPutMessage)); | ||
527 | GDS_CLIENTS_process_put (ntohl (dht_msg->options), | ||
528 | ntohl (dht_msg->type), | ||
529 | 0, | ||
530 | ntohl (dht_msg->desired_replication_level), | ||
531 | 1, | ||
532 | GDS_NEIGHBOURS_get_id (), | ||
533 | GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | ||
534 | &dht_msg->key, | ||
535 | &dht_msg[1], | ||
536 | size - sizeof(struct GNUNET_DHT_ClientPutMessage)); | ||
537 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
538 | GNUNET_SERVICE_client_continue (ch->client); | 550 | GNUNET_SERVICE_client_continue (ch->client); |
539 | } | 551 | } |
540 | 552 | ||
541 | 553 | ||
542 | /** | 554 | /** |
555 | * Handle a result from local datacache for a GET operation. | ||
556 | * | ||
557 | * @param cls the `struct ClientHandle` of the client doing the query | ||
558 | * @param bd details about the block that was found | ||
559 | */ | ||
560 | static void | ||
561 | handle_local_result (void *cls, | ||
562 | const struct GDS_DATACACHE_BlockData *bd) | ||
563 | { | ||
564 | /* FIXME: use 'cls' instead of looking up the client? */ | ||
565 | GDS_CLIENTS_handle_reply (bd, | ||
566 | &bd->key, | ||
567 | 0, NULL /* get_path */); | ||
568 | } | ||
569 | |||
570 | |||
571 | /** | ||
543 | * Check DHT GET messages from the client. | 572 | * Check DHT GET messages from the client. |
544 | * | 573 | * |
545 | * @param cls the client we received this message from | 574 | * @param cls the client we received this message from |
546 | * @param message the actual message received | 575 | * @param message the actual message received |
547 | * @return #GNUNET_OK (always) | 576 | * @return #GNUNET_OK (always) |
548 | */ | 577 | */ |
549 | static int | 578 | static enum GNUNET_GenericReturnValue |
550 | check_dht_local_get (void *cls, | 579 | check_dht_local_get (void *cls, |
551 | const struct GNUNET_DHT_ClientGetMessage *get) | 580 | const struct GNUNET_DHT_ClientGetMessage *get) |
552 | { | 581 | { |
582 | (void) cls; | ||
583 | (void) get; | ||
553 | /* always well-formed */ | 584 | /* always well-formed */ |
554 | return GNUNET_OK; | 585 | return GNUNET_OK; |
555 | } | 586 | } |
556 | 587 | ||
557 | 588 | ||
558 | /** | 589 | /** |
559 | * Handle a result from local datacache for a GET operation. | ||
560 | * | ||
561 | * @param cls the `struct ClientHandle` of the client doing the query | ||
562 | * @param type type of the block | ||
563 | * @param expiration_time when does the content expire | ||
564 | * @param key key for the content | ||
565 | * @param put_path_length number of entries in @a put_path | ||
566 | * @param put_path peers the original PUT traversed (if tracked) | ||
567 | * @param get_path_length number of entries in @a get_path | ||
568 | * @param get_path peers this reply has traversed so far (if tracked) | ||
569 | * @param data payload of the reply | ||
570 | * @param data_size number of bytes in @a data | ||
571 | */ | ||
572 | static void | ||
573 | handle_local_result (void *cls, | ||
574 | enum GNUNET_BLOCK_Type type, | ||
575 | struct GNUNET_TIME_Absolute expiration_time, | ||
576 | const struct GNUNET_HashCode *key, | ||
577 | unsigned int put_path_length, | ||
578 | const struct GNUNET_PeerIdentity *put_path, | ||
579 | unsigned int get_path_length, | ||
580 | const struct GNUNET_PeerIdentity *get_path, | ||
581 | const void *data, | ||
582 | size_t data_size) | ||
583 | { | ||
584 | // FIXME: this needs some clean up: inline the function, | ||
585 | // possibly avoid even looking up the client! | ||
586 | GDS_CLIENTS_handle_reply (expiration_time, | ||
587 | key, | ||
588 | 0, NULL, | ||
589 | put_path_length, put_path, | ||
590 | type, | ||
591 | data_size, data); | ||
592 | } | ||
593 | |||
594 | |||
595 | /** | ||
596 | * Handler for DHT GET messages from the client. | 590 | * Handler for DHT GET messages from the client. |
597 | * | 591 | * |
598 | * @param cls the client we received this message from | 592 | * @param cls the client we received this message from |
@@ -604,23 +598,20 @@ handle_dht_local_get (void *cls, | |||
604 | { | 598 | { |
605 | struct ClientHandle *ch = cls; | 599 | struct ClientHandle *ch = cls; |
606 | struct ClientQueryRecord *cqr; | 600 | struct ClientQueryRecord *cqr; |
607 | size_t xquery_size; | 601 | uint16_t size = ntohs (get->header.size); |
608 | const char *xquery; | 602 | const char *xquery = (const char *) &get[1]; |
609 | uint16_t size; | 603 | size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage); |
610 | 604 | ||
611 | size = ntohs (get->header.size); | ||
612 | xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage); | ||
613 | xquery = (const char *) &get[1]; | ||
614 | GNUNET_STATISTICS_update (GDS_stats, | ||
615 | gettext_noop | ||
616 | ("# GET requests received from clients"), 1, | ||
617 | GNUNET_NO); | ||
618 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 605 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
619 | "Received GET request for %s from local client %p, xq: %.*s\n", | 606 | "Received GET request for %s from local client %p, xq: %.*s\n", |
620 | GNUNET_h2s (&get->key), | 607 | GNUNET_h2s (&get->key), |
621 | ch->client, | 608 | ch->client, |
622 | (int) xquery_size, | 609 | (int) xquery_size, |
623 | xquery); | 610 | xquery); |
611 | GNUNET_STATISTICS_update (GDS_stats, | ||
612 | "# GET requests received from clients", | ||
613 | 1, | ||
614 | GNUNET_NO); | ||
624 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 615 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
625 | "CLIENT-GET %s\n", | 616 | "CLIENT-GET %s\n", |
626 | GNUNET_h2s_full (&get->key)); | 617 | GNUNET_h2s_full (&get->key)); |
@@ -628,15 +619,19 @@ handle_dht_local_get (void *cls, | |||
628 | cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size); | 619 | cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size); |
629 | cqr->key = get->key; | 620 | cqr->key = get->key; |
630 | cqr->ch = ch; | 621 | cqr->ch = ch; |
631 | cqr->xquery = (void *) &cqr[1]; | 622 | cqr->xquery = (const void *) &cqr[1]; |
632 | GNUNET_memcpy (&cqr[1], xquery, xquery_size); | 623 | GNUNET_memcpy (&cqr[1], |
633 | cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); | 624 | xquery, |
625 | xquery_size); | ||
626 | cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, | ||
627 | cqr, | ||
628 | 0); | ||
634 | cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; | 629 | cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; |
635 | cqr->retry_time = GNUNET_TIME_absolute_get (); | 630 | cqr->retry_time = GNUNET_TIME_absolute_get (); |
636 | cqr->unique_id = get->unique_id; | 631 | cqr->unique_id = get->unique_id; |
637 | cqr->xquery_size = xquery_size; | 632 | cqr->xquery_size = xquery_size; |
638 | cqr->replication = ntohl (get->desired_replication_level); | 633 | cqr->replication = ntohl (get->desired_replication_level); |
639 | cqr->msg_options = ntohl (get->options); | 634 | cqr->msg_options = (enum GNUNET_DHT_RouteOption) ntohl (get->options); |
640 | cqr->type = ntohl (get->type); | 635 | cqr->type = ntohl (get->type); |
641 | GNUNET_CONTAINER_DLL_insert (ch->cqr_head, | 636 | GNUNET_CONTAINER_DLL_insert (ch->cqr_head, |
642 | ch->cqr_tail, | 637 | ch->cqr_tail, |
@@ -645,11 +640,11 @@ handle_dht_local_get (void *cls, | |||
645 | &cqr->key, | 640 | &cqr->key, |
646 | cqr, | 641 | cqr, |
647 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 642 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
648 | GDS_CLIENTS_process_get (ntohl (get->options), | 643 | GDS_CLIENTS_process_get (cqr->msg_options, |
649 | ntohl (get->type), | 644 | cqr->type, |
650 | 0, | 645 | 0, /* hop count */ |
651 | ntohl (get->desired_replication_level), | 646 | cqr->replication, |
652 | 1, | 647 | 1, /* path length */ |
653 | GDS_NEIGHBOURS_get_id (), | 648 | GDS_NEIGHBOURS_get_id (), |
654 | &get->key); | 649 | &get->key); |
655 | /* start remote requests */ | 650 | /* start remote requests */ |
@@ -679,6 +674,9 @@ struct FindByUniqueIdContext | |||
679 | */ | 674 | */ |
680 | struct ClientQueryRecord *cqr; | 675 | struct ClientQueryRecord *cqr; |
681 | 676 | ||
677 | /** | ||
678 | * Unique ID to look for. | ||
679 | */ | ||
682 | uint64_t unique_id; | 680 | uint64_t unique_id; |
683 | }; | 681 | }; |
684 | 682 | ||
@@ -693,7 +691,7 @@ struct FindByUniqueIdContext | |||
693 | * @param value the `struct ClientQueryRecord` | 691 | * @param value the `struct ClientQueryRecord` |
694 | * @return #GNUNET_YES to continue iteration (result not yet found) | 692 | * @return #GNUNET_YES to continue iteration (result not yet found) |
695 | */ | 693 | */ |
696 | static int | 694 | static enum GNUNET_GenericReturnValue |
697 | find_by_unique_id (void *cls, | 695 | find_by_unique_id (void *cls, |
698 | const struct GNUNET_HashCode *key, | 696 | const struct GNUNET_HashCode *key, |
699 | void *value) | 697 | void *value) |
@@ -715,19 +713,17 @@ find_by_unique_id (void *cls, | |||
715 | * @param message the actual message received | 713 | * @param message the actual message received |
716 | * @return #GNUNET_OK if @a seen is well-formed | 714 | * @return #GNUNET_OK if @a seen is well-formed |
717 | */ | 715 | */ |
718 | static int | 716 | static enum GNUNET_GenericReturnValue |
719 | check_dht_local_get_result_seen (void *cls, | 717 | check_dht_local_get_result_seen ( |
720 | const struct | 718 | void *cls, |
721 | GNUNET_DHT_ClientGetResultSeenMessage *seen) | 719 | const struct GNUNET_DHT_ClientGetResultSeenMessage *seen) |
722 | { | 720 | { |
723 | uint16_t size; | 721 | uint16_t size = ntohs (seen->header.size); |
724 | unsigned int hash_count; | 722 | unsigned int hash_count = |
725 | 723 | (size - sizeof(*seen)) | |
726 | size = ntohs (seen->header.size); | 724 | / sizeof(struct GNUNET_HashCode); |
727 | hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)) | 725 | |
728 | / sizeof(struct GNUNET_HashCode); | 726 | if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode)) |
729 | if (size != sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage) | ||
730 | + hash_count * sizeof(struct GNUNET_HashCode)) | ||
731 | { | 727 | { |
732 | GNUNET_break (0); | 728 | GNUNET_break (0); |
733 | return GNUNET_SYSERR; | 729 | return GNUNET_SYSERR; |
@@ -743,24 +739,21 @@ check_dht_local_get_result_seen (void *cls, | |||
743 | * @param message the actual message received | 739 | * @param message the actual message received |
744 | */ | 740 | */ |
745 | static void | 741 | static void |
746 | handle_dht_local_get_result_seen (void *cls, | 742 | handle_dht_local_get_result_seen ( |
747 | const struct | 743 | void *cls, |
748 | GNUNET_DHT_ClientGetResultSeenMessage *seen) | 744 | const struct GNUNET_DHT_ClientGetResultSeenMessage *seen) |
749 | { | 745 | { |
750 | struct ClientHandle *ch = cls; | 746 | struct ClientHandle *ch = cls; |
751 | uint16_t size; | 747 | uint16_t size = ntohs (seen->header.size); |
752 | unsigned int hash_count; | 748 | unsigned int hash_count = (size - sizeof(*seen)) |
749 | / sizeof(struct GNUNET_HashCode); | ||
750 | const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1]; | ||
751 | struct FindByUniqueIdContext fui_ctx = { | ||
752 | .unique_id = seen->unique_id | ||
753 | }; | ||
753 | unsigned int old_count; | 754 | unsigned int old_count; |
754 | const struct GNUNET_HashCode *hc; | ||
755 | struct FindByUniqueIdContext fui_ctx; | ||
756 | struct ClientQueryRecord *cqr; | 755 | struct ClientQueryRecord *cqr; |
757 | 756 | ||
758 | size = ntohs (seen->header.size); | ||
759 | hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)) | ||
760 | / sizeof(struct GNUNET_HashCode); | ||
761 | hc = (const struct GNUNET_HashCode*) &seen[1]; | ||
762 | fui_ctx.unique_id = seen->unique_id; | ||
763 | fui_ctx.cqr = NULL; | ||
764 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | 757 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, |
765 | &seen->key, | 758 | &seen->key, |
766 | &find_by_unique_id, | 759 | &find_by_unique_id, |
@@ -808,7 +801,7 @@ struct RemoveByUniqueIdContext | |||
808 | * @param value value in the hash map, a ClientQueryRecord | 801 | * @param value value in the hash map, a ClientQueryRecord |
809 | * @return #GNUNET_YES (we should continue to iterate) | 802 | * @return #GNUNET_YES (we should continue to iterate) |
810 | */ | 803 | */ |
811 | static int | 804 | static enum GNUNET_GenericReturnValue |
812 | remove_by_unique_id (void *cls, | 805 | remove_by_unique_id (void *cls, |
813 | const struct GNUNET_HashCode *key, | 806 | const struct GNUNET_HashCode *key, |
814 | void *value) | 807 | void *value) |
@@ -822,7 +815,7 @@ remove_by_unique_id (void *cls, | |||
822 | "Removing client %p's record for key %s (by unique id)\n", | 815 | "Removing client %p's record for key %s (by unique id)\n", |
823 | ctx->ch->client, | 816 | ctx->ch->client, |
824 | GNUNET_h2s (key)); | 817 | GNUNET_h2s (key)); |
825 | remove_client_record (cqr); | 818 | remove_client_query_record (cqr); |
826 | return GNUNET_YES; | 819 | return GNUNET_YES; |
827 | } | 820 | } |
828 | 821 | ||
@@ -836,16 +829,16 @@ remove_by_unique_id (void *cls, | |||
836 | * | 829 | * |
837 | */ | 830 | */ |
838 | static void | 831 | static void |
839 | handle_dht_local_get_stop (void *cls, | 832 | handle_dht_local_get_stop ( |
840 | const struct | 833 | void *cls, |
841 | GNUNET_DHT_ClientGetStopMessage *dht_stop_msg) | 834 | const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg) |
842 | { | 835 | { |
843 | struct ClientHandle *ch = cls; | 836 | struct ClientHandle *ch = cls; |
844 | struct RemoveByUniqueIdContext ctx; | 837 | struct RemoveByUniqueIdContext ctx; |
845 | 838 | ||
846 | GNUNET_STATISTICS_update (GDS_stats, | 839 | GNUNET_STATISTICS_update (GDS_stats, |
847 | gettext_noop | 840 | "# GET STOP requests received from clients", |
848 | ("# GET STOP requests received from clients"), 1, | 841 | 1, |
849 | GNUNET_NO); | 842 | GNUNET_NO); |
850 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 843 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
851 | "Received GET STOP request for %s from local client %p\n", | 844 | "Received GET STOP request for %s from local client %p\n", |
@@ -862,99 +855,14 @@ handle_dht_local_get_stop (void *cls, | |||
862 | 855 | ||
863 | 856 | ||
864 | /** | 857 | /** |
865 | * Handler for monitor start messages | ||
866 | * | ||
867 | * @param cls the client we received this message from | ||
868 | * @param msg the actual message received | ||
869 | * | ||
870 | */ | ||
871 | static void | ||
872 | handle_dht_local_monitor (void *cls, | ||
873 | const struct GNUNET_DHT_MonitorStartStopMessage *msg) | ||
874 | { | ||
875 | struct ClientHandle *ch = cls; | ||
876 | struct ClientMonitorRecord *r; | ||
877 | |||
878 | r = GNUNET_new (struct ClientMonitorRecord); | ||
879 | r->ch = ch; | ||
880 | r->type = ntohl (msg->type); | ||
881 | r->get = ntohs (msg->get); | ||
882 | r->get_resp = ntohs (msg->get_resp); | ||
883 | r->put = ntohs (msg->put); | ||
884 | if (0 == ntohs (msg->filter_key)) | ||
885 | { | ||
886 | r->key = NULL; | ||
887 | } | ||
888 | else | ||
889 | { | ||
890 | r->key = GNUNET_new (struct GNUNET_HashCode); | ||
891 | GNUNET_memcpy (r->key, | ||
892 | &msg->key, | ||
893 | sizeof(struct GNUNET_HashCode)); | ||
894 | } | ||
895 | GNUNET_CONTAINER_DLL_insert (monitor_head, | ||
896 | monitor_tail, | ||
897 | r); | ||
898 | GNUNET_SERVICE_client_continue (ch->client); | ||
899 | } | ||
900 | |||
901 | |||
902 | /** | ||
903 | * Handler for monitor stop messages | ||
904 | * | ||
905 | * @param cls the client we received this message from | ||
906 | * @param msg the actual message received | ||
907 | */ | ||
908 | static void | ||
909 | handle_dht_local_monitor_stop (void *cls, | ||
910 | const struct | ||
911 | GNUNET_DHT_MonitorStartStopMessage *msg) | ||
912 | { | ||
913 | struct ClientHandle *ch = cls; | ||
914 | struct ClientMonitorRecord *r; | ||
915 | int keys_match; | ||
916 | |||
917 | GNUNET_SERVICE_client_continue (ch->client); | ||
918 | for (r = monitor_head; NULL != r; r = r->next) | ||
919 | { | ||
920 | if (NULL == r->key) | ||
921 | { | ||
922 | keys_match = (0 == ntohs (msg->filter_key)); | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | keys_match = ((0 != ntohs (msg->filter_key)) && | ||
927 | (! memcmp (r->key, | ||
928 | &msg->key, | ||
929 | sizeof(struct GNUNET_HashCode)))); | ||
930 | } | ||
931 | if ((ch == r->ch) && | ||
932 | (ntohl (msg->type) == r->type) && | ||
933 | (r->get == msg->get) && | ||
934 | (r->get_resp == msg->get_resp) && | ||
935 | (r->put == msg->put) && | ||
936 | keys_match) | ||
937 | { | ||
938 | GNUNET_CONTAINER_DLL_remove (monitor_head, | ||
939 | monitor_tail, | ||
940 | r); | ||
941 | GNUNET_free (r->key); | ||
942 | GNUNET_free (r); | ||
943 | return; /* Delete only ONE entry */ | ||
944 | } | ||
945 | } | ||
946 | } | ||
947 | |||
948 | |||
949 | /** | ||
950 | * Closure for #forward_reply() | 858 | * Closure for #forward_reply() |
951 | */ | 859 | */ |
952 | struct ForwardReplyContext | 860 | struct ForwardReplyContext |
953 | { | 861 | { |
954 | /** | 862 | /** |
955 | * Expiration time of the reply. | 863 | * Block details. |
956 | */ | 864 | */ |
957 | struct GNUNET_TIME_Absolute expiration; | 865 | const struct GDS_DATACACHE_BlockData *bd; |
958 | 866 | ||
959 | /** | 867 | /** |
960 | * GET path taken. | 868 | * GET path taken. |
@@ -962,34 +870,10 @@ struct ForwardReplyContext | |||
962 | const struct GNUNET_PeerIdentity *get_path; | 870 | const struct GNUNET_PeerIdentity *get_path; |
963 | 871 | ||
964 | /** | 872 | /** |
965 | * PUT path taken. | ||
966 | */ | ||
967 | const struct GNUNET_PeerIdentity *put_path; | ||
968 | |||
969 | /** | ||
970 | * Embedded payload. | ||
971 | */ | ||
972 | const void *data; | ||
973 | |||
974 | /** | ||
975 | * Number of bytes in data. | ||
976 | */ | ||
977 | size_t data_size; | ||
978 | |||
979 | /** | ||
980 | * Number of entries in @e get_path. | 873 | * Number of entries in @e get_path. |
981 | */ | 874 | */ |
982 | unsigned int get_path_length; | 875 | unsigned int get_path_length; |
983 | 876 | ||
984 | /** | ||
985 | * Number of entries in @e put_path. | ||
986 | */ | ||
987 | unsigned int put_path_length; | ||
988 | |||
989 | /** | ||
990 | * Type of the data. | ||
991 | */ | ||
992 | enum GNUNET_BLOCK_Type type; | ||
993 | }; | 877 | }; |
994 | 878 | ||
995 | 879 | ||
@@ -998,334 +882,298 @@ struct ForwardReplyContext | |||
998 | * each of the matching clients. With some tricky recycling | 882 | * each of the matching clients. With some tricky recycling |
999 | * of the buffer. | 883 | * of the buffer. |
1000 | * | 884 | * |
1001 | * @param cls the 'struct ForwardReplyContext' | 885 | * @param cls the `struct ForwardReplyContext` |
1002 | * @param key current key | 886 | * @param query_hash hash of the query for which this may be a reply |
1003 | * @param value value in the hash map, a ClientQueryRecord | 887 | * @param value value in the hash map, a ClientQueryRecord |
1004 | * @return #GNUNET_YES (we should continue to iterate), | 888 | * @return #GNUNET_YES (we should continue to iterate), |
1005 | * if the result is mal-formed, #GNUNET_NO | 889 | * if the result is mal-formed, #GNUNET_NO |
1006 | */ | 890 | */ |
1007 | static int | 891 | static enum GNUNET_GenericReturnValue |
1008 | forward_reply (void *cls, | 892 | forward_reply (void *cls, |
1009 | const struct GNUNET_HashCode *key, | 893 | const struct GNUNET_HashCode *query_hash, |
1010 | void *value) | 894 | void *value) |
1011 | { | 895 | { |
1012 | struct ForwardReplyContext *frc = cls; | 896 | struct ForwardReplyContext *frc = cls; |
1013 | struct ClientQueryRecord *record = value; | 897 | struct ClientQueryRecord *record = value; |
1014 | struct GNUNET_MQ_Envelope *env; | 898 | struct GNUNET_MQ_Envelope *env; |
1015 | struct GNUNET_DHT_ClientResultMessage *reply; | 899 | struct GNUNET_DHT_ClientResultMessage *reply; |
1016 | enum GNUNET_BLOCK_EvaluationResult eval; | 900 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
1017 | int do_free; | 901 | bool do_free; |
1018 | struct GNUNET_HashCode ch; | 902 | struct GNUNET_HashCode ch; |
1019 | struct GNUNET_PeerIdentity *paths; | 903 | struct GNUNET_PeerIdentity *paths; |
1020 | 904 | ||
1021 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 905 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
1022 | "CLIENT-RESULT %s\n", | 906 | "CLIENT-RESULT %s\n", |
1023 | GNUNET_h2s_full (key)); | 907 | GNUNET_h2s_full (&frc->bd->key)); |
1024 | if ((record->type != GNUNET_BLOCK_TYPE_ANY) && | 908 | if ( (record->type != GNUNET_BLOCK_TYPE_ANY) && |
1025 | (record->type != frc->type)) | 909 | (record->type != frc->bd->type) ) |
1026 | { | 910 | { |
1027 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 911 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1028 | "Record type mismatch, not passing request for key %s to local client\n", | 912 | "Record type mismatch, not passing request for key %s to local client\n", |
1029 | GNUNET_h2s (key)); | 913 | GNUNET_h2s (&frc->bd->key)); |
1030 | GNUNET_STATISTICS_update (GDS_stats, | 914 | GNUNET_STATISTICS_update (GDS_stats, |
1031 | gettext_noop | 915 | "# Key match, type mismatches in REPLY to CLIENT", |
1032 | ( | 916 | 1, |
1033 | "# Key match, type mismatches in REPLY to CLIENT"), | 917 | GNUNET_NO); |
1034 | 1, GNUNET_NO); | ||
1035 | return GNUNET_YES; /* type mismatch */ | 918 | return GNUNET_YES; /* type mismatch */ |
1036 | } | 919 | } |
1037 | GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); | 920 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) && |
921 | (0 != GNUNET_memcmp (&frc->bd->key, | ||
922 | query_hash)) ) | ||
923 | { | ||
924 | GNUNET_STATISTICS_update (GDS_stats, | ||
925 | "# Inexact key match, but exact match required", | ||
926 | 1, | ||
927 | GNUNET_NO); | ||
928 | return GNUNET_YES; /* type mismatch */ | ||
929 | } | ||
930 | GNUNET_CRYPTO_hash (frc->bd->data, | ||
931 | frc->bd->data_size, | ||
932 | &ch); | ||
1038 | for (unsigned int i = 0; i < record->seen_replies_count; i++) | 933 | for (unsigned int i = 0; i < record->seen_replies_count; i++) |
1039 | if (0 == memcmp (&record->seen_replies[i], | 934 | if (0 == |
1040 | &ch, | 935 | GNUNET_memcmp (&record->seen_replies[i], |
1041 | sizeof(struct GNUNET_HashCode))) | 936 | &ch)) |
1042 | { | 937 | { |
1043 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 938 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1044 | "Duplicate reply, not passing request for key %s to local client\n", | 939 | "Duplicate reply, not passing request for key %s to local client\n", |
1045 | GNUNET_h2s (key)); | 940 | GNUNET_h2s (&frc->bd->key)); |
1046 | GNUNET_STATISTICS_update (GDS_stats, | 941 | GNUNET_STATISTICS_update (GDS_stats, |
1047 | gettext_noop | 942 | "# Duplicate REPLIES to CLIENT request dropped", |
1048 | ( | 943 | 1, |
1049 | "# Duplicate REPLIES to CLIENT request dropped"), | 944 | GNUNET_NO); |
1050 | 1, GNUNET_NO); | ||
1051 | return GNUNET_YES; /* duplicate */ | 945 | return GNUNET_YES; /* duplicate */ |
1052 | } | 946 | } |
1053 | eval | 947 | eval |
1054 | = GNUNET_BLOCK_evaluate (GDS_block_context, | 948 | = GNUNET_BLOCK_check_reply (GDS_block_context, |
1055 | record->type, | 949 | record->type, |
1056 | NULL, | 950 | NULL, |
1057 | GNUNET_BLOCK_EO_NONE, | 951 | &frc->bd->key, |
1058 | key, | 952 | record->xquery, |
1059 | record->xquery, | 953 | record->xquery_size, |
1060 | record->xquery_size, | 954 | frc->bd->data, |
1061 | frc->data, | 955 | frc->bd->data_size); |
1062 | frc->data_size); | ||
1063 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 956 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1064 | "Evaluation result is %d for key %s for local client's query\n", | 957 | "Evaluation result is %d for key %s for local client's query\n", |
1065 | (int) eval, | 958 | (int) eval, |
1066 | GNUNET_h2s (key)); | 959 | GNUNET_h2s (&frc->bd->key)); |
1067 | switch (eval) | 960 | switch (eval) |
1068 | { | 961 | { |
1069 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | 962 | case GNUNET_BLOCK_REPLY_OK_LAST: |
1070 | do_free = GNUNET_YES; | 963 | do_free = true; |
1071 | break; | 964 | break; |
1072 | 965 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: | |
1073 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | 966 | case GNUNET_BLOCK_REPLY_OK_MORE: |
1074 | GNUNET_array_append (record->seen_replies, | 967 | GNUNET_array_append (record->seen_replies, |
1075 | record->seen_replies_count, | 968 | record->seen_replies_count, |
1076 | ch); | 969 | ch); |
1077 | do_free = GNUNET_NO; | 970 | do_free = false; |
1078 | break; | 971 | break; |
1079 | 972 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | |
1080 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
1081 | /* should be impossible to encounter here */ | 973 | /* should be impossible to encounter here */ |
1082 | GNUNET_break (0); | 974 | GNUNET_break (0); |
1083 | return GNUNET_YES; | 975 | return GNUNET_YES; |
1084 | 976 | case GNUNET_BLOCK_REPLY_INVALID: | |
1085 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
1086 | GNUNET_break_op (0); | 977 | GNUNET_break_op (0); |
1087 | return GNUNET_NO; | 978 | return GNUNET_NO; |
1088 | 979 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | |
1089 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
1090 | GNUNET_break (0); | ||
1091 | return GNUNET_NO; | ||
1092 | |||
1093 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
1094 | GNUNET_break (0); | ||
1095 | return GNUNET_NO; | ||
1096 | |||
1097 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
1098 | return GNUNET_YES; | 980 | return GNUNET_YES; |
1099 | |||
1100 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
1101 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1102 | _ ("Unsupported block type (%u) in request!\n"), record->type); | ||
1103 | return GNUNET_NO; | ||
1104 | |||
1105 | default: | 981 | default: |
1106 | GNUNET_break (0); | 982 | GNUNET_break (0); |
1107 | return GNUNET_NO; | 983 | return GNUNET_NO; |
1108 | } | 984 | } |
1109 | GNUNET_STATISTICS_update (GDS_stats, | 985 | GNUNET_STATISTICS_update (GDS_stats, |
1110 | gettext_noop ("# RESULTS queued for clients"), | 986 | "# RESULTS queued for clients", |
1111 | 1, | 987 | 1, |
1112 | GNUNET_NO); | 988 | GNUNET_NO); |
1113 | env = GNUNET_MQ_msg_extra (reply, | 989 | env = GNUNET_MQ_msg_extra (reply, |
1114 | frc->data_size | 990 | frc->bd->data_size |
1115 | + (frc->get_path_length + frc->put_path_length) | 991 | + (frc->get_path_length + frc->bd->put_path_length) |
1116 | * sizeof(struct GNUNET_PeerIdentity), | 992 | * sizeof(struct GNUNET_PeerIdentity), |
1117 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); | 993 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); |
1118 | reply->type = htonl (frc->type); | 994 | reply->type = htonl (frc->bd->type); |
1119 | reply->get_path_length = htonl (frc->get_path_length); | 995 | reply->get_path_length = htonl (frc->get_path_length); |
1120 | reply->put_path_length = htonl (frc->put_path_length); | 996 | reply->put_path_length = htonl (frc->bd->put_path_length); |
1121 | reply->unique_id = record->unique_id; | 997 | reply->unique_id = record->unique_id; |
1122 | reply->expiration = GNUNET_TIME_absolute_hton (frc->expiration); | 998 | reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); |
1123 | reply->key = *key; | 999 | reply->key = frc->bd->key; |
1124 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; | 1000 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; |
1125 | GNUNET_memcpy (paths, | 1001 | GNUNET_memcpy (paths, |
1126 | frc->put_path, | 1002 | frc->bd->put_path, |
1127 | sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length); | 1003 | sizeof(struct GNUNET_PeerIdentity) * frc->bd->put_path_length); |
1128 | GNUNET_memcpy (&paths[frc->put_path_length], | 1004 | GNUNET_memcpy (&paths[frc->bd->put_path_length], |
1129 | frc->get_path, | 1005 | frc->get_path, |
1130 | sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length); | 1006 | sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length); |
1131 | GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length], | 1007 | GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length], |
1132 | frc->data, | 1008 | frc->bd->data, |
1133 | frc->data_size); | 1009 | frc->bd->data_size); |
1134 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1010 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1135 | "Sending reply to query %s for client %p\n", | 1011 | "Sending reply to query %s for client %p\n", |
1136 | GNUNET_h2s (key), | 1012 | GNUNET_h2s (query_hash), |
1137 | record->ch->client); | 1013 | record->ch->client); |
1138 | GNUNET_MQ_send (record->ch->mq, | 1014 | GNUNET_MQ_send (record->ch->mq, |
1139 | env); | 1015 | env); |
1140 | if (GNUNET_YES == do_free) | 1016 | if (GNUNET_YES == do_free) |
1141 | remove_client_record (record); | 1017 | remove_client_query_record (record); |
1142 | return GNUNET_YES; | 1018 | return GNUNET_YES; |
1143 | } | 1019 | } |
1144 | 1020 | ||
1145 | 1021 | ||
1146 | /** | ||
1147 | * Handle a reply we've received from another peer. If the reply | ||
1148 | * matches any of our pending queries, forward it to the respective | ||
1149 | * client(s). | ||
1150 | * | ||
1151 | * @param expiration when will the reply expire | ||
1152 | * @param key the query this reply is for | ||
1153 | * @param get_path_length number of peers in @a get_path | ||
1154 | * @param get_path path the reply took on get | ||
1155 | * @param put_path_length number of peers in @a put_path | ||
1156 | * @param put_path path the reply took on put | ||
1157 | * @param type type of the reply | ||
1158 | * @param data_size number of bytes in @a data | ||
1159 | * @param data application payload data | ||
1160 | */ | ||
1161 | void | 1022 | void |
1162 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | 1023 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
1163 | const struct GNUNET_HashCode *key, | 1024 | const struct GNUNET_HashCode *query_hash, |
1164 | unsigned int get_path_length, | 1025 | unsigned int get_path_length, |
1165 | const struct GNUNET_PeerIdentity *get_path, | 1026 | const struct GNUNET_PeerIdentity *get_path) |
1166 | unsigned int put_path_length, | ||
1167 | const struct GNUNET_PeerIdentity *put_path, | ||
1168 | enum GNUNET_BLOCK_Type type, | ||
1169 | size_t data_size, | ||
1170 | const void *data) | ||
1171 | { | 1027 | { |
1172 | struct ForwardReplyContext frc; | 1028 | struct ForwardReplyContext frc; |
1173 | size_t msize; | 1029 | size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage) |
1030 | + bd->data_size | ||
1031 | + (get_path_length + bd->put_path_length) | ||
1032 | * sizeof(struct GNUNET_PeerIdentity); | ||
1174 | 1033 | ||
1175 | msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size | ||
1176 | + (get_path_length + put_path_length) * sizeof(struct | ||
1177 | GNUNET_PeerIdentity); | ||
1178 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) | 1034 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) |
1179 | { | 1035 | { |
1180 | GNUNET_break (0); | 1036 | GNUNET_break (0); |
1181 | return; | 1037 | return; |
1182 | } | 1038 | } |
1183 | if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, | 1039 | frc.bd = bd; |
1184 | key)) | 1040 | frc.get_path = get_path; |
1041 | frc.get_path_length = get_path_length; | ||
1042 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1043 | "Forwarding reply for query hash %s to client\n", | ||
1044 | GNUNET_h2s (query_hash)); | ||
1045 | if (0 == | ||
1046 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
1047 | query_hash, | ||
1048 | &forward_reply, | ||
1049 | &frc)) | ||
1185 | { | 1050 | { |
1186 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1051 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1187 | "No matching client for reply for key %s\n", | 1052 | "No matching client for reply for query %s\n", |
1188 | GNUNET_h2s (key)); | 1053 | GNUNET_h2s (query_hash)); |
1189 | GNUNET_STATISTICS_update (GDS_stats, | 1054 | GNUNET_STATISTICS_update (GDS_stats, |
1190 | gettext_noop ( | 1055 | "# REPLIES ignored for CLIENTS (no match)", |
1191 | "# REPLIES ignored for CLIENTS (no match)"), | ||
1192 | 1, | 1056 | 1, |
1193 | GNUNET_NO); | 1057 | GNUNET_NO); |
1194 | return; /* no matching request, fast exit! */ | ||
1195 | } | 1058 | } |
1196 | frc.expiration = expiration; | ||
1197 | frc.get_path = get_path; | ||
1198 | frc.put_path = put_path; | ||
1199 | frc.data = data; | ||
1200 | frc.data_size = data_size; | ||
1201 | frc.get_path_length = get_path_length; | ||
1202 | frc.put_path_length = put_path_length; | ||
1203 | frc.type = type; | ||
1204 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1205 | "Forwarding reply for key %s to client\n", | ||
1206 | GNUNET_h2s (key)); | ||
1207 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
1208 | key, | ||
1209 | &forward_reply, | ||
1210 | &frc); | ||
1211 | } | 1059 | } |
1212 | 1060 | ||
1213 | 1061 | ||
1062 | /* ************* logic for monitors ************** */ | ||
1063 | |||
1064 | |||
1214 | /** | 1065 | /** |
1215 | * Check if some client is monitoring GET messages and notify | 1066 | * Handler for monitor start messages |
1216 | * them in that case. | 1067 | * |
1068 | * @param cls the client we received this message from | ||
1069 | * @param msg the actual message received | ||
1217 | * | 1070 | * |
1218 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
1219 | * @param type The type of data in the request. | ||
1220 | * @param hop_count Hop count so far. | ||
1221 | * @param path_length number of entries in path (or 0 if not recorded). | ||
1222 | * @param path peers on the GET path (or NULL if not recorded). | ||
1223 | * @param desired_replication_level Desired replication level. | ||
1224 | * @param key Key of the requested data. | ||
1225 | */ | 1071 | */ |
1226 | void | 1072 | static void |
1227 | GDS_CLIENTS_process_get (uint32_t options, | 1073 | handle_dht_local_monitor (void *cls, |
1228 | enum GNUNET_BLOCK_Type type, | 1074 | const struct GNUNET_DHT_MonitorStartStopMessage *msg) |
1229 | uint32_t hop_count, | ||
1230 | uint32_t desired_replication_level, | ||
1231 | unsigned int path_length, | ||
1232 | const struct GNUNET_PeerIdentity *path, | ||
1233 | const struct GNUNET_HashCode *key) | ||
1234 | { | 1075 | { |
1235 | struct ClientMonitorRecord *m; | 1076 | struct ClientHandle *ch = cls; |
1236 | struct ClientHandle **cl; | 1077 | struct ClientMonitorRecord *r; |
1237 | unsigned int cl_size; | ||
1238 | 1078 | ||
1239 | cl = NULL; | 1079 | r = GNUNET_new (struct ClientMonitorRecord); |
1240 | cl_size = 0; | 1080 | r->ch = ch; |
1241 | for (m = monitor_head; NULL != m; m = m->next) | 1081 | r->type = ntohl (msg->type); |
1242 | { | 1082 | r->get = ntohs (msg->get); |
1243 | if (((GNUNET_BLOCK_TYPE_ANY == m->type) || | 1083 | r->get_resp = ntohs (msg->get_resp); |
1244 | (m->type == type)) && | 1084 | r->put = ntohs (msg->put); |
1245 | ((NULL == m->key) || | 1085 | if (0 != ntohs (msg->filter_key)) |
1246 | (0 == memcmp (key, | 1086 | r->key = msg->key; |
1247 | m->key, | 1087 | GNUNET_CONTAINER_DLL_insert (monitor_head, |
1248 | sizeof(struct GNUNET_HashCode))))) | 1088 | monitor_tail, |
1249 | { | 1089 | r); |
1250 | struct GNUNET_MQ_Envelope *env; | 1090 | GNUNET_SERVICE_client_continue (ch->client); |
1251 | struct GNUNET_DHT_MonitorGetMessage *mmsg; | 1091 | } |
1252 | struct GNUNET_PeerIdentity *msg_path; | ||
1253 | size_t msize; | ||
1254 | unsigned int i; | ||
1255 | 1092 | ||
1256 | /* Don't send duplicates */ | ||
1257 | for (i = 0; i < cl_size; i++) | ||
1258 | if (cl[i] == m->ch) | ||
1259 | break; | ||
1260 | if (i < cl_size) | ||
1261 | continue; | ||
1262 | GNUNET_array_append (cl, | ||
1263 | cl_size, | ||
1264 | m->ch); | ||
1265 | 1093 | ||
1266 | msize = path_length * sizeof(struct GNUNET_PeerIdentity); | 1094 | /** |
1267 | env = GNUNET_MQ_msg_extra (mmsg, | 1095 | * Handler for monitor stop messages |
1268 | msize, | 1096 | * |
1269 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); | 1097 | * @param cls the client we received this message from |
1270 | mmsg->options = htonl (options); | 1098 | * @param msg the actual message received |
1271 | mmsg->type = htonl (type); | 1099 | */ |
1272 | mmsg->hop_count = htonl (hop_count); | 1100 | static void |
1273 | mmsg->desired_replication_level = htonl (desired_replication_level); | 1101 | handle_dht_local_monitor_stop ( |
1274 | mmsg->get_path_length = htonl (path_length); | 1102 | void *cls, |
1275 | mmsg->key = *key; | 1103 | const struct GNUNET_DHT_MonitorStartStopMessage *msg) |
1276 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | 1104 | { |
1277 | GNUNET_memcpy (msg_path, | 1105 | struct ClientHandle *ch = cls; |
1278 | path, | 1106 | |
1279 | path_length * sizeof(struct GNUNET_PeerIdentity)); | 1107 | GNUNET_SERVICE_client_continue (ch->client); |
1280 | GNUNET_MQ_send (m->ch->mq, | 1108 | for (struct ClientMonitorRecord *r = monitor_head; |
1281 | env); | 1109 | NULL != r; |
1110 | r = r->next) | ||
1111 | { | ||
1112 | bool keys_match; | ||
1113 | |||
1114 | keys_match = | ||
1115 | (GNUNET_is_zero (&r->key)) | ||
1116 | ? (0 == ntohs (msg->filter_key)) | ||
1117 | : ( (0 != ntohs (msg->filter_key)) && | ||
1118 | (! GNUNET_memcmp (&r->key, | ||
1119 | &msg->key)) ); | ||
1120 | if ( (ch == r->ch) && | ||
1121 | (ntohl (msg->type) == r->type) && | ||
1122 | (r->get == msg->get) && | ||
1123 | (r->get_resp == msg->get_resp) && | ||
1124 | (r->put == msg->put) && | ||
1125 | keys_match) | ||
1126 | { | ||
1127 | GNUNET_CONTAINER_DLL_remove (monitor_head, | ||
1128 | monitor_tail, | ||
1129 | r); | ||
1130 | GNUNET_free (r); | ||
1131 | return; /* Delete only ONE entry */ | ||
1282 | } | 1132 | } |
1283 | } | 1133 | } |
1284 | GNUNET_free (cl); | ||
1285 | } | 1134 | } |
1286 | 1135 | ||
1287 | 1136 | ||
1288 | /** | 1137 | /** |
1289 | * Check if some client is monitoring GET RESP messages and notify | 1138 | * Function to call by #for_matching_monitors(). |
1290 | * them in that case. | ||
1291 | * | 1139 | * |
1292 | * @param type The type of data in the result. | 1140 | * @param cls closure |
1293 | * @param get_path Peers on GET path (or NULL if not recorded). | 1141 | * @param m a matching monitor |
1294 | * @param get_path_length number of entries in get_path. | ||
1295 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
1296 | * @param put_path_length number of entries in get_path. | ||
1297 | * @param exp Expiration time of the data. | ||
1298 | * @param key Key of the data. | ||
1299 | * @param data Pointer to the result data. | ||
1300 | * @param size Number of bytes in @a data. | ||
1301 | */ | 1142 | */ |
1302 | void | 1143 | typedef void |
1303 | GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | 1144 | (*MonitorAction)(void *cls, |
1304 | const struct GNUNET_PeerIdentity *get_path, | 1145 | struct ClientMonitorRecord *m); |
1305 | unsigned int get_path_length, | 1146 | |
1306 | const struct GNUNET_PeerIdentity *put_path, | 1147 | |
1307 | unsigned int put_path_length, | 1148 | /** |
1308 | struct GNUNET_TIME_Absolute exp, | 1149 | * Call @a cb on all monitors that watch for blocks of @a type |
1309 | const struct GNUNET_HashCode *key, | 1150 | * and key @a key. |
1310 | const void *data, | 1151 | * |
1311 | size_t size) | 1152 | * @param type the type to match |
1153 | * @param key the key to match | ||
1154 | * @param cb function to call | ||
1155 | * @param cb_cls closure for @a cb | ||
1156 | */ | ||
1157 | static void | ||
1158 | for_matching_monitors (enum GNUNET_BLOCK_Type type, | ||
1159 | const struct GNUNET_HashCode *key, | ||
1160 | MonitorAction cb, | ||
1161 | void *cb_cls) | ||
1312 | { | 1162 | { |
1313 | struct ClientMonitorRecord *m; | 1163 | struct ClientHandle **cl = NULL; |
1314 | struct ClientHandle **cl; | 1164 | unsigned int cl_size = 0; |
1315 | unsigned int cl_size; | ||
1316 | 1165 | ||
1317 | cl = NULL; | 1166 | for (struct ClientMonitorRecord *m = monitor_head; |
1318 | cl_size = 0; | 1167 | NULL != m; |
1319 | for (m = monitor_head; NULL != m; m = m->next) | 1168 | m = m->next) |
1320 | { | 1169 | { |
1321 | if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) && | 1170 | if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || |
1322 | ((NULL == m->key) || | 1171 | (m->type == type) ) && |
1323 | (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) )) | 1172 | ( (GNUNET_is_zero (&m->key)) || |
1173 | (0 == | ||
1174 | GNUNET_memcmp (key, | ||
1175 | &m->key)) ) ) | ||
1324 | { | 1176 | { |
1325 | struct GNUNET_MQ_Envelope *env; | ||
1326 | struct GNUNET_DHT_MonitorGetRespMessage *mmsg; | ||
1327 | struct GNUNET_PeerIdentity *path; | ||
1328 | size_t msize; | ||
1329 | unsigned int i; | 1177 | unsigned int i; |
1330 | 1178 | ||
1331 | /* Don't send duplicates */ | 1179 | /* Don't send duplicates */ |
@@ -1337,30 +1185,8 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
1337 | GNUNET_array_append (cl, | 1185 | GNUNET_array_append (cl, |
1338 | cl_size, | 1186 | cl_size, |
1339 | m->ch); | 1187 | m->ch); |
1340 | 1188 | cb (cb_cls, | |
1341 | msize = size; | 1189 | m); |
1342 | msize += (get_path_length + put_path_length) | ||
1343 | * sizeof(struct GNUNET_PeerIdentity); | ||
1344 | env = GNUNET_MQ_msg_extra (mmsg, | ||
1345 | msize, | ||
1346 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); | ||
1347 | mmsg->type = htonl (type); | ||
1348 | mmsg->put_path_length = htonl (put_path_length); | ||
1349 | mmsg->get_path_length = htonl (get_path_length); | ||
1350 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp); | ||
1351 | mmsg->key = *key; | ||
1352 | path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
1353 | GNUNET_memcpy (path, | ||
1354 | put_path, | ||
1355 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1356 | GNUNET_memcpy (path, | ||
1357 | get_path, | ||
1358 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1359 | GNUNET_memcpy (&path[get_path_length], | ||
1360 | data, | ||
1361 | size); | ||
1362 | GNUNET_MQ_send (m->ch->mq, | ||
1363 | env); | ||
1364 | } | 1190 | } |
1365 | } | 1191 | } |
1366 | GNUNET_free (cl); | 1192 | GNUNET_free (cl); |
@@ -1368,94 +1194,254 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | |||
1368 | 1194 | ||
1369 | 1195 | ||
1370 | /** | 1196 | /** |
1371 | * Check if some client is monitoring PUT messages and notify | 1197 | * Closure for #get_action(); |
1372 | * them in that case. | 1198 | */ |
1199 | struct GetActionContext | ||
1200 | { | ||
1201 | enum GNUNET_DHT_RouteOption options; | ||
1202 | enum GNUNET_BLOCK_Type type; | ||
1203 | uint32_t hop_count; | ||
1204 | uint32_t desired_replication_level; | ||
1205 | unsigned int get_path_length; | ||
1206 | const struct GNUNET_PeerIdentity *get_path; | ||
1207 | const struct GNUNET_HashCode *key; | ||
1208 | }; | ||
1209 | |||
1210 | |||
1211 | /** | ||
1212 | * Function called on monitors that match a GET. | ||
1213 | * Sends the GET notification to the monitor. | ||
1214 | * | ||
1215 | * @param cls a `struct GetActionContext` | ||
1216 | * @param m a matching monitor | ||
1217 | */ | ||
1218 | static void | ||
1219 | get_action (void *cls, | ||
1220 | struct ClientMonitorRecord *m) | ||
1221 | { | ||
1222 | struct GetActionContext *gac = cls; | ||
1223 | struct GNUNET_MQ_Envelope *env; | ||
1224 | struct GNUNET_DHT_MonitorGetMessage *mmsg; | ||
1225 | struct GNUNET_PeerIdentity *msg_path; | ||
1226 | size_t msize; | ||
1227 | |||
1228 | msize = gac->get_path_length * sizeof(struct GNUNET_PeerIdentity); | ||
1229 | env = GNUNET_MQ_msg_extra (mmsg, | ||
1230 | msize, | ||
1231 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); | ||
1232 | mmsg->options = htonl (gac->options); | ||
1233 | mmsg->type = htonl (gac->type); | ||
1234 | mmsg->hop_count = htonl (gac->hop_count); | ||
1235 | mmsg->desired_replication_level = htonl (gac->desired_replication_level); | ||
1236 | mmsg->get_path_length = htonl (gac->get_path_length); | ||
1237 | mmsg->key = *gac->key; | ||
1238 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
1239 | GNUNET_memcpy (msg_path, | ||
1240 | gac->get_path, | ||
1241 | gac->get_path_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1242 | GNUNET_MQ_send (m->ch->mq, | ||
1243 | env); | ||
1244 | } | ||
1245 | |||
1246 | |||
1247 | /** | ||
1248 | * Check if some client is monitoring GET messages and notify | ||
1249 | * them in that case. If tracked, @a path should include the local peer. | ||
1373 | * | 1250 | * |
1374 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | 1251 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. |
1375 | * @param type The type of data in the request. | 1252 | * @param type The type of data in the request. |
1376 | * @param hop_count Hop count so far. | 1253 | * @param hop_count Hop count so far. |
1377 | * @param path_length number of entries in path (or 0 if not recorded). | 1254 | * @param path_length number of entries in path (or 0 if not recorded). |
1378 | * @param path peers on the PUT path (or NULL if not recorded). | 1255 | * @param path peers on the GET path (or NULL if not recorded). |
1379 | * @param desired_replication_level Desired replication level. | 1256 | * @param desired_replication_level Desired replication level. |
1380 | * @param exp Expiration time of the data. | 1257 | * @param key Key of the requested data. |
1381 | * @param key Key under which data is to be stored. | ||
1382 | * @param data Pointer to the data carried. | ||
1383 | * @param size Number of bytes in data. | ||
1384 | */ | 1258 | */ |
1385 | void | 1259 | void |
1386 | GDS_CLIENTS_process_put (uint32_t options, | 1260 | GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options, |
1387 | enum GNUNET_BLOCK_Type type, | 1261 | enum GNUNET_BLOCK_Type type, |
1388 | uint32_t hop_count, | 1262 | uint32_t hop_count, |
1389 | uint32_t desired_replication_level, | 1263 | uint32_t desired_replication_level, |
1390 | unsigned int path_length, | 1264 | unsigned int path_length, |
1391 | const struct GNUNET_PeerIdentity *path, | 1265 | const struct GNUNET_PeerIdentity *path, |
1392 | struct GNUNET_TIME_Absolute exp, | 1266 | const struct GNUNET_HashCode *key) |
1393 | const struct GNUNET_HashCode *key, | ||
1394 | const void *data, | ||
1395 | size_t size) | ||
1396 | { | 1267 | { |
1397 | struct ClientMonitorRecord *m; | 1268 | struct GetActionContext gac = { |
1398 | struct ClientHandle **cl; | 1269 | .options = options, |
1399 | unsigned int cl_size; | 1270 | .type = type, |
1271 | .hop_count = hop_count, | ||
1272 | .desired_replication_level = desired_replication_level, | ||
1273 | .get_path_length = path_length, | ||
1274 | .get_path = path, | ||
1275 | .key = key | ||
1276 | }; | ||
1277 | |||
1278 | for_matching_monitors (type, | ||
1279 | key, | ||
1280 | &get_action, | ||
1281 | &gac); | ||
1282 | } | ||
1400 | 1283 | ||
1401 | cl = NULL; | ||
1402 | cl_size = 0; | ||
1403 | for (m = monitor_head; NULL != m; m = m->next) | ||
1404 | { | ||
1405 | if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) && | ||
1406 | ((NULL == m->key) || | ||
1407 | (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) )) | ||
1408 | { | ||
1409 | struct GNUNET_MQ_Envelope *env; | ||
1410 | struct GNUNET_DHT_MonitorPutMessage *mmsg; | ||
1411 | struct GNUNET_PeerIdentity *msg_path; | ||
1412 | size_t msize; | ||
1413 | unsigned int i; | ||
1414 | 1284 | ||
1415 | /* Don't send duplicates */ | 1285 | /** |
1416 | for (i = 0; i < cl_size; i++) | 1286 | * Closure for response_action(). |
1417 | if (cl[i] == m->ch) | 1287 | */ |
1418 | break; | 1288 | struct ResponseActionContext |
1419 | if (i < cl_size) | 1289 | { |
1420 | continue; | 1290 | const struct GDS_DATACACHE_BlockData *bd; |
1421 | GNUNET_array_append (cl, | 1291 | const struct GNUNET_PeerIdentity *get_path; |
1422 | cl_size, | 1292 | unsigned int get_path_length; |
1423 | m->ch); | 1293 | }; |
1424 | 1294 | ||
1425 | msize = size; | 1295 | |
1426 | msize += path_length * sizeof(struct GNUNET_PeerIdentity); | 1296 | /** |
1427 | env = GNUNET_MQ_msg_extra (mmsg, | 1297 | * Function called on monitors that match a response. |
1428 | msize, | 1298 | * Sends the response notification to the monitor. |
1429 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); | 1299 | * |
1430 | mmsg->options = htonl (options); | 1300 | * @param cls a `struct ResponseActionContext` |
1431 | mmsg->type = htonl (type); | 1301 | * @param m a matching monitor |
1432 | mmsg->hop_count = htonl (hop_count); | 1302 | */ |
1433 | mmsg->desired_replication_level = htonl (desired_replication_level); | 1303 | static void |
1434 | mmsg->put_path_length = htonl (path_length); | 1304 | response_action (void *cls, |
1435 | mmsg->key = *key; | 1305 | struct ClientMonitorRecord *m) |
1436 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (exp); | 1306 | { |
1437 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | 1307 | const struct ResponseActionContext *resp_ctx = cls; |
1438 | GNUNET_memcpy (msg_path, | 1308 | const struct GDS_DATACACHE_BlockData *bd = resp_ctx->bd; |
1439 | path, | 1309 | |
1440 | path_length * sizeof(struct GNUNET_PeerIdentity)); | 1310 | struct GNUNET_MQ_Envelope *env; |
1441 | GNUNET_memcpy (&msg_path[path_length], | 1311 | struct GNUNET_DHT_MonitorGetRespMessage *mmsg; |
1442 | data, | 1312 | struct GNUNET_PeerIdentity *path; |
1443 | size); | 1313 | size_t msize; |
1444 | GNUNET_MQ_send (m->ch->mq, | 1314 | |
1445 | env); | 1315 | msize = bd->data_size; |
1446 | } | 1316 | msize += (resp_ctx->get_path_length + bd->put_path_length) |
1447 | } | 1317 | * sizeof(struct GNUNET_PeerIdentity); |
1448 | GNUNET_free (cl); | 1318 | env = GNUNET_MQ_msg_extra (mmsg, |
1319 | msize, | ||
1320 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); | ||
1321 | mmsg->type = htonl (bd->type); | ||
1322 | mmsg->put_path_length = htonl (bd->put_path_length); | ||
1323 | mmsg->get_path_length = htonl (resp_ctx->get_path_length); | ||
1324 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); | ||
1325 | mmsg->key = bd->key; | ||
1326 | path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
1327 | GNUNET_memcpy (path, | ||
1328 | bd->put_path, | ||
1329 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1330 | GNUNET_memcpy (path, | ||
1331 | resp_ctx->get_path, | ||
1332 | resp_ctx->get_path_length * sizeof(struct | ||
1333 | GNUNET_PeerIdentity)); | ||
1334 | GNUNET_memcpy (&path[resp_ctx->get_path_length], | ||
1335 | bd->data, | ||
1336 | bd->data_size); | ||
1337 | GNUNET_MQ_send (m->ch->mq, | ||
1338 | env); | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | void | ||
1343 | GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, | ||
1344 | const struct GNUNET_PeerIdentity *get_path, | ||
1345 | unsigned int get_path_length) | ||
1346 | { | ||
1347 | struct ResponseActionContext rac = { | ||
1348 | .bd = bd, | ||
1349 | .get_path = get_path, | ||
1350 | .get_path_length = get_path_length | ||
1351 | }; | ||
1352 | |||
1353 | for_matching_monitors (bd->type, | ||
1354 | &bd->key, | ||
1355 | &response_action, | ||
1356 | &rac); | ||
1357 | } | ||
1358 | |||
1359 | |||
1360 | /** | ||
1361 | * Closure for put_action(). | ||
1362 | */ | ||
1363 | struct PutActionContext | ||
1364 | { | ||
1365 | const struct GDS_DATACACHE_BlockData *bd; | ||
1366 | enum GNUNET_DHT_RouteOption options; | ||
1367 | uint32_t hop_count; | ||
1368 | uint32_t desired_replication_level; | ||
1369 | }; | ||
1370 | |||
1371 | |||
1372 | /** | ||
1373 | * Function called on monitors that match a PUT. | ||
1374 | * Sends the PUT notification to the monitor. | ||
1375 | * | ||
1376 | * @param cls a `struct PutActionContext` | ||
1377 | * @param m a matching monitor | ||
1378 | */ | ||
1379 | static void | ||
1380 | put_action (void *cls, | ||
1381 | struct ClientMonitorRecord *m) | ||
1382 | { | ||
1383 | const struct PutActionContext *put_ctx = cls; | ||
1384 | const struct GDS_DATACACHE_BlockData *bd = put_ctx->bd; | ||
1385 | struct GNUNET_MQ_Envelope *env; | ||
1386 | struct GNUNET_DHT_MonitorPutMessage *mmsg; | ||
1387 | struct GNUNET_PeerIdentity *msg_path; | ||
1388 | size_t msize; | ||
1389 | |||
1390 | msize = bd->data_size | ||
1391 | + bd->put_path_length | ||
1392 | * sizeof(struct GNUNET_PeerIdentity); | ||
1393 | env = GNUNET_MQ_msg_extra (mmsg, | ||
1394 | msize, | ||
1395 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); | ||
1396 | mmsg->options = htonl (put_ctx->options); | ||
1397 | mmsg->type = htonl (bd->type); | ||
1398 | mmsg->hop_count = htonl (put_ctx->hop_count); | ||
1399 | mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level); | ||
1400 | mmsg->put_path_length = htonl (bd->put_path_length); | ||
1401 | mmsg->key = bd->key; | ||
1402 | mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); | ||
1403 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
1404 | GNUNET_memcpy (msg_path, | ||
1405 | bd->put_path, | ||
1406 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); | ||
1407 | GNUNET_memcpy (&msg_path[bd->put_path_length], | ||
1408 | bd->data, | ||
1409 | bd->data_size); | ||
1410 | GNUNET_MQ_send (m->ch->mq, | ||
1411 | env); | ||
1449 | } | 1412 | } |
1450 | 1413 | ||
1451 | 1414 | ||
1415 | void | ||
1416 | GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, | ||
1417 | const struct GDS_DATACACHE_BlockData *bd, | ||
1418 | uint32_t hop_count, | ||
1419 | uint32_t desired_replication_level) | ||
1420 | { | ||
1421 | struct PutActionContext put_ctx = { | ||
1422 | .bd = bd, | ||
1423 | .hop_count = hop_count, | ||
1424 | .desired_replication_level = desired_replication_level, | ||
1425 | .options = options | ||
1426 | }; | ||
1427 | |||
1428 | for_matching_monitors (bd->type, | ||
1429 | &bd->key, | ||
1430 | &put_action, | ||
1431 | &put_ctx); | ||
1432 | } | ||
1433 | |||
1434 | |||
1435 | /* ********************** Initialization logic ***************** */ | ||
1436 | |||
1437 | |||
1452 | /** | 1438 | /** |
1453 | * Initialize client subsystem. | 1439 | * Initialize client subsystem. |
1454 | * | 1440 | * |
1455 | * @param server the initialized server | 1441 | * @param server the initialized server |
1456 | */ | 1442 | */ |
1457 | static void | 1443 | static void |
1458 | GDS_CLIENTS_init () | 1444 | GDS_CLIENTS_init (void) |
1459 | { | 1445 | { |
1460 | forward_map | 1446 | forward_map |
1461 | = GNUNET_CONTAINER_multihashmap_create (1024, | 1447 | = GNUNET_CONTAINER_multihashmap_create (1024, |
@@ -1469,7 +1455,7 @@ GDS_CLIENTS_init () | |||
1469 | * Shutdown client subsystem. | 1455 | * Shutdown client subsystem. |
1470 | */ | 1456 | */ |
1471 | static void | 1457 | static void |
1472 | GDS_CLIENTS_stop () | 1458 | GDS_CLIENTS_stop (void) |
1473 | { | 1459 | { |
1474 | if (NULL != retry_task) | 1460 | if (NULL != retry_task) |
1475 | { | 1461 | { |
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 7eded2152..214c4a3f4 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011, 2015, 2017 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2015, 2017, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -38,67 +38,53 @@ | |||
38 | */ | 38 | */ |
39 | #define NUM_CLOSEST 42 | 39 | #define NUM_CLOSEST 42 |
40 | 40 | ||
41 | |||
41 | /** | 42 | /** |
42 | * Handle to the datacache service (for inserting/retrieving data) | 43 | * Handle to the datacache service (for inserting/retrieving data) |
43 | */ | 44 | */ |
44 | static struct GNUNET_DATACACHE_Handle *datacache; | 45 | static struct GNUNET_DATACACHE_Handle *datacache; |
45 | 46 | ||
46 | 47 | ||
47 | /** | ||
48 | * Handle a datum we've received from another peer. Cache if | ||
49 | * possible. | ||
50 | * | ||
51 | * @param expiration when will the reply expire | ||
52 | * @param key the query this reply is for | ||
53 | * @param put_path_length number of peers in @a put_path | ||
54 | * @param put_path path the reply took on put | ||
55 | * @param type type of the reply | ||
56 | * @param data_size number of bytes in @a data | ||
57 | * @param data application payload data | ||
58 | */ | ||
59 | void | 48 | void |
60 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | 49 | GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd) |
61 | const struct GNUNET_HashCode *key, | ||
62 | unsigned int put_path_length, | ||
63 | const struct GNUNET_PeerIdentity *put_path, | ||
64 | enum GNUNET_BLOCK_Type type, | ||
65 | size_t data_size, | ||
66 | const void *data) | ||
67 | { | 50 | { |
68 | int r; | 51 | struct GNUNET_HashCode xor; |
52 | enum GNUNET_GenericReturnValue r; | ||
69 | 53 | ||
70 | if (NULL == datacache) | 54 | if (NULL == datacache) |
71 | { | 55 | { |
72 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 56 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
73 | _ ("%s request received, but have no datacache!\n"), "PUT"); | 57 | "PUT request received, but have no datacache!\n"); |
74 | return; | 58 | return; |
75 | } | 59 | } |
76 | if (data_size >= GNUNET_MAX_MESSAGE_SIZE) | 60 | if (bd->data_size >= GNUNET_MAX_MESSAGE_SIZE) |
77 | { | 61 | { |
78 | GNUNET_break (0); | 62 | GNUNET_break (0); |
79 | return; | 63 | return; |
80 | } | 64 | } |
81 | /* Put size is actual data size plus struct overhead plus path length (if any) */ | 65 | /* Put size is actual data size plus struct overhead plus path length (if any) */ |
82 | GNUNET_STATISTICS_update (GDS_stats, | 66 | GNUNET_STATISTICS_update (GDS_stats, |
83 | gettext_noop ("# ITEMS stored in datacache"), | 67 | "# ITEMS stored in datacache", |
84 | 1, | 68 | 1, |
85 | GNUNET_NO); | 69 | GNUNET_NO); |
70 | GNUNET_CRYPTO_hash_xor (&bd->key, | ||
71 | &my_identity_hash, | ||
72 | &xor); | ||
86 | r = GNUNET_DATACACHE_put (datacache, | 73 | r = GNUNET_DATACACHE_put (datacache, |
87 | key, | 74 | &bd->key, |
88 | GNUNET_CRYPTO_hash_matching_bits (key, | 75 | GNUNET_CRYPTO_hash_count_leading_zeros (&xor), |
89 | &my_identity_hash), | 76 | bd->data_size, |
90 | data_size, | 77 | bd->data, |
91 | data, | 78 | bd->type, |
92 | type, | 79 | bd->expiration_time, |
93 | expiration, | 80 | bd->put_path_length, |
94 | put_path_length, | 81 | bd->put_path); |
95 | put_path); | ||
96 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 82 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
97 | "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", | 83 | "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", |
98 | GNUNET_h2s (key), | 84 | GNUNET_h2s (&bd->key), |
99 | (unsigned long) data_size, | 85 | (unsigned long) bd->data_size, |
100 | r, | 86 | r, |
101 | put_path_length); | 87 | bd->put_path_length); |
102 | } | 88 | } |
103 | 89 | ||
104 | 90 | ||
@@ -158,7 +144,7 @@ struct GetRequestContext | |||
158 | * @return #GNUNET_OK to continue iteration, anything else | 144 | * @return #GNUNET_OK to continue iteration, anything else |
159 | * to stop iteration. | 145 | * to stop iteration. |
160 | */ | 146 | */ |
161 | static int | 147 | static enum GNUNET_GenericReturnValue |
162 | datacache_get_iterator (void *cls, | 148 | datacache_get_iterator (void *cls, |
163 | const struct GNUNET_HashCode *key, | 149 | const struct GNUNET_HashCode *key, |
164 | size_t data_size, | 150 | size_t data_size, |
@@ -168,111 +154,74 @@ datacache_get_iterator (void *cls, | |||
168 | unsigned int put_path_length, | 154 | unsigned int put_path_length, |
169 | const struct GNUNET_PeerIdentity *put_path) | 155 | const struct GNUNET_PeerIdentity *put_path) |
170 | { | 156 | { |
171 | static char non_null; | ||
172 | struct GetRequestContext *ctx = cls; | 157 | struct GetRequestContext *ctx = cls; |
173 | enum GNUNET_BLOCK_EvaluationResult eval; | 158 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
174 | 159 | struct GDS_DATACACHE_BlockData bd = { | |
175 | if (0 == GNUNET_TIME_absolute_get_remaining (exp).rel_value_us) | 160 | .key = *key, |
161 | .expiration_time = exp, | ||
162 | .put_path = put_path, | ||
163 | .data = data, | ||
164 | .data_size = data_size, | ||
165 | .put_path_length = put_path_length, | ||
166 | .type = type | ||
167 | }; | ||
168 | |||
169 | if (GNUNET_TIME_absolute_is_past (exp)) | ||
176 | { | 170 | { |
177 | GNUNET_break (0); /* why does datacache return expired values? */ | 171 | GNUNET_break (0); /* why does datacache return expired values? */ |
178 | return GNUNET_OK; /* skip expired record */ | 172 | return GNUNET_OK; /* skip expired record */ |
179 | } | 173 | } |
180 | if ((NULL == data) && | ||
181 | (0 == data_size)) | ||
182 | data = &non_null; /* point anywhere, but not to NULL */ | ||
183 | |||
184 | eval | 174 | eval |
185 | = GNUNET_BLOCK_evaluate (GDS_block_context, | 175 | = GNUNET_BLOCK_check_reply (GDS_block_context, |
186 | type, | 176 | bd.type, |
187 | ctx->bg, | 177 | ctx->bg, |
188 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | 178 | &bd.key, |
189 | key, | 179 | ctx->xquery, |
190 | ctx->xquery, | 180 | ctx->xquery_size, |
191 | ctx->xquery_size, | 181 | bd.data, |
192 | data, | 182 | bd.data_size); |
193 | data_size); | ||
194 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 183 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
195 | "Found reply for query %s in datacache, evaluation result is %d\n", | 184 | "Evaluated reply for query %s in datacache, result is %d\n", |
196 | GNUNET_h2s (key), | 185 | GNUNET_h2s (key), |
197 | (int) eval); | 186 | (int) eval); |
198 | ctx->eval = eval; | 187 | ctx->eval = eval; |
199 | switch (eval) | 188 | switch (eval) |
200 | { | 189 | { |
201 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | 190 | case GNUNET_BLOCK_REPLY_OK_MORE: |
202 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | 191 | case GNUNET_BLOCK_REPLY_OK_LAST: |
203 | /* forward to local clients */ | 192 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: |
204 | GNUNET_STATISTICS_update (GDS_stats, | 193 | /* forward to initiator */ |
205 | gettext_noop | ||
206 | ("# Good RESULTS found in datacache"), 1, | ||
207 | GNUNET_NO); | ||
208 | ctx->gc (ctx->gc_cls, | ||
209 | type, | ||
210 | exp, | ||
211 | key, | ||
212 | put_path_length, put_path, | ||
213 | 0, NULL, | ||
214 | data, data_size); | ||
215 | break; | ||
216 | |||
217 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
218 | GNUNET_STATISTICS_update (GDS_stats, | 194 | GNUNET_STATISTICS_update (GDS_stats, |
219 | gettext_noop ( | 195 | "# Good RESULTS found in datacache", |
220 | "# Duplicate RESULTS found in datacache"), | ||
221 | 1, | 196 | 1, |
222 | GNUNET_NO); | 197 | GNUNET_NO); |
198 | ctx->gc (ctx->gc_cls, | ||
199 | &bd); | ||
223 | break; | 200 | break; |
224 | 201 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | |
225 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
226 | GNUNET_STATISTICS_update (GDS_stats, | 202 | GNUNET_STATISTICS_update (GDS_stats, |
227 | gettext_noop ( | 203 | "# Duplicate RESULTS found in datacache", |
228 | "# Invalid RESULTS found in datacache"), | ||
229 | 1, | 204 | 1, |
230 | GNUNET_NO); | 205 | GNUNET_NO); |
231 | break; | 206 | break; |
232 | 207 | case GNUNET_BLOCK_REPLY_INVALID: | |
233 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | 208 | /* maybe it expired? */ |
234 | GNUNET_STATISTICS_update (GDS_stats, | 209 | GNUNET_STATISTICS_update (GDS_stats, |
235 | gettext_noop ( | 210 | "# Invalid RESULTS found in datacache", |
236 | "# Irrelevant RESULTS found in datacache"), | ||
237 | 1, | 211 | 1, |
238 | GNUNET_NO); | 212 | GNUNET_NO); |
239 | break; | 213 | break; |
240 | 214 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | |
241 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
242 | GNUNET_break (0); | ||
243 | break; | ||
244 | |||
245 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
246 | GNUNET_break_op (0); | ||
247 | return GNUNET_SYSERR; | ||
248 | |||
249 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
250 | GNUNET_STATISTICS_update (GDS_stats, | 215 | GNUNET_STATISTICS_update (GDS_stats, |
251 | gettext_noop ( | 216 | "# Irrelevant RESULTS found in datacache", |
252 | "# Unsupported RESULTS found in datacache"), | ||
253 | 1, | 217 | 1, |
254 | GNUNET_NO); | 218 | GNUNET_NO); |
255 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
256 | _ ("Unsupported block type (%u) in local response!\n"), | ||
257 | type); | ||
258 | break; | 219 | break; |
259 | } | 220 | } |
260 | return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; | 221 | return (eval == GNUNET_BLOCK_REPLY_OK_LAST) ? GNUNET_NO : GNUNET_OK; |
261 | } | 222 | } |
262 | 223 | ||
263 | 224 | ||
264 | /** | ||
265 | * Handle a GET request we've received from another peer. | ||
266 | * | ||
267 | * @param key the query | ||
268 | * @param type requested data type | ||
269 | * @param xquery extended query | ||
270 | * @param xquery_size number of bytes in @a xquery | ||
271 | * @param bg block group to use for reply evaluation | ||
272 | * @param gc function to call on the results | ||
273 | * @param gc_cls closure for @a gc | ||
274 | * @return evaluation result for the local replies | ||
275 | */ | ||
276 | enum GNUNET_BLOCK_EvaluationResult | 225 | enum GNUNET_BLOCK_EvaluationResult |
277 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | 226 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, |
278 | enum GNUNET_BLOCK_Type type, | 227 | enum GNUNET_BLOCK_Type type, |
@@ -288,7 +237,7 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
288 | if (NULL == datacache) | 237 | if (NULL == datacache) |
289 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | 238 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; |
290 | GNUNET_STATISTICS_update (GDS_stats, | 239 | GNUNET_STATISTICS_update (GDS_stats, |
291 | gettext_noop ("# GET requests given to datacache"), | 240 | "# GET requests given to datacache", |
292 | 1, | 241 | 1, |
293 | GNUNET_NO); | 242 | GNUNET_NO); |
294 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | 243 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; |
@@ -313,62 +262,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
313 | 262 | ||
314 | 263 | ||
315 | /** | 264 | /** |
316 | * Function called with a random element from the datacache. | ||
317 | * Stores the key in the closure. | ||
318 | * | ||
319 | * @param cls a `struct GNUNET_HashCode *`, where to store the @a key | ||
320 | * @param key key for the content | ||
321 | * @param data_size number of bytes in @a data | ||
322 | * @param data content stored | ||
323 | * @param type type of the content | ||
324 | * @param exp when will the content expire? | ||
325 | * @param path_info_len number of entries in @a path_info | ||
326 | * @param path_info a path through the network | ||
327 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort | ||
328 | */ | ||
329 | static int | ||
330 | datacache_random_iterator (void *cls, | ||
331 | const struct GNUNET_HashCode *key, | ||
332 | size_t data_size, | ||
333 | const char *data, | ||
334 | enum GNUNET_BLOCK_Type type, | ||
335 | struct GNUNET_TIME_Absolute exp, | ||
336 | unsigned int path_info_len, | ||
337 | const struct GNUNET_PeerIdentity *path_info) | ||
338 | { | ||
339 | struct GNUNET_HashCode *dest = cls; | ||
340 | |||
341 | *dest = *key; | ||
342 | return GNUNET_OK; /* should actually not matter which we return */ | ||
343 | } | ||
344 | |||
345 | |||
346 | /** | ||
347 | * Obtain a random key from the datacache. | ||
348 | * Used by Whanau for load-balancing. | ||
349 | * | ||
350 | * @param[out] key where to store the key of a random element, | ||
351 | * randomized by PRNG if datacache is empty | ||
352 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
353 | */ | ||
354 | int | ||
355 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) | ||
356 | { | ||
357 | if (0 == | ||
358 | GNUNET_DATACACHE_get_random (datacache, | ||
359 | &datacache_random_iterator, | ||
360 | key)) | ||
361 | { | ||
362 | /* randomize key in this case */ | ||
363 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
364 | key); | ||
365 | return GNUNET_SYSERR; | ||
366 | } | ||
367 | return GNUNET_OK; | ||
368 | } | ||
369 | |||
370 | |||
371 | /** | ||
372 | * Closure for #datacache_get_successors_iterator(). | 265 | * Closure for #datacache_get_successors_iterator(). |
373 | */ | 266 | */ |
374 | struct SuccContext | 267 | struct SuccContext |
@@ -376,12 +269,13 @@ struct SuccContext | |||
376 | /** | 269 | /** |
377 | * Function to call on the result | 270 | * Function to call on the result |
378 | */ | 271 | */ |
379 | GDS_DATACACHE_SuccessorCallback cb; | 272 | GDS_DATACACHE_GetCallback cb; |
380 | 273 | ||
381 | /** | 274 | /** |
382 | * Closure for @e cb. | 275 | * Closure for @e cb. |
383 | */ | 276 | */ |
384 | void *cb_cls; | 277 | void *cb_cls; |
278 | |||
385 | }; | 279 | }; |
386 | 280 | ||
387 | 281 | ||
@@ -399,7 +293,7 @@ struct SuccContext | |||
399 | * @return #GNUNET_OK to continue iteration, anything else | 293 | * @return #GNUNET_OK to continue iteration, anything else |
400 | * to stop iteration. | 294 | * to stop iteration. |
401 | */ | 295 | */ |
402 | static int | 296 | static enum GNUNET_GenericReturnValue |
403 | datacache_get_successors_iterator (void *cls, | 297 | datacache_get_successors_iterator (void *cls, |
404 | const struct GNUNET_HashCode *key, | 298 | const struct GNUNET_HashCode *key, |
405 | size_t size, | 299 | size_t size, |
@@ -410,40 +304,36 @@ datacache_get_successors_iterator (void *cls, | |||
410 | const struct GNUNET_PeerIdentity *put_path) | 304 | const struct GNUNET_PeerIdentity *put_path) |
411 | { | 305 | { |
412 | const struct SuccContext *sc = cls; | 306 | const struct SuccContext *sc = cls; |
307 | struct GDS_DATACACHE_BlockData bd = { | ||
308 | .key = *key, | ||
309 | .expiration_time = exp, | ||
310 | .put_path = put_path, | ||
311 | .data = data, | ||
312 | .data_size = size, | ||
313 | .put_path_length = put_path_length, | ||
314 | .type = type | ||
315 | }; | ||
413 | 316 | ||
414 | /* NOTE: The datacache currently does not store the RO from | 317 | /* NOTE: The datacache currently does not store the RO from |
415 | the original 'put', so we don't know the 'correct' option | 318 | the original 'put', so we don't know the 'correct' option |
416 | at this point anymore. Thus, we conservatively assume | 319 | at this point anymore. Thus, we conservatively assume |
417 | that recording is desired (for now). */ | 320 | that recording is desired (for now). */ |
418 | sc->cb (sc->cb_cls, | 321 | sc->cb (sc->cb_cls, |
419 | GNUNET_DHT_RO_RECORD_ROUTE, | 322 | &bd); |
420 | key, | ||
421 | type, | ||
422 | put_path_length, put_path, | ||
423 | exp, | ||
424 | data, | ||
425 | size); | ||
426 | return GNUNET_OK; | 323 | return GNUNET_OK; |
427 | } | 324 | } |
428 | 325 | ||
429 | 326 | ||
430 | /** | ||
431 | * Handle a request for data close to a key that we have received from | ||
432 | * another peer. | ||
433 | * | ||
434 | * @param key the location at which the peer is looking for data that is close | ||
435 | * @param cb function to call with the result | ||
436 | * @param cb_cls closure for @a cb | ||
437 | */ | ||
438 | void | 327 | void |
439 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | 328 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
440 | GDS_DATACACHE_SuccessorCallback cb, | 329 | GDS_DATACACHE_GetCallback cb, |
441 | void *cb_cls) | 330 | void *cb_cls) |
442 | { | 331 | { |
443 | struct SuccContext sc; | 332 | struct SuccContext sc = { |
333 | .cb = cb, | ||
334 | .cb_cls = cb_cls | ||
335 | }; | ||
444 | 336 | ||
445 | sc.cb = cb; | ||
446 | sc.cb_cls = cb_cls; | ||
447 | (void) GNUNET_DATACACHE_get_closest (datacache, | 337 | (void) GNUNET_DATACACHE_get_closest (datacache, |
448 | key, | 338 | key, |
449 | NUM_CLOSEST, | 339 | NUM_CLOSEST, |
@@ -452,19 +342,14 @@ GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | |||
452 | } | 342 | } |
453 | 343 | ||
454 | 344 | ||
455 | /** | ||
456 | * Initialize datacache subsystem. | ||
457 | */ | ||
458 | void | 345 | void |
459 | GDS_DATACACHE_init () | 346 | GDS_DATACACHE_init () |
460 | { | 347 | { |
461 | datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); | 348 | datacache = GNUNET_DATACACHE_create (GDS_cfg, |
349 | "dhtcache"); | ||
462 | } | 350 | } |
463 | 351 | ||
464 | 352 | ||
465 | /** | ||
466 | * Shutdown datacache subsystem. | ||
467 | */ | ||
468 | void | 353 | void |
469 | GDS_DATACACHE_done () | 354 | GDS_DATACACHE_done () |
470 | { | 355 | { |
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 5be59c90e..249bb8ee3 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -31,53 +31,68 @@ | |||
31 | #include "gnunet_block_lib.h" | 31 | #include "gnunet_block_lib.h" |
32 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
33 | 33 | ||
34 | |||
35 | /** | ||
36 | * Information about a block stored in the datacache. | ||
37 | */ | ||
38 | struct GDS_DATACACHE_BlockData | ||
39 | { | ||
40 | /** | ||
41 | * Key of the block. | ||
42 | */ | ||
43 | struct GNUNET_HashCode key; | ||
44 | |||
45 | /** | ||
46 | * When does the block expire? | ||
47 | */ | ||
48 | struct GNUNET_TIME_Absolute expiration_time; | ||
49 | |||
50 | /** | ||
51 | * PUT path taken by the block, array of peer identities. | ||
52 | */ | ||
53 | const struct GNUNET_PeerIdentity *put_path; | ||
54 | |||
55 | /** | ||
56 | * Actual block data. | ||
57 | */ | ||
58 | const void *data; | ||
59 | |||
60 | /** | ||
61 | * Number of bytes in @a data. | ||
62 | */ | ||
63 | size_t data_size; | ||
64 | |||
65 | /** | ||
66 | * Length of the @e put_path array. | ||
67 | */ | ||
68 | unsigned int put_path_length; | ||
69 | |||
70 | /** | ||
71 | * Type of the block. | ||
72 | */ | ||
73 | enum GNUNET_BLOCK_Type type; | ||
74 | }; | ||
75 | |||
76 | |||
34 | /** | 77 | /** |
35 | * Handle a datum we've received from another peer. Cache if | 78 | * Handle a datum we've received from another peer. Cache if |
36 | * possible. | 79 | * possible. |
37 | * | 80 | * |
38 | * @param expiration when will the reply expire | 81 | * @param bd block data to cache |
39 | * @param key the query this reply is for | ||
40 | * @param put_path_length number of peers in 'put_path' | ||
41 | * @param put_path path the reply took on put | ||
42 | * @param type type of the reply | ||
43 | * @param data_size number of bytes in 'data' | ||
44 | * @param data application payload data | ||
45 | */ | 82 | */ |
46 | void | 83 | void |
47 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | 84 | GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd); |
48 | const struct GNUNET_HashCode *key, | ||
49 | unsigned int put_path_length, | ||
50 | const struct GNUNET_PeerIdentity *put_path, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | size_t data_size, | ||
53 | const void *data); | ||
54 | 85 | ||
55 | 86 | ||
56 | /** | 87 | /** |
57 | * Handle a result for a GET operation. | 88 | * Handle a result for a GET operation. |
58 | * | 89 | * |
59 | * @param cls closure | 90 | * @param cls closure |
60 | * @param type type of the block | 91 | * @param bd block details |
61 | * @param expiration_time when does the content expire | ||
62 | * @param key key for the content | ||
63 | * @param put_path_length number of entries in @a put_path | ||
64 | * @param put_path peers the original PUT traversed (if tracked) | ||
65 | * @param get_path_length number of entries in @a get_path | ||
66 | * @param get_path peers this reply has traversed so far (if tracked) | ||
67 | * @param data payload of the reply | ||
68 | * @param data_size number of bytes in @a data | ||
69 | */ | 92 | */ |
70 | typedef void | 93 | typedef void |
71 | (*GDS_DATACACHE_GetCallback)(void *cls, | 94 | (*GDS_DATACACHE_GetCallback)(void *cls, |
72 | enum GNUNET_BLOCK_Type type, | 95 | const struct GDS_DATACACHE_BlockData *bd); |
73 | struct GNUNET_TIME_Absolute expiration_time, | ||
74 | const struct GNUNET_HashCode *key, | ||
75 | unsigned int put_path_length, | ||
76 | const struct GNUNET_PeerIdentity *put_path, | ||
77 | unsigned int get_path_length, | ||
78 | const struct GNUNET_PeerIdentity *get_path, | ||
79 | const void *data, | ||
80 | size_t data_size); | ||
81 | 96 | ||
82 | 97 | ||
83 | /** | 98 | /** |
@@ -103,43 +118,6 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
103 | 118 | ||
104 | 119 | ||
105 | /** | 120 | /** |
106 | * Obtain a random key from the datacache. | ||
107 | * Used by Whanau for load-balancing. | ||
108 | * | ||
109 | * @param[out] key where to store the key of a random element, | ||
110 | * randomized by PRNG if datacache is empty | ||
111 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
112 | */ | ||
113 | int | ||
114 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Send the get result to requesting client. | ||
119 | * | ||
120 | * @param cls closure | ||
121 | * @param options routing options (from GET request) | ||
122 | * @param key key of the requested data. | ||
123 | * @param type block type | ||
124 | * @param put_path_length number of peers in @a put_path | ||
125 | * @param put_path path taken to put the data at its stored location. | ||
126 | * @param expiration when will this result expire? | ||
127 | * @param data payload to store | ||
128 | * @param data_size size of the @a data | ||
129 | */ | ||
130 | typedef void | ||
131 | (*GDS_DATACACHE_SuccessorCallback)(void *cls, | ||
132 | enum GNUNET_DHT_RouteOption options, | ||
133 | const struct GNUNET_HashCode *key, | ||
134 | enum GNUNET_BLOCK_Type type, | ||
135 | unsigned int put_path_length, | ||
136 | const struct GNUNET_PeerIdentity *put_path, | ||
137 | struct GNUNET_TIME_Absolute expiration, | ||
138 | const void *data, | ||
139 | size_t data_size); | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Handle a request for data close to a key that we have received from | 121 | * Handle a request for data close to a key that we have received from |
144 | * another peer. | 122 | * another peer. |
145 | * | 123 | * |
@@ -148,9 +126,9 @@ typedef void | |||
148 | * @param cb_cls closure for @a cb | 126 | * @param cb_cls closure for @a cb |
149 | */ | 127 | */ |
150 | void | 128 | void |
151 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | 129 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
152 | GDS_DATACACHE_SuccessorCallback cb, | 130 | GDS_DATACACHE_GetCallback cb, |
153 | void *cb_cls); | 131 | void *cb_cls); |
154 | 132 | ||
155 | 133 | ||
156 | /** | 134 | /** |
diff --git a/src/dht/gnunet-service-dht_hello.c b/src/dht/gnunet-service-dht_hello.c index 906391334..949456575 100644 --- a/src/dht/gnunet-service-dht_hello.c +++ b/src/dht/gnunet-service-dht_hello.c | |||
@@ -54,7 +54,8 @@ GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer) | |||
54 | { | 54 | { |
55 | if (NULL == peer_to_hello) | 55 | if (NULL == peer_to_hello) |
56 | return NULL; | 56 | return NULL; |
57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | 57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, |
58 | peer); | ||
58 | } | 59 | } |
59 | 60 | ||
60 | 61 | ||
@@ -83,15 +84,20 @@ process_hello (void *cls, | |||
83 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) | 84 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) |
84 | return; | 85 | return; |
85 | GNUNET_STATISTICS_update (GDS_stats, | 86 | GNUNET_STATISTICS_update (GDS_stats, |
86 | gettext_noop ("# HELLOs obtained from peerinfo"), 1, | 87 | "# HELLOs obtained from peerinfo", |
88 | 1, | ||
87 | GNUNET_NO); | 89 | GNUNET_NO); |
88 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | 90 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, |
91 | peer); | ||
89 | GNUNET_free (hm); | 92 | GNUNET_free (hm); |
90 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); | 93 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); |
91 | GNUNET_memcpy (hm, hello, GNUNET_HELLO_size (hello)); | 94 | GNUNET_memcpy (hm, |
95 | hello, | ||
96 | GNUNET_HELLO_size (hello)); | ||
92 | GNUNET_assert (GNUNET_SYSERR != | 97 | GNUNET_assert (GNUNET_SYSERR != |
93 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, | 98 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, |
94 | peer, hm, | 99 | peer, |
100 | hm, | ||
95 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); | 101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); |
96 | } | 102 | } |
97 | 103 | ||
@@ -114,7 +120,7 @@ GDS_HELLO_init () | |||
114 | /** | 120 | /** |
115 | * Free memory occopied by the HELLO. | 121 | * Free memory occopied by the HELLO. |
116 | */ | 122 | */ |
117 | static int | 123 | static enum GNUNET_GenericReturnValue |
118 | free_hello (void *cls, | 124 | free_hello (void *cls, |
119 | const struct GNUNET_PeerIdentity *key, | 125 | const struct GNUNET_PeerIdentity *key, |
120 | void *hello) | 126 | void *hello) |
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 02dab849b..35502e0f5 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2017, 2021 GNUnet e.V. | 3 | Copyright (C) 2009-2017, 2021, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -25,21 +25,12 @@ | |||
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_block_lib.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | #include "gnunet_constants.h" | 28 | #include "gnunet_constants.h" |
32 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
33 | #include "gnunet_nse_service.h" | ||
34 | #include "gnunet_ats_service.h" | 30 | #include "gnunet_ats_service.h" |
35 | #include "gnunet_core_service.h" | 31 | #include "gnunet_core_service.h" |
36 | #include "gnunet_datacache_lib.h" | ||
37 | #include "gnunet_transport_service.h" | ||
38 | #include "gnunet_hello_lib.h" | 32 | #include "gnunet_hello_lib.h" |
39 | #include "gnunet_dht_service.h" | ||
40 | #include "gnunet_statistics_service.h" | ||
41 | #include "gnunet-service-dht.h" | 33 | #include "gnunet-service-dht.h" |
42 | #include "gnunet-service-dht_datacache.h" | ||
43 | #include "gnunet-service-dht_hello.h" | 34 | #include "gnunet-service-dht_hello.h" |
44 | #include "gnunet-service-dht_neighbours.h" | 35 | #include "gnunet-service-dht_neighbours.h" |
45 | #include "gnunet-service-dht_nse.h" | 36 | #include "gnunet-service-dht_nse.h" |
@@ -55,7 +46,7 @@ | |||
55 | #define SANITY_CHECKS 1 | 46 | #define SANITY_CHECKS 1 |
56 | 47 | ||
57 | /** | 48 | /** |
58 | * How many buckets will we allow total. | 49 | * How many buckets will we allow in total. |
59 | */ | 50 | */ |
60 | #define MAX_BUCKETS sizeof(struct GNUNET_HashCode) * 8 | 51 | #define MAX_BUCKETS sizeof(struct GNUNET_HashCode) * 8 |
61 | 52 | ||
@@ -70,26 +61,29 @@ | |||
70 | #define FIND_PEER_REPLICATION_LEVEL 4 | 61 | #define FIND_PEER_REPLICATION_LEVEL 4 |
71 | 62 | ||
72 | /** | 63 | /** |
73 | * Maximum allowed replication level for all requests. | ||
74 | */ | ||
75 | #define MAXIMUM_REPLICATION_LEVEL 16 | ||
76 | |||
77 | /** | ||
78 | * Maximum allowed number of pending messages per peer. | 64 | * Maximum allowed number of pending messages per peer. |
79 | */ | 65 | */ |
80 | #define MAXIMUM_PENDING_PER_PEER 64 | 66 | #define MAXIMUM_PENDING_PER_PEER 64 |
81 | 67 | ||
82 | /** | 68 | /** |
83 | * How long at least to wait before sending another find peer request. | 69 | * How long at least to wait before sending another find peer request. |
70 | * This is basically the frequency at which we will usually send out | ||
71 | * requests when we are 'perfectly' connected. | ||
84 | */ | 72 | */ |
85 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 73 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
86 | GNUNET_TIME_UNIT_SECONDS, 30) | 74 | GNUNET_TIME_UNIT_MINUTES, 2) |
87 | 75 | ||
88 | /** | 76 | /** |
89 | * How long at most to wait before sending another find peer request. | 77 | * How long to additionally wait on average per #bucket_size to send out the |
78 | * FIND PEER requests if we did successfully connect (!) to a a new peer and | ||
79 | * added it to a bucket (as counted in #newly_found_peers). This time is | ||
80 | * Multiplied by 100 * newly_found_peers / bucket_size to get the new delay | ||
81 | * for finding peers (the #DHT_MINIMUM_FIND_PEER_INTERVAL is still added on | ||
82 | * top). Also the range in which we randomize, so the effective value | ||
83 | * is half of the number given here. | ||
90 | */ | 84 | */ |
91 | #define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 85 | #define DHT_AVG_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
92 | GNUNET_TIME_UNIT_MINUTES, 10) | 86 | GNUNET_TIME_UNIT_SECONDS, 6) |
93 | 87 | ||
94 | /** | 88 | /** |
95 | * How long at most to wait for transmission of a GET request to another peer? | 89 | * How long at most to wait for transmission of a GET request to another peer? |
@@ -424,20 +418,24 @@ static struct GNUNET_ATS_ConnectivityHandle *ats_ch; | |||
424 | * Find the optimal bucket for this key. | 418 | * Find the optimal bucket for this key. |
425 | * | 419 | * |
426 | * @param hc the hashcode to compare our identity to | 420 | * @param hc the hashcode to compare our identity to |
427 | * @return the proper bucket index, or #GNUNET_SYSERR | 421 | * @return the proper bucket index, or -1 |
428 | * on error (same hashcode) | 422 | * on error (same hashcode) |
429 | */ | 423 | */ |
430 | static int | 424 | static int |
431 | find_bucket (const struct GNUNET_HashCode *hc) | 425 | find_bucket (const struct GNUNET_HashCode *hc) |
432 | { | 426 | { |
427 | struct GNUNET_HashCode xor; | ||
433 | unsigned int bits; | 428 | unsigned int bits; |
434 | 429 | ||
435 | bits = GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, hc); | 430 | GNUNET_CRYPTO_hash_xor (hc, |
431 | &my_identity_hash, | ||
432 | &xor); | ||
433 | bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | ||
436 | if (bits == MAX_BUCKETS) | 434 | if (bits == MAX_BUCKETS) |
437 | { | 435 | { |
438 | /* How can all bits match? Got my own ID? */ | 436 | /* How can all bits match? Got my own ID? */ |
439 | GNUNET_break (0); | 437 | GNUNET_break (0); |
440 | return GNUNET_SYSERR; | 438 | return -1; |
441 | } | 439 | } |
442 | return MAX_BUCKETS - bits - 1; | 440 | return MAX_BUCKETS - bits - 1; |
443 | } | 441 | } |
@@ -466,7 +464,7 @@ offer_hello_done (void *cls) | |||
466 | * @param value the value to remove | 464 | * @param value the value to remove |
467 | * @return #GNUNET_YES | 465 | * @return #GNUNET_YES |
468 | */ | 466 | */ |
469 | static int | 467 | static enum GNUNET_GenericReturnValue |
470 | free_connect_info (void *cls, | 468 | free_connect_info (void *cls, |
471 | const struct GNUNET_PeerIdentity *peer, | 469 | const struct GNUNET_PeerIdentity *peer, |
472 | void *value) | 470 | void *value) |
@@ -505,33 +503,34 @@ static void | |||
505 | try_connect (const struct GNUNET_PeerIdentity *pid, | 503 | try_connect (const struct GNUNET_PeerIdentity *pid, |
506 | const struct GNUNET_MessageHeader *h) | 504 | const struct GNUNET_MessageHeader *h) |
507 | { | 505 | { |
508 | int bucket; | 506 | int bucket_idx; |
509 | struct GNUNET_HashCode pid_hash; | 507 | struct GNUNET_HashCode pid_hash; |
510 | struct ConnectInfo *ci; | 508 | struct ConnectInfo *ci; |
511 | uint32_t strength; | 509 | uint32_t strength; |
510 | struct PeerBucket *bucket; | ||
512 | 511 | ||
513 | GNUNET_CRYPTO_hash (pid, | 512 | GNUNET_CRYPTO_hash (pid, |
514 | sizeof(struct GNUNET_PeerIdentity), | 513 | sizeof(struct GNUNET_PeerIdentity), |
515 | &pid_hash); | 514 | &pid_hash); |
516 | bucket = find_bucket (&pid_hash); | 515 | bucket_idx = find_bucket (&pid_hash); |
517 | if (bucket < 0) | 516 | if (bucket_idx < 0) |
518 | return; /* self? */ | 517 | { |
518 | GNUNET_break (0); | ||
519 | return; /* self!? */ | ||
520 | } | ||
521 | bucket = &k_buckets[bucket_idx]; | ||
519 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, | 522 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, |
520 | pid); | 523 | pid); |
521 | 524 | if (bucket->peers_size < bucket_size) | |
522 | if (k_buckets[bucket].peers_size < bucket_size) | 525 | strength = (bucket_size - bucket->peers_size) * bucket_idx; |
523 | strength = (bucket_size - k_buckets[bucket].peers_size) * bucket; | ||
524 | else | 526 | else |
525 | strength = bucket; /* minimum value of connectivity */ | 527 | strength = 0; |
526 | if (GNUNET_YES == | 528 | if (GNUNET_YES == |
527 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, | 529 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, |
528 | pid)) | 530 | pid)) |
529 | strength *= 2; /* double for connected peers */ | 531 | strength *= 2; /* double for connected peers */ |
530 | else if (k_buckets[bucket].peers_size > bucket_size) | 532 | if ( (0 == strength) && |
531 | strength = 0; /* bucket full, we really do not care about more */ | 533 | (NULL != ci) ) |
532 | |||
533 | if ((0 == strength) && | ||
534 | (NULL != ci)) | ||
535 | { | 534 | { |
536 | /* release request */ | 535 | /* release request */ |
537 | GNUNET_assert (GNUNET_YES == | 536 | GNUNET_assert (GNUNET_YES == |
@@ -549,22 +548,24 @@ try_connect (const struct GNUNET_PeerIdentity *pid, | |||
549 | ci, | 548 | ci, |
550 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 549 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
551 | } | 550 | } |
552 | if ((NULL != ci->oh) && | 551 | if ( (NULL != ci->oh) && |
553 | (NULL != h)) | 552 | (NULL != h) ) |
554 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | 553 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); |
555 | if (NULL != h) | 554 | if (NULL != h) |
556 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, | 555 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, |
557 | h, | 556 | h, |
558 | &offer_hello_done, | 557 | &offer_hello_done, |
559 | ci); | 558 | ci); |
560 | if ((NULL != ci->sh) && | 559 | if ( (NULL != ci->sh) && |
561 | (ci->strength != strength)) | 560 | (ci->strength != strength) ) |
562 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); | 561 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); |
563 | if (ci->strength != strength) | 562 | if (ci->strength != strength) |
563 | { | ||
564 | ci->sh = GNUNET_ATS_connectivity_suggest (ats_ch, | 564 | ci->sh = GNUNET_ATS_connectivity_suggest (ats_ch, |
565 | pid, | 565 | pid, |
566 | strength); | 566 | strength); |
567 | ci->strength = strength; | 567 | ci->strength = strength; |
568 | } | ||
568 | } | 569 | } |
569 | 570 | ||
570 | 571 | ||
@@ -580,7 +581,7 @@ try_connect (const struct GNUNET_PeerIdentity *pid, | |||
580 | * @param value unused | 581 | * @param value unused |
581 | * @return #GNUNET_YES (continue to iterate) | 582 | * @return #GNUNET_YES (continue to iterate) |
582 | */ | 583 | */ |
583 | static int | 584 | static enum GNUNET_GenericReturnValue |
584 | update_desire_strength (void *cls, | 585 | update_desire_strength (void *cls, |
585 | const struct GNUNET_PeerIdentity *pid, | 586 | const struct GNUNET_PeerIdentity *pid, |
586 | void *value) | 587 | void *value) |
@@ -595,12 +596,9 @@ update_desire_strength (void *cls, | |||
595 | 596 | ||
596 | /** | 597 | /** |
597 | * Update our preferences for connectivity as given to ATS. | 598 | * Update our preferences for connectivity as given to ATS. |
598 | * | ||
599 | * @param cls the `struct PeerInfo` of the peer | ||
600 | * @param tc scheduler context. | ||
601 | */ | 599 | */ |
602 | static void | 600 | static void |
603 | update_connect_preferences () | 601 | update_connect_preferences (void) |
604 | { | 602 | { |
605 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, | 603 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, |
606 | &update_desire_strength, | 604 | &update_desire_strength, |
@@ -609,32 +607,27 @@ update_connect_preferences () | |||
609 | 607 | ||
610 | 608 | ||
611 | /** | 609 | /** |
612 | * Add each of the peers we already know to the bloom filter of | 610 | * Add each of the peers we already know to the Bloom filter of |
613 | * the request so that we don't get duplicate HELLOs. | 611 | * the request so that we don't get duplicate HELLOs. |
614 | * | 612 | * |
615 | * @param cls the `struct GNUNET_BLOCK_Group` | 613 | * @param cls the `struct GNUNET_BLOCK_Group` |
616 | * @param key peer identity to add to the bloom filter | 614 | * @param key peer identity to add to the bloom filter |
617 | * @param value value the peer information (unused) | 615 | * @param value the peer information |
618 | * @return #GNUNET_YES (we should continue to iterate) | 616 | * @return #GNUNET_YES (we should continue to iterate) |
619 | */ | 617 | */ |
620 | static int | 618 | static enum GNUNET_GenericReturnValue |
621 | add_known_to_bloom (void *cls, | 619 | add_known_to_bloom (void *cls, |
622 | const struct GNUNET_PeerIdentity *key, | 620 | const struct GNUNET_PeerIdentity *key, |
623 | void *value) | 621 | void *value) |
624 | { | 622 | { |
625 | struct GNUNET_BLOCK_Group *bg = cls; | 623 | struct GNUNET_BLOCK_Group *bg = cls; |
626 | struct GNUNET_HashCode key_hash; | 624 | struct PeerInfo *pi = value; |
627 | 625 | ||
628 | (void) cls; | ||
629 | (void) value; | ||
630 | GNUNET_CRYPTO_hash (key, | ||
631 | sizeof(struct GNUNET_PeerIdentity), | ||
632 | &key_hash); | ||
633 | GNUNET_BLOCK_group_set_seen (bg, | 626 | GNUNET_BLOCK_group_set_seen (bg, |
634 | &key_hash, | 627 | &pi->phash, |
635 | 1); | 628 | 1); |
636 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 629 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
637 | "Adding known peer (%s) to bloomfilter for FIND PEER\n", | 630 | "Adding known peer (%s) to Bloom filter for FIND PEER\n", |
638 | GNUNET_i2s (key)); | 631 | GNUNET_i2s (key)); |
639 | return GNUNET_YES; | 632 | return GNUNET_YES; |
640 | } | 633 | } |
@@ -645,73 +638,88 @@ add_known_to_bloom (void *cls, | |||
645 | * so that we can find the closest peers in the network to ourselves | 638 | * so that we can find the closest peers in the network to ourselves |
646 | * and attempt to connect to them. | 639 | * and attempt to connect to them. |
647 | * | 640 | * |
648 | * @param cls closure for this task | 641 | * @param cls closure for this task, NULL |
649 | */ | 642 | */ |
650 | static void | 643 | static void |
651 | send_find_peer_message (void *cls) | 644 | send_find_peer_message (void *cls) |
652 | { | 645 | { |
653 | struct GNUNET_TIME_Relative next_send_time; | ||
654 | struct GNUNET_BLOCK_Group *bg; | ||
655 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | ||
656 | |||
657 | (void) cls; | 646 | (void) cls; |
658 | find_peer_task = NULL; | 647 | |
659 | if (newly_found_peers > bucket_size) | 648 | /* Compute when to do this again (and if we should |
649 | even send a message right now) */ | ||
660 | { | 650 | { |
661 | /* If we are finding many peers already, no need to send out our request right now! */ | 651 | struct GNUNET_TIME_Relative next_send_time; |
652 | bool done_early; | ||
653 | |||
654 | find_peer_task = NULL; | ||
655 | done_early = (newly_found_peers > bucket_size); | ||
656 | /* schedule next round, taking longer if we found more peers | ||
657 | in the last round. */ | ||
658 | next_send_time.rel_value_us = | ||
659 | DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
660 | + GNUNET_CRYPTO_random_u64 ( | ||
661 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
662 | GNUNET_TIME_relative_multiply ( | ||
663 | DHT_AVG_FIND_PEER_INTERVAL, | ||
664 | 100 * (1 + newly_found_peers) / bucket_size).rel_value_us); | ||
665 | newly_found_peers = 0; | ||
666 | GNUNET_assert (NULL == find_peer_task); | ||
662 | find_peer_task = | 667 | find_peer_task = |
663 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, | 668 | GNUNET_SCHEDULER_add_delayed (next_send_time, |
664 | &send_find_peer_message, | 669 | &send_find_peer_message, |
665 | NULL); | 670 | NULL); |
666 | newly_found_peers = 0; | 671 | if (done_early) |
667 | return; | 672 | return; |
673 | } | ||
674 | |||
675 | /* actually send 'find peer' request */ | ||
676 | { | ||
677 | struct GNUNET_BLOCK_Group *bg; | ||
678 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | ||
679 | |||
680 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
681 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
682 | GNUNET_CRYPTO_random_u32 ( | ||
683 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
684 | UINT32_MAX), | ||
685 | NULL, | ||
686 | 0, | ||
687 | "filter-size", | ||
688 | DHT_BLOOM_SIZE, | ||
689 | NULL); | ||
690 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, | ||
691 | &add_known_to_bloom, | ||
692 | bg); | ||
693 | peer_bf | ||
694 | = GNUNET_CONTAINER_bloomfilter_init (NULL, | ||
695 | DHT_BLOOM_SIZE, | ||
696 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
697 | if (GNUNET_OK != | ||
698 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
699 | GNUNET_DHT_RO_FIND_PEER | ||
700 | | GNUNET_DHT_RO_RECORD_ROUTE, | ||
701 | FIND_PEER_REPLICATION_LEVEL, | ||
702 | 0, /* hop count */ | ||
703 | &my_identity_hash, | ||
704 | NULL, 0, /* xquery */ | ||
705 | bg, | ||
706 | peer_bf)) | ||
707 | { | ||
708 | GNUNET_STATISTICS_update (GDS_stats, | ||
709 | "# Failed to initiate FIND PEER lookup", | ||
710 | 1, | ||
711 | GNUNET_NO); | ||
712 | } | ||
713 | else | ||
714 | { | ||
715 | GNUNET_STATISTICS_update (GDS_stats, | ||
716 | "# FIND PEER messages initiated", | ||
717 | 1, | ||
718 | GNUNET_NO); | ||
719 | } | ||
720 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
721 | GNUNET_BLOCK_group_destroy (bg); | ||
668 | } | 722 | } |
669 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
670 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
671 | GNUNET_CRYPTO_random_u32 ( | ||
672 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
673 | UINT32_MAX), | ||
674 | NULL, | ||
675 | 0, | ||
676 | "filter-size", | ||
677 | DHT_BLOOM_SIZE, | ||
678 | NULL); | ||
679 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, | ||
680 | &add_known_to_bloom, | ||
681 | bg); | ||
682 | GNUNET_STATISTICS_update (GDS_stats, | ||
683 | gettext_noop ("# FIND PEER messages initiated"), | ||
684 | 1, | ||
685 | GNUNET_NO); | ||
686 | peer_bf | ||
687 | = GNUNET_CONTAINER_bloomfilter_init (NULL, | ||
688 | DHT_BLOOM_SIZE, | ||
689 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
690 | // FIXME: pass priority!? | ||
691 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
692 | GNUNET_DHT_RO_FIND_PEER | ||
693 | | GNUNET_DHT_RO_RECORD_ROUTE, | ||
694 | FIND_PEER_REPLICATION_LEVEL, | ||
695 | 0, | ||
696 | &my_identity_hash, | ||
697 | NULL, | ||
698 | 0, | ||
699 | bg, | ||
700 | peer_bf); | ||
701 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
702 | GNUNET_BLOCK_group_destroy (bg); | ||
703 | /* schedule next round */ | ||
704 | next_send_time.rel_value_us = | ||
705 | DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
706 | + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
707 | DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value_us | ||
708 | / (newly_found_peers + 1)); | ||
709 | newly_found_peers = 0; | ||
710 | GNUNET_assert (NULL == find_peer_task); | ||
711 | find_peer_task = | ||
712 | GNUNET_SCHEDULER_add_delayed (next_send_time, | ||
713 | &send_find_peer_message, | ||
714 | NULL); | ||
715 | } | 723 | } |
716 | 724 | ||
717 | 725 | ||
@@ -729,6 +737,7 @@ handle_core_connect (void *cls, | |||
729 | struct GNUNET_MQ_Handle *mq) | 737 | struct GNUNET_MQ_Handle *mq) |
730 | { | 738 | { |
731 | struct PeerInfo *pi; | 739 | struct PeerInfo *pi; |
740 | struct PeerBucket *bucket; | ||
732 | 741 | ||
733 | (void) cls; | 742 | (void) cls; |
734 | /* Check for connect to self message */ | 743 | /* Check for connect to self message */ |
@@ -736,13 +745,13 @@ handle_core_connect (void *cls, | |||
736 | peer)) | 745 | peer)) |
737 | return NULL; | 746 | return NULL; |
738 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
739 | "Connected to %s\n", | 748 | "Connected to peer %s\n", |
740 | GNUNET_i2s (peer)); | 749 | GNUNET_i2s (peer)); |
741 | GNUNET_assert (GNUNET_NO == | 750 | GNUNET_assert (NULL == |
742 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, | 751 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, |
743 | peer)); | 752 | peer)); |
744 | GNUNET_STATISTICS_update (GDS_stats, | 753 | GNUNET_STATISTICS_update (GDS_stats, |
745 | gettext_noop ("# peers connected"), | 754 | "# peers connected", |
746 | 1, | 755 | 1, |
747 | GNUNET_NO); | 756 | GNUNET_NO); |
748 | pi = GNUNET_new (struct PeerInfo); | 757 | pi = GNUNET_new (struct PeerInfo); |
@@ -752,27 +761,27 @@ handle_core_connect (void *cls, | |||
752 | sizeof(struct GNUNET_PeerIdentity), | 761 | sizeof(struct GNUNET_PeerIdentity), |
753 | &pi->phash); | 762 | &pi->phash); |
754 | pi->peer_bucket = find_bucket (&pi->phash); | 763 | pi->peer_bucket = find_bucket (&pi->phash); |
755 | GNUNET_assert ((pi->peer_bucket >= 0) && | 764 | GNUNET_assert ( (pi->peer_bucket >= 0) && |
756 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | 765 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); |
757 | GNUNET_CONTAINER_DLL_insert_tail (k_buckets[pi->peer_bucket].head, | 766 | bucket = &k_buckets[pi->peer_bucket]; |
758 | k_buckets[pi->peer_bucket].tail, | 767 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, |
768 | bucket->tail, | ||
759 | pi); | 769 | pi); |
760 | k_buckets[pi->peer_bucket].peers_size++; | 770 | bucket->peers_size++; |
761 | closest_bucket = GNUNET_MAX (closest_bucket, | 771 | closest_bucket = GNUNET_MAX (closest_bucket, |
762 | (unsigned int) pi->peer_bucket); | 772 | (unsigned int) pi->peer_bucket + 1); |
763 | GNUNET_assert (GNUNET_OK == | 773 | GNUNET_assert (GNUNET_OK == |
764 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | 774 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, |
765 | pi->id, | 775 | pi->id, |
766 | pi, | 776 | pi, |
767 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 777 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
768 | if ((pi->peer_bucket > 0) && | 778 | if (bucket->peers_size <= bucket_size) |
769 | (k_buckets[pi->peer_bucket].peers_size <= bucket_size)) | ||
770 | { | 779 | { |
771 | update_connect_preferences (); | 780 | update_connect_preferences (); |
772 | newly_found_peers++; | 781 | newly_found_peers++; |
773 | } | 782 | } |
774 | if ((1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 783 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
775 | (GNUNET_YES != disable_try_connect)) | 784 | (GNUNET_YES != disable_try_connect) ) |
776 | { | 785 | { |
777 | /* got a first connection, good time to start with FIND PEER requests... */ | 786 | /* got a first connection, good time to start with FIND PEER requests... */ |
778 | GNUNET_assert (NULL == find_peer_task); | 787 | GNUNET_assert (NULL == find_peer_task); |
@@ -796,38 +805,40 @@ handle_core_disconnect (void *cls, | |||
796 | void *internal_cls) | 805 | void *internal_cls) |
797 | { | 806 | { |
798 | struct PeerInfo *to_remove = internal_cls; | 807 | struct PeerInfo *to_remove = internal_cls; |
808 | struct PeerBucket *bucket; | ||
799 | 809 | ||
800 | (void) cls; | 810 | (void) cls; |
801 | /* Check for disconnect from self message */ | 811 | /* Check for disconnect from self message (on shutdown) */ |
802 | if (NULL == to_remove) | 812 | if (NULL == to_remove) |
803 | return; | 813 | return; |
804 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
805 | "Disconnected %s\n", | 815 | "Disconnected from peer %s\n", |
806 | GNUNET_i2s (peer)); | 816 | GNUNET_i2s (peer)); |
807 | GNUNET_STATISTICS_update (GDS_stats, | 817 | GNUNET_STATISTICS_update (GDS_stats, |
808 | gettext_noop ("# peers connected"), | 818 | "# peers connected", |
809 | -1, | 819 | -1, |
810 | GNUNET_NO); | 820 | GNUNET_NO); |
811 | GNUNET_assert (GNUNET_YES == | 821 | GNUNET_assert (GNUNET_YES == |
812 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, | 822 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, |
813 | peer, | 823 | peer, |
814 | to_remove)); | 824 | to_remove)); |
815 | if ((0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 825 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
816 | (GNUNET_YES != disable_try_connect)) | 826 | (GNUNET_YES != disable_try_connect)) |
817 | { | 827 | { |
818 | GNUNET_SCHEDULER_cancel (find_peer_task); | 828 | GNUNET_SCHEDULER_cancel (find_peer_task); |
819 | find_peer_task = NULL; | 829 | find_peer_task = NULL; |
820 | } | 830 | } |
821 | GNUNET_assert (to_remove->peer_bucket >= 0); | 831 | GNUNET_assert (to_remove->peer_bucket >= 0); |
822 | GNUNET_CONTAINER_DLL_remove (k_buckets[to_remove->peer_bucket].head, | 832 | bucket = &k_buckets[to_remove->peer_bucket]; |
823 | k_buckets[to_remove->peer_bucket].tail, | 833 | GNUNET_CONTAINER_DLL_remove (bucket->head, |
834 | bucket->tail, | ||
824 | to_remove); | 835 | to_remove); |
825 | GNUNET_assert (k_buckets[to_remove->peer_bucket].peers_size > 0); | 836 | GNUNET_assert (bucket->peers_size > 0); |
826 | k_buckets[to_remove->peer_bucket].peers_size--; | 837 | bucket->peers_size--; |
827 | while ((closest_bucket > 0) && | 838 | while ( (closest_bucket > 0) && |
828 | (0 == k_buckets[to_remove->peer_bucket].peers_size)) | 839 | (0 == k_buckets[closest_bucket - 1].peers_size)) |
829 | closest_bucket--; | 840 | closest_bucket--; |
830 | if (k_buckets[to_remove->peer_bucket].peers_size < bucket_size) | 841 | if (bucket->peers_size < bucket_size) |
831 | update_connect_preferences (); | 842 | update_connect_preferences (); |
832 | GNUNET_free (to_remove); | 843 | GNUNET_free (to_remove); |
833 | } | 844 | } |
@@ -851,14 +862,15 @@ get_forward_count (uint32_t hop_count, | |||
851 | 862 | ||
852 | if (0 == target_replication) | 863 | if (0 == target_replication) |
853 | target_replication = 1; /* 0 is verboten */ | 864 | target_replication = 1; /* 0 is verboten */ |
854 | if (target_replication > MAXIMUM_REPLICATION_LEVEL) | 865 | if (target_replication > GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL) |
855 | target_replication = MAXIMUM_REPLICATION_LEVEL; | 866 | target_replication = GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL; |
856 | if (hop_count > GDS_NSE_get () * 4.0) | 867 | if (hop_count > GDS_NSE_get () * 4.0) |
857 | { | 868 | { |
858 | /* forcefully terminate */ | 869 | /* forcefully terminate */ |
859 | GNUNET_STATISTICS_update (GDS_stats, | 870 | GNUNET_STATISTICS_update (GDS_stats, |
860 | gettext_noop ("# requests TTL-dropped"), | 871 | "# requests TTL-dropped", |
861 | 1, GNUNET_NO); | 872 | 1, |
873 | GNUNET_NO); | ||
862 | return 0; | 874 | return 0; |
863 | } | 875 | } |
864 | if (hop_count > GDS_NSE_get () * 2.0) | 876 | if (hop_count > GDS_NSE_get () * 2.0) |
@@ -868,7 +880,8 @@ get_forward_count (uint32_t hop_count, | |||
868 | } | 880 | } |
869 | /* bound by system-wide maximum */ | 881 | /* bound by system-wide maximum */ |
870 | target_replication = | 882 | target_replication = |
871 | GNUNET_MIN (MAXIMUM_REPLICATION_LEVEL, target_replication); | 883 | GNUNET_MIN (GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL, |
884 | target_replication); | ||
872 | target_value = | 885 | target_value = |
873 | 1 + (target_replication - 1.0) / (GDS_NSE_get () | 886 | 1 + (target_replication - 1.0) / (GDS_NSE_get () |
874 | + ((float) (target_replication - 1.0) | 887 | + ((float) (target_replication - 1.0) |
@@ -879,46 +892,12 @@ get_forward_count (uint32_t hop_count, | |||
879 | forward_count = (uint32_t) target_value; | 892 | forward_count = (uint32_t) target_value; |
880 | /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */ | 893 | /* Subtract forward_count (floor) from target_value (yields value between 0 and 1) */ |
881 | target_value = target_value - forward_count; | 894 | target_value = target_value - forward_count; |
882 | random_value = | 895 | random_value = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
883 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); | 896 | UINT32_MAX); |
884 | if (random_value < (target_value * UINT32_MAX)) | 897 | if (random_value < (target_value * UINT32_MAX)) |
885 | forward_count++; | 898 | forward_count++; |
886 | return GNUNET_MIN (forward_count, | 899 | return GNUNET_MIN (forward_count, |
887 | MAXIMUM_REPLICATION_LEVEL); | 900 | GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL); |
888 | } | ||
889 | |||
890 | |||
891 | /** | ||
892 | * Compute the distance between have and target as a 64-bit value. | ||
893 | * Differences in the lower bits must count stronger than differences | ||
894 | * in the higher bits. | ||
895 | * | ||
896 | * @param target | ||
897 | * @param have | ||
898 | * @param bucket up to which offset are @a target and @a have identical and thus those bits should not be considered | ||
899 | * @return 0 if have==target, otherwise a number | ||
900 | * that is larger as the distance between | ||
901 | * the two hash codes increases | ||
902 | */ | ||
903 | static uint64_t | ||
904 | get_distance (const struct GNUNET_HashCode *target, | ||
905 | const struct GNUNET_HashCode *have, | ||
906 | unsigned int bucket) | ||
907 | { | ||
908 | uint64_t lsb = 0; | ||
909 | |||
910 | for (unsigned int i = bucket + 1; | ||
911 | (i < sizeof(struct GNUNET_HashCode) * 8) && | ||
912 | (i < bucket + 1 + 64); | ||
913 | i++) | ||
914 | { | ||
915 | if (GNUNET_CRYPTO_hash_get_bit_rtl (target, i) != | ||
916 | GNUNET_CRYPTO_hash_get_bit_rtl (have, i)) | ||
917 | lsb |= (1LLU << (bucket + 64 - i)); /* first bit set will be 1, | ||
918 | * last bit set will be 63 -- if | ||
919 | * i does not reach 512 first... */ | ||
920 | } | ||
921 | return lsb; | ||
922 | } | 901 | } |
923 | 902 | ||
924 | 903 | ||
@@ -932,60 +911,74 @@ get_distance (const struct GNUNET_HashCode *target, | |||
932 | * @return #GNUNET_YES if node location is closest, | 911 | * @return #GNUNET_YES if node location is closest, |
933 | * #GNUNET_NO otherwise. | 912 | * #GNUNET_NO otherwise. |
934 | */ | 913 | */ |
935 | int | 914 | enum GNUNET_GenericReturnValue |
936 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, | 915 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, |
937 | const struct GNUNET_CONTAINER_BloomFilter *bloom) | 916 | const struct GNUNET_CONTAINER_BloomFilter *bloom) |
938 | { | 917 | { |
939 | int bits; | ||
940 | int other_bits; | ||
941 | int bucket_num; | ||
942 | struct PeerInfo *pos; | ||
943 | |||
944 | if (0 == GNUNET_memcmp (&my_identity_hash, | 918 | if (0 == GNUNET_memcmp (&my_identity_hash, |
945 | key)) | 919 | key)) |
946 | return GNUNET_YES; | 920 | return GNUNET_YES; |
947 | bucket_num = find_bucket (key); | 921 | for (int bucket_num = find_bucket (key); |
948 | GNUNET_assert (bucket_num >= 0); | 922 | bucket_num < closest_bucket; |
949 | bits = GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, | 923 | bucket_num++) |
950 | key); | ||
951 | pos = k_buckets[bucket_num].head; | ||
952 | while (NULL != pos) | ||
953 | { | 924 | { |
954 | if ((NULL != bloom) && | 925 | unsigned int count = 0; |
955 | (GNUNET_YES == | 926 | |
956 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 927 | GNUNET_assert (bucket_num >= 0); |
957 | &pos->phash))) | 928 | for (struct PeerInfo *pos = k_buckets[bucket_num].head; |
929 | NULL != pos; | ||
930 | pos = pos->next) | ||
958 | { | 931 | { |
959 | pos = pos->next; | 932 | if (count >= bucket_size) |
960 | continue; /* Skip already checked entries */ | 933 | break; /* we only consider first #bucket_size entries per bucket */ |
934 | count++; | ||
935 | if ( (NULL != bloom) && | ||
936 | (GNUNET_YES == | ||
937 | GNUNET_CONTAINER_bloomfilter_test (bloom, | ||
938 | &pos->phash)) ) | ||
939 | continue; /* Ignore filtered peers */ | ||
940 | /* All peers in this bucket must be closer than us, as | ||
941 | they mismatch with our PID on the pivotal bit. So | ||
942 | because an unfiltered peer exists, we are not the | ||
943 | closest. */ | ||
944 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, | ||
945 | &my_identity_hash, | ||
946 | key); | ||
947 | switch (delta) | ||
948 | { | ||
949 | case -1: /* pos closer */ | ||
950 | return GNUNET_NO; | ||
951 | case 0: /* identical, impossible! */ | ||
952 | GNUNET_assert (0); | ||
953 | break; | ||
954 | case 1: /* I am closer */ | ||
955 | break; | ||
956 | } | ||
961 | } | 957 | } |
962 | other_bits = GNUNET_CRYPTO_hash_matching_bits (&pos->phash, | ||
963 | key); | ||
964 | if (other_bits > bits) | ||
965 | return GNUNET_NO; | ||
966 | if (other_bits == bits) /* We match the same number of bits */ | ||
967 | return GNUNET_YES; | ||
968 | pos = pos->next; | ||
969 | } | 958 | } |
970 | /* No peers closer, we are the closest! */ | 959 | /* No closer (unfiltered) peers found; we must be the closest! */ |
971 | return GNUNET_YES; | 960 | return GNUNET_YES; |
972 | } | 961 | } |
973 | 962 | ||
974 | 963 | ||
975 | /** | 964 | /** |
976 | * Select a peer from the routing table that would be a good routing | 965 | * Select a peer from the routing table that would be a good routing |
977 | * destination for sending a message for "key". The resulting peer | 966 | * destination for sending a message for @a key. The resulting peer |
978 | * must not be in the set of blocked peers.<p> | 967 | * must not be in the set of @a bloom blocked peers. |
979 | * | 968 | * |
980 | * Note that we should not ALWAYS select the closest peer to the | 969 | * Note that we should not ALWAYS select the closest peer to the |
981 | * target, peers further away from the target should be chosen with | 970 | * target, we do a "random" peer selection if the number of @a hops |
982 | * exponentially declining probability. | 971 | * is below the logarithm of the network size estimate. |
983 | * | ||
984 | * FIXME: double-check that this is fine | ||
985 | * | 972 | * |
973 | * In all cases, we only consider at most the first #bucket_size peers of any | ||
974 | * #k_buckets. The other peers in the bucket are there because GNUnet doesn't | ||
975 | * really allow the DHT to "reject" connections, but we only use the first | ||
976 | * #bucket_size, even if more exist. (The idea is to ensure that those | ||
977 | * connections are frequently used, and for others to be not used by the DHT, | ||
978 | * and thus possibly dropped by transport due to disuse). | ||
986 | * | 979 | * |
987 | * @param key the key we are selecting a peer to route to | 980 | * @param key the key we are selecting a peer to route to |
988 | * @param bloom a bloomfilter containing entries this request has seen already | 981 | * @param bloom a Bloom filter containing entries this request has seen already |
989 | * @param hops how many hops has this message traversed thus far | 982 | * @param hops how many hops has this message traversed thus far |
990 | * @return Peer to route to, or NULL on error | 983 | * @return Peer to route to, or NULL on error |
991 | */ | 984 | */ |
@@ -994,139 +987,194 @@ select_peer (const struct GNUNET_HashCode *key, | |||
994 | const struct GNUNET_CONTAINER_BloomFilter *bloom, | 987 | const struct GNUNET_CONTAINER_BloomFilter *bloom, |
995 | uint32_t hops) | 988 | uint32_t hops) |
996 | { | 989 | { |
997 | unsigned int bc; | 990 | if (0 == closest_bucket) |
998 | unsigned int count; | 991 | { |
999 | unsigned int selected; | 992 | GNUNET_STATISTICS_update (GDS_stats, |
1000 | struct PeerInfo *pos; | 993 | "# Peer selection failed", |
1001 | struct PeerInfo *chosen; | 994 | 1, |
1002 | 995 | GNUNET_NO); | |
996 | return NULL; /* we have zero connections */ | ||
997 | } | ||
1003 | if (hops >= GDS_NSE_get ()) | 998 | if (hops >= GDS_NSE_get ()) |
1004 | { | 999 | { |
1005 | /* greedy selection (closest peer that is not in bloomfilter) */ | 1000 | /* greedy selection (closest peer that is not in Bloom filter) */ |
1006 | unsigned int best_bucket = 0; | 1001 | struct PeerInfo *chosen = NULL; |
1007 | uint64_t best_in_bucket = UINT64_MAX; | 1002 | int best_bucket; |
1003 | int bucket_offset; | ||
1008 | 1004 | ||
1009 | chosen = NULL; | ||
1010 | for (bc = 0; bc <= closest_bucket; bc++) | ||
1011 | { | 1005 | { |
1012 | count = 0; | 1006 | struct GNUNET_HashCode xor; |
1013 | for (pos = k_buckets[bc].head; | 1007 | |
1014 | (pos != NULL) && | 1008 | GNUNET_CRYPTO_hash_xor (key, |
1015 | (count < bucket_size); | 1009 | &my_identity_hash, |
1010 | &xor); | ||
1011 | best_bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | ||
1012 | } | ||
1013 | if (best_bucket >= closest_bucket) | ||
1014 | bucket_offset = closest_bucket - 1; | ||
1015 | else | ||
1016 | bucket_offset = best_bucket; | ||
1017 | while (-1 != bucket_offset) | ||
1018 | { | ||
1019 | struct PeerBucket *bucket = &k_buckets[bucket_offset]; | ||
1020 | unsigned int count = 0; | ||
1021 | |||
1022 | for (struct PeerInfo *pos = bucket->head; | ||
1023 | NULL != pos; | ||
1016 | pos = pos->next) | 1024 | pos = pos->next) |
1017 | { | 1025 | { |
1018 | unsigned int bucket; | 1026 | if (count >= bucket_size) |
1019 | uint64_t dist; | 1027 | break; /* we only consider first #bucket_size entries per bucket */ |
1020 | 1028 | count++; | |
1021 | bucket = GNUNET_CRYPTO_hash_matching_bits (key, | 1029 | if (GNUNET_YES == |
1022 | &pos->phash); | 1030 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1023 | dist = get_distance (key, | 1031 | &pos->phash)) |
1024 | &pos->phash, | 1032 | { |
1025 | bucket); | 1033 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1026 | if (bucket < best_bucket) | 1034 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", |
1027 | continue; | 1035 | GNUNET_i2s (pos->id), |
1028 | if (dist > best_in_bucket) | 1036 | GNUNET_h2s (key)); |
1029 | continue; | 1037 | continue; |
1030 | best_bucket = bucket; | 1038 | } |
1031 | best_in_bucket = dist; | 1039 | if (NULL == chosen) |
1032 | if ( (NULL == bloom) || | ||
1033 | (GNUNET_NO == | ||
1034 | GNUNET_CONTAINER_bloomfilter_test (bloom, | ||
1035 | &pos->phash)) ) | ||
1036 | { | 1040 | { |
1041 | /* First candidate */ | ||
1037 | chosen = pos; | 1042 | chosen = pos; |
1038 | } | 1043 | } |
1039 | else | 1044 | else |
1040 | { | 1045 | { |
1041 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1046 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, |
1042 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", | 1047 | &chosen->phash, |
1043 | GNUNET_i2s (pos->id), | 1048 | key); |
1044 | GNUNET_h2s (key)); | 1049 | switch (delta) |
1045 | GNUNET_STATISTICS_update (GDS_stats, | 1050 | { |
1046 | gettext_noop ( | 1051 | case -1: /* pos closer */ |
1047 | "# Peers excluded from routing due to Bloomfilter"), | 1052 | chosen = pos; |
1048 | 1, | 1053 | break; |
1049 | GNUNET_NO); | 1054 | case 0: /* identical, impossible! */ |
1050 | chosen = NULL; | 1055 | GNUNET_assert (0); |
1056 | break; | ||
1057 | case 1: /* chosen closer */ | ||
1058 | break; | ||
1059 | } | ||
1051 | } | 1060 | } |
1052 | count++; | 1061 | count++; |
1062 | } /* for all (#bucket_size) peers in bucket */ | ||
1063 | if (NULL != chosen) | ||
1064 | break; | ||
1065 | |||
1066 | /* If we chose nothing in first iteration, first go through deeper | ||
1067 | buckets (best chance to find a good match), and if we still found | ||
1068 | nothing, then to shallower buckets. Terminate on any match in the | ||
1069 | current bucket, as this search order guarantees that it can only get | ||
1070 | worse as we keep going. */ | ||
1071 | if (bucket_offset > best_bucket) | ||
1072 | { | ||
1073 | /* Go through more deeper buckets */ | ||
1074 | bucket_offset++; | ||
1075 | if (bucket_offset == closest_bucket) | ||
1076 | { | ||
1077 | /* Can't go any deeper, if nothing selected, | ||
1078 | go for shallower buckets */ | ||
1079 | bucket_offset = best_bucket - 1; | ||
1080 | } | ||
1053 | } | 1081 | } |
1054 | } | 1082 | else |
1083 | { | ||
1084 | /* We're either at the 'best_bucket' or already moving | ||
1085 | on to shallower buckets. */ | ||
1086 | if (bucket_offset == best_bucket) | ||
1087 | bucket_offset++; /* go for deeper buckets */ | ||
1088 | else | ||
1089 | bucket_offset--; /* go for shallower buckets */ | ||
1090 | } | ||
1091 | } /* for applicable buckets (starting at best match) */ | ||
1055 | if (NULL == chosen) | 1092 | if (NULL == chosen) |
1093 | { | ||
1056 | GNUNET_STATISTICS_update (GDS_stats, | 1094 | GNUNET_STATISTICS_update (GDS_stats, |
1057 | gettext_noop ("# Peer selection failed"), | 1095 | "# Peer selection failed", |
1058 | 1, | 1096 | 1, |
1059 | GNUNET_NO); | 1097 | GNUNET_NO); |
1060 | else | 1098 | return NULL; |
1061 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1099 | } |
1062 | "Selected peer `%s' in greedy routing for %s\n", | 1100 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1063 | GNUNET_i2s (chosen->id), | 1101 | "Selected peer `%s' in greedy routing for %s\n", |
1064 | GNUNET_h2s (key)); | 1102 | GNUNET_i2s (chosen->id), |
1103 | GNUNET_h2s (key)); | ||
1065 | return chosen; | 1104 | return chosen; |
1066 | } | 1105 | } /* end of 'greedy' peer selection */ |
1067 | 1106 | ||
1068 | /* select "random" peer */ | 1107 | /* select "random" peer */ |
1069 | /* count number of peers that are available and not filtered */ | 1108 | /* count number of peers that are available and not filtered, |
1070 | count = 0; | 1109 | but limit to at most #bucket_size peers, starting with |
1071 | for (bc = 0; bc <= closest_bucket; bc++) | 1110 | those 'furthest' from us. */ |
1072 | { | 1111 | { |
1073 | pos = k_buckets[bc].head; | 1112 | unsigned int total = 0; |
1074 | while ((NULL != pos) && (count < bucket_size)) | 1113 | unsigned int selected; |
1114 | |||
1115 | for (unsigned int bc = 0; bc < closest_bucket; bc++) | ||
1075 | { | 1116 | { |
1076 | if ((NULL != bloom) && | 1117 | unsigned int count = 0; |
1077 | (GNUNET_YES == | 1118 | |
1078 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1119 | for (struct PeerInfo *pos = k_buckets[bc].head; |
1079 | &pos->phash))) | 1120 | NULL != pos; |
1121 | pos = pos->next) | ||
1080 | { | 1122 | { |
1081 | GNUNET_STATISTICS_update (GDS_stats, | 1123 | count++; |
1082 | gettext_noop | 1124 | if (count > bucket_size) |
1083 | ( | 1125 | break; /* limits search to #bucket_size peers per bucket */ |
1084 | "# Peers excluded from routing due to Bloomfilter"), | 1126 | if (GNUNET_YES == |
1085 | 1, GNUNET_NO); | 1127 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1086 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1128 | &pos->phash)) |
1087 | "Excluded peer `%s' due to BF match in random routing for %s\n", | 1129 | { |
1088 | GNUNET_i2s (pos->id), | 1130 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1089 | GNUNET_h2s (key)); | 1131 | "Excluded peer `%s' due to BF match in random routing for %s\n", |
1090 | pos = pos->next; | 1132 | GNUNET_i2s (pos->id), |
1091 | continue; /* Ignore bloomfiltered peers */ | 1133 | GNUNET_h2s (key)); |
1092 | } | 1134 | continue; /* Ignore filtered peers */ |
1093 | count++; | 1135 | } |
1094 | pos = pos->next; | 1136 | total++; |
1137 | } /* for all peers in bucket */ | ||
1138 | } /* for all buckets */ | ||
1139 | if (0 == total) /* No peers to select from! */ | ||
1140 | { | ||
1141 | GNUNET_STATISTICS_update (GDS_stats, | ||
1142 | "# Peer selection failed", | ||
1143 | 1, | ||
1144 | GNUNET_NO); | ||
1145 | return NULL; | ||
1095 | } | 1146 | } |
1096 | } | 1147 | |
1097 | if (0 == count) /* No peers to select from! */ | 1148 | /* Now actually choose a peer */ |
1098 | { | 1149 | selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
1099 | GNUNET_STATISTICS_update (GDS_stats, | 1150 | total); |
1100 | gettext_noop ("# Peer selection failed"), 1, | 1151 | for (unsigned int bc = 0; bc < closest_bucket; bc++) |
1101 | GNUNET_NO); | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | /* Now actually choose a peer */ | ||
1105 | selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1106 | count); | ||
1107 | count = 0; | ||
1108 | for (bc = 0; bc <= closest_bucket; bc++) | ||
1109 | { | ||
1110 | for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size)); | ||
1111 | pos = pos->next) | ||
1112 | { | 1152 | { |
1113 | if ((bloom != NULL) && | 1153 | unsigned int count = 0; |
1114 | (GNUNET_YES == | 1154 | |
1115 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1155 | for (struct PeerInfo *pos = k_buckets[bc].head; |
1116 | &pos->phash))) | 1156 | pos != NULL; |
1117 | { | 1157 | pos = pos->next) |
1118 | continue; /* Ignore bloomfiltered peers */ | ||
1119 | } | ||
1120 | if (0 == selected--) | ||
1121 | { | 1158 | { |
1122 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1159 | count++; |
1123 | "Selected peer `%s' in random routing for %s\n", | 1160 | if (count > bucket_size) |
1124 | GNUNET_i2s (pos->id), | 1161 | break; /* limits search to #bucket_size peers per bucket */ |
1125 | GNUNET_h2s (key)); | 1162 | |
1126 | return pos; | 1163 | if (GNUNET_YES == |
1127 | } | 1164 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1128 | } | 1165 | &pos->phash)) |
1129 | } | 1166 | continue; /* Ignore bloomfiltered peers */ |
1167 | if (0 == selected--) | ||
1168 | { | ||
1169 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1170 | "Selected peer `%s' in random routing for %s\n", | ||
1171 | GNUNET_i2s (pos->id), | ||
1172 | GNUNET_h2s (key)); | ||
1173 | return pos; | ||
1174 | } | ||
1175 | } /* for peers in bucket */ | ||
1176 | } /* for all buckets */ | ||
1177 | } /* random peer selection scope */ | ||
1130 | GNUNET_break (0); | 1178 | GNUNET_break (0); |
1131 | return NULL; | 1179 | return NULL; |
1132 | } | 1180 | } |
@@ -1137,13 +1185,13 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1137 | * forwarded to. | 1185 | * forwarded to. |
1138 | * | 1186 | * |
1139 | * @param key routing key | 1187 | * @param key routing key |
1140 | * @param bloom bloom filter excluding peers as targets, all selected | 1188 | * @param[in,out] bloom Bloom filter excluding peers as targets, |
1141 | * peers will be added to the bloom filter | 1189 | * all selected peers will be added to the Bloom filter |
1142 | * @param hop_count number of hops the request has traversed so far | 1190 | * @param hop_count number of hops the request has traversed so far |
1143 | * @param target_replication desired number of replicas | 1191 | * @param target_replication desired number of replicas |
1144 | * @param targets where to store an array of target peers (to be | 1192 | * @param[out] targets where to store an array of target peers (to be |
1145 | * free'd by the caller) | 1193 | * free()ed by the caller) |
1146 | * @return number of peers returned in 'targets'. | 1194 | * @return number of peers returned in @a targets. |
1147 | */ | 1195 | */ |
1148 | static unsigned int | 1196 | static unsigned int |
1149 | get_target_peers (const struct GNUNET_HashCode *key, | 1197 | get_target_peers (const struct GNUNET_HashCode *key, |
@@ -1152,23 +1200,24 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1152 | uint32_t target_replication, | 1200 | uint32_t target_replication, |
1153 | struct PeerInfo ***targets) | 1201 | struct PeerInfo ***targets) |
1154 | { | 1202 | { |
1155 | unsigned int ret; | 1203 | unsigned int target; |
1156 | unsigned int off; | 1204 | unsigned int off; |
1157 | struct PeerInfo **rtargets; | 1205 | struct PeerInfo **rtargets; |
1158 | struct PeerInfo *nxt; | ||
1159 | 1206 | ||
1160 | GNUNET_assert (NULL != bloom); | 1207 | GNUNET_assert (NULL != bloom); |
1161 | ret = get_forward_count (hop_count, | 1208 | target = get_forward_count (hop_count, |
1162 | target_replication); | 1209 | target_replication); |
1163 | if (0 == ret) | 1210 | if (0 == target) |
1164 | { | 1211 | { |
1165 | *targets = NULL; | 1212 | *targets = NULL; |
1166 | return 0; | 1213 | return 0; |
1167 | } | 1214 | } |
1168 | rtargets = GNUNET_new_array (ret, | 1215 | rtargets = GNUNET_new_array (target, |
1169 | struct PeerInfo *); | 1216 | struct PeerInfo *); |
1170 | for (off = 0; off < ret; off++) | 1217 | for (off = 0; off < target; off++) |
1171 | { | 1218 | { |
1219 | struct PeerInfo *nxt; | ||
1220 | |||
1172 | nxt = select_peer (key, | 1221 | nxt = select_peer (key, |
1173 | bloom, | 1222 | bloom, |
1174 | hop_count); | 1223 | hop_count); |
@@ -1187,7 +1236,7 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1187 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers), | 1236 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers), |
1188 | (unsigned int) hop_count, | 1237 | (unsigned int) hop_count, |
1189 | GNUNET_h2s (key), | 1238 | GNUNET_h2s (key), |
1190 | ret); | 1239 | target); |
1191 | if (0 == off) | 1240 | if (0 == off) |
1192 | { | 1241 | { |
1193 | GNUNET_free (rtargets); | 1242 | GNUNET_free (rtargets); |
@@ -1199,67 +1248,37 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1199 | "Forwarding query `%s' to %u peers (goal was %u peers)\n", | 1248 | "Forwarding query `%s' to %u peers (goal was %u peers)\n", |
1200 | GNUNET_h2s (key), | 1249 | GNUNET_h2s (key), |
1201 | off, | 1250 | off, |
1202 | ret); | 1251 | target); |
1203 | return off; | 1252 | return off; |
1204 | } | 1253 | } |
1205 | 1254 | ||
1206 | 1255 | ||
1207 | /** | 1256 | enum GNUNET_GenericReturnValue |
1208 | * Perform a PUT operation. Forwards the given request to other | 1257 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
1209 | * peers. Does not store the data locally. Does not give the | ||
1210 | * data to local clients. May do nothing if this is the only | ||
1211 | * peer in the network (or if we are the closest peer in the | ||
1212 | * network). | ||
1213 | * | ||
1214 | * @param type type of the block | ||
1215 | * @param options routing options | ||
1216 | * @param desired_replication_level desired replication count | ||
1217 | * @param expiration_time when does the content expire | ||
1218 | * @param hop_count how many hops has this message traversed so far | ||
1219 | * @param bf Bloom filter of peers this PUT has already traversed | ||
1220 | * @param key key for the content | ||
1221 | * @param put_path_length number of entries in @a put_path | ||
1222 | * @param put_path peers this request has traversed so far (if tracked) | ||
1223 | * @param data payload to store | ||
1224 | * @param data_size number of bytes in @a data | ||
1225 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
1226 | */ | ||
1227 | int | ||
1228 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | ||
1229 | enum GNUNET_DHT_RouteOption options, | 1258 | enum GNUNET_DHT_RouteOption options, |
1230 | uint32_t desired_replication_level, | 1259 | uint32_t desired_replication_level, |
1231 | struct GNUNET_TIME_Absolute expiration_time, | ||
1232 | uint32_t hop_count, | 1260 | uint32_t hop_count, |
1233 | struct GNUNET_CONTAINER_BloomFilter *bf, | 1261 | struct GNUNET_CONTAINER_BloomFilter *bf) |
1234 | const struct GNUNET_HashCode *key, | ||
1235 | unsigned int put_path_length, | ||
1236 | struct GNUNET_PeerIdentity *put_path, | ||
1237 | const void *data, | ||
1238 | size_t data_size) | ||
1239 | { | 1262 | { |
1240 | unsigned int target_count; | 1263 | unsigned int target_count; |
1241 | unsigned int i; | ||
1242 | struct PeerInfo **targets; | 1264 | struct PeerInfo **targets; |
1243 | struct PeerInfo *target; | ||
1244 | size_t msize; | 1265 | size_t msize; |
1245 | struct GNUNET_MQ_Envelope *env; | ||
1246 | struct PeerPutMessage *ppm; | ||
1247 | struct GNUNET_PeerIdentity *pp; | ||
1248 | unsigned int skip_count; | 1266 | unsigned int skip_count; |
1267 | unsigned int put_path_length = bd->put_path_length; | ||
1249 | 1268 | ||
1250 | GNUNET_assert (NULL != bf); | 1269 | GNUNET_assert (NULL != bf); |
1251 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1270 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1252 | "Adding myself (%s) to PUT bloomfilter for %s\n", | 1271 | "Adding myself (%s) to PUT bloomfilter for %s\n", |
1253 | GNUNET_i2s (&my_identity), | 1272 | GNUNET_i2s (&my_identity), |
1254 | GNUNET_h2s (key)); | 1273 | GNUNET_h2s (&bd->key)); |
1255 | GNUNET_CONTAINER_bloomfilter_add (bf, | 1274 | GNUNET_CONTAINER_bloomfilter_add (bf, |
1256 | &my_identity_hash); | 1275 | &my_identity_hash); |
1257 | GNUNET_STATISTICS_update (GDS_stats, | 1276 | GNUNET_STATISTICS_update (GDS_stats, |
1258 | gettext_noop ("# PUT requests routed"), | 1277 | "# PUT requests routed", |
1259 | 1, | 1278 | 1, |
1260 | GNUNET_NO); | 1279 | GNUNET_NO); |
1261 | target_count | 1280 | target_count |
1262 | = get_target_peers (key, | 1281 | = get_target_peers (&bd->key, |
1263 | bf, | 1282 | bf, |
1264 | hop_count, | 1283 | hop_count, |
1265 | desired_replication_level, | 1284 | desired_replication_level, |
@@ -1268,17 +1287,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1268 | { | 1287 | { |
1269 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1270 | "Routing PUT for %s terminates after %u hops at %s\n", | 1289 | "Routing PUT for %s terminates after %u hops at %s\n", |
1271 | GNUNET_h2s (key), | 1290 | GNUNET_h2s (&bd->key), |
1272 | (unsigned int) hop_count, | 1291 | (unsigned int) hop_count, |
1273 | GNUNET_i2s (&my_identity)); | 1292 | GNUNET_i2s (&my_identity)); |
1274 | return GNUNET_NO; | 1293 | return GNUNET_NO; |
1275 | } | 1294 | } |
1276 | msize = put_path_length * sizeof(struct GNUNET_PeerIdentity) + data_size; | 1295 | msize = bd->put_path_length * sizeof(struct GNUNET_PeerIdentity) |
1296 | + bd->data_size; | ||
1277 | if (msize + sizeof(struct PeerPutMessage) | 1297 | if (msize + sizeof(struct PeerPutMessage) |
1278 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 1298 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
1279 | { | 1299 | { |
1280 | put_path_length = 0; | 1300 | put_path_length = 0; |
1281 | msize = data_size; | 1301 | msize = bd->data_size; |
1282 | } | 1302 | } |
1283 | if (msize + sizeof(struct PeerPutMessage) | 1303 | if (msize + sizeof(struct PeerPutMessage) |
1284 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 1304 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
@@ -1287,21 +1307,19 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1287 | GNUNET_free (targets); | 1307 | GNUNET_free (targets); |
1288 | return GNUNET_NO; | 1308 | return GNUNET_NO; |
1289 | } | 1309 | } |
1290 | GNUNET_STATISTICS_update (GDS_stats, | ||
1291 | gettext_noop ( | ||
1292 | "# PUT messages queued for transmission"), | ||
1293 | target_count, | ||
1294 | GNUNET_NO); | ||
1295 | skip_count = 0; | 1310 | skip_count = 0; |
1296 | for (i = 0; i < target_count; i++) | 1311 | for (unsigned int i = 0; i < target_count; i++) |
1297 | { | 1312 | { |
1298 | target = targets[i]; | 1313 | struct PeerInfo *target = targets[i]; |
1314 | struct GNUNET_MQ_Envelope *env; | ||
1315 | struct PeerPutMessage *ppm; | ||
1316 | struct GNUNET_PeerIdentity *pp; | ||
1317 | |||
1299 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | 1318 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) |
1300 | { | 1319 | { |
1301 | /* skip */ | 1320 | /* skip */ |
1302 | GNUNET_STATISTICS_update (GDS_stats, | 1321 | GNUNET_STATISTICS_update (GDS_stats, |
1303 | gettext_noop ( | 1322 | "# P2P messages dropped due to full queue", |
1304 | "# P2P messages dropped due to full queue"), | ||
1305 | 1, | 1323 | 1, |
1306 | GNUNET_NO); | 1324 | GNUNET_NO); |
1307 | skip_count++; | 1325 | skip_count++; |
@@ -1309,18 +1327,18 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1309 | } | 1327 | } |
1310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1311 | "Routing PUT for %s after %u hops to %s\n", | 1329 | "Routing PUT for %s after %u hops to %s\n", |
1312 | GNUNET_h2s (key), | 1330 | GNUNET_h2s (&bd->key), |
1313 | (unsigned int) hop_count, | 1331 | (unsigned int) hop_count, |
1314 | GNUNET_i2s (target->id)); | 1332 | GNUNET_i2s (target->id)); |
1315 | env = GNUNET_MQ_msg_extra (ppm, | 1333 | env = GNUNET_MQ_msg_extra (ppm, |
1316 | msize, | 1334 | msize, |
1317 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); | 1335 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); |
1318 | ppm->options = htonl (options); | 1336 | ppm->options = htonl (options); |
1319 | ppm->type = htonl (type); | 1337 | ppm->type = htonl (bd->type); |
1320 | ppm->hop_count = htonl (hop_count + 1); | 1338 | ppm->hop_count = htonl (hop_count + 1); |
1321 | ppm->desired_replication_level = htonl (desired_replication_level); | 1339 | ppm->desired_replication_level = htonl (desired_replication_level); |
1322 | ppm->put_path_length = htonl (put_path_length); | 1340 | ppm->put_path_length = htonl (put_path_length); |
1323 | ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); | 1341 | ppm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1324 | GNUNET_break (GNUNET_YES == | 1342 | GNUNET_break (GNUNET_YES == |
1325 | GNUNET_CONTAINER_bloomfilter_test (bf, | 1343 | GNUNET_CONTAINER_bloomfilter_test (bf, |
1326 | &target->phash)); | 1344 | &target->phash)); |
@@ -1328,40 +1346,27 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1328 | GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, | 1346 | GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, |
1329 | ppm->bloomfilter, | 1347 | ppm->bloomfilter, |
1330 | DHT_BLOOM_SIZE)); | 1348 | DHT_BLOOM_SIZE)); |
1331 | ppm->key = *key; | 1349 | ppm->key = bd->key; |
1332 | pp = (struct GNUNET_PeerIdentity *) &ppm[1]; | 1350 | pp = (struct GNUNET_PeerIdentity *) &ppm[1]; |
1333 | GNUNET_memcpy (pp, | 1351 | GNUNET_memcpy (pp, |
1334 | put_path, | 1352 | bd->put_path, |
1335 | sizeof(struct GNUNET_PeerIdentity) * put_path_length); | 1353 | sizeof(struct GNUNET_PeerIdentity) * put_path_length); |
1336 | GNUNET_memcpy (&pp[put_path_length], | 1354 | GNUNET_memcpy (&pp[put_path_length], |
1337 | data, | 1355 | bd->data, |
1338 | data_size); | 1356 | bd->data_size); |
1339 | GNUNET_MQ_send (target->mq, | 1357 | GNUNET_MQ_send (target->mq, |
1340 | env); | 1358 | env); |
1341 | } | 1359 | } |
1342 | GNUNET_free (targets); | 1360 | GNUNET_free (targets); |
1361 | GNUNET_STATISTICS_update (GDS_stats, | ||
1362 | "# PUT messages queued for transmission", | ||
1363 | target_count - skip_count, | ||
1364 | GNUNET_NO); | ||
1343 | return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO; | 1365 | return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO; |
1344 | } | 1366 | } |
1345 | 1367 | ||
1346 | 1368 | ||
1347 | /** | 1369 | enum GNUNET_GenericReturnValue |
1348 | * Perform a GET operation. Forwards the given request to other | ||
1349 | * peers. Does not lookup the key locally. May do nothing if this is | ||
1350 | * the only peer in the network (or if we are the closest peer in the | ||
1351 | * network). | ||
1352 | * | ||
1353 | * @param type type of the block | ||
1354 | * @param options routing options | ||
1355 | * @param desired_replication_level desired replication count | ||
1356 | * @param hop_count how many hops did this request traverse so far? | ||
1357 | * @param key key for the content | ||
1358 | * @param xquery extended query | ||
1359 | * @param xquery_size number of bytes in @a xquery | ||
1360 | * @param bg group to use for filtering replies | ||
1361 | * @param peer_bf filter for peers not to select (again) | ||
1362 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
1363 | */ | ||
1364 | int | ||
1365 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 1370 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
1366 | enum GNUNET_DHT_RouteOption options, | 1371 | enum GNUNET_DHT_RouteOption options, |
1367 | uint32_t desired_replication_level, | 1372 | uint32_t desired_replication_level, |
@@ -1374,11 +1379,7 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1374 | { | 1379 | { |
1375 | unsigned int target_count; | 1380 | unsigned int target_count; |
1376 | struct PeerInfo **targets; | 1381 | struct PeerInfo **targets; |
1377 | struct PeerInfo *target; | ||
1378 | struct GNUNET_MQ_Envelope *env; | ||
1379 | size_t msize; | 1382 | size_t msize; |
1380 | struct PeerGetMessage *pgm; | ||
1381 | char *xq; | ||
1382 | size_t reply_bf_size; | 1383 | size_t reply_bf_size; |
1383 | void *reply_bf; | 1384 | void *reply_bf; |
1384 | unsigned int skip_count; | 1385 | unsigned int skip_count; |
@@ -1386,7 +1387,7 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1386 | 1387 | ||
1387 | GNUNET_assert (NULL != peer_bf); | 1388 | GNUNET_assert (NULL != peer_bf); |
1388 | GNUNET_STATISTICS_update (GDS_stats, | 1389 | GNUNET_STATISTICS_update (GDS_stats, |
1389 | gettext_noop ("# GET requests routed"), | 1390 | "# GET requests routed", |
1390 | 1, | 1391 | 1, |
1391 | GNUNET_NO); | 1392 | GNUNET_NO); |
1392 | target_count = get_target_peers (key, | 1393 | target_count = get_target_peers (key, |
@@ -1428,23 +1429,22 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1428 | GNUNET_free (targets); | 1429 | GNUNET_free (targets); |
1429 | return GNUNET_NO; | 1430 | return GNUNET_NO; |
1430 | } | 1431 | } |
1431 | GNUNET_STATISTICS_update (GDS_stats, | ||
1432 | gettext_noop ( | ||
1433 | "# GET messages queued for transmission"), | ||
1434 | target_count, | ||
1435 | GNUNET_NO); | ||
1436 | /* forward request */ | 1432 | /* forward request */ |
1437 | skip_count = 0; | 1433 | skip_count = 0; |
1438 | for (unsigned int i = 0; i < target_count; i++) | 1434 | for (unsigned int i = 0; i < target_count; i++) |
1439 | { | 1435 | { |
1440 | target = targets[i]; | 1436 | struct PeerInfo *target = targets[i]; |
1437 | struct GNUNET_MQ_Envelope *env; | ||
1438 | struct PeerGetMessage *pgm; | ||
1439 | char *xq; | ||
1440 | |||
1441 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | 1441 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) |
1442 | { | 1442 | { |
1443 | /* skip */ | 1443 | /* skip */ |
1444 | GNUNET_STATISTICS_update (GDS_stats, | 1444 | GNUNET_STATISTICS_update (GDS_stats, |
1445 | gettext_noop ( | 1445 | "# P2P messages dropped due to full queue", |
1446 | "# P2P messages dropped due to full queue"), | 1446 | 1, |
1447 | 1, GNUNET_NO); | 1447 | GNUNET_NO); |
1448 | skip_count++; | 1448 | skip_count++; |
1449 | continue; | 1449 | continue; |
1450 | } | 1450 | } |
@@ -1480,115 +1480,94 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1480 | GNUNET_MQ_send (target->mq, | 1480 | GNUNET_MQ_send (target->mq, |
1481 | env); | 1481 | env); |
1482 | } | 1482 | } |
1483 | GNUNET_STATISTICS_update (GDS_stats, | ||
1484 | "# GET messages queued for transmission", | ||
1485 | target_count - skip_count, | ||
1486 | GNUNET_NO); | ||
1483 | GNUNET_free (targets); | 1487 | GNUNET_free (targets); |
1484 | GNUNET_free (reply_bf); | 1488 | GNUNET_free (reply_bf); |
1485 | return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO; | 1489 | return (skip_count < target_count) ? GNUNET_OK : GNUNET_NO; |
1486 | } | 1490 | } |
1487 | 1491 | ||
1488 | 1492 | ||
1489 | /** | 1493 | struct PeerInfo * |
1490 | * Handle a reply (route to origin). Only forwards the reply back to | 1494 | GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target) |
1491 | * the given peer. Does not do local caching or forwarding to local | 1495 | { |
1492 | * clients. | 1496 | return GNUNET_CONTAINER_multipeermap_get (all_connected_peers, |
1493 | * | 1497 | target); |
1494 | * @param target neighbour that should receive the block (if still connected) | 1498 | } |
1495 | * @param type type of the block | 1499 | |
1496 | * @param expiration_time when does the content expire | 1500 | |
1497 | * @param key key for the content | ||
1498 | * @param put_path_length number of entries in @a put_path | ||
1499 | * @param put_path peers the original PUT traversed (if tracked) | ||
1500 | * @param get_path_length number of entries in @a get_path | ||
1501 | * @param get_path peers this reply has traversed so far (if tracked) | ||
1502 | * @param data payload of the reply | ||
1503 | * @param data_size number of bytes in @a data | ||
1504 | */ | ||
1505 | void | 1501 | void |
1506 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | 1502 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, |
1507 | enum GNUNET_BLOCK_Type type, | 1503 | const struct GDS_DATACACHE_BlockData *bd, |
1508 | struct GNUNET_TIME_Absolute expiration_time, | 1504 | const struct GNUNET_HashCode *query_hash, |
1509 | const struct GNUNET_HashCode *key, | ||
1510 | unsigned int put_path_length, | ||
1511 | const struct GNUNET_PeerIdentity *put_path, | ||
1512 | unsigned int get_path_length, | 1505 | unsigned int get_path_length, |
1513 | const struct GNUNET_PeerIdentity *get_path, | 1506 | const struct GNUNET_PeerIdentity *get_path) |
1514 | const void *data, | ||
1515 | size_t data_size) | ||
1516 | { | 1507 | { |
1517 | struct PeerInfo *pi; | ||
1518 | struct GNUNET_MQ_Envelope *env; | 1508 | struct GNUNET_MQ_Envelope *env; |
1519 | size_t msize; | ||
1520 | struct PeerResultMessage *prm; | 1509 | struct PeerResultMessage *prm; |
1521 | struct GNUNET_PeerIdentity *paths; | 1510 | struct GNUNET_PeerIdentity *paths; |
1511 | size_t msize; | ||
1522 | 1512 | ||
1523 | msize = data_size + (get_path_length + put_path_length) | 1513 | msize = bd->data_size + (get_path_length + bd->put_path_length) |
1524 | * sizeof(struct GNUNET_PeerIdentity); | 1514 | * sizeof(struct GNUNET_PeerIdentity); |
1525 | if ((msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || | 1515 | if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || |
1526 | (get_path_length > | 1516 | (get_path_length > |
1527 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | 1517 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || |
1528 | (put_path_length > | 1518 | (bd->put_path_length > |
1529 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | 1519 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || |
1530 | (data_size > GNUNET_MAX_MESSAGE_SIZE)) | 1520 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) |
1531 | { | 1521 | { |
1532 | GNUNET_break (0); | 1522 | GNUNET_break (0); |
1533 | return; | 1523 | return; |
1534 | } | 1524 | } |
1535 | pi = GNUNET_CONTAINER_multipeermap_get (all_connected_peers, | ||
1536 | target); | ||
1537 | if (NULL == pi) | ||
1538 | { | ||
1539 | /* peer disconnected in the meantime, drop reply */ | ||
1540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1541 | "No matching peer for reply for key %s\n", | ||
1542 | GNUNET_h2s (key)); | ||
1543 | return; | ||
1544 | } | ||
1545 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) | 1525 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) |
1546 | { | 1526 | { |
1547 | /* skip */ | 1527 | /* skip */ |
1548 | GNUNET_STATISTICS_update (GDS_stats, | 1528 | GNUNET_STATISTICS_update (GDS_stats, |
1549 | gettext_noop ( | 1529 | "# P2P messages dropped due to full queue", |
1550 | "# P2P messages dropped due to full queue"), | ||
1551 | 1, | 1530 | 1, |
1552 | GNUNET_NO); | 1531 | GNUNET_NO); |
1553 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1554 | "Peer queue full, ignoring reply for key %s\n", | 1533 | "Peer queue full, ignoring reply for key %s\n", |
1555 | GNUNET_h2s (key)); | 1534 | GNUNET_h2s (&bd->key)); |
1556 | return; | 1535 | return; |
1557 | } | 1536 | } |
1558 | 1537 | ||
1559 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1538 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1560 | "Forwarding reply for key %s to peer %s\n", | 1539 | "Forwarding reply for key %s to peer %s\n", |
1561 | GNUNET_h2s (key), | 1540 | GNUNET_h2s (query_hash), |
1562 | GNUNET_i2s (target)); | 1541 | GNUNET_i2s (pi->id)); |
1563 | GNUNET_STATISTICS_update (GDS_stats, | 1542 | GNUNET_STATISTICS_update (GDS_stats, |
1564 | gettext_noop | 1543 | "# RESULT messages queued for transmission", |
1565 | ("# RESULT messages queued for transmission"), 1, | 1544 | 1, |
1566 | GNUNET_NO); | 1545 | GNUNET_NO); |
1567 | env = GNUNET_MQ_msg_extra (prm, | 1546 | env = GNUNET_MQ_msg_extra (prm, |
1568 | msize, | 1547 | msize, |
1569 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); | 1548 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); |
1570 | prm->type = htonl (type); | 1549 | prm->type = htonl (bd->type); |
1571 | prm->put_path_length = htonl (put_path_length); | 1550 | prm->put_path_length = htonl (bd->put_path_length); |
1572 | prm->get_path_length = htonl (get_path_length); | 1551 | prm->get_path_length = htonl (get_path_length); |
1573 | prm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); | 1552 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1574 | prm->key = *key; | 1553 | prm->key = *query_hash; |
1575 | paths = (struct GNUNET_PeerIdentity *) &prm[1]; | 1554 | paths = (struct GNUNET_PeerIdentity *) &prm[1]; |
1576 | GNUNET_memcpy (paths, | 1555 | GNUNET_memcpy (paths, |
1577 | put_path, | 1556 | bd->put_path, |
1578 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1557 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1579 | GNUNET_memcpy (&paths[put_path_length], | 1558 | GNUNET_memcpy (&paths[bd->put_path_length], |
1580 | get_path, | 1559 | get_path, |
1581 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 1560 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
1582 | GNUNET_memcpy (&paths[put_path_length + get_path_length], | 1561 | GNUNET_memcpy (&paths[bd->put_path_length + get_path_length], |
1583 | data, | 1562 | bd->data, |
1584 | data_size); | 1563 | bd->data_size); |
1585 | GNUNET_MQ_send (pi->mq, | 1564 | GNUNET_MQ_send (pi->mq, |
1586 | env); | 1565 | env); |
1587 | } | 1566 | } |
1588 | 1567 | ||
1589 | 1568 | ||
1590 | /** | 1569 | /** |
1591 | * To be called on core init/fail. | 1570 | * To be called on core init. |
1592 | * | 1571 | * |
1593 | * @param cls service closure | 1572 | * @param cls service closure |
1594 | * @param identity the public identity of this peer | 1573 | * @param identity the public identity of this peer |
@@ -1603,7 +1582,7 @@ core_init (void *cls, | |||
1603 | GNUNET_i2s (identity)); | 1582 | GNUNET_i2s (identity)); |
1604 | my_identity = *identity; | 1583 | my_identity = *identity; |
1605 | GNUNET_CRYPTO_hash (identity, | 1584 | GNUNET_CRYPTO_hash (identity, |
1606 | sizeof(struct GNUNET_PeerIdentity), | 1585 | sizeof(struct GNUNET_PeerIdentity), |
1607 | &my_identity_hash); | 1586 | &my_identity_hash); |
1608 | GNUNET_SERVICE_resume (GDS_service); | 1587 | GNUNET_SERVICE_resume (GDS_service); |
1609 | } | 1588 | } |
@@ -1616,21 +1595,19 @@ core_init (void *cls, | |||
1616 | * @param message message | 1595 | * @param message message |
1617 | * @return #GNUNET_OK if the message is valid | 1596 | * @return #GNUNET_OK if the message is valid |
1618 | */ | 1597 | */ |
1619 | static int | 1598 | static enum GNUNET_GenericReturnValue |
1620 | check_dht_p2p_put (void *cls, | 1599 | check_dht_p2p_put (void *cls, |
1621 | const struct PeerPutMessage *put) | 1600 | const struct PeerPutMessage *put) |
1622 | { | 1601 | { |
1623 | uint32_t putlen; | 1602 | uint16_t msize = ntohs (put->header.size); |
1624 | uint16_t msize; | 1603 | uint32_t putlen = ntohl (put->put_path_length); |
1625 | 1604 | ||
1626 | (void) cls; | 1605 | (void) cls; |
1627 | msize = ntohs (put->header.size); | 1606 | if ( (msize < |
1628 | putlen = ntohl (put->put_path_length); | 1607 | sizeof(struct PeerPutMessage) |
1629 | if ((msize < | 1608 | + putlen * sizeof(struct GNUNET_PeerIdentity)) || |
1630 | sizeof(struct PeerPutMessage) | 1609 | (putlen > |
1631 | + putlen * sizeof(struct GNUNET_PeerIdentity)) || | 1610 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ) |
1632 | (putlen > | ||
1633 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity))) | ||
1634 | { | 1611 | { |
1635 | GNUNET_break_op (0); | 1612 | GNUNET_break_op (0); |
1636 | return GNUNET_SYSERR; | 1613 | return GNUNET_SYSERR; |
@@ -1650,51 +1627,55 @@ handle_dht_p2p_put (void *cls, | |||
1650 | const struct PeerPutMessage *put) | 1627 | const struct PeerPutMessage *put) |
1651 | { | 1628 | { |
1652 | struct PeerInfo *peer = cls; | 1629 | struct PeerInfo *peer = cls; |
1653 | const struct GNUNET_PeerIdentity *put_path; | 1630 | uint16_t msize = ntohs (put->header.size); |
1654 | const void *payload; | 1631 | enum GNUNET_DHT_RouteOption options |
1655 | uint32_t putlen; | 1632 | = (enum GNUNET_DHT_RouteOption) ntohl (put->options); |
1656 | uint16_t msize; | 1633 | struct GDS_DATACACHE_BlockData bd = { |
1657 | size_t payload_size; | 1634 | .key = put->key, |
1658 | enum GNUNET_DHT_RouteOption options; | 1635 | .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), |
1659 | struct GNUNET_CONTAINER_BloomFilter *bf; | 1636 | .type = ntohl (put->type) |
1660 | struct GNUNET_HashCode test_key; | 1637 | }; |
1661 | int forwarded; | 1638 | const struct GNUNET_PeerIdentity *put_path |
1662 | struct GNUNET_TIME_Absolute exp_time; | 1639 | = (const struct GNUNET_PeerIdentity *) &put[1]; |
1663 | 1640 | uint32_t putlen | |
1664 | exp_time = GNUNET_TIME_absolute_ntoh (put->expiration_time); | 1641 | = ntohl (put->put_path_length); |
1665 | if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us) | 1642 | |
1643 | bd.data_size = msize - (sizeof(*put) | ||
1644 | + putlen * sizeof(struct GNUNET_PeerIdentity)); | ||
1645 | bd.data = &put_path[putlen]; | ||
1646 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1647 | "PUT for `%s' from %s\n", | ||
1648 | GNUNET_h2s (&put->key), | ||
1649 | GNUNET_i2s (peer->id)); | ||
1650 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) | ||
1666 | { | 1651 | { |
1667 | GNUNET_STATISTICS_update (GDS_stats, | 1652 | GNUNET_STATISTICS_update (GDS_stats, |
1668 | gettext_noop ("# Expired PUTs discarded"), | 1653 | "# Expired PUTs discarded", |
1669 | 1, | 1654 | 1, |
1670 | GNUNET_NO); | 1655 | GNUNET_NO); |
1671 | return; | 1656 | return; |
1672 | } | 1657 | } |
1673 | msize = ntohs (put->header.size); | ||
1674 | putlen = ntohl (put->put_path_length); | ||
1675 | GNUNET_STATISTICS_update (GDS_stats, | 1658 | GNUNET_STATISTICS_update (GDS_stats, |
1676 | gettext_noop ("# P2P PUT requests received"), | 1659 | "# P2P PUT requests received", |
1677 | 1, | 1660 | 1, |
1678 | GNUNET_NO); | 1661 | GNUNET_NO); |
1679 | GNUNET_STATISTICS_update (GDS_stats, | 1662 | GNUNET_STATISTICS_update (GDS_stats, |
1680 | gettext_noop ("# P2P PUT bytes received"), | 1663 | "# P2P PUT bytes received", |
1681 | msize, | 1664 | msize, |
1682 | GNUNET_NO); | 1665 | GNUNET_NO); |
1683 | put_path = (const struct GNUNET_PeerIdentity *) &put[1]; | ||
1684 | payload = &put_path[putlen]; | ||
1685 | options = ntohl (put->options); | ||
1686 | payload_size = msize - (sizeof(struct PeerPutMessage) | ||
1687 | + putlen * sizeof(struct GNUNET_PeerIdentity)); | ||
1688 | |||
1689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1690 | "PUT for `%s' from %s\n", | ||
1691 | GNUNET_h2s (&put->key), | ||
1692 | GNUNET_i2s (peer->id)); | ||
1693 | if (GNUNET_YES == log_route_details_stderr) | 1666 | if (GNUNET_YES == log_route_details_stderr) |
1694 | { | 1667 | { |
1695 | char *tmp; | 1668 | char *tmp; |
1696 | char *pp; | 1669 | char *pp; |
1697 | 1670 | struct GNUNET_HashCode mxor; | |
1671 | struct GNUNET_HashCode pxor; | ||
1672 | |||
1673 | GNUNET_CRYPTO_hash_xor (&my_identity_hash, | ||
1674 | &put->key, | ||
1675 | &mxor); | ||
1676 | GNUNET_CRYPTO_hash_xor (&peer->phash, | ||
1677 | &put->key, | ||
1678 | &pxor); | ||
1698 | pp = GNUNET_STRINGS_pp2s (put_path, | 1679 | pp = GNUNET_STRINGS_pp2s (put_path, |
1699 | putlen); | 1680 | putlen); |
1700 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 1681 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
@@ -1704,83 +1685,65 @@ handle_dht_p2p_put (void *cls, | |||
1704 | GNUNET_i2s (peer->id), | 1685 | GNUNET_i2s (peer->id), |
1705 | tmp, | 1686 | tmp, |
1706 | ntohl (put->hop_count), | 1687 | ntohl (put->hop_count), |
1707 | GNUNET_CRYPTO_hash_matching_bits (&peer->phash, | 1688 | GNUNET_CRYPTO_hash_count_leading_zeros (&pxor), |
1708 | &put->key), | 1689 | GNUNET_CRYPTO_hash_count_leading_zeros (&mxor), |
1709 | GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, | ||
1710 | &put->key), | ||
1711 | pp); | 1690 | pp); |
1712 | GNUNET_free (pp); | 1691 | GNUNET_free (pp); |
1713 | GNUNET_free (tmp); | 1692 | GNUNET_free (tmp); |
1714 | } | 1693 | } |
1715 | switch (GNUNET_BLOCK_get_key | 1694 | |
1716 | (GDS_block_context, | ||
1717 | ntohl (put->type), | ||
1718 | payload, | ||
1719 | payload_size, | ||
1720 | &test_key)) | ||
1721 | { | 1695 | { |
1722 | case GNUNET_YES: | 1696 | struct GNUNET_HashCode test_key; |
1723 | if (0 != memcmp (&test_key, | 1697 | enum GNUNET_GenericReturnValue ret; |
1724 | &put->key, | 1698 | |
1725 | sizeof(struct GNUNET_HashCode))) | 1699 | ret = GNUNET_BLOCK_get_key (GDS_block_context, |
1700 | bd.type, | ||
1701 | bd.data, | ||
1702 | bd.data_size, | ||
1703 | &test_key); | ||
1704 | switch (ret) | ||
1726 | { | 1705 | { |
1727 | char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key)); | 1706 | case GNUNET_YES: |
1728 | 1707 | if (0 != GNUNET_memcmp (&test_key, | |
1708 | &bd.key)) | ||
1709 | { | ||
1710 | GNUNET_break_op (0); | ||
1711 | return; | ||
1712 | } | ||
1713 | break; | ||
1714 | case GNUNET_NO: | ||
1729 | GNUNET_break_op (0); | 1715 | GNUNET_break_op (0); |
1730 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1731 | "PUT with key `%s' for block with key %s\n", | ||
1732 | put_s, | ||
1733 | GNUNET_h2s_full (&test_key)); | ||
1734 | GNUNET_free (put_s); | ||
1735 | return; | 1716 | return; |
1717 | case GNUNET_SYSERR: | ||
1718 | /* cannot verify, good luck */ | ||
1719 | break; | ||
1736 | } | 1720 | } |
1737 | break; | 1721 | } |
1738 | 1722 | ||
1739 | case GNUNET_NO: | 1723 | if (GNUNET_NO == |
1724 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
1725 | bd.type, | ||
1726 | &bd.key, | ||
1727 | bd.data, | ||
1728 | bd.data_size)) | ||
1729 | { | ||
1740 | GNUNET_break_op (0); | 1730 | GNUNET_break_op (0); |
1741 | return; | 1731 | return; |
1742 | |||
1743 | case GNUNET_SYSERR: | ||
1744 | /* cannot verify, good luck */ | ||
1745 | break; | ||
1746 | } | ||
1747 | if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */ | ||
1748 | { | ||
1749 | switch (GNUNET_BLOCK_evaluate (GDS_block_context, | ||
1750 | ntohl (put->type), | ||
1751 | NULL, /* query group */ | ||
1752 | GNUNET_BLOCK_EO_NONE, | ||
1753 | NULL, /* query */ | ||
1754 | NULL, 0, /* xquery */ | ||
1755 | payload, | ||
1756 | payload_size)) | ||
1757 | { | ||
1758 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
1759 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
1760 | break; | ||
1761 | |||
1762 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
1763 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
1764 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
1765 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
1766 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
1767 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
1768 | default: | ||
1769 | GNUNET_break_op (0); | ||
1770 | return; | ||
1771 | } | ||
1772 | } | 1732 | } |
1773 | 1733 | ||
1774 | bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, | ||
1775 | DHT_BLOOM_SIZE, | ||
1776 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
1777 | GNUNET_break_op (GNUNET_YES == | ||
1778 | GNUNET_CONTAINER_bloomfilter_test (bf, | ||
1779 | &peer->phash)); | ||
1780 | { | 1734 | { |
1735 | struct GNUNET_CONTAINER_BloomFilter *bf; | ||
1781 | struct GNUNET_PeerIdentity pp[putlen + 1]; | 1736 | struct GNUNET_PeerIdentity pp[putlen + 1]; |
1782 | 1737 | ||
1738 | bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, | ||
1739 | DHT_BLOOM_SIZE, | ||
1740 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
1741 | GNUNET_break_op (GNUNET_YES == | ||
1742 | GNUNET_CONTAINER_bloomfilter_test (bf, | ||
1743 | &peer->phash)); | ||
1783 | /* extend 'put path' by sender */ | 1744 | /* extend 'put path' by sender */ |
1745 | bd.put_path = (const struct GNUNET_PeerIdentity *) pp; | ||
1746 | bd.put_path_length = putlen + 1; | ||
1784 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) | 1747 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) |
1785 | { | 1748 | { |
1786 | #if SANITY_CHECKS | 1749 | #if SANITY_CHECKS |
@@ -1788,13 +1751,13 @@ handle_dht_p2p_put (void *cls, | |||
1788 | { | 1751 | { |
1789 | for (unsigned int j = 0; j < i; j++) | 1752 | for (unsigned int j = 0; j < i; j++) |
1790 | { | 1753 | { |
1791 | GNUNET_break (0 != memcmp (&pp[i], | 1754 | GNUNET_break (0 != |
1792 | &pp[j], | 1755 | GNUNET_memcmp (&pp[i], |
1793 | sizeof(struct GNUNET_PeerIdentity))); | 1756 | &pp[j])); |
1794 | } | 1757 | } |
1795 | GNUNET_break (0 != memcmp (&pp[i], | 1758 | GNUNET_break (0 != |
1796 | peer->id, | 1759 | GNUNET_memcmp (&pp[i], |
1797 | sizeof(struct GNUNET_PeerIdentity))); | 1760 | peer->id)); |
1798 | } | 1761 | } |
1799 | #endif | 1762 | #endif |
1800 | GNUNET_memcpy (pp, | 1763 | GNUNET_memcpy (pp, |
@@ -1804,56 +1767,41 @@ handle_dht_p2p_put (void *cls, | |||
1804 | putlen++; | 1767 | putlen++; |
1805 | } | 1768 | } |
1806 | else | 1769 | else |
1807 | putlen = 0; | 1770 | { |
1771 | bd.put_path_length = 0; | ||
1772 | } | ||
1808 | 1773 | ||
1809 | /* give to local clients */ | 1774 | /* give to local clients */ |
1810 | GDS_CLIENTS_handle_reply (exp_time, | 1775 | GDS_CLIENTS_handle_reply (&bd, |
1811 | &put->key, | 1776 | &bd.key, |
1812 | 0, | 1777 | 0, NULL /* get path */); |
1813 | NULL, | 1778 | |
1814 | putlen, | ||
1815 | pp, | ||
1816 | ntohl (put->type), | ||
1817 | payload_size, | ||
1818 | payload); | ||
1819 | /* store locally */ | 1779 | /* store locally */ |
1820 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 1780 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
1821 | (GDS_am_closest_peer (&put->key, bf))) | 1781 | (GDS_am_closest_peer (&put->key, |
1822 | GDS_DATACACHE_handle_put (exp_time, | 1782 | bf)) ) |
1823 | &put->key, | 1783 | GDS_DATACACHE_handle_put (&bd); |
1824 | putlen, | 1784 | { |
1825 | pp, | 1785 | enum GNUNET_GenericReturnValue forwarded; |
1826 | ntohl (put->type), | 1786 | |
1827 | payload_size, | 1787 | /* route to other peers */ |
1828 | payload); | 1788 | forwarded |
1829 | /* route to other peers */ | 1789 | = GDS_NEIGHBOURS_handle_put (&bd, |
1830 | forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), | 1790 | options, |
1831 | options, | 1791 | ntohl (put->desired_replication_level), |
1832 | ntohl ( | 1792 | ntohl (put->hop_count), |
1833 | put->desired_replication_level), | 1793 | bf); |
1834 | exp_time, | 1794 | /* notify monitoring clients */ |
1835 | ntohl (put->hop_count), | 1795 | GDS_CLIENTS_process_put (options |
1836 | bf, | 1796 | | ((GNUNET_OK == forwarded) |
1837 | &put->key, | ||
1838 | putlen, | ||
1839 | pp, | ||
1840 | payload, | ||
1841 | payload_size); | ||
1842 | /* notify monitoring clients */ | ||
1843 | GDS_CLIENTS_process_put (options | ||
1844 | | ((GNUNET_OK == forwarded) | ||
1845 | ? GNUNET_DHT_RO_LAST_HOP | 1797 | ? GNUNET_DHT_RO_LAST_HOP |
1846 | : 0), | 1798 | : 0), |
1847 | ntohl (put->type), | 1799 | &bd, |
1848 | ntohl (put->hop_count), | 1800 | ntohl (put->hop_count), |
1849 | ntohl (put->desired_replication_level), | 1801 | ntohl (put->desired_replication_level)); |
1850 | putlen, pp, | 1802 | } |
1851 | exp_time, | 1803 | GNUNET_CONTAINER_bloomfilter_free (bf); |
1852 | &put->key, | ||
1853 | payload, | ||
1854 | payload_size); | ||
1855 | } | 1804 | } |
1856 | GNUNET_CONTAINER_bloomfilter_free (bf); | ||
1857 | } | 1805 | } |
1858 | 1806 | ||
1859 | 1807 | ||
@@ -1861,55 +1809,51 @@ handle_dht_p2p_put (void *cls, | |||
1861 | * We have received a FIND PEER request. Send matching | 1809 | * We have received a FIND PEER request. Send matching |
1862 | * HELLOs back. | 1810 | * HELLOs back. |
1863 | * | 1811 | * |
1864 | * @param sender sender of the FIND PEER request | 1812 | * @param pi sender of the FIND PEER request |
1865 | * @param key peers close to this key are desired | 1813 | * @param key peers close to this key are desired |
1866 | * @param bg group for filtering peers | 1814 | * @param bg group for filtering peers |
1867 | */ | 1815 | */ |
1868 | static void | 1816 | static void |
1869 | handle_find_peer (const struct GNUNET_PeerIdentity *sender, | 1817 | handle_find_peer (struct PeerInfo *pi, |
1870 | const struct GNUNET_HashCode *key, | 1818 | const struct GNUNET_HashCode *query_hash, |
1871 | struct GNUNET_BLOCK_Group *bg) | 1819 | struct GNUNET_BLOCK_Group *bg) |
1872 | { | 1820 | { |
1873 | int bucket_idx; | 1821 | int bucket_idx; |
1874 | struct PeerBucket *bucket; | 1822 | struct PeerBucket *bucket; |
1875 | struct PeerInfo *peer; | 1823 | struct PeerInfo *peer; |
1876 | unsigned int choice; | 1824 | unsigned int choice; |
1877 | const struct GNUNET_HELLO_Message *hello; | 1825 | struct GDS_DATACACHE_BlockData bd = { |
1878 | size_t hello_size; | 1826 | .type = GNUNET_BLOCK_TYPE_DHT_HELLO |
1827 | }; | ||
1879 | 1828 | ||
1880 | /* first, check about our own HELLO */ | 1829 | /* first, check about our own HELLO */ |
1881 | if (NULL != GDS_my_hello) | 1830 | if (NULL != GDS_my_hello) |
1882 | { | 1831 | { |
1883 | hello_size = GNUNET_HELLO_size ((const struct | 1832 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( |
1884 | GNUNET_HELLO_Message *) GDS_my_hello); | 1833 | hello_expiration), |
1885 | GNUNET_break (hello_size >= sizeof(struct GNUNET_MessageHeader)); | 1834 | bd.key = my_identity_hash, |
1886 | if (GNUNET_BLOCK_EVALUATION_OK_MORE == | 1835 | bd.data = GDS_my_hello; |
1887 | GNUNET_BLOCK_evaluate (GDS_block_context, | 1836 | bd.data_size = GNUNET_HELLO_size ( |
1888 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1837 | (const struct GNUNET_HELLO_Message *) GDS_my_hello); |
1889 | bg, | 1838 | GNUNET_break (bd.data_size >= sizeof(struct GNUNET_MessageHeader)); |
1890 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | 1839 | if (GNUNET_BLOCK_REPLY_OK_MORE == |
1891 | &my_identity_hash, | 1840 | GNUNET_BLOCK_check_reply (GDS_block_context, |
1892 | NULL, 0, | 1841 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
1893 | GDS_my_hello, | 1842 | bg, |
1894 | hello_size)) | 1843 | &my_identity_hash, |
1844 | NULL, 0, | ||
1845 | bd.data, | ||
1846 | bd.data_size)) | ||
1895 | { | 1847 | { |
1896 | GDS_NEIGHBOURS_handle_reply (sender, | 1848 | GDS_NEIGHBOURS_handle_reply (pi, |
1897 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1849 | &bd, |
1898 | GNUNET_TIME_relative_to_absolute ( | 1850 | query_hash, |
1899 | hello_expiration), | 1851 | 0, NULL /* get path */); |
1900 | key, | ||
1901 | 0, | ||
1902 | NULL, | ||
1903 | 0, | ||
1904 | NULL, | ||
1905 | GDS_my_hello, | ||
1906 | hello_size); | ||
1907 | } | 1852 | } |
1908 | else | 1853 | else |
1909 | { | 1854 | { |
1910 | GNUNET_STATISTICS_update (GDS_stats, | 1855 | GNUNET_STATISTICS_update (GDS_stats, |
1911 | gettext_noop ( | 1856 | "# FIND PEER requests ignored due to Bloomfilter", |
1912 | "# FIND PEER requests ignored due to Bloomfilter"), | ||
1913 | 1, | 1857 | 1, |
1914 | GNUNET_NO); | 1858 | GNUNET_NO); |
1915 | } | 1859 | } |
@@ -1917,20 +1861,20 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1917 | else | 1861 | else |
1918 | { | 1862 | { |
1919 | GNUNET_STATISTICS_update (GDS_stats, | 1863 | GNUNET_STATISTICS_update (GDS_stats, |
1920 | gettext_noop ( | 1864 | "# FIND PEER requests ignored due to lack of HELLO", |
1921 | "# FIND PEER requests ignored due to lack of HELLO"), | ||
1922 | 1, | 1865 | 1, |
1923 | GNUNET_NO); | 1866 | GNUNET_NO); |
1924 | } | 1867 | } |
1925 | 1868 | ||
1926 | /* then, also consider sending a random HELLO from the closest bucket */ | 1869 | /* then, also consider sending a random HELLO from the closest bucket */ |
1927 | if (0 == memcmp (&my_identity_hash, | 1870 | /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ |
1928 | key, | 1871 | if (0 == |
1929 | sizeof(struct GNUNET_HashCode))) | 1872 | GNUNET_memcmp (&my_identity_hash, |
1930 | bucket_idx = closest_bucket; | 1873 | query_hash)) |
1874 | bucket_idx = closest_bucket - 1; | ||
1931 | else | 1875 | else |
1932 | bucket_idx = GNUNET_MIN ((int) closest_bucket, | 1876 | bucket_idx = GNUNET_MIN ((int) closest_bucket - 1, |
1933 | find_bucket (key)); | 1877 | find_bucket (query_hash)); |
1934 | if (bucket_idx < 0) | 1878 | if (bucket_idx < 0) |
1935 | return; | 1879 | return; |
1936 | bucket = &k_buckets[bucket_idx]; | 1880 | bucket = &k_buckets[bucket_idx]; |
@@ -1946,82 +1890,69 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1946 | choice--; | 1890 | choice--; |
1947 | } | 1891 | } |
1948 | choice = bucket->peers_size; | 1892 | choice = bucket->peers_size; |
1949 | do | 1893 | |
1950 | { | 1894 | { |
1951 | peer = peer->next; | 1895 | const struct GNUNET_HELLO_Message *hello; |
1952 | if (0 == choice--) | 1896 | size_t hello_size; |
1953 | return; /* no non-masked peer available */ | 1897 | |
1954 | if (NULL == peer) | 1898 | do |
1955 | peer = bucket->head; | 1899 | { |
1956 | hello = GDS_HELLO_get (peer->id); | 1900 | peer = peer->next; |
1901 | if (0 == choice--) | ||
1902 | return; /* no non-masked peer available */ | ||
1903 | if (NULL == peer) | ||
1904 | peer = bucket->head; | ||
1905 | hello = GDS_HELLO_get (peer->id); | ||
1906 | } while ( (NULL == hello) || | ||
1907 | (GNUNET_BLOCK_REPLY_OK_MORE != | ||
1908 | GNUNET_BLOCK_check_reply ( | ||
1909 | GDS_block_context, | ||
1910 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1911 | bg, | ||
1912 | &peer->phash, | ||
1913 | NULL, 0, /* xquery */ | ||
1914 | hello, | ||
1915 | (hello_size = GNUNET_HELLO_size (hello))))); | ||
1916 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
1917 | GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); | ||
1918 | bd.key = peer->phash; | ||
1919 | bd.data = hello; | ||
1920 | bd.data_size = hello_size; | ||
1921 | GDS_NEIGHBOURS_handle_reply (pi, | ||
1922 | &bd, | ||
1923 | query_hash, | ||
1924 | 0, NULL /* get path */); | ||
1957 | } | 1925 | } |
1958 | while ((NULL == hello) || | ||
1959 | (GNUNET_BLOCK_EVALUATION_OK_MORE != | ||
1960 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
1961 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1962 | bg, | ||
1963 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | ||
1964 | &peer->phash, | ||
1965 | NULL, 0, | ||
1966 | hello, | ||
1967 | (hello_size = GNUNET_HELLO_size (hello))))); | ||
1968 | GDS_NEIGHBOURS_handle_reply (sender, | ||
1969 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1970 | GNUNET_TIME_relative_to_absolute | ||
1971 | (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION), | ||
1972 | key, | ||
1973 | 0, | ||
1974 | NULL, | ||
1975 | 0, | ||
1976 | NULL, | ||
1977 | hello, | ||
1978 | hello_size); | ||
1979 | } | 1926 | } |
1980 | 1927 | ||
1981 | 1928 | ||
1982 | /** | 1929 | /** |
1983 | * Handle a result from local datacache for a GET operation. | 1930 | * Handle an exact result from local datacache for a GET operation. |
1984 | * | 1931 | * |
1985 | * @param cls the `struct PeerInfo` for which this is a reply | 1932 | * @param cls the `struct PeerInfo` for which this is a reply |
1986 | * @param type type of the block | 1933 | * @param bd details about the block we found locally |
1987 | * @param expiration_time when does the content expire | ||
1988 | * @param key key for the content | ||
1989 | * @param put_path_length number of entries in @a put_path | ||
1990 | * @param put_path peers the original PUT traversed (if tracked) | ||
1991 | * @param get_path_length number of entries in @a get_path | ||
1992 | * @param get_path peers this reply has traversed so far (if tracked) | ||
1993 | * @param data payload of the reply | ||
1994 | * @param data_size number of bytes in @a data | ||
1995 | */ | 1934 | */ |
1996 | static void | 1935 | static void |
1997 | handle_local_result (void *cls, | 1936 | handle_local_result (void *cls, |
1998 | enum GNUNET_BLOCK_Type type, | 1937 | const struct GDS_DATACACHE_BlockData *bd) |
1999 | struct GNUNET_TIME_Absolute expiration_time, | ||
2000 | const struct GNUNET_HashCode *key, | ||
2001 | unsigned int put_path_length, | ||
2002 | const struct GNUNET_PeerIdentity *put_path, | ||
2003 | unsigned int get_path_length, | ||
2004 | const struct GNUNET_PeerIdentity *get_path, | ||
2005 | const void *data, | ||
2006 | size_t data_size) | ||
2007 | { | 1938 | { |
2008 | struct PeerInfo *peer = cls; | 1939 | struct PeerInfo *peer = cls; |
2009 | char *pp; | ||
2010 | 1940 | ||
2011 | pp = GNUNET_STRINGS_pp2s (put_path, | 1941 | { |
2012 | put_path_length); | 1942 | char *pp; |
2013 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1943 | |
2014 | "Found local result for %s (PP: %s)\n", | 1944 | pp = GNUNET_STRINGS_pp2s (bd->put_path, |
2015 | GNUNET_h2s (key), | 1945 | bd->put_path_length); |
2016 | pp); | 1946 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2017 | GNUNET_free (pp); | 1947 | "Found local result for %s (PP: %s)\n", |
2018 | GDS_NEIGHBOURS_handle_reply (peer->id, | 1948 | GNUNET_h2s (&bd->key), |
2019 | type, | 1949 | pp); |
2020 | expiration_time, | 1950 | GNUNET_free (pp); |
2021 | key, | 1951 | } |
2022 | put_path_length, put_path, | 1952 | GDS_NEIGHBOURS_handle_reply (peer, |
2023 | get_path_length, get_path, | 1953 | bd, |
2024 | data, data_size); | 1954 | &bd->key, |
1955 | 0, NULL /* get path */); | ||
2025 | } | 1956 | } |
2026 | 1957 | ||
2027 | 1958 | ||
@@ -2032,17 +1963,15 @@ handle_local_result (void *cls, | |||
2032 | * @param get the message | 1963 | * @param get the message |
2033 | * @return #GNUNET_OK if the message is well-formed | 1964 | * @return #GNUNET_OK if the message is well-formed |
2034 | */ | 1965 | */ |
2035 | static int | 1966 | static enum GNUNET_GenericReturnValue |
2036 | check_dht_p2p_get (void *cls, | 1967 | check_dht_p2p_get (void *cls, |
2037 | const struct PeerGetMessage *get) | 1968 | const struct PeerGetMessage *get) |
2038 | { | 1969 | { |
2039 | uint32_t xquery_size; | 1970 | uint16_t msize = ntohs (get->header.size); |
2040 | uint16_t msize; | 1971 | uint32_t xquery_size = ntohl (get->xquery_size); |
2041 | 1972 | ||
2042 | (void) cls; | 1973 | (void) cls; |
2043 | msize = ntohs (get->header.size); | 1974 | if (msize < sizeof(*get) + xquery_size) |
2044 | xquery_size = ntohl (get->xquery_size); | ||
2045 | if (msize < sizeof(struct PeerGetMessage) + xquery_size) | ||
2046 | { | 1975 | { |
2047 | GNUNET_break_op (0); | 1976 | GNUNET_break_op (0); |
2048 | return GNUNET_SYSERR; | 1977 | return GNUNET_SYSERR; |
@@ -2062,265 +1991,236 @@ handle_dht_p2p_get (void *cls, | |||
2062 | const struct PeerGetMessage *get) | 1991 | const struct PeerGetMessage *get) |
2063 | { | 1992 | { |
2064 | struct PeerInfo *peer = cls; | 1993 | struct PeerInfo *peer = cls; |
2065 | uint32_t xquery_size; | 1994 | uint16_t msize = ntohs (get->header.size); |
2066 | size_t reply_bf_size; | 1995 | uint32_t xquery_size = ntohl (get->xquery_size); |
2067 | uint16_t msize; | 1996 | uint32_t hop_count = ntohl (get->hop_count); |
2068 | enum GNUNET_BLOCK_Type type; | 1997 | size_t reply_bf_size = msize - (sizeof(*get) + xquery_size); |
2069 | enum GNUNET_DHT_RouteOption options; | 1998 | enum GNUNET_BLOCK_Type type = (enum GNUNET_BLOCK_Type) ntohl (get->type); |
2070 | enum GNUNET_BLOCK_EvaluationResult eval; | 1999 | enum GNUNET_DHT_RouteOption options = (enum GNUNET_DHT_RouteOption) ntohl (get->options); |
2071 | struct GNUNET_BLOCK_Group *bg; | 2000 | enum GNUNET_BLOCK_ReplyEvaluationResult eval = GNUNET_BLOCK_REPLY_OK_MORE; |
2072 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 2001 | const void *xquery = (const void *) &get[1]; |
2073 | const char *xquery; | ||
2074 | int forwarded; | ||
2075 | 2002 | ||
2076 | /* parse and validate message */ | 2003 | /* parse and validate message */ |
2077 | msize = ntohs (get->header.size); | ||
2078 | xquery_size = ntohl (get->xquery_size); | ||
2079 | reply_bf_size = msize - (sizeof(struct PeerGetMessage) + xquery_size); | ||
2080 | type = ntohl (get->type); | ||
2081 | options = ntohl (get->options); | ||
2082 | xquery = (const char *) &get[1]; | ||
2083 | GNUNET_STATISTICS_update (GDS_stats, | 2004 | GNUNET_STATISTICS_update (GDS_stats, |
2084 | gettext_noop ("# P2P GET requests received"), | 2005 | "# P2P GET requests received", |
2085 | 1, | 2006 | 1, |
2086 | GNUNET_NO); | 2007 | GNUNET_NO); |
2087 | GNUNET_STATISTICS_update (GDS_stats, | 2008 | GNUNET_STATISTICS_update (GDS_stats, |
2088 | gettext_noop ("# P2P GET bytes received"), | 2009 | "# P2P GET bytes received", |
2089 | msize, | 2010 | msize, |
2090 | GNUNET_NO); | 2011 | GNUNET_NO); |
2091 | if (GNUNET_YES == log_route_details_stderr) | 2012 | if (GNUNET_YES == log_route_details_stderr) |
2092 | { | 2013 | { |
2093 | char *tmp; | 2014 | char *tmp; |
2094 | 2015 | struct GNUNET_HashCode mxor; | |
2016 | struct GNUNET_HashCode pxor; | ||
2017 | |||
2018 | GNUNET_CRYPTO_hash_xor (&my_identity_hash, | ||
2019 | &get->key, | ||
2020 | &mxor); | ||
2021 | GNUNET_CRYPTO_hash_xor (&peer->phash, | ||
2022 | &get->key, | ||
2023 | &pxor); | ||
2095 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 2024 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
2096 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 2025 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
2097 | "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n", | 2026 | "R5N GET %s: %s->%s (%u, %u=>%u) xq: %.*s\n", |
2098 | GNUNET_h2s (&get->key), | 2027 | GNUNET_h2s (&get->key), |
2099 | GNUNET_i2s (peer->id), | 2028 | GNUNET_i2s (peer->id), |
2100 | tmp, | 2029 | tmp, |
2101 | ntohl (get->hop_count), | 2030 | hop_count, |
2102 | GNUNET_CRYPTO_hash_matching_bits (&peer->phash, | 2031 | GNUNET_CRYPTO_hash_count_leading_zeros (&pxor), |
2103 | &get->key), | 2032 | GNUNET_CRYPTO_hash_count_leading_zeros (&mxor), |
2104 | GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, | ||
2105 | &get->key), | ||
2106 | ntohl (get->xquery_size), | 2033 | ntohl (get->xquery_size), |
2107 | xquery); | 2034 | (const char *) xquery); |
2108 | GNUNET_free (tmp); | 2035 | GNUNET_free (tmp); |
2109 | } | 2036 | } |
2110 | eval | 2037 | if (GNUNET_NO == |
2111 | = GNUNET_BLOCK_evaluate (GDS_block_context, | 2038 | GNUNET_BLOCK_check_query (GDS_block_context, |
2112 | type, | 2039 | type, |
2113 | NULL, | 2040 | &get->key, |
2114 | GNUNET_BLOCK_EO_NONE, | 2041 | xquery, |
2115 | &get->key, | 2042 | xquery_size)) |
2116 | xquery, | ||
2117 | xquery_size, | ||
2118 | NULL, | ||
2119 | 0); | ||
2120 | if (eval != GNUNET_BLOCK_EVALUATION_REQUEST_VALID) | ||
2121 | { | 2043 | { |
2122 | /* request invalid or block type not supported */ | 2044 | /* request invalid */ |
2123 | GNUNET_break_op (eval == GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED); | 2045 | GNUNET_break_op (0); |
2124 | return; | 2046 | return; |
2125 | } | 2047 | } |
2126 | peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter, | 2048 | |
2127 | DHT_BLOOM_SIZE, | ||
2128 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
2129 | GNUNET_break_op (GNUNET_YES == | ||
2130 | GNUNET_CONTAINER_bloomfilter_test (peer_bf, | ||
2131 | &peer->phash)); | ||
2132 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
2133 | type, | ||
2134 | get->bf_mutator, | ||
2135 | &xquery[xquery_size], | ||
2136 | reply_bf_size, | ||
2137 | "filter-size", | ||
2138 | reply_bf_size, | ||
2139 | NULL); | ||
2140 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2141 | "GET for %s at %s after %u hops\n", | ||
2142 | GNUNET_h2s (&get->key), | ||
2143 | GNUNET_i2s (&my_identity), | ||
2144 | (unsigned int) ntohl (get->hop_count)); | ||
2145 | /* local lookup (this may update the reply_bf) */ | ||
2146 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | ||
2147 | (GDS_am_closest_peer (&get->key, | ||
2148 | peer_bf))) | ||
2149 | { | 2049 | { |
2150 | if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) | 2050 | struct GNUNET_BLOCK_Group *bg; |
2051 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | ||
2052 | |||
2053 | peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter, | ||
2054 | DHT_BLOOM_SIZE, | ||
2055 | GNUNET_CONSTANTS_BLOOMFILTER_K); | ||
2056 | GNUNET_break_op (GNUNET_YES == | ||
2057 | GNUNET_CONTAINER_bloomfilter_test (peer_bf, | ||
2058 | &peer->phash)); | ||
2059 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
2060 | type, | ||
2061 | get->bf_mutator, | ||
2062 | xquery + xquery_size, | ||
2063 | reply_bf_size, | ||
2064 | "filter-size", | ||
2065 | reply_bf_size, | ||
2066 | NULL); | ||
2067 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2068 | "GET for %s at %s after %u hops\n", | ||
2069 | GNUNET_h2s (&get->key), | ||
2070 | GNUNET_i2s (&my_identity), | ||
2071 | (unsigned int) hop_count); | ||
2072 | /* local lookup (this may update the reply_bf) */ | ||
2073 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | ||
2074 | (GDS_am_closest_peer (&get->key, | ||
2075 | peer_bf)) ) | ||
2151 | { | 2076 | { |
2152 | GNUNET_STATISTICS_update (GDS_stats, | 2077 | if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) |
2153 | gettext_noop ( | 2078 | { |
2154 | "# P2P FIND PEER requests processed"), | 2079 | GNUNET_STATISTICS_update (GDS_stats, |
2155 | 1, | 2080 | "# P2P FIND PEER requests processed", |
2156 | GNUNET_NO); | 2081 | 1, |
2157 | handle_find_peer (peer->id, | 2082 | GNUNET_NO); |
2158 | &get->key, | 2083 | handle_find_peer (peer, |
2159 | bg); | 2084 | &get->key, |
2085 | bg); | ||
2086 | } | ||
2087 | else | ||
2088 | { | ||
2089 | eval = GDS_DATACACHE_handle_get (&get->key, | ||
2090 | type, | ||
2091 | xquery, | ||
2092 | xquery_size, | ||
2093 | bg, | ||
2094 | &handle_local_result, | ||
2095 | peer); | ||
2096 | } | ||
2160 | } | 2097 | } |
2161 | else | 2098 | else |
2099 | { | ||
2100 | GNUNET_STATISTICS_update (GDS_stats, | ||
2101 | "# P2P GET requests ONLY routed", | ||
2102 | 1, | ||
2103 | GNUNET_NO); | ||
2104 | } | ||
2105 | |||
2106 | /* remember request for routing replies */ | ||
2107 | GDS_ROUTING_add (peer->id, | ||
2108 | type, | ||
2109 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | ||
2110 | options, | ||
2111 | &get->key, | ||
2112 | xquery, | ||
2113 | xquery_size); | ||
2114 | |||
2115 | /* P2P forwarding */ | ||
2162 | { | 2116 | { |
2163 | eval = GDS_DATACACHE_handle_get (&get->key, | 2117 | bool forwarded = false; |
2164 | type, | 2118 | uint32_t desired_replication_level = ntohl (get->desired_replication_level); |
2165 | xquery, | 2119 | |
2166 | xquery_size, | 2120 | if (eval != GNUNET_BLOCK_REPLY_OK_LAST) |
2167 | bg, | 2121 | forwarded = (GNUNET_OK == |
2168 | &handle_local_result, | 2122 | GDS_NEIGHBOURS_handle_get (type, |
2169 | peer); | 2123 | options, |
2124 | desired_replication_level, | ||
2125 | hop_count, | ||
2126 | &get->key, | ||
2127 | xquery, | ||
2128 | xquery_size, | ||
2129 | bg, | ||
2130 | peer_bf)); | ||
2131 | GDS_CLIENTS_process_get ( | ||
2132 | options | | ||
2133 | (forwarded | ||
2134 | ? 0 | ||
2135 | : GNUNET_DHT_RO_LAST_HOP), | ||
2136 | type, | ||
2137 | hop_count, | ||
2138 | desired_replication_level, | ||
2139 | 0, | ||
2140 | NULL, | ||
2141 | &get->key); | ||
2170 | } | 2142 | } |
2143 | /* clean up; note that 'bg' is owned by routing now! */ | ||
2144 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
2171 | } | 2145 | } |
2172 | else | ||
2173 | { | ||
2174 | GNUNET_STATISTICS_update (GDS_stats, | ||
2175 | gettext_noop ("# P2P GET requests ONLY routed"), | ||
2176 | 1, | ||
2177 | GNUNET_NO); | ||
2178 | } | ||
2179 | |||
2180 | /* remember request for routing replies */ | ||
2181 | GDS_ROUTING_add (peer->id, | ||
2182 | type, | ||
2183 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | ||
2184 | options, | ||
2185 | &get->key, | ||
2186 | xquery, | ||
2187 | xquery_size); | ||
2188 | |||
2189 | /* P2P forwarding */ | ||
2190 | forwarded = GNUNET_NO; | ||
2191 | if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) | ||
2192 | forwarded = GDS_NEIGHBOURS_handle_get (type, | ||
2193 | options, | ||
2194 | ntohl ( | ||
2195 | get->desired_replication_level), | ||
2196 | ntohl (get->hop_count), | ||
2197 | &get->key, | ||
2198 | xquery, | ||
2199 | xquery_size, | ||
2200 | bg, | ||
2201 | peer_bf); | ||
2202 | GDS_CLIENTS_process_get (options | ||
2203 | | ((GNUNET_OK == forwarded) | ||
2204 | ? GNUNET_DHT_RO_LAST_HOP : 0), | ||
2205 | type, | ||
2206 | ntohl (get->hop_count), | ||
2207 | ntohl (get->desired_replication_level), | ||
2208 | 0, | ||
2209 | NULL, | ||
2210 | &get->key); | ||
2211 | |||
2212 | /* clean up; note that 'bg' is owned by routing now! */ | ||
2213 | GNUNET_CONTAINER_bloomfilter_free (peer_bf); | ||
2214 | } | ||
2215 | |||
2216 | |||
2217 | /** | ||
2218 | * Check validity of p2p result message. | ||
2219 | * | ||
2220 | * @param cls closure | ||
2221 | * @param message message | ||
2222 | * @return #GNUNET_YES if the message is well-formed | ||
2223 | */ | ||
2224 | static int | ||
2225 | check_dht_p2p_result (void *cls, | ||
2226 | const struct PeerResultMessage *prm) | ||
2227 | { | ||
2228 | uint32_t get_path_length; | ||
2229 | uint32_t put_path_length; | ||
2230 | uint16_t msize; | ||
2231 | |||
2232 | (void) cls; | ||
2233 | msize = ntohs (prm->header.size); | ||
2234 | put_path_length = ntohl (prm->put_path_length); | ||
2235 | get_path_length = ntohl (prm->get_path_length); | ||
2236 | if ((msize < | ||
2237 | sizeof(struct PeerResultMessage) + (get_path_length | ||
2238 | + put_path_length) | ||
2239 | * sizeof(struct GNUNET_PeerIdentity)) || | ||
2240 | (get_path_length > | ||
2241 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | ||
2242 | (put_path_length > | ||
2243 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity))) | ||
2244 | { | ||
2245 | GNUNET_break_op (0); | ||
2246 | return GNUNET_SYSERR; | ||
2247 | } | ||
2248 | return GNUNET_OK; | ||
2249 | } | 2146 | } |
2250 | 2147 | ||
2251 | 2148 | ||
2252 | /** | 2149 | /** |
2253 | * Process a reply, after the @a get_path has been updated. | 2150 | * Process a reply, after the @a get_path has been updated. |
2254 | * | 2151 | * |
2255 | * @param expiration_time when does the reply expire | 2152 | * @param bd block details |
2256 | * @param key key matching the query | 2153 | * @param query_hash hash of the original query, might not match key in @a bd |
2257 | * @param get_path_length number of entries in @a get_path | 2154 | * @param get_path_length number of entries in @a get_path |
2258 | * @param get_path path the reply has taken | 2155 | * @param get_path path the reply has taken |
2259 | * @param put_path_length number of entries in @a put_path | ||
2260 | * @param put_path path the PUT has taken | ||
2261 | * @param type type of the block | ||
2262 | * @param data_size number of bytes in @a data | ||
2263 | * @param data payload of the reply | ||
2264 | */ | 2156 | */ |
2265 | static void | 2157 | static void |
2266 | process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, | 2158 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, |
2267 | const struct GNUNET_HashCode *key, | 2159 | const struct GNUNET_HashCode *query_hash, |
2268 | unsigned int get_path_length, | 2160 | unsigned int get_path_length, |
2269 | const struct GNUNET_PeerIdentity *get_path, | 2161 | const struct GNUNET_PeerIdentity *get_path) |
2270 | unsigned int put_path_length, | ||
2271 | const struct GNUNET_PeerIdentity *put_path, | ||
2272 | enum GNUNET_BLOCK_Type type, | ||
2273 | size_t data_size, | ||
2274 | const void *data) | ||
2275 | { | 2162 | { |
2276 | /* forward to local clients */ | 2163 | /* forward to local clients */ |
2277 | GDS_CLIENTS_handle_reply (expiration_time, | 2164 | GDS_CLIENTS_handle_reply (bd, |
2278 | key, | 2165 | query_hash, |
2279 | get_path_length, | 2166 | get_path_length, |
2280 | get_path, | 2167 | get_path); |
2281 | put_path_length, | 2168 | GDS_CLIENTS_process_get_resp (bd, |
2282 | put_path, | ||
2283 | type, | ||
2284 | data_size, | ||
2285 | data); | ||
2286 | GDS_CLIENTS_process_get_resp (type, | ||
2287 | get_path, | 2169 | get_path, |
2288 | get_path_length, | 2170 | get_path_length); |
2289 | put_path, | ||
2290 | put_path_length, | ||
2291 | expiration_time, | ||
2292 | key, | ||
2293 | data, | ||
2294 | data_size); | ||
2295 | if (GNUNET_YES == cache_results) | 2171 | if (GNUNET_YES == cache_results) |
2296 | { | 2172 | { |
2297 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | 2173 | struct GNUNET_PeerIdentity xput_path[GNUNET_NZL (get_path_length |
2174 | + bd->put_path_length)]; | ||
2175 | struct GDS_DATACACHE_BlockData bdx = *bd; | ||
2298 | 2176 | ||
2299 | GNUNET_memcpy (xput_path, | 2177 | GNUNET_memcpy (xput_path, |
2300 | put_path, | 2178 | bd->put_path, |
2301 | put_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2179 | bd->put_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2302 | GNUNET_memcpy (&xput_path[put_path_length], | 2180 | GNUNET_memcpy (&xput_path[bd->put_path_length], |
2303 | get_path, | 2181 | get_path, |
2304 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2182 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2305 | 2183 | bdx.put_path = xput_path; | |
2306 | GDS_DATACACHE_handle_put (expiration_time, | 2184 | bdx.put_path_length += get_path_length; |
2307 | key, | 2185 | GDS_DATACACHE_handle_put (&bdx); |
2308 | get_path_length + put_path_length, | ||
2309 | xput_path, | ||
2310 | type, | ||
2311 | data_size, | ||
2312 | data); | ||
2313 | } | 2186 | } |
2314 | /* forward to other peers */ | 2187 | /* forward to other peers */ |
2315 | GDS_ROUTING_process (type, | 2188 | GDS_ROUTING_process (bd, |
2316 | expiration_time, | 2189 | query_hash, |
2317 | key, | ||
2318 | put_path_length, | ||
2319 | put_path, | ||
2320 | get_path_length, | 2190 | get_path_length, |
2321 | get_path, | 2191 | get_path); |
2322 | data, | 2192 | } |
2323 | data_size); | 2193 | |
2194 | |||
2195 | /** | ||
2196 | * Check validity of p2p result message. | ||
2197 | * | ||
2198 | * @param cls closure | ||
2199 | * @param message message | ||
2200 | * @return #GNUNET_YES if the message is well-formed | ||
2201 | */ | ||
2202 | static enum GNUNET_GenericReturnValue | ||
2203 | check_dht_p2p_result (void *cls, | ||
2204 | const struct PeerResultMessage *prm) | ||
2205 | { | ||
2206 | uint32_t get_path_length = ntohl (prm->get_path_length); | ||
2207 | uint32_t put_path_length = ntohl (prm->put_path_length); | ||
2208 | uint16_t msize = ntohs (prm->header.size); | ||
2209 | |||
2210 | (void) cls; | ||
2211 | if ( (msize < | ||
2212 | sizeof(struct PeerResultMessage) | ||
2213 | + (get_path_length + put_path_length) | ||
2214 | * sizeof(struct GNUNET_PeerIdentity)) || | ||
2215 | (get_path_length > | ||
2216 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) || | ||
2217 | (put_path_length > | ||
2218 | GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_PeerIdentity)) ) | ||
2219 | { | ||
2220 | GNUNET_break_op (0); | ||
2221 | return GNUNET_SYSERR; | ||
2222 | } | ||
2223 | return GNUNET_OK; | ||
2324 | } | 2224 | } |
2325 | 2225 | ||
2326 | 2226 | ||
@@ -2335,45 +2235,66 @@ handle_dht_p2p_result (void *cls, | |||
2335 | const struct PeerResultMessage *prm) | 2235 | const struct PeerResultMessage *prm) |
2336 | { | 2236 | { |
2337 | struct PeerInfo *peer = cls; | 2237 | struct PeerInfo *peer = cls; |
2338 | const struct GNUNET_PeerIdentity *put_path; | 2238 | uint16_t msize = ntohs (prm->header.size); |
2339 | const struct GNUNET_PeerIdentity *get_path; | 2239 | uint32_t get_path_length = ntohl (prm->get_path_length); |
2340 | const void *data; | 2240 | struct GDS_DATACACHE_BlockData bd = { |
2341 | uint32_t get_path_length; | 2241 | .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2342 | uint32_t put_path_length; | 2242 | .put_path = (const struct GNUNET_PeerIdentity *) &prm[1], |
2343 | uint16_t msize; | 2243 | .put_path_length = ntohl (prm->put_path_length), |
2344 | size_t data_size; | 2244 | .type = ntohl (prm->type) |
2345 | enum GNUNET_BLOCK_Type type; | 2245 | }; |
2346 | struct GNUNET_TIME_Absolute exp_time; | 2246 | const struct GNUNET_PeerIdentity *get_path |
2247 | = &bd.put_path[bd.put_path_length]; | ||
2347 | 2248 | ||
2348 | /* parse and validate message */ | 2249 | /* parse and validate message */ |
2349 | exp_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time); | 2250 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) |
2350 | if (0 == GNUNET_TIME_absolute_get_remaining (exp_time).rel_value_us) | ||
2351 | { | 2251 | { |
2352 | GNUNET_STATISTICS_update (GDS_stats, | 2252 | GNUNET_STATISTICS_update (GDS_stats, |
2353 | gettext_noop ("# Expired results discarded"), | 2253 | "# Expired results discarded", |
2354 | 1, | 2254 | 1, |
2355 | GNUNET_NO); | 2255 | GNUNET_NO); |
2356 | return; | 2256 | return; |
2357 | } | 2257 | } |
2358 | msize = ntohs (prm->header.size); | 2258 | get_path = &bd.put_path[bd.put_path_length]; |
2359 | put_path_length = ntohl (prm->put_path_length); | 2259 | bd.data = (const void *) &get_path[get_path_length]; |
2360 | get_path_length = ntohl (prm->get_path_length); | 2260 | bd.data_size = msize - (sizeof(struct PeerResultMessage) |
2361 | put_path = (const struct GNUNET_PeerIdentity *) &prm[1]; | 2261 | + (get_path_length + bd.put_path_length) |
2362 | get_path = &put_path[put_path_length]; | 2262 | * sizeof(struct GNUNET_PeerIdentity)); |
2363 | type = ntohl (prm->type); | ||
2364 | data = (const void *) &get_path[get_path_length]; | ||
2365 | data_size = msize - (sizeof(struct PeerResultMessage) | ||
2366 | + (get_path_length | ||
2367 | + put_path_length) * sizeof(struct | ||
2368 | GNUNET_PeerIdentity)); | ||
2369 | GNUNET_STATISTICS_update (GDS_stats, | 2263 | GNUNET_STATISTICS_update (GDS_stats, |
2370 | gettext_noop ("# P2P RESULTS received"), | 2264 | "# P2P RESULTS received", |
2371 | 1, | 2265 | 1, |
2372 | GNUNET_NO); | 2266 | GNUNET_NO); |
2373 | GNUNET_STATISTICS_update (GDS_stats, | 2267 | GNUNET_STATISTICS_update (GDS_stats, |
2374 | gettext_noop ("# P2P RESULT bytes received"), | 2268 | "# P2P RESULT bytes received", |
2375 | msize, | 2269 | msize, |
2376 | GNUNET_NO); | 2270 | GNUNET_NO); |
2271 | { | ||
2272 | enum GNUNET_GenericReturnValue ret; | ||
2273 | const struct GNUNET_HashCode *pquery; | ||
2274 | |||
2275 | ret = GNUNET_BLOCK_get_key (GDS_block_context, | ||
2276 | bd.type, | ||
2277 | bd.data, | ||
2278 | bd.data_size, | ||
2279 | &bd.key); | ||
2280 | if (GNUNET_NO == ret) | ||
2281 | { | ||
2282 | GNUNET_break_op (0); | ||
2283 | return; | ||
2284 | } | ||
2285 | pquery = (GNUNET_OK == ret) ? &bd.key : &prm->key; | ||
2286 | if (GNUNET_OK != | ||
2287 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
2288 | bd.type, | ||
2289 | pquery, | ||
2290 | bd.data, | ||
2291 | bd.data_size)) | ||
2292 | { | ||
2293 | GNUNET_break_op (0); | ||
2294 | return; | ||
2295 | } | ||
2296 | } | ||
2297 | |||
2377 | if (GNUNET_YES == log_route_details_stderr) | 2298 | if (GNUNET_YES == log_route_details_stderr) |
2378 | { | 2299 | { |
2379 | char *tmp; | 2300 | char *tmp; |
@@ -2382,8 +2303,8 @@ handle_dht_p2p_result (void *cls, | |||
2382 | 2303 | ||
2383 | gp = GNUNET_STRINGS_pp2s (get_path, | 2304 | gp = GNUNET_STRINGS_pp2s (get_path, |
2384 | get_path_length); | 2305 | get_path_length); |
2385 | pp = GNUNET_STRINGS_pp2s (put_path, | 2306 | pp = GNUNET_STRINGS_pp2s (bd.put_path, |
2386 | put_path_length); | 2307 | bd.put_path_length); |
2387 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 2308 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
2388 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 2309 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
2389 | "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n", | 2310 | "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n", |
@@ -2396,22 +2317,22 @@ handle_dht_p2p_result (void *cls, | |||
2396 | GNUNET_free (pp); | 2317 | GNUNET_free (pp); |
2397 | GNUNET_free (tmp); | 2318 | GNUNET_free (tmp); |
2398 | } | 2319 | } |
2320 | |||
2399 | /* if we got a HELLO, consider it for our own routing table */ | 2321 | /* if we got a HELLO, consider it for our own routing table */ |
2400 | if (GNUNET_BLOCK_TYPE_DHT_HELLO == type) | 2322 | if (GNUNET_BLOCK_TYPE_DHT_HELLO == bd.type) |
2401 | { | 2323 | { |
2402 | const struct GNUNET_MessageHeader *h; | 2324 | const struct GNUNET_MessageHeader *h = bd.data; |
2403 | struct GNUNET_PeerIdentity pid; | 2325 | struct GNUNET_PeerIdentity pid; |
2404 | 2326 | ||
2405 | /* Should be a HELLO, validate and consider using it! */ | 2327 | /* Should be a HELLO, validate and consider using it! */ |
2406 | if (data_size < sizeof(struct GNUNET_HELLO_Message)) | 2328 | if (bd.data_size < sizeof(struct GNUNET_HELLO_Message)) |
2407 | { | 2329 | { |
2408 | GNUNET_break_op (0); | 2330 | GNUNET_break (0); |
2409 | return; | 2331 | return; |
2410 | } | 2332 | } |
2411 | h = data; | 2333 | if (bd.data_size != ntohs (h->size)) |
2412 | if (data_size != ntohs (h->size)) | ||
2413 | { | 2334 | { |
2414 | GNUNET_break_op (0); | 2335 | GNUNET_break (0); |
2415 | return; | 2336 | return; |
2416 | } | 2337 | } |
2417 | if (GNUNET_OK != | 2338 | if (GNUNET_OK != |
@@ -2421,10 +2342,9 @@ handle_dht_p2p_result (void *cls, | |||
2421 | GNUNET_break_op (0); | 2342 | GNUNET_break_op (0); |
2422 | return; | 2343 | return; |
2423 | } | 2344 | } |
2424 | if ((GNUNET_YES != disable_try_connect) && | 2345 | if ( (GNUNET_YES != disable_try_connect) && |
2425 | (0 != memcmp (&my_identity, | 2346 | (0 != GNUNET_memcmp (&my_identity, |
2426 | &pid, | 2347 | &pid)) ) |
2427 | sizeof(struct GNUNET_PeerIdentity)))) | ||
2428 | try_connect (&pid, | 2348 | try_connect (&pid, |
2429 | h); | 2349 | h); |
2430 | } | 2350 | } |
@@ -2432,19 +2352,12 @@ handle_dht_p2p_result (void *cls, | |||
2432 | /* First, check if 'peer' is already on the path, and if | 2352 | /* First, check if 'peer' is already on the path, and if |
2433 | so, truncate it instead of expanding. */ | 2353 | so, truncate it instead of expanding. */ |
2434 | for (unsigned int i = 0; i <= get_path_length; i++) | 2354 | for (unsigned int i = 0; i <= get_path_length; i++) |
2435 | if (0 == memcmp (&get_path[i], | 2355 | if (0 == GNUNET_memcmp (&get_path[i], |
2436 | peer->id, | 2356 | peer->id)) |
2437 | sizeof(struct GNUNET_PeerIdentity))) | ||
2438 | { | 2357 | { |
2439 | process_reply_with_path (exp_time, | 2358 | process_reply_with_path (&bd, |
2440 | &prm->key, | 2359 | &prm->key, |
2441 | i, | 2360 | i, get_path); |
2442 | get_path, | ||
2443 | put_path_length, | ||
2444 | put_path, | ||
2445 | type, | ||
2446 | data_size, | ||
2447 | data); | ||
2448 | return; | 2361 | return; |
2449 | } | 2362 | } |
2450 | 2363 | ||
@@ -2456,26 +2369,14 @@ handle_dht_p2p_result (void *cls, | |||
2456 | get_path, | 2369 | get_path, |
2457 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); | 2370 | get_path_length * sizeof(struct GNUNET_PeerIdentity)); |
2458 | xget_path[get_path_length] = *peer->id; | 2371 | xget_path[get_path_length] = *peer->id; |
2459 | 2372 | process_reply_with_path (&bd, | |
2460 | process_reply_with_path (exp_time, | ||
2461 | &prm->key, | 2373 | &prm->key, |
2462 | get_path_length + 1, | 2374 | get_path_length + 1, xget_path); |
2463 | xget_path, | ||
2464 | put_path_length, | ||
2465 | put_path, | ||
2466 | type, | ||
2467 | data_size, | ||
2468 | data); | ||
2469 | } | 2375 | } |
2470 | } | 2376 | } |
2471 | 2377 | ||
2472 | 2378 | ||
2473 | /** | 2379 | enum GNUNET_GenericReturnValue |
2474 | * Initialize neighbours subsystem. | ||
2475 | * | ||
2476 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
2477 | */ | ||
2478 | int | ||
2479 | GDS_NEIGHBOURS_init () | 2380 | GDS_NEIGHBOURS_init () |
2480 | { | 2381 | { |
2481 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | 2382 | struct GNUNET_MQ_MessageHandler core_handlers[] = { |
@@ -2529,9 +2430,6 @@ GDS_NEIGHBOURS_init () | |||
2529 | } | 2430 | } |
2530 | 2431 | ||
2531 | 2432 | ||
2532 | /** | ||
2533 | * Shutdown neighbours subsystem. | ||
2534 | */ | ||
2535 | void | 2433 | void |
2536 | GDS_NEIGHBOURS_done () | 2434 | GDS_NEIGHBOURS_done () |
2537 | { | 2435 | { |
@@ -2554,11 +2452,6 @@ GDS_NEIGHBOURS_done () | |||
2554 | } | 2452 | } |
2555 | 2453 | ||
2556 | 2454 | ||
2557 | /** | ||
2558 | * Get the ID of the local node. | ||
2559 | * | ||
2560 | * @return identity of the local node | ||
2561 | */ | ||
2562 | struct GNUNET_PeerIdentity * | 2455 | struct GNUNET_PeerIdentity * |
2563 | GDS_NEIGHBOURS_get_id () | 2456 | GDS_NEIGHBOURS_get_id () |
2564 | { | 2457 | { |
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 55cc5b135..28468c740 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | 3 | Copyright (C) 2009, 2010, 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -30,6 +30,7 @@ | |||
30 | #include "gnunet_util_lib.h" | 30 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_block_lib.h" | 31 | #include "gnunet_block_lib.h" |
32 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
33 | #include "gnunet-service-dht_datacache.h" | ||
33 | 34 | ||
34 | /** | 35 | /** |
35 | * Hash of the identity of this peer. | 36 | * Hash of the identity of this peer. |
@@ -37,6 +38,18 @@ | |||
37 | extern struct GNUNET_HashCode my_identity_hash; | 38 | extern struct GNUNET_HashCode my_identity_hash; |
38 | 39 | ||
39 | 40 | ||
41 | struct PeerInfo; | ||
42 | |||
43 | /** | ||
44 | * Lookup peer by peer's identity. | ||
45 | * | ||
46 | * @param target peer to look up | ||
47 | * @return NULL if we are not connected to @a target | ||
48 | */ | ||
49 | struct PeerInfo * | ||
50 | GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target); | ||
51 | |||
52 | |||
40 | /** | 53 | /** |
41 | * Perform a PUT operation. Forwards the given request to other | 54 | * Perform a PUT operation. Forwards the given request to other |
42 | * peers. Does not store the data locally. Does not give the | 55 | * peers. Does not store the data locally. Does not give the |
@@ -44,30 +57,19 @@ extern struct GNUNET_HashCode my_identity_hash; | |||
44 | * peer in the network (or if we are the closest peer in the | 57 | * peer in the network (or if we are the closest peer in the |
45 | * network). | 58 | * network). |
46 | * | 59 | * |
47 | * @param type type of the block | 60 | * @param bd data about the block |
48 | * @param options routing options | 61 | * @param options routing options |
49 | * @param desired_replication_level desired replication level | 62 | * @param desired_replication_level desired replication level |
50 | * @param expiration_time when does the content expire | ||
51 | * @param hop_count how many hops has this message traversed so far | 63 | * @param hop_count how many hops has this message traversed so far |
52 | * @param bf Bloom filter of peers this PUT has already traversed | 64 | * @param bf Bloom filter of peers this PUT has already traversed |
53 | * @param key key for the content | ||
54 | * @param put_path_length number of entries in put_path | ||
55 | * @param put_path peers this request has traversed so far (if tracked) | ||
56 | * @param data payload to store | ||
57 | * @param data_size number of bytes in data | ||
58 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | 65 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not |
59 | */ | 66 | */ |
60 | int | 67 | enum GNUNET_GenericReturnValue |
61 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | 68 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
62 | enum GNUNET_DHT_RouteOption options, | 69 | enum GNUNET_DHT_RouteOption options, |
63 | uint32_t desired_replication_level, | 70 | uint32_t desired_replication_level, |
64 | struct GNUNET_TIME_Absolute expiration_time, | ||
65 | uint32_t hop_count, | 71 | uint32_t hop_count, |
66 | struct GNUNET_CONTAINER_BloomFilter *bf, | 72 | struct GNUNET_CONTAINER_BloomFilter *bf); |
67 | const struct GNUNET_HashCode *key, | ||
68 | unsigned int put_path_length, | ||
69 | struct GNUNET_PeerIdentity *put_path, | ||
70 | const void *data, size_t data_size); | ||
71 | 73 | ||
72 | 74 | ||
73 | /** | 75 | /** |
@@ -87,7 +89,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
87 | * @param peer_bf filter for peers not to select (again, updated) | 89 | * @param peer_bf filter for peers not to select (again, updated) |
88 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | 90 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not |
89 | */ | 91 | */ |
90 | int | 92 | enum GNUNET_GenericReturnValue |
91 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 93 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
92 | enum GNUNET_DHT_RouteOption options, | 94 | enum GNUNET_DHT_RouteOption options, |
93 | uint32_t desired_replication_level, | 95 | uint32_t desired_replication_level, |
@@ -104,28 +106,19 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
104 | * other peers waiting for it. Does not do local caching or | 106 | * other peers waiting for it. Does not do local caching or |
105 | * forwarding to local clients. | 107 | * forwarding to local clients. |
106 | * | 108 | * |
107 | * @param target neighbour that should receive the block (if still connected) | 109 | * @param pi neighbour that should receive the block |
108 | * @param type type of the block | 110 | * @param type type of the block |
109 | * @param expiration_time when does the content expire | 111 | * @param bd details about the reply |
110 | * @param key key for the content | 112 | * @param query_hash query that was used for the request |
111 | * @param put_path_length number of entries in put_path | ||
112 | * @param put_path peers the original PUT traversed (if tracked) | ||
113 | * @param get_path_length number of entries in put_path | 113 | * @param get_path_length number of entries in put_path |
114 | * @param get_path peers this reply has traversed so far (if tracked) | 114 | * @param get_path peers this reply has traversed so far (if tracked) |
115 | * @param data payload of the reply | ||
116 | * @param data_size number of bytes in data | ||
117 | */ | 115 | */ |
118 | void | 116 | void |
119 | GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | 117 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, |
120 | enum GNUNET_BLOCK_Type type, | 118 | const struct GDS_DATACACHE_BlockData *bd, |
121 | struct GNUNET_TIME_Absolute expiration_time, | 119 | const struct GNUNET_HashCode *query_hash, |
122 | const struct GNUNET_HashCode *key, | ||
123 | unsigned int put_path_length, | ||
124 | const struct GNUNET_PeerIdentity *put_path, | ||
125 | unsigned int get_path_length, | 120 | unsigned int get_path_length, |
126 | const struct GNUNET_PeerIdentity *get_path, | 121 | const struct GNUNET_PeerIdentity *get_path); |
127 | const void *data, | ||
128 | size_t data_size); | ||
129 | 122 | ||
130 | 123 | ||
131 | /** | 124 | /** |
@@ -138,7 +131,7 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | |||
138 | * @return #GNUNET_YES if node location is closest, | 131 | * @return #GNUNET_YES if node location is closest, |
139 | * #GNUNET_NO otherwise. | 132 | * #GNUNET_NO otherwise. |
140 | */ | 133 | */ |
141 | int | 134 | enum GNUNET_GenericReturnValue |
142 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, | 135 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, |
143 | const struct GNUNET_CONTAINER_BloomFilter *bloom); | 136 | const struct GNUNET_CONTAINER_BloomFilter *bloom); |
144 | 137 | ||
@@ -148,7 +141,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
148 | * | 141 | * |
149 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 142 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
150 | */ | 143 | */ |
151 | int | 144 | enum GNUNET_GenericReturnValue |
152 | GDS_NEIGHBOURS_init (void); | 145 | GDS_NEIGHBOURS_init (void); |
153 | 146 | ||
154 | 147 | ||
diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c index 7f411cf71..58f18816a 100644 --- a/src/dht/gnunet-service-dht_nse.c +++ b/src/dht/gnunet-service-dht_nse.c | |||
@@ -52,11 +52,13 @@ static struct GNUNET_NSE_Handle *nse; | |||
52 | * | 52 | * |
53 | */ | 53 | */ |
54 | static void | 54 | static void |
55 | update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp, | 55 | update_network_size_estimate (void *cls, |
56 | double logestimate, double std_dev) | 56 | struct GNUNET_TIME_Absolute timestamp, |
57 | double logestimate, | ||
58 | double std_dev) | ||
57 | { | 59 | { |
58 | GNUNET_STATISTICS_update (GDS_stats, | 60 | GNUNET_STATISTICS_update (GDS_stats, |
59 | gettext_noop ("# Network size estimates received"), | 61 | "# Network size estimates received", |
60 | 1, GNUNET_NO); | 62 | 1, GNUNET_NO); |
61 | /* do not allow estimates < 0.5 */ | 63 | /* do not allow estimates < 0.5 */ |
62 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); | 64 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); |
@@ -83,20 +85,22 @@ GDS_NSE_init () | |||
83 | { | 85 | { |
84 | unsigned long long hops; | 86 | unsigned long long hops; |
85 | 87 | ||
86 | if ((GNUNET_YES == | 88 | if ( (GNUNET_YES == |
87 | GNUNET_CONFIGURATION_have_value (GDS_cfg, | 89 | GNUNET_CONFIGURATION_have_value (GDS_cfg, |
88 | "dht", | 90 | "dht", |
89 | "FORCE_NSE")) && | 91 | "FORCE_NSE")) && |
90 | (GNUNET_OK == | 92 | (GNUNET_OK == |
91 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, | 93 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, |
92 | "dht", | 94 | "dht", |
93 | "FORCE_NSE", | 95 | "FORCE_NSE", |
94 | &hops))) | 96 | &hops)) ) |
95 | { | 97 | { |
96 | log_of_network_size_estimate = (double) hops; | 98 | log_of_network_size_estimate = (double) hops; |
97 | return; | 99 | return; |
98 | } | 100 | } |
99 | nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); | 101 | nse = GNUNET_NSE_connect (GDS_cfg, |
102 | &update_network_size_estimate, | ||
103 | NULL); | ||
100 | } | 104 | } |
101 | 105 | ||
102 | 106 | ||
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index b05fb76d3..ec36eae75 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2011 GNUnet e.V. | 3 | Copyright (C) 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -31,8 +31,9 @@ | |||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Number of requests we track at most (for routing replies). | 33 | * Number of requests we track at most (for routing replies). |
34 | * TODO: make configurable! | ||
34 | */ | 35 | */ |
35 | #define DHT_MAX_RECENT (1024 * 16) | 36 | #define DHT_MAX_RECENT (1024 * 128) |
36 | 37 | ||
37 | 38 | ||
38 | /** | 39 | /** |
@@ -62,11 +63,6 @@ struct RecentRequest | |||
62 | struct GNUNET_BLOCK_Group *bg; | 63 | struct GNUNET_BLOCK_Group *bg; |
63 | 64 | ||
64 | /** | 65 | /** |
65 | * Type of the requested block. | ||
66 | */ | ||
67 | enum GNUNET_BLOCK_Type type; | ||
68 | |||
69 | /** | ||
70 | * extended query (see gnunet_block_lib.h). Allocated at the | 66 | * extended query (see gnunet_block_lib.h). Allocated at the |
71 | * end of this struct. | 67 | * end of this struct. |
72 | */ | 68 | */ |
@@ -78,6 +74,11 @@ struct RecentRequest | |||
78 | size_t xquery_size; | 74 | size_t xquery_size; |
79 | 75 | ||
80 | /** | 76 | /** |
77 | * Type of the requested block. | ||
78 | */ | ||
79 | enum GNUNET_BLOCK_Type type; | ||
80 | |||
81 | /** | ||
81 | * Request options. | 82 | * Request options. |
82 | */ | 83 | */ |
83 | enum GNUNET_DHT_RouteOption options; | 84 | enum GNUNET_DHT_RouteOption options; |
@@ -96,14 +97,14 @@ static struct GNUNET_CONTAINER_MultiHashMap *recent_map; | |||
96 | 97 | ||
97 | 98 | ||
98 | /** | 99 | /** |
99 | * Closure for the 'process' function. | 100 | * Closure for the process() function. |
100 | */ | 101 | */ |
101 | struct ProcessContext | 102 | struct ProcessContext |
102 | { | 103 | { |
103 | /** | 104 | /** |
104 | * Path of the original PUT | 105 | * Block data. |
105 | */ | 106 | */ |
106 | const struct GNUNET_PeerIdentity *put_path; | 107 | const struct GDS_DATACACHE_BlockData *bd; |
107 | 108 | ||
108 | /** | 109 | /** |
109 | * Path of the reply. | 110 | * Path of the reply. |
@@ -111,34 +112,10 @@ struct ProcessContext | |||
111 | const struct GNUNET_PeerIdentity *get_path; | 112 | const struct GNUNET_PeerIdentity *get_path; |
112 | 113 | ||
113 | /** | 114 | /** |
114 | * Payload of the reply. | ||
115 | */ | ||
116 | const void *data; | ||
117 | |||
118 | /** | ||
119 | * Expiration time of the result. | ||
120 | */ | ||
121 | struct GNUNET_TIME_Absolute expiration_time; | ||
122 | |||
123 | /** | ||
124 | * Number of entries in @e put_path. | ||
125 | */ | ||
126 | unsigned int put_path_length; | ||
127 | |||
128 | /** | ||
129 | * Number of entries in @e get_path. | 115 | * Number of entries in @e get_path. |
130 | */ | 116 | */ |
131 | unsigned int get_path_length; | 117 | unsigned int get_path_length; |
132 | 118 | ||
133 | /** | ||
134 | * Number of bytes in @e data. | ||
135 | */ | ||
136 | size_t data_size; | ||
137 | |||
138 | /** | ||
139 | * Type of the reply. | ||
140 | */ | ||
141 | enum GNUNET_BLOCK_Type type; | ||
142 | }; | 119 | }; |
143 | 120 | ||
144 | 121 | ||
@@ -146,132 +123,106 @@ struct ProcessContext | |||
146 | * Forward the result to the given peer if it matches the request. | 123 | * Forward the result to the given peer if it matches the request. |
147 | * | 124 | * |
148 | * @param cls the `struct ProcessContext` with the result | 125 | * @param cls the `struct ProcessContext` with the result |
149 | * @param key the query | 126 | * @param query_hash the hash from the original query |
150 | * @param value the `struct RecentRequest` with the request | 127 | * @param value the `struct RecentRequest` with the request |
151 | * @return #GNUNET_OK (continue to iterate), | 128 | * @return #GNUNET_OK (continue to iterate) |
152 | * #GNUNET_SYSERR if the result is malformed or type unsupported | ||
153 | */ | 129 | */ |
154 | static int | 130 | static enum GNUNET_GenericReturnValue |
155 | process (void *cls, | 131 | process (void *cls, |
156 | const struct GNUNET_HashCode *key, | 132 | const struct GNUNET_HashCode *query_hash, |
157 | void *value) | 133 | void *value) |
158 | { | 134 | { |
159 | struct ProcessContext *pc = cls; | 135 | struct ProcessContext *pc = cls; |
160 | struct RecentRequest *rr = value; | 136 | struct RecentRequest *rr = value; |
161 | enum GNUNET_BLOCK_EvaluationResult eval; | 137 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
162 | unsigned int gpl; | 138 | unsigned int get_path_length; |
163 | unsigned int ppl; | 139 | struct GDS_DATACACHE_BlockData bdx = *pc->bd; |
164 | struct GNUNET_HashCode hc; | ||
165 | const struct GNUNET_HashCode *eval_key; | ||
166 | |||
167 | if ((rr->type != GNUNET_BLOCK_TYPE_ANY) && | ||
168 | (rr->type != pc->type)) | ||
169 | return GNUNET_OK; /* type mismatch */ | ||
170 | 140 | ||
141 | if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) && | ||
142 | (rr->type != pc->bd->type) ) | ||
143 | return GNUNET_OK; /* type mismatch */ | ||
171 | if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) | 144 | if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) |
172 | { | 145 | { |
173 | gpl = pc->get_path_length; | 146 | get_path_length = pc->get_path_length; |
174 | ppl = pc->put_path_length; | ||
175 | } | 147 | } |
176 | else | 148 | else |
177 | { | 149 | { |
178 | gpl = 0; | 150 | get_path_length = 0; |
179 | ppl = 0; | 151 | bdx.put_path_length = 0; |
152 | bdx.put_path = NULL; | ||
180 | } | 153 | } |
181 | if ((0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) && | 154 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) && |
182 | (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO)) | 155 | (0 != GNUNET_memcmp (query_hash, |
156 | &bdx.key)) ) | ||
183 | { | 157 | { |
184 | /* key may not match HELLO, which is OK since | 158 | GNUNET_STATISTICS_update (GDS_stats, |
185 | * the search is approximate. Still, the evaluation | 159 | "# Inexact matches discarded in exact search", |
186 | * would fail since the match is not exact. So | 160 | 1, |
187 | * we fake it by changing the key to the actual PID ... */ | 161 | GNUNET_NO); |
188 | GNUNET_BLOCK_get_key (GDS_block_context, | 162 | return GNUNET_OK; /* exact search, but inexact match */ |
189 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
190 | pc->data, | ||
191 | pc->data_size, | ||
192 | &hc); | ||
193 | eval_key = &hc; | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | eval_key = key; | ||
198 | } | 163 | } |
199 | eval | 164 | eval = GNUNET_BLOCK_check_reply (GDS_block_context, |
200 | = GNUNET_BLOCK_evaluate (GDS_block_context, | 165 | bdx.type, |
201 | pc->type, | 166 | rr->bg, |
202 | rr->bg, | 167 | &bdx.key, |
203 | GNUNET_BLOCK_EO_NONE, | 168 | rr->xquery, |
204 | eval_key, | 169 | rr->xquery_size, |
205 | rr->xquery, | 170 | bdx.data, |
206 | rr->xquery_size, | 171 | bdx.data_size); |
207 | pc->data, | ||
208 | pc->data_size); | ||
209 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
210 | "Result for %s of type %d was evaluated as %d\n", | 173 | "Result for %s of type %d was evaluated as %d\n", |
211 | GNUNET_h2s (key), | 174 | GNUNET_h2s (&bdx.key), |
212 | pc->type, | 175 | bdx.type, |
213 | eval); | 176 | eval); |
214 | switch (eval) | 177 | switch (eval) |
215 | { | 178 | { |
216 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | 179 | case GNUNET_BLOCK_REPLY_OK_MORE: |
217 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | 180 | case GNUNET_BLOCK_REPLY_OK_LAST: |
218 | GNUNET_STATISTICS_update (GDS_stats, | 181 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: |
219 | gettext_noop | 182 | { |
220 | ("# Good REPLIES matched against routing table"), | 183 | struct PeerInfo *pi; |
221 | 1, GNUNET_NO); | 184 | |
222 | GDS_NEIGHBOURS_handle_reply (&rr->peer, | 185 | GNUNET_STATISTICS_update (GDS_stats, |
223 | pc->type, | 186 | "# Good REPLIES matched against routing table", |
224 | pc->expiration_time, | 187 | 1, |
225 | key, | 188 | GNUNET_NO); |
226 | ppl, pc->put_path, | 189 | pi = GDS_NEIGHBOURS_lookup_peer (&rr->peer); |
227 | gpl, pc->get_path, | 190 | if (NULL == pi) |
228 | pc->data, | 191 | { |
229 | pc->data_size); | 192 | /* peer disconnected in the meantime, drop reply */ |
193 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
194 | "No matching peer for reply for key %s\n", | ||
195 | GNUNET_h2s (query_hash)); | ||
196 | return GNUNET_OK; | ||
197 | } | ||
198 | GDS_NEIGHBOURS_handle_reply (pi, | ||
199 | &bdx, | ||
200 | query_hash, | ||
201 | get_path_length, pc->get_path); | ||
202 | } | ||
230 | break; | 203 | break; |
231 | 204 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | |
232 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
233 | GNUNET_STATISTICS_update (GDS_stats, | ||
234 | gettext_noop | ||
235 | ( | ||
236 | "# Duplicate REPLIES matched against routing table"), | ||
237 | 1, GNUNET_NO); | ||
238 | return GNUNET_OK; | ||
239 | |||
240 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
241 | GNUNET_STATISTICS_update (GDS_stats, | 205 | GNUNET_STATISTICS_update (GDS_stats, |
242 | gettext_noop | 206 | "# Duplicate REPLIES matched against routing table", |
243 | ( | 207 | 1, |
244 | "# Invalid REPLIES matched against routing table"), | 208 | GNUNET_NO); |
245 | 1, GNUNET_NO); | ||
246 | return GNUNET_SYSERR; | ||
247 | |||
248 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
249 | GNUNET_STATISTICS_update (GDS_stats, | ||
250 | gettext_noop | ||
251 | ( | ||
252 | "# Irrelevant REPLIES matched against routing table"), | ||
253 | 1, GNUNET_NO); | ||
254 | return GNUNET_OK; | ||
255 | |||
256 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
257 | GNUNET_break (0); | ||
258 | return GNUNET_OK; | 209 | return GNUNET_OK; |
259 | 210 | case GNUNET_BLOCK_REPLY_INVALID: | |
260 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
261 | GNUNET_break (0); | 211 | GNUNET_break (0); |
212 | GNUNET_STATISTICS_update (GDS_stats, | ||
213 | "# Invalid REPLIES matched against routing table", | ||
214 | 1, | ||
215 | GNUNET_NO); | ||
262 | return GNUNET_OK; | 216 | return GNUNET_OK; |
263 | 217 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | |
264 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
265 | GNUNET_STATISTICS_update (GDS_stats, | 218 | GNUNET_STATISTICS_update (GDS_stats, |
266 | gettext_noop | 219 | "# Irrelevant REPLIES matched against routing table", |
267 | ( | 220 | 1, |
268 | "# Unsupported REPLIES matched against routing table"), | 221 | GNUNET_NO); |
269 | 1, GNUNET_NO); | 222 | return GNUNET_OK; |
270 | return GNUNET_SYSERR; | ||
271 | |||
272 | default: | 223 | default: |
273 | GNUNET_break (0); | 224 | GNUNET_break (0); |
274 | return GNUNET_SYSERR; | 225 | return GNUNET_OK; |
275 | } | 226 | } |
276 | return GNUNET_OK; | 227 | return GNUNET_OK; |
277 | } | 228 | } |
@@ -281,52 +232,28 @@ process (void *cls, | |||
281 | * Handle a reply (route to origin). Only forwards the reply back to | 232 | * Handle a reply (route to origin). Only forwards the reply back to |
282 | * other peers waiting for it. Does not do local caching or | 233 | * other peers waiting for it. Does not do local caching or |
283 | * forwarding to local clients. Essentially calls | 234 | * forwarding to local clients. Essentially calls |
284 | * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching | 235 | * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching |
285 | * request recently. | 236 | * request recently. |
286 | * | 237 | * |
287 | * @param type type of the block | 238 | * @param bd block details |
288 | * @param expiration_time when does the content expire | 239 | * @param query_hash query used in the inquiry |
289 | * @param key key for the content | ||
290 | * @param put_path_length number of entries in @a put_path | ||
291 | * @param put_path peers the original PUT traversed (if tracked) | ||
292 | * @param get_path_length number of entries in @a get_path | 240 | * @param get_path_length number of entries in @a get_path |
293 | * @param get_path peers this reply has traversed so far (if tracked) | 241 | * @param get_path peers this reply has traversed so far (if tracked) |
294 | * @param data payload of the reply | ||
295 | * @param data_size number of bytes in data | ||
296 | */ | 242 | */ |
297 | void | 243 | void |
298 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 244 | GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, |
299 | struct GNUNET_TIME_Absolute expiration_time, | 245 | const struct GNUNET_HashCode *query_hash, |
300 | const struct GNUNET_HashCode *key, | ||
301 | unsigned int put_path_length, | ||
302 | const struct GNUNET_PeerIdentity *put_path, | ||
303 | unsigned int get_path_length, | 246 | unsigned int get_path_length, |
304 | const struct GNUNET_PeerIdentity *get_path, | 247 | const struct GNUNET_PeerIdentity *get_path) |
305 | const void *data, | ||
306 | size_t data_size) | ||
307 | { | 248 | { |
308 | struct ProcessContext pc; | 249 | struct ProcessContext pc = { |
309 | 250 | .bd = bd, | |
310 | pc.type = type; | 251 | .get_path = get_path, |
311 | pc.expiration_time = expiration_time; | 252 | .get_path_length = get_path_length |
312 | pc.put_path_length = put_path_length; | 253 | }; |
313 | pc.put_path = put_path; | 254 | |
314 | pc.get_path_length = get_path_length; | ||
315 | pc.get_path = get_path; | ||
316 | pc.data = data; | ||
317 | pc.data_size = data_size; | ||
318 | if (NULL == data) | ||
319 | { | ||
320 | /* Some apps might have an 'empty' reply as a valid reply; however, | ||
321 | 'process' will call GNUNET_BLOCK_evaluate' which treats a 'NULL' | ||
322 | reply as request-validation (but we need response-validation). | ||
323 | So we set 'data' to a 0-byte non-NULL value just to be sure */ | ||
324 | GNUNET_break (0 == data_size); | ||
325 | pc.data_size = 0; | ||
326 | pc.data = ""; /* something not null */ | ||
327 | } | ||
328 | GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, | 255 | GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, |
329 | key, | 256 | query_hash, |
330 | &process, | 257 | &process, |
331 | &pc); | 258 | &pc); |
332 | } | 259 | } |
@@ -338,13 +265,13 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | |||
338 | * in the heap and hashmap. | 265 | * in the heap and hashmap. |
339 | */ | 266 | */ |
340 | static void | 267 | static void |
341 | expire_oldest_entry () | 268 | expire_oldest_entry (void) |
342 | { | 269 | { |
343 | struct RecentRequest *recent_req; | 270 | struct RecentRequest *recent_req; |
344 | 271 | ||
345 | GNUNET_STATISTICS_update (GDS_stats, | 272 | GNUNET_STATISTICS_update (GDS_stats, |
346 | gettext_noop | 273 | "# Old entries removed from routing table", |
347 | ("# Entries removed from routing table"), 1, | 274 | 1, |
348 | GNUNET_NO); | 275 | GNUNET_NO); |
349 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); | 276 | recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); |
350 | GNUNET_assert (recent_req != NULL); | 277 | GNUNET_assert (recent_req != NULL); |
@@ -362,13 +289,13 @@ expire_oldest_entry () | |||
362 | * Try to combine multiple recent requests for the same value | 289 | * Try to combine multiple recent requests for the same value |
363 | * (if they come from the same peer). | 290 | * (if they come from the same peer). |
364 | * | 291 | * |
365 | * @param cls the new 'struct RecentRequest' (to discard upon successful combination) | 292 | * @param cls the new `struct RecentRequest` (to discard upon successful combination) |
366 | * @param key the query | 293 | * @param key the query |
367 | * @param value the existing 'struct RecentRequest' (to update upon successful combination) | 294 | * @param value the existing `struct RecentRequest` (to update upon successful combination) |
368 | * @return #GNUNET_OK (continue to iterate), | 295 | * @return #GNUNET_OK (continue to iterate), |
369 | * #GNUNET_SYSERR if the request was successfully combined | 296 | * #GNUNET_SYSERR if the request was successfully combined |
370 | */ | 297 | */ |
371 | static int | 298 | static enum GNUNET_GenericReturnValue |
372 | try_combine_recent (void *cls, | 299 | try_combine_recent (void *cls, |
373 | const struct GNUNET_HashCode *key, | 300 | const struct GNUNET_HashCode *key, |
374 | void *value) | 301 | void *value) |
@@ -376,13 +303,13 @@ try_combine_recent (void *cls, | |||
376 | struct RecentRequest *in = cls; | 303 | struct RecentRequest *in = cls; |
377 | struct RecentRequest *rr = value; | 304 | struct RecentRequest *rr = value; |
378 | 305 | ||
379 | if ((0 != GNUNET_memcmp (&in->peer, | 306 | if ( (0 != GNUNET_memcmp (&in->peer, |
380 | &rr->peer)) || | 307 | &rr->peer)) || |
381 | (in->type != rr->type) || | 308 | (in->type != rr->type) || |
382 | (in->xquery_size != rr->xquery_size) || | 309 | (in->xquery_size != rr->xquery_size) || |
383 | (0 != memcmp (in->xquery, | 310 | (0 != memcmp (in->xquery, |
384 | rr->xquery, | 311 | rr->xquery, |
385 | in->xquery_size))) | 312 | in->xquery_size) ) ) |
386 | return GNUNET_OK; | 313 | return GNUNET_OK; |
387 | GNUNET_break (GNUNET_SYSERR != | 314 | GNUNET_break (GNUNET_SYSERR != |
388 | GNUNET_BLOCK_group_merge (in->bg, | 315 | GNUNET_BLOCK_group_merge (in->bg, |
@@ -419,7 +346,7 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, | |||
419 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) | 346 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) |
420 | expire_oldest_entry (); | 347 | expire_oldest_entry (); |
421 | GNUNET_STATISTICS_update (GDS_stats, | 348 | GNUNET_STATISTICS_update (GDS_stats, |
422 | gettext_noop ("# Entries added to routing table"), | 349 | "# Entries added to routing table", |
423 | 1, | 350 | 1, |
424 | GNUNET_NO); | 351 | GNUNET_NO); |
425 | recent_req = GNUNET_malloc (sizeof(struct RecentRequest) + xquery_size); | 352 | recent_req = GNUNET_malloc (sizeof(struct RecentRequest) + xquery_size); |
@@ -440,19 +367,21 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, | |||
440 | recent_req)) | 367 | recent_req)) |
441 | { | 368 | { |
442 | GNUNET_STATISTICS_update (GDS_stats, | 369 | GNUNET_STATISTICS_update (GDS_stats, |
443 | gettext_noop | 370 | "# DHT requests combined", |
444 | ("# DHT requests combined"), | 371 | 1, |
445 | 1, GNUNET_NO); | 372 | GNUNET_NO); |
446 | return; | 373 | return; |
447 | } | 374 | } |
448 | recent_req->heap_node | 375 | recent_req->heap_node |
449 | = GNUNET_CONTAINER_heap_insert (recent_heap, | 376 | = GNUNET_CONTAINER_heap_insert ( |
450 | recent_req, | 377 | recent_heap, |
451 | GNUNET_TIME_absolute_get ().abs_value_us); | 378 | recent_req, |
452 | GNUNET_CONTAINER_multihashmap_put (recent_map, | 379 | GNUNET_TIME_absolute_get ().abs_value_us); |
453 | key, | 380 | (void) GNUNET_CONTAINER_multihashmap_put ( |
454 | recent_req, | 381 | recent_map, |
455 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 382 | key, |
383 | recent_req, | ||
384 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
456 | } | 385 | } |
457 | 386 | ||
458 | 387 | ||
@@ -476,10 +405,12 @@ GDS_ROUTING_done () | |||
476 | { | 405 | { |
477 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) | 406 | while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) |
478 | expire_oldest_entry (); | 407 | expire_oldest_entry (); |
479 | GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap)); | 408 | GNUNET_assert (0 == |
409 | GNUNET_CONTAINER_heap_get_size (recent_heap)); | ||
480 | GNUNET_CONTAINER_heap_destroy (recent_heap); | 410 | GNUNET_CONTAINER_heap_destroy (recent_heap); |
481 | recent_heap = NULL; | 411 | recent_heap = NULL; |
482 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent_map)); | 412 | GNUNET_assert (0 == |
413 | GNUNET_CONTAINER_multihashmap_size (recent_map)); | ||
483 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); | 414 | GNUNET_CONTAINER_multihashmap_destroy (recent_map); |
484 | recent_map = NULL; | 415 | recent_map = NULL; |
485 | } | 416 | } |
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 7fea01bae..1a1514cc5 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2011 GNUnet e.V. | 3 | Copyright (C) 2011, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -35,29 +35,19 @@ | |||
35 | * Handle a reply (route to origin). Only forwards the reply back to | 35 | * Handle a reply (route to origin). Only forwards the reply back to |
36 | * other peers waiting for it. Does not do local caching or | 36 | * other peers waiting for it. Does not do local caching or |
37 | * forwarding to local clients. Essentially calls | 37 | * forwarding to local clients. Essentially calls |
38 | * #GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching | 38 | * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching |
39 | * request recently. | 39 | * request recently. |
40 | * | 40 | * |
41 | * @param type type of the block | 41 | * @param bd block details |
42 | * @param expiration_time when does the content expire | 42 | * @param query_hash query used in the inquiry |
43 | * @param key key for the content | ||
44 | * @param put_path_length number of entries in @a put_path | ||
45 | * @param put_path peers the original PUT traversed (if tracked) | ||
46 | * @param get_path_length number of entries in @a get_path | 43 | * @param get_path_length number of entries in @a get_path |
47 | * @param get_path peers this reply has traversed so far (if tracked) | 44 | * @param get_path peers this reply has traversed so far (if tracked) |
48 | * @param data payload of the reply | ||
49 | * @param data_size number of bytes in @a data | ||
50 | */ | 45 | */ |
51 | void | 46 | void |
52 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 47 | GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd, |
53 | struct GNUNET_TIME_Absolute expiration_time, | 48 | const struct GNUNET_HashCode *query_hash, |
54 | const struct GNUNET_HashCode *key, | ||
55 | unsigned int put_path_length, | ||
56 | const struct GNUNET_PeerIdentity *put_path, | ||
57 | unsigned int get_path_length, | 49 | unsigned int get_path_length, |
58 | const struct GNUNET_PeerIdentity *get_path, | 50 | const struct GNUNET_PeerIdentity *get_path); |
59 | const void *data, | ||
60 | size_t data_size); | ||
61 | 51 | ||
62 | 52 | ||
63 | /** | 53 | /** |
diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index a9f336240..7c6fb9ed6 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c | |||
@@ -159,6 +159,145 @@ block_plugin_dht_evaluate (void *cls, | |||
159 | 159 | ||
160 | 160 | ||
161 | /** | 161 | /** |
162 | * Function called to validate a query. | ||
163 | * | ||
164 | * @param cls closure | ||
165 | * @param ctx block context | ||
166 | * @param type block type | ||
167 | * @param query original query (hash) | ||
168 | * @param xquery extrended query data (can be NULL, depending on type) | ||
169 | * @param xquery_size number of bytes in @a xquery | ||
170 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
171 | */ | ||
172 | static enum GNUNET_GenericReturnValue | ||
173 | block_plugin_dht_check_query (void *cls, | ||
174 | enum GNUNET_BLOCK_Type type, | ||
175 | const struct GNUNET_HashCode *query, | ||
176 | const void *xquery, | ||
177 | size_t xquery_size) | ||
178 | { | ||
179 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | ||
180 | return GNUNET_SYSERR; | ||
181 | if (0 != xquery_size) | ||
182 | { | ||
183 | GNUNET_break_op (0); | ||
184 | return GNUNET_NO; | ||
185 | } | ||
186 | return GNUNET_OK; | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Function called to validate a block for storage. | ||
192 | * | ||
193 | * @param cls closure | ||
194 | * @param type block type | ||
195 | * @param query key for the block (hash), must match exactly | ||
196 | * @param block block data to validate | ||
197 | * @param block_size number of bytes in @a block | ||
198 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
199 | */ | ||
200 | static enum GNUNET_GenericReturnValue | ||
201 | block_plugin_dht_check_block (void *cls, | ||
202 | enum GNUNET_BLOCK_Type type, | ||
203 | const struct GNUNET_HashCode *query, | ||
204 | const void *block, | ||
205 | size_t block_size) | ||
206 | { | ||
207 | const struct GNUNET_HELLO_Message *hello; | ||
208 | struct GNUNET_PeerIdentity pid; | ||
209 | const struct GNUNET_MessageHeader *msg; | ||
210 | |||
211 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | ||
212 | return GNUNET_SYSERR; | ||
213 | if (block_size < sizeof(struct GNUNET_MessageHeader)) | ||
214 | { | ||
215 | GNUNET_break_op (0); | ||
216 | return GNUNET_NO; | ||
217 | } | ||
218 | msg = block; | ||
219 | if (block_size != ntohs (msg->size)) | ||
220 | { | ||
221 | GNUNET_break_op (0); | ||
222 | return GNUNET_NO; | ||
223 | } | ||
224 | hello = block; | ||
225 | if (GNUNET_OK != | ||
226 | GNUNET_HELLO_get_id (hello, | ||
227 | &pid)) | ||
228 | { | ||
229 | GNUNET_break_op (0); | ||
230 | return GNUNET_NO; | ||
231 | } | ||
232 | return GNUNET_OK; | ||
233 | } | ||
234 | |||
235 | |||
236 | /** | ||
237 | * Function called to validate a reply to a request. Note that it is assumed | ||
238 | * that the reply has already been matched to the key (and signatures checked) | ||
239 | * as it would be done with the GetKeyFunction and the | ||
240 | * BlockEvaluationFunction. | ||
241 | * | ||
242 | * @param cls closure | ||
243 | * @param type block type | ||
244 | * @param group which block group to use for evaluation | ||
245 | * @param query original query (hash) | ||
246 | * @param xquery extrended query data (can be NULL, depending on type) | ||
247 | * @param xquery_size number of bytes in @a xquery | ||
248 | * @param reply_block response to validate | ||
249 | * @param reply_block_size number of bytes in @a reply_block | ||
250 | * @return characterization of result | ||
251 | */ | ||
252 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
253 | block_plugin_dht_check_reply ( | ||
254 | void *cls, | ||
255 | enum GNUNET_BLOCK_Type type, | ||
256 | struct GNUNET_BLOCK_Group *group, | ||
257 | const struct GNUNET_HashCode *query, | ||
258 | const void *xquery, | ||
259 | size_t xquery_size, | ||
260 | const void *reply_block, | ||
261 | size_t reply_block_size) | ||
262 | { | ||
263 | const struct GNUNET_HELLO_Message *hello; | ||
264 | struct GNUNET_PeerIdentity pid; | ||
265 | const struct GNUNET_MessageHeader *msg; | ||
266 | struct GNUNET_HashCode phash; | ||
267 | |||
268 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | ||
269 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
270 | if (reply_block_size < sizeof(struct GNUNET_MessageHeader)) | ||
271 | { | ||
272 | GNUNET_break_op (0); | ||
273 | return GNUNET_BLOCK_REPLY_INVALID; | ||
274 | } | ||
275 | msg = reply_block; | ||
276 | if (reply_block_size != ntohs (msg->size)) | ||
277 | { | ||
278 | GNUNET_break_op (0); | ||
279 | return GNUNET_BLOCK_REPLY_INVALID; | ||
280 | } | ||
281 | hello = reply_block; | ||
282 | if (GNUNET_OK != | ||
283 | GNUNET_HELLO_get_id (hello, | ||
284 | &pid)) | ||
285 | { | ||
286 | GNUNET_break_op (0); | ||
287 | return GNUNET_BLOCK_REPLY_INVALID; | ||
288 | } | ||
289 | GNUNET_CRYPTO_hash (&pid, | ||
290 | sizeof(pid), | ||
291 | &phash); | ||
292 | if (GNUNET_YES == | ||
293 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
294 | &phash)) | ||
295 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
296 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
297 | } | ||
298 | |||
299 | |||
300 | /** | ||
162 | * Function called to obtain the key for a block. | 301 | * Function called to obtain the key for a block. |
163 | * | 302 | * |
164 | * @param cls closure | 303 | * @param cls closure |
@@ -169,7 +308,7 @@ block_plugin_dht_evaluate (void *cls, | |||
169 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 308 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
170 | * (or if extracting a key from a block of this type does not work) | 309 | * (or if extracting a key from a block of this type does not work) |
171 | */ | 310 | */ |
172 | static int | 311 | static enum GNUNET_GenericReturnValue |
173 | block_plugin_dht_get_key (void *cls, | 312 | block_plugin_dht_get_key (void *cls, |
174 | enum GNUNET_BLOCK_Type type, | 313 | enum GNUNET_BLOCK_Type type, |
175 | const void *block, | 314 | const void *block, |
@@ -229,6 +368,9 @@ libgnunet_plugin_block_dht_init (void *cls) | |||
229 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 368 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
230 | api->evaluate = &block_plugin_dht_evaluate; | 369 | api->evaluate = &block_plugin_dht_evaluate; |
231 | api->get_key = &block_plugin_dht_get_key; | 370 | api->get_key = &block_plugin_dht_get_key; |
371 | api->check_query = &block_plugin_dht_check_query; | ||
372 | api->check_block = &block_plugin_dht_check_block; | ||
373 | api->check_reply = &block_plugin_dht_check_reply; | ||
232 | api->create_group = &block_plugin_dht_create_group; | 374 | api->create_group = &block_plugin_dht_create_group; |
233 | api->types = types; | 375 | api->types = types; |
234 | return api; | 376 | return api; |
diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c index e0beccb52..d3eb7d2b9 100644 --- a/src/dns/plugin_block_dns.c +++ b/src/dns/plugin_block_dns.c | |||
@@ -177,6 +177,141 @@ block_plugin_dns_evaluate (void *cls, | |||
177 | 177 | ||
178 | 178 | ||
179 | /** | 179 | /** |
180 | * Function called to validate a query. | ||
181 | * | ||
182 | * @param cls closure | ||
183 | * @param ctx block context | ||
184 | * @param type block type | ||
185 | * @param query original query (hash) | ||
186 | * @param xquery extrended query data (can be NULL, depending on type) | ||
187 | * @param xquery_size number of bytes in @a xquery | ||
188 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
189 | */ | ||
190 | static enum GNUNET_GenericReturnValue | ||
191 | block_plugin_dns_check_query (void *cls, | ||
192 | enum GNUNET_BLOCK_Type type, | ||
193 | const struct GNUNET_HashCode *query, | ||
194 | const void *xquery, | ||
195 | size_t xquery_size) | ||
196 | { | ||
197 | switch (type) | ||
198 | { | ||
199 | case GNUNET_BLOCK_TYPE_DNS: | ||
200 | if (0 != xquery_size) | ||
201 | return GNUNET_NO; | ||
202 | return GNUNET_OK; | ||
203 | default: | ||
204 | return GNUNET_SYSERR; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Function called to validate a block for storage. | ||
211 | * | ||
212 | * @param cls closure | ||
213 | * @param type block type | ||
214 | * @param query key for the block (hash), must match exactly | ||
215 | * @param block block data to validate | ||
216 | * @param block_size number of bytes in @a block | ||
217 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
218 | */ | ||
219 | static enum GNUNET_GenericReturnValue | ||
220 | block_plugin_dns_check_block (void *cls, | ||
221 | enum GNUNET_BLOCK_Type type, | ||
222 | const struct GNUNET_HashCode *query, | ||
223 | const void *block, | ||
224 | size_t block_size) | ||
225 | { | ||
226 | const struct GNUNET_DNS_Advertisement *ad; | ||
227 | |||
228 | switch (type) | ||
229 | { | ||
230 | case GNUNET_BLOCK_TYPE_DNS: | ||
231 | if (sizeof(struct GNUNET_DNS_Advertisement) != block_size) | ||
232 | { | ||
233 | GNUNET_break_op (0); | ||
234 | return GNUNET_NO; | ||
235 | } | ||
236 | ad = block; | ||
237 | |||
238 | if (ntohl (ad->purpose.size) != | ||
239 | sizeof(struct GNUNET_DNS_Advertisement) | ||
240 | - sizeof(struct GNUNET_CRYPTO_EddsaSignature)) | ||
241 | { | ||
242 | GNUNET_break_op (0); | ||
243 | return GNUNET_NO; | ||
244 | } | ||
245 | if (GNUNET_TIME_absolute_is_past ( | ||
246 | GNUNET_TIME_absolute_ntoh (ad->expiration_time))) | ||
247 | { | ||
248 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
249 | "DNS advertisement has expired\n"); | ||
250 | return GNUNET_NO; | ||
251 | } | ||
252 | if (GNUNET_OK != | ||
253 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, | ||
254 | &ad->purpose, | ||
255 | &ad->signature, | ||
256 | &ad->peer.public_key)) | ||
257 | { | ||
258 | GNUNET_break_op (0); | ||
259 | return GNUNET_NO; | ||
260 | } | ||
261 | return GNUNET_OK; | ||
262 | default: | ||
263 | return GNUNET_SYSERR; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Function called to validate a reply to a request. Note that it is assumed | ||
270 | * that the reply has already been matched to the key (and signatures checked) | ||
271 | * as it would be done with the GetKeyFunction and the | ||
272 | * BlockEvaluationFunction. | ||
273 | * | ||
274 | * @param cls closure | ||
275 | * @param type block type | ||
276 | * @param group which block group to use for evaluation | ||
277 | * @param query original query (hash) | ||
278 | * @param xquery extrended query data (can be NULL, depending on type) | ||
279 | * @param xquery_size number of bytes in @a xquery | ||
280 | * @param reply_block response to validate | ||
281 | * @param reply_block_size number of bytes in @a reply_block | ||
282 | * @return characterization of result | ||
283 | */ | ||
284 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
285 | block_plugin_dns_check_reply ( | ||
286 | void *cls, | ||
287 | enum GNUNET_BLOCK_Type type, | ||
288 | struct GNUNET_BLOCK_Group *group, | ||
289 | const struct GNUNET_HashCode *query, | ||
290 | const void *xquery, | ||
291 | size_t xquery_size, | ||
292 | const void *reply_block, | ||
293 | size_t reply_block_size) | ||
294 | { | ||
295 | struct GNUNET_HashCode phash; | ||
296 | |||
297 | switch (type) | ||
298 | { | ||
299 | case GNUNET_BLOCK_TYPE_DNS: | ||
300 | GNUNET_CRYPTO_hash (reply_block, | ||
301 | reply_block_size, | ||
302 | &phash); | ||
303 | if (GNUNET_YES == | ||
304 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
305 | &phash)) | ||
306 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
307 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
308 | default: | ||
309 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | |||
314 | /** | ||
180 | * Function called to obtain the key for a block. | 315 | * Function called to obtain the key for a block. |
181 | * | 316 | * |
182 | * @param cls closure | 317 | * @param cls closure |
@@ -187,7 +322,7 @@ block_plugin_dns_evaluate (void *cls, | |||
187 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 322 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
188 | * (or if extracting a key from a block of this type does not work) | 323 | * (or if extracting a key from a block of this type does not work) |
189 | */ | 324 | */ |
190 | static int | 325 | static enum GNUNET_GenericReturnValue |
191 | block_plugin_dns_get_key (void *cls, | 326 | block_plugin_dns_get_key (void *cls, |
192 | enum GNUNET_BLOCK_Type type, | 327 | enum GNUNET_BLOCK_Type type, |
193 | const void *block, | 328 | const void *block, |
@@ -214,6 +349,9 @@ libgnunet_plugin_block_dns_init (void *cls) | |||
214 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 349 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
215 | api->evaluate = &block_plugin_dns_evaluate; | 350 | api->evaluate = &block_plugin_dns_evaluate; |
216 | api->get_key = &block_plugin_dns_get_key; | 351 | api->get_key = &block_plugin_dns_get_key; |
352 | api->check_query = &block_plugin_dns_check_query; | ||
353 | api->check_block = &block_plugin_dns_check_block; | ||
354 | api->check_reply = &block_plugin_dns_check_reply; | ||
217 | api->create_group = &block_plugin_dns_create_group; | 355 | api->create_group = &block_plugin_dns_create_group; |
218 | api->types = types; | 356 | api->types = types; |
219 | return api; | 357 | return api; |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index e90ba4c8b..8c6c39885 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -395,7 +395,7 @@ client_request_destroy (void *cls) | |||
395 | */ | 395 | */ |
396 | static void | 396 | static void |
397 | client_response_handler (void *cls, | 397 | client_response_handler (void *cls, |
398 | enum GNUNET_BLOCK_EvaluationResult eval, | 398 | enum GNUNET_BLOCK_ReplyEvaluationResult eval, |
399 | struct GSF_PendingRequest *pr, | 399 | struct GSF_PendingRequest *pr, |
400 | uint32_t reply_anonymity_level, | 400 | uint32_t reply_anonymity_level, |
401 | struct GNUNET_TIME_Absolute expiration, | 401 | struct GNUNET_TIME_Absolute expiration, |
@@ -447,7 +447,7 @@ client_response_handler (void *cls, | |||
447 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 447 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
448 | "Queued reply to query `%s' for local client\n", | 448 | "Queued reply to query `%s' for local client\n", |
449 | GNUNET_h2s (&prd->query)); | 449 | GNUNET_h2s (&prd->query)); |
450 | if (GNUNET_BLOCK_EVALUATION_OK_LAST != eval) | 450 | if (GNUNET_BLOCK_REPLY_OK_LAST != eval) |
451 | { | 451 | { |
452 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 452 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
453 | "Evaluation %d - keeping query alive\n", | 453 | "Evaluation %d - keeping query alive\n", |
@@ -668,9 +668,9 @@ consider_request_for_forwarding (void *cls, | |||
668 | void | 668 | void |
669 | GSF_consider_forwarding (void *cls, | 669 | GSF_consider_forwarding (void *cls, |
670 | struct GSF_PendingRequest *pr, | 670 | struct GSF_PendingRequest *pr, |
671 | enum GNUNET_BLOCK_EvaluationResult result) | 671 | enum GNUNET_BLOCK_ReplyEvaluationResult result) |
672 | { | 672 | { |
673 | if (GNUNET_BLOCK_EVALUATION_OK_LAST == result) | 673 | if (GNUNET_BLOCK_REPLY_OK_LAST == result) |
674 | return; /* we're done... */ | 674 | return; /* we're done... */ |
675 | if (GNUNET_YES != | 675 | if (GNUNET_YES != |
676 | GSF_pending_request_test_active_ (pr)) | 676 | GSF_pending_request_test_active_ (pr)) |
@@ -737,13 +737,13 @@ check_p2p_get (void *cls, | |||
737 | static void | 737 | static void |
738 | start_p2p_processing (void *cls, | 738 | start_p2p_processing (void *cls, |
739 | struct GSF_PendingRequest *pr, | 739 | struct GSF_PendingRequest *pr, |
740 | enum GNUNET_BLOCK_EvaluationResult result) | 740 | enum GNUNET_BLOCK_ReplyEvaluationResult result) |
741 | { | 741 | { |
742 | struct GSF_LocalClient *lc = cls; | 742 | struct GSF_LocalClient *lc = cls; |
743 | struct GSF_PendingRequestData *prd; | 743 | struct GSF_PendingRequestData *prd; |
744 | 744 | ||
745 | GNUNET_SERVICE_client_continue (lc->client); | 745 | GNUNET_SERVICE_client_continue (lc->client); |
746 | if (GNUNET_BLOCK_EVALUATION_OK_LAST == result) | 746 | if (GNUNET_BLOCK_REPLY_OK_LAST == result) |
747 | return; /* we're done, 'pr' was already destroyed... */ | 747 | return; /* we're done, 'pr' was already destroyed... */ |
748 | prd = GSF_pending_request_get_data_ (pr); | 748 | prd = GSF_pending_request_get_data_ (pr); |
749 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 749 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/fs/gnunet-service-fs.h b/src/fs/gnunet-service-fs.h index 9c87115ed..a6b73db09 100644 --- a/src/fs/gnunet-service-fs.h +++ b/src/fs/gnunet-service-fs.h | |||
@@ -280,7 +280,7 @@ extern unsigned int GSF_datastore_queue_size; | |||
280 | void | 280 | void |
281 | GSF_consider_forwarding (void *cls, | 281 | GSF_consider_forwarding (void *cls, |
282 | struct GSF_PendingRequest *pr, | 282 | struct GSF_PendingRequest *pr, |
283 | enum GNUNET_BLOCK_EvaluationResult result); | 283 | enum GNUNET_BLOCK_ReplyEvaluationResult result); |
284 | 284 | ||
285 | 285 | ||
286 | /** | 286 | /** |
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index c174ad611..5476aa2be 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c | |||
@@ -836,7 +836,7 @@ get_randomized_delay () | |||
836 | */ | 836 | */ |
837 | static void | 837 | static void |
838 | handle_p2p_reply (void *cls, | 838 | handle_p2p_reply (void *cls, |
839 | enum GNUNET_BLOCK_EvaluationResult eval, | 839 | enum GNUNET_BLOCK_ReplyEvaluationResult eval, |
840 | struct GSF_PendingRequest *pr, | 840 | struct GSF_PendingRequest *pr, |
841 | uint32_t reply_anonymity_level, | 841 | uint32_t reply_anonymity_level, |
842 | struct GNUNET_TIME_Absolute expiration, | 842 | struct GNUNET_TIME_Absolute expiration, |
@@ -862,11 +862,11 @@ handle_p2p_reply (void *cls, | |||
862 | return; | 862 | return; |
863 | } | 863 | } |
864 | GNUNET_break (GNUNET_BLOCK_TYPE_ANY != type); | 864 | GNUNET_break (GNUNET_BLOCK_TYPE_ANY != type); |
865 | if ((prd->type != type) && (GNUNET_BLOCK_TYPE_ANY != prd->type)) | 865 | if ( (prd->type != type) && |
866 | (GNUNET_BLOCK_TYPE_ANY != prd->type) ) | ||
866 | { | 867 | { |
867 | GNUNET_STATISTICS_update (GSF_stats, | 868 | GNUNET_STATISTICS_update (GSF_stats, |
868 | gettext_noop | 869 | "# replies dropped due to type mismatch", |
869 | ("# replies dropped due to type mismatch"), | ||
870 | 1, GNUNET_NO); | 870 | 1, GNUNET_NO); |
871 | return; | 871 | return; |
872 | } | 872 | } |
@@ -874,22 +874,22 @@ handle_p2p_reply (void *cls, | |||
874 | "Transmitting result for query `%s' to peer\n", | 874 | "Transmitting result for query `%s' to peer\n", |
875 | GNUNET_h2s (&prd->query)); | 875 | GNUNET_h2s (&prd->query)); |
876 | GNUNET_STATISTICS_update (GSF_stats, | 876 | GNUNET_STATISTICS_update (GSF_stats, |
877 | gettext_noop ("# replies received for other peers"), | 877 | "# replies received for other peers", |
878 | 1, GNUNET_NO); | 878 | 1, |
879 | GNUNET_NO); | ||
879 | msize = sizeof(struct PutMessage) + data_len; | 880 | msize = sizeof(struct PutMessage) + data_len; |
880 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) | 881 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) |
881 | { | 882 | { |
882 | GNUNET_break (0); | 883 | GNUNET_break (0); |
883 | return; | 884 | return; |
884 | } | 885 | } |
885 | if ((UINT32_MAX != reply_anonymity_level) && (reply_anonymity_level > 1)) | 886 | if ( (UINT32_MAX != reply_anonymity_level) && |
887 | (reply_anonymity_level > 1) ) | ||
886 | { | 888 | { |
887 | if (reply_anonymity_level - 1 > GSF_cover_content_count) | 889 | if (reply_anonymity_level - 1 > GSF_cover_content_count) |
888 | { | 890 | { |
889 | GNUNET_STATISTICS_update (GSF_stats, | 891 | GNUNET_STATISTICS_update (GSF_stats, |
890 | gettext_noop | 892 | "# replies dropped due to insufficient cover traffic", |
891 | ( | ||
892 | "# replies dropped due to insufficient cover traffic"), | ||
893 | 1, GNUNET_NO); | 893 | 1, GNUNET_NO); |
894 | return; | 894 | return; |
895 | } | 895 | } |
@@ -930,14 +930,12 @@ handle_p2p_reply (void *cls, | |||
930 | UINT32_MAX, | 930 | UINT32_MAX, |
931 | env); | 931 | env); |
932 | } | 932 | } |
933 | if (GNUNET_BLOCK_EVALUATION_OK_LAST != eval) | 933 | if (GNUNET_BLOCK_REPLY_OK_LAST != eval) |
934 | return; | 934 | return; |
935 | if (NULL == peerreq->kill_task) | 935 | if (NULL == peerreq->kill_task) |
936 | { | 936 | { |
937 | GNUNET_STATISTICS_update (GSF_stats, | 937 | GNUNET_STATISTICS_update (GSF_stats, |
938 | gettext_noop | 938 | "# P2P searches destroyed due to ultimate reply", |
939 | ( | ||
940 | "# P2P searches destroyed due to ultimate reply"), | ||
941 | 1, | 939 | 1, |
942 | GNUNET_NO); | 940 | GNUNET_NO); |
943 | peerreq->kill_task = | 941 | peerreq->kill_task = |
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index a5db4b6b7..c3fe5ff58 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c | |||
@@ -135,7 +135,7 @@ struct GSF_PendingRequest | |||
135 | /** | 135 | /** |
136 | * Last result from the local datastore lookup evaluation. | 136 | * Last result from the local datastore lookup evaluation. |
137 | */ | 137 | */ |
138 | enum GNUNET_BLOCK_EvaluationResult local_result; | 138 | enum GNUNET_BLOCK_ReplyEvaluationResult local_result; |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * Identity of the peer that we should use for the 'sender' | 141 | * Identity of the peer that we should use for the 'sender' |
@@ -619,7 +619,9 @@ clean_request (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
619 | if (NULL != (cont = pr->llc_cont)) | 619 | if (NULL != (cont = pr->llc_cont)) |
620 | { | 620 | { |
621 | pr->llc_cont = NULL; | 621 | pr->llc_cont = NULL; |
622 | cont (pr->llc_cont_cls, pr, pr->local_result); | 622 | cont (pr->llc_cont_cls, |
623 | pr, | ||
624 | pr->local_result); | ||
623 | } | 625 | } |
624 | GSF_plan_notify_request_done_ (pr); | 626 | GSF_plan_notify_request_done_ (pr); |
625 | GNUNET_free (pr->replies_seen); | 627 | GNUNET_free (pr->replies_seen); |
@@ -689,7 +691,9 @@ GSF_pending_request_cancel_ (struct GSF_PendingRequest *pr, int full_cleanup) | |||
689 | if (NULL != (cont = pr->llc_cont)) | 691 | if (NULL != (cont = pr->llc_cont)) |
690 | { | 692 | { |
691 | pr->llc_cont = NULL; | 693 | pr->llc_cont = NULL; |
692 | cont (pr->llc_cont_cls, pr, pr->local_result); | 694 | cont (pr->llc_cont_cls, |
695 | pr, | ||
696 | pr->local_result); | ||
693 | } | 697 | } |
694 | GSF_plan_notify_request_done_ (pr); | 698 | GSF_plan_notify_request_done_ (pr); |
695 | if (NULL != pr->qe) | 699 | if (NULL != pr->qe) |
@@ -778,7 +782,7 @@ struct ProcessReplyClosure | |||
778 | /** | 782 | /** |
779 | * Evaluation result (returned). | 783 | * Evaluation result (returned). |
780 | */ | 784 | */ |
781 | enum GNUNET_BLOCK_EvaluationResult eval; | 785 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
782 | 786 | ||
783 | /** | 787 | /** |
784 | * Did we find a matching request? | 788 | * Did we find a matching request? |
@@ -814,8 +818,10 @@ update_request_performance_data (struct ProcessReplyClosure *prq, | |||
814 | * @param value value in the hash map (info about the query) | 818 | * @param value value in the hash map (info about the query) |
815 | * @return #GNUNET_YES (we should continue to iterate) | 819 | * @return #GNUNET_YES (we should continue to iterate) |
816 | */ | 820 | */ |
817 | static int | 821 | static enum GNUNET_GenericReturnValue |
818 | process_reply (void *cls, const struct GNUNET_HashCode *key, void *value) | 822 | process_reply (void *cls, |
823 | const struct GNUNET_HashCode *key, | ||
824 | void *value) | ||
819 | { | 825 | { |
820 | struct ProcessReplyClosure *prq = cls; | 826 | struct ProcessReplyClosure *prq = cls; |
821 | struct GSF_PendingRequest *pr = value; | 827 | struct GSF_PendingRequest *pr = value; |
@@ -832,22 +838,20 @@ process_reply (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
832 | gettext_noop ("# replies received and matched"), | 838 | gettext_noop ("# replies received and matched"), |
833 | 1, | 839 | 1, |
834 | GNUNET_NO); | 840 | GNUNET_NO); |
835 | prq->eval = GNUNET_BLOCK_evaluate (GSF_block_ctx, | 841 | prq->eval = GNUNET_BLOCK_check_reply (GSF_block_ctx, |
836 | prq->type, | 842 | prq->type, |
837 | pr->bg, | 843 | pr->bg, |
838 | prq->eo, | 844 | key, |
839 | key, | 845 | NULL, 0, |
840 | NULL, | 846 | prq->data, |
841 | 0, | 847 | prq->size); |
842 | prq->data, | ||
843 | prq->size); | ||
844 | switch (prq->eval) | 848 | switch (prq->eval) |
845 | { | 849 | { |
846 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | 850 | case GNUNET_BLOCK_REPLY_OK_MORE: |
847 | update_request_performance_data (prq, pr); | 851 | update_request_performance_data (prq, pr); |
848 | break; | 852 | break; |
849 | 853 | ||
850 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | 854 | case GNUNET_BLOCK_REPLY_OK_LAST: |
851 | /* short cut: stop processing early, no BF-update, etc. */ | 855 | /* short cut: stop processing early, no BF-update, etc. */ |
852 | update_request_performance_data (prq, pr); | 856 | update_request_performance_data (prq, pr); |
853 | GNUNET_LOAD_update (GSF_rt_entry_lifetime, | 857 | GNUNET_LOAD_update (GSF_rt_entry_lifetime, |
@@ -859,8 +863,7 @@ process_reply (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
859 | .pr_head, | 863 | .pr_head, |
860 | prq->sender, | 864 | prq->sender, |
861 | &last_transmission)) | 865 | &last_transmission)) |
862 | last_transmission.abs_value_us = | 866 | last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS; |
863 | GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
864 | /* pass on to other peers / local clients */ | 867 | /* pass on to other peers / local clients */ |
865 | pr->rh (pr->rh_cls, | 868 | pr->rh (pr->rh_cls, |
866 | prq->eval, | 869 | prq->eval, |
@@ -872,46 +875,38 @@ process_reply (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
872 | prq->data, | 875 | prq->data, |
873 | prq->size); | 876 | prq->size); |
874 | return GNUNET_YES; | 877 | return GNUNET_YES; |
875 | 878 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | |
876 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
877 | #if INSANE_STATISTICS | 879 | #if INSANE_STATISTICS |
878 | GNUNET_STATISTICS_update (GSF_stats, | 880 | GNUNET_STATISTICS_update (GSF_stats, |
879 | gettext_noop ( | 881 | "# duplicate replies discarded (bloomfilter)", |
880 | "# duplicate replies discarded (bloomfilter)"), | ||
881 | 1, | 882 | 1, |
882 | GNUNET_NO); | 883 | GNUNET_NO); |
883 | #endif | 884 | #endif |
884 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Duplicate response, discarding.\n"); | 885 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
886 | "Duplicate response, discarding.\n"); | ||
885 | return GNUNET_YES; /* duplicate */ | 887 | return GNUNET_YES; /* duplicate */ |
886 | 888 | ||
887 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | 889 | case GNUNET_BLOCK_REPLY_IRRELEVANT: |
888 | GNUNET_STATISTICS_update (GSF_stats, | 890 | GNUNET_STATISTICS_update (GSF_stats, |
889 | gettext_noop ("# irrelevant replies discarded"), | 891 | "# irrelevant replies discarded", |
890 | 1, | 892 | 1, |
891 | GNUNET_NO); | 893 | GNUNET_NO); |
892 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Irrelevant response, ignoring.\n"); | 894 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
893 | return GNUNET_YES; | 895 | "Irrelevant response, ignoring.\n"); |
894 | |||
895 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
896 | return GNUNET_YES; /* wrong namespace */ | ||
897 | |||
898 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
899 | GNUNET_break (0); | ||
900 | return GNUNET_YES; | 896 | return GNUNET_YES; |
901 | 897 | case GNUNET_BLOCK_REPLY_INVALID: | |
902 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
903 | GNUNET_break (0); | ||
904 | return GNUNET_YES; | 898 | return GNUNET_YES; |
905 | 899 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: | |
906 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | 900 | GNUNET_break (0); /* bad installation? */ |
907 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
908 | _ ("Unsupported block type %u\n"), | ||
909 | prq->type); | ||
910 | return GNUNET_NO; | 901 | return GNUNET_NO; |
911 | } | 902 | } |
912 | /* update bloomfilter */ | 903 | /* update bloomfilter */ |
913 | GNUNET_CRYPTO_hash (prq->data, prq->size, &chash); | 904 | GNUNET_CRYPTO_hash (prq->data, |
914 | GSF_pending_request_update_ (pr, &chash, 1); | 905 | prq->size, |
906 | &chash); | ||
907 | GSF_pending_request_update_ (pr, | ||
908 | &chash, | ||
909 | 1); | ||
915 | if (NULL == prq->sender) | 910 | if (NULL == prq->sender) |
916 | { | 911 | { |
917 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 912 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -936,7 +931,7 @@ process_reply (void *cls, const struct GNUNET_HashCode *key, void *value) | |||
936 | .pr_head, | 931 | .pr_head, |
937 | prq->sender, | 932 | prq->sender, |
938 | &last_transmission)) | 933 | &last_transmission)) |
939 | last_transmission.abs_value_us = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | 934 | last_transmission = GNUNET_TIME_UNIT_FOREVER_ABS; |
940 | pr->rh (pr->rh_cls, | 935 | pr->rh (pr->rh_cls, |
941 | prq->eval, | 936 | prq->eval, |
942 | pr, | 937 | pr, |
@@ -1363,12 +1358,12 @@ call_continuation (struct GSF_PendingRequest *pr) | |||
1363 | pr->llc_cont = NULL; | 1358 | pr->llc_cont = NULL; |
1364 | if (0 != (GSF_PRO_LOCAL_ONLY & pr->public_data.options)) | 1359 | if (0 != (GSF_PRO_LOCAL_ONLY & pr->public_data.options)) |
1365 | { | 1360 | { |
1366 | if (GNUNET_BLOCK_EVALUATION_OK_LAST != pr->local_result) | 1361 | if (GNUNET_BLOCK_REPLY_OK_LAST != pr->local_result) |
1367 | { | 1362 | { |
1368 | /* Signal that we are done and that there won't be any | 1363 | /* Signal that we are done and that there won't be any |
1369 | additional results to allow client to clean up state. */ | 1364 | additional results to allow client to clean up state. */ |
1370 | pr->rh (pr->rh_cls, | 1365 | pr->rh (pr->rh_cls, |
1371 | GNUNET_BLOCK_EVALUATION_OK_LAST, | 1366 | GNUNET_BLOCK_REPLY_OK_LAST, |
1372 | pr, | 1367 | pr, |
1373 | UINT32_MAX, | 1368 | UINT32_MAX, |
1374 | GNUNET_TIME_UNIT_ZERO_ABS, | 1369 | GNUNET_TIME_UNIT_ZERO_ABS, |
@@ -1380,11 +1375,15 @@ call_continuation (struct GSF_PendingRequest *pr) | |||
1380 | /* Finally, call our continuation to signal that we are | 1375 | /* Finally, call our continuation to signal that we are |
1381 | done with local processing of this request; i.e. to | 1376 | done with local processing of this request; i.e. to |
1382 | start reading again from the client. */ | 1377 | start reading again from the client. */ |
1383 | cont (pr->llc_cont_cls, NULL, GNUNET_BLOCK_EVALUATION_OK_LAST); | 1378 | cont (pr->llc_cont_cls, |
1379 | NULL, | ||
1380 | GNUNET_BLOCK_REPLY_OK_LAST); | ||
1384 | return; | 1381 | return; |
1385 | } | 1382 | } |
1386 | 1383 | ||
1387 | cont (pr->llc_cont_cls, pr, pr->local_result); | 1384 | cont (pr->llc_cont_cls, |
1385 | pr, | ||
1386 | pr->local_result); | ||
1388 | } | 1387 | } |
1389 | 1388 | ||
1390 | 1389 | ||
@@ -1635,7 +1634,7 @@ called_from_on_demand: | |||
1635 | prq.eo = GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO; | 1634 | prq.eo = GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO; |
1636 | process_reply (&prq, key, pr); | 1635 | process_reply (&prq, key, pr); |
1637 | pr->local_result = prq.eval; | 1636 | pr->local_result = prq.eval; |
1638 | if (GNUNET_BLOCK_EVALUATION_OK_LAST == prq.eval) | 1637 | if (GNUNET_BLOCK_REPLY_OK_LAST == prq.eval) |
1639 | { | 1638 | { |
1640 | GNUNET_STATISTICS_update ( | 1639 | GNUNET_STATISTICS_update ( |
1641 | GSF_stats, | 1640 | GSF_stats, |
diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h index 58fdd334e..a10fb9b4c 100644 --- a/src/fs/gnunet-service-fs_pr.h +++ b/src/fs/gnunet-service-fs_pr.h | |||
@@ -184,16 +184,17 @@ struct GSF_PendingRequestData | |||
184 | * @param data_len number of bytes in @a data | 184 | * @param data_len number of bytes in @a data |
185 | */ | 185 | */ |
186 | typedef void | 186 | typedef void |
187 | (*GSF_PendingRequestReplyHandler) (void *cls, | 187 | (*GSF_PendingRequestReplyHandler) ( |
188 | enum GNUNET_BLOCK_EvaluationResult eval, | 188 | void *cls, |
189 | struct GSF_PendingRequest *pr, | 189 | enum GNUNET_BLOCK_ReplyEvaluationResult eval, |
190 | uint32_t reply_anonymity_level, | 190 | struct GSF_PendingRequest *pr, |
191 | struct GNUNET_TIME_Absolute expiration, | 191 | uint32_t reply_anonymity_level, |
192 | struct GNUNET_TIME_Absolute | 192 | struct GNUNET_TIME_Absolute expiration, |
193 | last_transmission, | 193 | struct GNUNET_TIME_Absolute |
194 | enum GNUNET_BLOCK_Type type, | 194 | last_transmission, |
195 | const void *data, | 195 | enum GNUNET_BLOCK_Type type, |
196 | size_t data_len); | 196 | const void *data, |
197 | size_t data_len); | ||
197 | 198 | ||
198 | 199 | ||
199 | /** | 200 | /** |
@@ -374,9 +375,10 @@ GSF_cadet_lookup_ (struct GSF_PendingRequest *pr); | |||
374 | * @param result final datastore lookup result | 375 | * @param result final datastore lookup result |
375 | */ | 376 | */ |
376 | typedef void | 377 | typedef void |
377 | (*GSF_LocalLookupContinuation) (void *cls, | 378 | (*GSF_LocalLookupContinuation) ( |
378 | struct GSF_PendingRequest *pr, | 379 | void *cls, |
379 | enum GNUNET_BLOCK_EvaluationResult result); | 380 | struct GSF_PendingRequest *pr, |
381 | enum GNUNET_BLOCK_ReplyEvaluationResult result); | ||
380 | 382 | ||
381 | 383 | ||
382 | /** | 384 | /** |
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 6a9ab3f41..43380b3b6 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2010, 2013 GNUnet e.V. | 3 | Copyright (C) 2010, 2013, 2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -225,7 +225,7 @@ block_plugin_fs_evaluate (void *cls, | |||
225 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 225 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
226 | * (or if extracting a key from a block of this type does not work) | 226 | * (or if extracting a key from a block of this type does not work) |
227 | */ | 227 | */ |
228 | static int | 228 | static enum GNUNET_GenericReturnValue |
229 | block_plugin_fs_get_key (void *cls, | 229 | block_plugin_fs_get_key (void *cls, |
230 | enum GNUNET_BLOCK_Type type, | 230 | enum GNUNET_BLOCK_Type type, |
231 | const void *block, | 231 | const void *block, |
@@ -238,9 +238,10 @@ block_plugin_fs_get_key (void *cls, | |||
238 | { | 238 | { |
239 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | 239 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: |
240 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | 240 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: |
241 | GNUNET_CRYPTO_hash (block, block_size, key); | 241 | GNUNET_CRYPTO_hash (block, |
242 | block_size, | ||
243 | key); | ||
242 | return GNUNET_OK; | 244 | return GNUNET_OK; |
243 | |||
244 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | 245 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: |
245 | if (block_size < sizeof(struct UBlock)) | 246 | if (block_size < sizeof(struct UBlock)) |
246 | { | 247 | { |
@@ -252,7 +253,6 @@ block_plugin_fs_get_key (void *cls, | |||
252 | sizeof(ub->verification_key), | 253 | sizeof(ub->verification_key), |
253 | key); | 254 | key); |
254 | return GNUNET_OK; | 255 | return GNUNET_OK; |
255 | |||
256 | default: | 256 | default: |
257 | GNUNET_break (0); | 257 | GNUNET_break (0); |
258 | return GNUNET_SYSERR; | 258 | return GNUNET_SYSERR; |
@@ -261,12 +261,153 @@ block_plugin_fs_get_key (void *cls, | |||
261 | 261 | ||
262 | 262 | ||
263 | /** | 263 | /** |
264 | * Function called to validate a query. | ||
265 | * | ||
266 | * @param cls closure | ||
267 | * @param ctx block context | ||
268 | * @param type block type | ||
269 | * @param query original query (hash) | ||
270 | * @param xquery extrended query data (can be NULL, depending on type) | ||
271 | * @param xquery_size number of bytes in @a xquery | ||
272 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
273 | */ | ||
274 | static enum GNUNET_GenericReturnValue | ||
275 | block_plugin_fs_check_query (void *cls, | ||
276 | enum GNUNET_BLOCK_Type type, | ||
277 | const struct GNUNET_HashCode *query, | ||
278 | const void *xquery, | ||
279 | size_t xquery_size) | ||
280 | { | ||
281 | switch (type) | ||
282 | { | ||
283 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | ||
284 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | ||
285 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | ||
286 | if (0 != xquery_size) | ||
287 | { | ||
288 | GNUNET_break_op (0); | ||
289 | return GNUNET_NO; | ||
290 | } | ||
291 | return GNUNET_OK; | ||
292 | default: | ||
293 | return GNUNET_SYSERR; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Function called to validate a block for storage. | ||
300 | * | ||
301 | * @param cls closure | ||
302 | * @param type block type | ||
303 | * @param query key for the block (hash), must match exactly | ||
304 | * @param block block data to validate | ||
305 | * @param block_size number of bytes in @a block | ||
306 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
307 | */ | ||
308 | static enum GNUNET_GenericReturnValue | ||
309 | block_plugin_fs_check_block (void *cls, | ||
310 | enum GNUNET_BLOCK_Type type, | ||
311 | const struct GNUNET_HashCode *query, | ||
312 | const void *block, | ||
313 | size_t block_size) | ||
314 | { | ||
315 | switch (type) | ||
316 | { | ||
317 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | ||
318 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | ||
319 | return GNUNET_OK; | ||
320 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | ||
321 | { | ||
322 | const struct UBlock *ub; | ||
323 | |||
324 | if (block_size < sizeof(struct UBlock)) | ||
325 | { | ||
326 | GNUNET_break_op (0); | ||
327 | return GNUNET_NO; | ||
328 | } | ||
329 | ub = block; | ||
330 | if (block_size != | ||
331 | ntohl (ub->purpose.size) + | ||
332 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)) | ||
333 | { | ||
334 | GNUNET_break_op (0); | ||
335 | return GNUNET_NO; | ||
336 | } | ||
337 | if (GNUNET_OK != | ||
338 | GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK, | ||
339 | &ub->purpose, | ||
340 | &ub->signature, | ||
341 | &ub->verification_key)) | ||
342 | { | ||
343 | GNUNET_break_op (0); | ||
344 | return GNUNET_NO; | ||
345 | } | ||
346 | return GNUNET_OK; | ||
347 | } | ||
348 | default: | ||
349 | return GNUNET_SYSERR; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Function called to validate a reply to a request. Note that it is assumed | ||
356 | * that the reply has already been matched to the key (and signatures checked) | ||
357 | * as it would be done with the GetKeyFunction and the | ||
358 | * BlockEvaluationFunction. | ||
359 | * | ||
360 | * @param cls closure | ||
361 | * @param type block type | ||
362 | * @param group which block group to use for evaluation | ||
363 | * @param query original query (hash) | ||
364 | * @param xquery extrended query data (can be NULL, depending on type) | ||
365 | * @param xquery_size number of bytes in @a xquery | ||
366 | * @param reply_block response to validate | ||
367 | * @param reply_block_size number of bytes in @a reply_block | ||
368 | * @return characterization of result | ||
369 | */ | ||
370 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
371 | block_plugin_fs_check_reply (void *cls, | ||
372 | enum GNUNET_BLOCK_Type type, | ||
373 | struct GNUNET_BLOCK_Group *group, | ||
374 | const struct GNUNET_HashCode *query, | ||
375 | const void *xquery, | ||
376 | size_t xquery_size, | ||
377 | const void *reply_block, | ||
378 | size_t reply_block_size) | ||
379 | { | ||
380 | switch (type) | ||
381 | { | ||
382 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | ||
383 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | ||
384 | return GNUNET_BLOCK_REPLY_OK_LAST; | ||
385 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | ||
386 | { | ||
387 | struct GNUNET_HashCode chash; | ||
388 | |||
389 | GNUNET_CRYPTO_hash (reply_block, | ||
390 | reply_block_size, | ||
391 | &chash); | ||
392 | if (GNUNET_YES == | ||
393 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
394 | &chash)) | ||
395 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
396 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
397 | } | ||
398 | default: | ||
399 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | |||
404 | /** | ||
264 | * Entry point for the plugin. | 405 | * Entry point for the plugin. |
265 | */ | 406 | */ |
266 | void * | 407 | void * |
267 | libgnunet_plugin_block_fs_init (void *cls) | 408 | libgnunet_plugin_block_fs_init (void *cls) |
268 | { | 409 | { |
269 | static enum GNUNET_BLOCK_Type types[] = { | 410 | static const enum GNUNET_BLOCK_Type types[] = { |
270 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 411 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
271 | GNUNET_BLOCK_TYPE_FS_IBLOCK, | 412 | GNUNET_BLOCK_TYPE_FS_IBLOCK, |
272 | GNUNET_BLOCK_TYPE_FS_UBLOCK, | 413 | GNUNET_BLOCK_TYPE_FS_UBLOCK, |
@@ -278,6 +419,9 @@ libgnunet_plugin_block_fs_init (void *cls) | |||
278 | api->evaluate = &block_plugin_fs_evaluate; | 419 | api->evaluate = &block_plugin_fs_evaluate; |
279 | api->get_key = &block_plugin_fs_get_key; | 420 | api->get_key = &block_plugin_fs_get_key; |
280 | api->create_group = &block_plugin_fs_create_group; | 421 | api->create_group = &block_plugin_fs_create_group; |
422 | api->check_query = &block_plugin_fs_check_query; | ||
423 | api->check_block = &block_plugin_fs_check_block; | ||
424 | api->check_reply = &block_plugin_fs_check_reply; | ||
281 | api->types = types; | 425 | api->types = types; |
282 | return api; | 426 | return api; |
283 | } | 427 | } |
diff --git a/src/fs/test_plugin_block_fs.c b/src/fs/test_plugin_block_fs.c index 4f71c5d74..727cc37c2 100644 --- a/src/fs/test_plugin_block_fs.c +++ b/src/fs/test_plugin_block_fs.c | |||
@@ -34,36 +34,31 @@ test_fs (struct GNUNET_BLOCK_Context *ctx) | |||
34 | 34 | ||
35 | memset (block, 1, sizeof(block)); | 35 | memset (block, 1, sizeof(block)); |
36 | if (GNUNET_OK != | 36 | if (GNUNET_OK != |
37 | GNUNET_BLOCK_get_key (ctx, GNUNET_BLOCK_TYPE_FS_DBLOCK, block, | 37 | GNUNET_BLOCK_get_key (ctx, |
38 | sizeof(block), &key)) | 38 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
39 | block, | ||
40 | sizeof(block), | ||
41 | &key)) | ||
39 | return 1; | 42 | return 1; |
40 | if (GNUNET_BLOCK_EVALUATION_OK_LAST != | 43 | if (GNUNET_OK != |
41 | GNUNET_BLOCK_evaluate (ctx, | 44 | GNUNET_BLOCK_check_block (ctx, |
42 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 45 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
43 | NULL, | 46 | &key, |
44 | GNUNET_BLOCK_EO_NONE, | 47 | block, |
45 | &key, | 48 | sizeof(block))) |
46 | NULL, 0, | ||
47 | block, sizeof(block))) | ||
48 | return 2; | 49 | return 2; |
49 | if (GNUNET_BLOCK_EVALUATION_REQUEST_VALID != | 50 | if (GNUNET_OK != |
50 | GNUNET_BLOCK_evaluate (ctx, | 51 | GNUNET_BLOCK_check_query (ctx, |
51 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 52 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
52 | NULL, | 53 | &key, |
53 | GNUNET_BLOCK_EO_NONE, | 54 | NULL, 0)) |
54 | &key, | ||
55 | NULL, 0, | ||
56 | NULL, 0)) | ||
57 | return 4; | 55 | return 4; |
58 | GNUNET_log_skip (1, GNUNET_NO); | 56 | GNUNET_log_skip (1, GNUNET_NO); |
59 | if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID != | 57 | if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID != |
60 | GNUNET_BLOCK_evaluate (ctx, | 58 | GNUNET_BLOCK_check_query (ctx, |
61 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 59 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
62 | NULL, | 60 | &key, |
63 | GNUNET_BLOCK_EO_NONE, | 61 | "bogus", 5)) |
64 | &key, | ||
65 | "bogus", 5, | ||
66 | NULL, 0)) | ||
67 | return 8; | 62 | return 8; |
68 | GNUNET_log_skip (0, GNUNET_YES); | 63 | GNUNET_log_skip (0, GNUNET_YES); |
69 | return 0; | 64 | return 0; |
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 1380cba10..315b4dbf3 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -22,20 +22,6 @@ else | |||
22 | LIBIDN2= | 22 | LIBIDN2= |
23 | endif | 23 | endif |
24 | 24 | ||
25 | EXTRA_DIST = \ | ||
26 | test_gns_defaults.conf \ | ||
27 | test_gns_lookup.conf \ | ||
28 | test_gns_proxy.conf \ | ||
29 | test_gns_simple_lookup.conf \ | ||
30 | openssl.cnf \ | ||
31 | gnunet-gns-proxy-setup-ca.in \ | ||
32 | zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ | ||
33 | zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ | ||
34 | zonefiles/test_zonekey \ | ||
35 | $(check_SCRIPTS) \ | ||
36 | $(pkgdata_DATA) \ | ||
37 | test_gnunet_gns.sh.in | ||
38 | |||
39 | USE_VPN = $(top_builddir)/src/vpn/libgnunetvpn.la | 25 | USE_VPN = $(top_builddir)/src/vpn/libgnunetvpn.la |
40 | 26 | ||
41 | if USE_COVERAGE | 27 | if USE_COVERAGE |
@@ -50,6 +36,8 @@ plugindir = $(libdir)/gnunet | |||
50 | 36 | ||
51 | pkgcfg_DATA = \ | 37 | pkgcfg_DATA = \ |
52 | gns.conf | 38 | gns.conf |
39 | dist_pkgcfg_DATA = \ | ||
40 | tlds.conf | ||
53 | 41 | ||
54 | lib_LTLIBRARIES = \ | 42 | lib_LTLIBRARIES = \ |
55 | libgnunetgns.la | 43 | libgnunetgns.la |
@@ -294,6 +282,19 @@ endif | |||
294 | check_SCRIPTS += \ | 282 | check_SCRIPTS += \ |
295 | test_plugin_rest_gns.sh | 283 | test_plugin_rest_gns.sh |
296 | 284 | ||
285 | EXTRA_DIST = \ | ||
286 | test_gns_defaults.conf \ | ||
287 | test_gns_lookup.conf \ | ||
288 | test_gns_proxy.conf \ | ||
289 | test_gns_simple_lookup.conf \ | ||
290 | openssl.cnf \ | ||
291 | gnunet-gns-proxy-setup-ca.in \ | ||
292 | zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ | ||
293 | zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ | ||
294 | zonefiles/test_zonekey \ | ||
295 | $(check_SCRIPTS) \ | ||
296 | $(pkgdata_DATA) \ | ||
297 | test_gnunet_gns.sh.in | ||
297 | 298 | ||
298 | if ENABLE_TEST_RUN | 299 | if ENABLE_TEST_RUN |
299 | if HAVE_SQLITE | 300 | if HAVE_SQLITE |
diff --git a/src/gns/gns.conf.in b/src/gns/gns.conf.in index a458f69a2..13741bee9 100644 --- a/src/gns/gns.conf.in +++ b/src/gns/gns.conf.in | |||
@@ -24,9 +24,6 @@ INTERCEPT_DNS = NO | |||
24 | 24 | ||
25 | # PREFIX = valgrind --leak-check=full --track-origins=yes | 25 | # PREFIX = valgrind --leak-check=full --track-origins=yes |
26 | 26 | ||
27 | # Zones | ||
28 | .pin = 000G001MF6DVMZZ4Y8XRZQDXM1PB3D3VGEK29ZHXBA57EPSNW1QBPKT8J0 | ||
29 | |||
30 | [gns-proxy] | 27 | [gns-proxy] |
31 | BINARY = gnunet-gns-proxy | 28 | BINARY = gnunet-gns-proxy |
32 | START_ON_DEMAND = NO | 29 | START_ON_DEMAND = NO |
diff --git a/src/gns/gnunet-gns-proxy-setup-ca.in b/src/gns/gnunet-gns-proxy-setup-ca.in index 9a298f24a..b3ebfd11d 100644 --- a/src/gns/gnunet-gns-proxy-setup-ca.in +++ b/src/gns/gnunet-gns-proxy-setup-ca.in | |||
@@ -48,33 +48,45 @@ | |||
48 | 48 | ||
49 | dir=$(dirname "$0") | 49 | dir=$(dirname "$0") |
50 | 50 | ||
51 | if test -e @PKGDATADIRECTORY@/progname.sh | 51 | progname=${0##*/} |
52 | then | ||
53 | . @PKGDATADIRECTORY@/progname.sh | ||
54 | else | ||
55 | . $dir/../../contrib/build-common/sh/lib.sh/progname.sh | ||
56 | fi | ||
57 | 52 | ||
58 | if test -e @PKGDATADIRECTORY@/existence.sh | 53 | existence() { |
59 | then | 54 | command -v "$1" >/dev/null 2>&1 |
60 | . @PKGDATADIRECTORY@/existence.sh | 55 | } |
61 | else | 56 | |
62 | . $dir/../../contrib/build-common/sh/lib.sh/existence.sh | 57 | statusmsg() |
63 | fi | 58 | { |
59 | ${runcmd} echo "${tab}$@" | tee -a "${results}" | ||
60 | } | ||
61 | |||
62 | infomsg() | ||
63 | { | ||
64 | if [ x$verbosity = x1 ]; then | ||
65 | statusmsg "INFO:${tab}$@" | ||
66 | fi | ||
67 | } | ||
64 | 68 | ||
65 | if test -e @PKGDATADIRECTORY@/msg.sh | 69 | warningmsg() |
66 | then | 70 | { |
67 | . @PKGDATADIRECTORY@/msg.sh | 71 | statusmsg "WARNING:${tab}$@" |
68 | else | 72 | } |
69 | . $dir/../../contrib/build-common/sh/lib.sh/msg.sh | ||
70 | fi | ||
71 | 73 | ||
72 | if test -e @PKGDATADIRECTORY@/version_gnunet.sh | 74 | errormsg() |
73 | then | 75 | { |
74 | . @PKGDATADIRECTORY@/version_gnunet.sh | 76 | statusmsg "ERROR:${tab}$@" |
75 | else | 77 | } |
76 | . $dir/../../contrib/build-common/sh/lib.sh/version_gnunet.sh | 78 | |
77 | fi | 79 | linemsg() |
80 | { | ||
81 | statusmsg "=========================================" | ||
82 | } | ||
83 | |||
84 | |||
85 | print_version() | ||
86 | { | ||
87 | GNUNET_ARM_VERSION=`gnunet-arm -v | awk '{print $2 " " $3}'` | ||
88 | echo ${progname} $GNUNET_ARM_VERSION | ||
89 | } | ||
78 | 90 | ||
79 | # Whitespace normalization without depending on shell features: | 91 | # Whitespace normalization without depending on shell features: |
80 | tab=' ' | 92 | tab=' ' |
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index 9b58c9034..407754a8c 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c | |||
@@ -185,7 +185,7 @@ block_plugin_gns_evaluate (void *cls, | |||
185 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 185 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
186 | * (or if extracting a key from a block of this type does not work) | 186 | * (or if extracting a key from a block of this type does not work) |
187 | */ | 187 | */ |
188 | static int | 188 | static enum GNUNET_GenericReturnValue |
189 | block_plugin_gns_get_key (void *cls, | 189 | block_plugin_gns_get_key (void *cls, |
190 | enum GNUNET_BLOCK_Type type, | 190 | enum GNUNET_BLOCK_Type type, |
191 | const void *reply_block, | 191 | const void *reply_block, |
@@ -208,13 +208,139 @@ block_plugin_gns_get_key (void *cls, | |||
208 | } | 208 | } |
209 | 209 | ||
210 | 210 | ||
211 | |||
212 | /** | ||
213 | * Function called to validate a query. | ||
214 | * | ||
215 | * @param cls closure | ||
216 | * @param ctx block context | ||
217 | * @param type block type | ||
218 | * @param query original query (hash) | ||
219 | * @param xquery extrended query data (can be NULL, depending on type) | ||
220 | * @param xquery_size number of bytes in @a xquery | ||
221 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
222 | */ | ||
223 | static enum GNUNET_GenericReturnValue | ||
224 | block_plugin_gns_check_query (void *cls, | ||
225 | enum GNUNET_BLOCK_Type type, | ||
226 | const struct GNUNET_HashCode *query, | ||
227 | const void *xquery, | ||
228 | size_t xquery_size) | ||
229 | { | ||
230 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | ||
231 | return GNUNET_SYSERR; | ||
232 | if (0 != xquery_size) | ||
233 | { | ||
234 | GNUNET_break_op (0); | ||
235 | return GNUNET_NO; | ||
236 | } | ||
237 | return GNUNET_OK; | ||
238 | } | ||
239 | |||
240 | |||
241 | /** | ||
242 | * Function called to validate a block for storage. | ||
243 | * | ||
244 | * @param cls closure | ||
245 | * @param type block type | ||
246 | * @param query key for the block (hash), must match exactly | ||
247 | * @param block block data to validate | ||
248 | * @param block_size number of bytes in @a block | ||
249 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
250 | */ | ||
251 | static enum GNUNET_GenericReturnValue | ||
252 | block_plugin_gns_check_block (void *cls, | ||
253 | enum GNUNET_BLOCK_Type type, | ||
254 | const struct GNUNET_HashCode *query, | ||
255 | const void *block, | ||
256 | size_t block_size) | ||
257 | { | ||
258 | const struct GNUNET_GNSRECORD_Block *gblock; | ||
259 | |||
260 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | ||
261 | return GNUNET_SYSERR; | ||
262 | if (block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | ||
263 | { | ||
264 | GNUNET_break_op (0); | ||
265 | return GNUNET_NO; | ||
266 | } | ||
267 | gblock = block; | ||
268 | if (GNUNET_GNSRECORD_block_get_size (gblock) > block_size) | ||
269 | { | ||
270 | GNUNET_break_op (0); | ||
271 | return GNUNET_NO; | ||
272 | } | ||
273 | if (GNUNET_OK != | ||
274 | GNUNET_GNSRECORD_block_verify (gblock)) | ||
275 | { | ||
276 | GNUNET_break_op (0); | ||
277 | return GNUNET_NO; | ||
278 | } | ||
279 | return GNUNET_OK; | ||
280 | } | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Function called to validate a reply to a request. Note that it is assumed | ||
285 | * that the reply has already been matched to the key (and signatures checked) | ||
286 | * as it would be done with the GetKeyFunction and the | ||
287 | * BlockEvaluationFunction. | ||
288 | * | ||
289 | * @param cls closure | ||
290 | * @param type block type | ||
291 | * @param group which block group to use for evaluation | ||
292 | * @param query original query (hash) | ||
293 | * @param xquery extrended query data (can be NULL, depending on type) | ||
294 | * @param xquery_size number of bytes in @a xquery | ||
295 | * @param reply_block response to validate | ||
296 | * @param reply_block_size number of bytes in @a reply_block | ||
297 | * @return characterization of result | ||
298 | */ | ||
299 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
300 | block_plugin_gns_check_reply (void *cls, | ||
301 | enum GNUNET_BLOCK_Type type, | ||
302 | struct GNUNET_BLOCK_Group *group, | ||
303 | const struct GNUNET_HashCode *query, | ||
304 | const void *xquery, | ||
305 | size_t xquery_size, | ||
306 | const void *reply_block, | ||
307 | size_t reply_block_size) | ||
308 | { | ||
309 | const struct GNUNET_GNSRECORD_Block *block; | ||
310 | struct GNUNET_HashCode chash; | ||
311 | |||
312 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | ||
313 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
314 | /* this is a reply */ | ||
315 | if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | ||
316 | { | ||
317 | GNUNET_break_op (0); | ||
318 | return GNUNET_BLOCK_REPLY_INVALID; | ||
319 | } | ||
320 | block = reply_block; | ||
321 | if (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size) | ||
322 | { | ||
323 | GNUNET_break_op (0); | ||
324 | return GNUNET_BLOCK_REPLY_INVALID; | ||
325 | } | ||
326 | GNUNET_CRYPTO_hash (reply_block, | ||
327 | reply_block_size, | ||
328 | &chash); | ||
329 | if (GNUNET_YES == | ||
330 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
331 | &chash)) | ||
332 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
333 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
334 | } | ||
335 | |||
336 | |||
211 | /** | 337 | /** |
212 | * Entry point for the plugin. | 338 | * Entry point for the plugin. |
213 | */ | 339 | */ |
214 | void * | 340 | void * |
215 | libgnunet_plugin_block_gns_init (void *cls) | 341 | libgnunet_plugin_block_gns_init (void *cls) |
216 | { | 342 | { |
217 | static enum GNUNET_BLOCK_Type types[] = { | 343 | static const enum GNUNET_BLOCK_Type types[] = { |
218 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | 344 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, |
219 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 345 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
220 | }; | 346 | }; |
@@ -224,6 +350,9 @@ libgnunet_plugin_block_gns_init (void *cls) | |||
224 | api->evaluate = &block_plugin_gns_evaluate; | 350 | api->evaluate = &block_plugin_gns_evaluate; |
225 | api->get_key = &block_plugin_gns_get_key; | 351 | api->get_key = &block_plugin_gns_get_key; |
226 | api->create_group = &block_plugin_gns_create_group; | 352 | api->create_group = &block_plugin_gns_create_group; |
353 | api->check_query = &block_plugin_gns_check_query; | ||
354 | api->check_block = &block_plugin_gns_check_block; | ||
355 | api->check_reply = &block_plugin_gns_check_reply; | ||
227 | api->types = types; | 356 | api->types = types; |
228 | return api; | 357 | return api; |
229 | } | 358 | } |
diff --git a/src/gns/test_gnunet_gns.sh.in b/src/gns/test_gnunet_gns.sh.in index 8a96ff034..d0c07b4e4 100755 --- a/src/gns/test_gnunet_gns.sh.in +++ b/src/gns/test_gnunet_gns.sh.in | |||
@@ -8,12 +8,9 @@ | |||
8 | # but this works for now. | 8 | # but this works for now. |
9 | dir=$(dirname "$0") | 9 | dir=$(dirname "$0") |
10 | 10 | ||
11 | if test -e @PKGDATADIRECTORY@/existence.sh | 11 | existence() { |
12 | then | 12 | command -v "$1" >/dev/null 2>&1 |
13 | . @PKGDATADIRECTORY@/existence.sh | 13 | } |
14 | else | ||
15 | . $dir/../../contrib/build-common/sh/lib.sh/existence.sh | ||
16 | fi | ||
17 | 14 | ||
18 | LOCATION=`existence gnunet-config` | 15 | LOCATION=`existence gnunet-config` |
19 | if test -z $LOCATION; then | 16 | if test -z $LOCATION; then |
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am index 59ace6c41..e535c208a 100644 --- a/src/identity/Makefile.am +++ b/src/identity/Makefile.am | |||
@@ -71,9 +71,12 @@ check_PROGRAMS = \ | |||
71 | test_identity \ | 71 | test_identity \ |
72 | test_identity_defaults | 72 | test_identity_defaults |
73 | 73 | ||
74 | check_SCRIPTS = \ | ||
75 | test_identity_messages.sh | ||
76 | |||
74 | if ENABLE_TEST_RUN | 77 | if ENABLE_TEST_RUN |
75 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 78 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
76 | TESTS = $(check_PROGRAMS) | 79 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) |
77 | endif | 80 | endif |
78 | 81 | ||
79 | 82 | ||
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c index d8dc936d3..97dc2ce7e 100644 --- a/src/identity/gnunet-identity.c +++ b/src/identity/gnunet-identity.c | |||
@@ -71,6 +71,16 @@ static int quiet; | |||
71 | static int type_eddsa; | 71 | static int type_eddsa; |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * -W option | ||
75 | */ | ||
76 | static char *write_msg; | ||
77 | |||
78 | /** | ||
79 | * -R option | ||
80 | */ | ||
81 | static char *read_msg; | ||
82 | |||
83 | /** | ||
74 | * -C option | 84 | * -C option |
75 | */ | 85 | */ |
76 | static char *create_ego; | 86 | static char *create_ego; |
@@ -86,6 +96,11 @@ static char *delete_ego; | |||
86 | static char *privkey_ego; | 96 | static char *privkey_ego; |
87 | 97 | ||
88 | /** | 98 | /** |
99 | * -k option | ||
100 | */ | ||
101 | static char *pubkey_msg; | ||
102 | |||
103 | /** | ||
89 | * -s option. | 104 | * -s option. |
90 | */ | 105 | */ |
91 | static char *set_ego; | 106 | static char *set_ego; |
@@ -164,6 +179,8 @@ test_finished (void) | |||
164 | (NULL == delete_op) && | 179 | (NULL == delete_op) && |
165 | (NULL == set_op) && | 180 | (NULL == set_op) && |
166 | (NULL == set_subsystem) && | 181 | (NULL == set_subsystem) && |
182 | (NULL == write_msg) && | ||
183 | (NULL == read_msg) && | ||
167 | (! list) && | 184 | (! list) && |
168 | (! monitor)) | 185 | (! monitor)) |
169 | { | 186 | { |
@@ -260,6 +277,135 @@ set_done (void *cls, const char *emsg) | |||
260 | 277 | ||
261 | 278 | ||
262 | /** | 279 | /** |
280 | * Encrypt a message given with -W, encrypted using public key of | ||
281 | * an identity given with -k. | ||
282 | */ | ||
283 | static void | ||
284 | write_encrypted_message (void) | ||
285 | { | ||
286 | struct GNUNET_IDENTITY_PublicKey recipient; | ||
287 | if (GNUNET_IDENTITY_public_key_from_string (pubkey_msg, &recipient) != | ||
288 | GNUNET_SYSERR) | ||
289 | { | ||
290 | struct GNUNET_CRYPTO_EcdhePublicKey message_key; | ||
291 | size_t msg_len = strlen (write_msg); | ||
292 | ssize_t res = GNUNET_IDENTITY_encrypt (write_msg, | ||
293 | msg_len, | ||
294 | &recipient, | ||
295 | &message_key, | ||
296 | write_msg); | ||
297 | if (-1 != res) | ||
298 | { | ||
299 | char *keystr; | ||
300 | char *serialized_msg; | ||
301 | keystr = GNUNET_STRINGS_data_to_string_alloc (&message_key, | ||
302 | sizeof(struct | ||
303 | GNUNET_CRYPTO_EcdhePublicKey)); | ||
304 | serialized_msg = GNUNET_STRINGS_data_to_string_alloc (write_msg, | ||
305 | msg_len); | ||
306 | fprintf (stdout, | ||
307 | "%s.%s\n", | ||
308 | keystr, serialized_msg); | ||
309 | GNUNET_free (keystr); | ||
310 | GNUNET_free (serialized_msg); | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | fprintf (stderr, "Error during encryption.\n"); | ||
315 | global_ret = 1; | ||
316 | } | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | fprintf (stderr, "Invalid recipient public key.\n"); | ||
321 | global_ret = 1; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | |||
326 | /** | ||
327 | * Decrypt a message given with -R, encrypted using public key of @c ego | ||
328 | * and ephemeral key given with -k. | ||
329 | * | ||
330 | * @param ego ego whose private key is used for decryption | ||
331 | */ | ||
332 | static void | ||
333 | read_encrypted_message (struct GNUNET_IDENTITY_Ego *ego) | ||
334 | { | ||
335 | // message contains ECDHE key and ciphertext divided by ".", so split up first | ||
336 | char delim[2] = "."; | ||
337 | char *key_msg = strtok (read_msg, delim); | ||
338 | char *cipher; | ||
339 | if (NULL == key_msg) | ||
340 | { | ||
341 | fprintf (stderr, "Invalid message format.\n"); | ||
342 | global_ret = 1; | ||
343 | return; | ||
344 | } | ||
345 | cipher = strtok (NULL, delim); | ||
346 | if (NULL == cipher) | ||
347 | { | ||
348 | fprintf (stderr, "Invalid message format, text missing.\n"); | ||
349 | global_ret = 1; | ||
350 | return; | ||
351 | } | ||
352 | |||
353 | if (NULL != strtok (NULL, delim)) | ||
354 | { | ||
355 | fprintf (stderr, | ||
356 | "Invalid message format, expecting only key and cipher components.\n"); | ||
357 | global_ret = 1; | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | struct GNUNET_CRYPTO_EcdhePublicKey message_key; | ||
362 | if (GNUNET_OK == GNUNET_STRINGS_string_to_data (key_msg, strlen ( | ||
363 | key_msg), | ||
364 | &message_key, | ||
365 | sizeof(message_key))) | ||
366 | { | ||
367 | char *deserialized_msg; | ||
368 | size_t msg_len; | ||
369 | if (GNUNET_OK == GNUNET_STRINGS_string_to_data_alloc (cipher, strlen ( | ||
370 | cipher), | ||
371 | (void **) & | ||
372 | deserialized_msg, | ||
373 | &msg_len)) | ||
374 | { | ||
375 | ssize_t res = GNUNET_IDENTITY_decrypt (deserialized_msg, | ||
376 | msg_len, | ||
377 | GNUNET_IDENTITY_ego_get_private_key ( | ||
378 | ego), | ||
379 | &message_key, | ||
380 | deserialized_msg); | ||
381 | if (-1 != res) | ||
382 | { | ||
383 | fprintf (stdout, | ||
384 | "%s\n", | ||
385 | deserialized_msg); | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | fprintf (stderr, "Failed to decrypt message.\n"); | ||
390 | global_ret = 1; | ||
391 | } | ||
392 | GNUNET_free (deserialized_msg); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | fprintf (stderr, "Invalid message format.\n"); | ||
397 | global_ret = 1; | ||
398 | } | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | fprintf (stderr, "Invalid message ephemeral key.\n"); | ||
403 | global_ret = 1; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | |||
408 | /** | ||
263 | * If listing is enabled, prints information about the egos. | 409 | * If listing is enabled, prints information about the egos. |
264 | * | 410 | * |
265 | * This function is initially called for all egos and then again | 411 | * This function is initially called for all egos and then again |
@@ -330,13 +476,25 @@ print_ego (void *cls, | |||
330 | GNUNET_free (set_ego); | 476 | GNUNET_free (set_ego); |
331 | set_ego = NULL; | 477 | set_ego = NULL; |
332 | } | 478 | } |
479 | if ( (NULL == ego) && | ||
480 | (NULL != set_ego) && | ||
481 | (NULL != read_msg) ) | ||
482 | { | ||
483 | fprintf (stderr, | ||
484 | "Ego `%s' is not known, cannot decrypt message.\n", | ||
485 | set_ego); | ||
486 | GNUNET_free (read_msg); | ||
487 | read_msg = NULL; | ||
488 | GNUNET_free (set_ego); | ||
489 | set_ego = NULL; | ||
490 | } | ||
333 | if ((NULL == ego) && (! monitor)) | 491 | if ((NULL == ego) && (! monitor)) |
334 | { | 492 | { |
335 | list = 0; | 493 | list = 0; |
336 | test_finished (); | 494 | test_finished (); |
337 | return; | 495 | return; |
338 | } | 496 | } |
339 | if (! (list | monitor)) | 497 | if (! (list | monitor) && (NULL == read_msg)) |
340 | return; | 498 | return; |
341 | if ( (NULL == ego) || | 499 | if ( (NULL == ego) || |
342 | (NULL == identifier) ) | 500 | (NULL == identifier) ) |
@@ -349,7 +507,14 @@ print_ego (void *cls, | |||
349 | s = GNUNET_IDENTITY_public_key_to_string (&pk); | 507 | s = GNUNET_IDENTITY_public_key_to_string (&pk); |
350 | privs = GNUNET_IDENTITY_private_key_to_string ( | 508 | privs = GNUNET_IDENTITY_private_key_to_string ( |
351 | GNUNET_IDENTITY_ego_get_private_key (ego)); | 509 | GNUNET_IDENTITY_ego_get_private_key (ego)); |
352 | if ((monitor) || (NULL != identifier)) | 510 | if ((NULL != read_msg) && (NULL != set_ego)) |
511 | { | ||
512 | // due to the check above, set_ego and the identifier are equal | ||
513 | read_encrypted_message (ego); | ||
514 | GNUNET_free (read_msg); | ||
515 | read_msg = NULL; | ||
516 | } | ||
517 | else if ((monitor) || (NULL != identifier)) | ||
353 | { | 518 | { |
354 | if (quiet) | 519 | if (quiet) |
355 | { | 520 | { |
@@ -397,6 +562,19 @@ run (void *cls, | |||
397 | fprintf (stderr, "Option -s requires option -e to be specified as well.\n"); | 562 | fprintf (stderr, "Option -s requires option -e to be specified as well.\n"); |
398 | return; | 563 | return; |
399 | } | 564 | } |
565 | |||
566 | if ((NULL != read_msg) && (NULL == set_ego)) | ||
567 | { | ||
568 | fprintf (stderr, | ||
569 | "Option -R requires options -e to be specified as well.\n"); | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | if ((NULL != write_msg) && (NULL == pubkey_msg)) | ||
574 | { | ||
575 | fprintf (stderr, "Option -W requires option -k to be specified as well.\n"); | ||
576 | return; | ||
577 | } | ||
400 | sh = GNUNET_IDENTITY_connect (cfg, | 578 | sh = GNUNET_IDENTITY_connect (cfg, |
401 | (monitor | list) || | 579 | (monitor | list) || |
402 | (NULL != set_ego) || | 580 | (NULL != set_ego) || |
@@ -404,6 +582,13 @@ run (void *cls, | |||
404 | ? &print_ego | 582 | ? &print_ego |
405 | : NULL, | 583 | : NULL, |
406 | NULL); | 584 | NULL); |
585 | if (NULL != write_msg) | ||
586 | { | ||
587 | write_encrypted_message (); | ||
588 | GNUNET_free (write_msg); | ||
589 | write_msg = NULL; | ||
590 | } | ||
591 | // read message is handled in ego callback (print_ego) | ||
407 | if (NULL != delete_ego) | 592 | if (NULL != delete_ego) |
408 | delete_op = | 593 | delete_op = |
409 | GNUNET_IDENTITY_delete (sh, | 594 | GNUNET_IDENTITY_delete (sh, |
@@ -471,6 +656,18 @@ main (int argc, char *const *argv) | |||
471 | gettext_noop ( | 656 | gettext_noop ( |
472 | "set the private key for the identity to PRIVATE_KEY (use together with -C)"), | 657 | "set the private key for the identity to PRIVATE_KEY (use together with -C)"), |
473 | &privkey_ego), | 658 | &privkey_ego), |
659 | GNUNET_GETOPT_option_string ('R', | ||
660 | "read", | ||
661 | "MESSAGE", | ||
662 | gettext_noop ( | ||
663 | "Read and decrypt message encrypted for the given ego (use together with -e EGO)"), | ||
664 | &read_msg), | ||
665 | GNUNET_GETOPT_option_string ('W', | ||
666 | "write", | ||
667 | "MESSAGE", | ||
668 | gettext_noop ( | ||
669 | "Encrypt and write message for recipient identity PULBIC_KEY, (use together with -k RECIPIENT_PUBLIC_KEY)"), | ||
670 | &write_msg), | ||
474 | GNUNET_GETOPT_option_flag ('X', | 671 | GNUNET_GETOPT_option_flag ('X', |
475 | "eddsa", | 672 | "eddsa", |
476 | gettext_noop ( | 673 | gettext_noop ( |
@@ -489,8 +686,14 @@ main (int argc, char *const *argv) | |||
489 | "ego", | 686 | "ego", |
490 | "NAME", | 687 | "NAME", |
491 | gettext_noop ( | 688 | gettext_noop ( |
492 | "set default identity to NAME for a subsystem SUBSYSTEM (use together with -s) or restrict results to NAME (use together with -d)"), | 689 | "set default identity to NAME for a subsystem SUBSYSTEM (use together with -s), restrict results to NAME (use together with -d) or read and decrypt a message for NAME (use together with -R)"), |
493 | &set_ego), | 690 | &set_ego), |
691 | GNUNET_GETOPT_option_string ('k', | ||
692 | "key", | ||
693 | "PUBLIC_KEY", | ||
694 | gettext_noop ( | ||
695 | "The public key of the recipient (with -W)"), | ||
696 | &pubkey_msg), | ||
494 | GNUNET_GETOPT_option_flag ('m', | 697 | GNUNET_GETOPT_option_flag ('m', |
495 | "monitor", | 698 | "monitor", |
496 | gettext_noop ("run in monitor mode egos"), | 699 | gettext_noop ("run in monitor mode egos"), |
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c index 08a975e65..01f36b840 100644 --- a/src/identity/identity_api.c +++ b/src/identity/identity_api.c | |||
@@ -979,10 +979,8 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key) | |||
979 | { | 979 | { |
980 | case GNUNET_IDENTITY_TYPE_ECDSA: | 980 | case GNUNET_IDENTITY_TYPE_ECDSA: |
981 | return sizeof (key->type) + sizeof (key->ecdsa_key); | 981 | return sizeof (key->type) + sizeof (key->ecdsa_key); |
982 | break; | ||
983 | case GNUNET_IDENTITY_TYPE_EDDSA: | 982 | case GNUNET_IDENTITY_TYPE_EDDSA: |
984 | return sizeof (key->type) + sizeof (key->eddsa_key); | 983 | return sizeof (key->type) + sizeof (key->eddsa_key); |
985 | break; | ||
986 | default: | 984 | default: |
987 | GNUNET_break (0); | 985 | GNUNET_break (0); |
988 | } | 986 | } |
@@ -992,19 +990,22 @@ GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key) | |||
992 | 990 | ||
993 | ssize_t | 991 | ssize_t |
994 | GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key, | 992 | GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key, |
995 | const void*buffer, | 993 | const void *buffer, |
996 | size_t len) | 994 | size_t len) |
997 | { | 995 | { |
998 | if (len < sizeof (key->type)) | 996 | if (len < sizeof (key->type)) |
999 | return -1; | 997 | return -1; |
1000 | GNUNET_memcpy (&(key->type), buffer, sizeof (key->type)); | 998 | GNUNET_memcpy (&key->type, |
1001 | const ssize_t length = GNUNET_IDENTITY_key_get_length (key); | 999 | buffer, |
1000 | sizeof (key->type)); | ||
1001 | ssize_t length = GNUNET_IDENTITY_key_get_length (key); | ||
1002 | if (len < length) | 1002 | if (len < length) |
1003 | return -1; | 1003 | return -1; |
1004 | if (length < 0) | 1004 | if (length < 0) |
1005 | return -2; | 1005 | return -2; |
1006 | GNUNET_memcpy (&(key->ecdsa_key), buffer + sizeof (key->type), length | 1006 | GNUNET_memcpy (&key->ecdsa_key, |
1007 | - sizeof (key->type)); | 1007 | buffer + sizeof (key->type), |
1008 | length - sizeof (key->type)); | ||
1008 | return length; | 1009 | return length; |
1009 | } | 1010 | } |
1010 | 1011 | ||
diff --git a/src/identity/test_identity.conf b/src/identity/test_identity.conf index 9c433da77..14b915732 100644 --- a/src/identity/test_identity.conf +++ b/src/identity/test_identity.conf | |||
@@ -1,3 +1,6 @@ | |||
1 | [PATHS] | ||
2 | GNUNET_TEST_HOME = $GNUNET_TMP/test-identity-service/ | ||
3 | |||
1 | [arm] | 4 | [arm] |
2 | PORT = 12000 | 5 | PORT = 12000 |
3 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-p1-service-arm.sock | 6 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-p1-service-arm.sock |
diff --git a/src/identity/test_identity_messages.sh b/src/identity/test_identity_messages.sh new file mode 100755 index 000000000..250c6a6f1 --- /dev/null +++ b/src/identity/test_identity_messages.sh | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_identity.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_identity.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30" | ||
19 | |||
20 | TEST_MSG="This is a test message. 123" | ||
21 | gnunet-arm -s -c test_identity.conf | ||
22 | gnunet-identity -C recipientego -c test_identity.conf | ||
23 | RECIPIENT_KEY=$(gnunet-identity -d -e recipientego -q -c test_identity.conf) | ||
24 | MSG_ENC=$(gnunet-identity -W "$TEST_MSG" -k $RECIPIENT_KEY -c test_identity.conf) | ||
25 | MSG_DEC=$(gnunet-identity -R "$MSG_ENC" -e recipientego -c test_identity.conf) | ||
26 | |||
27 | if test "$TEST_MSG" != "$MSG_DEC" | ||
28 | then | ||
29 | echo "Failed - $TEST_MSG != $MSG_DEC" | ||
30 | exit 1 | ||
31 | fi | ||
32 | |||
33 | gnunet-identity -D recipientego -c test_identity.conf | ||
34 | gnunet-arm -e -c test_identity.conf | ||
diff --git a/src/include/.gitignore b/src/include/.gitignore new file mode 100644 index 000000000..6c12255e5 --- /dev/null +++ b/src/include/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | gnu_name_system_record_types.h | ||
2 | gnunet_signatures.h | ||
diff --git a/src/include/gnu_name_system_record_types.h b/src/include/gnu_name_system_record_types.h deleted file mode 100644 index 22b2c472e..000000000 --- a/src/include/gnu_name_system_record_types.h +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012-2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | #ifndef GNU_NAME_SYSTEM_RECORD_TYPES_H | ||
21 | #define GNU_NAME_SYSTEM_RECORD_TYPES_H | ||
22 | |||
23 | /** | ||
24 | * WARNING: | ||
25 | * This header is generated! | ||
26 | * In order to add GNS record types, you must register | ||
27 | * them in GANA, and then use the header generation script | ||
28 | * to create an update of this file. You may then replace this | ||
29 | * file with the update. | ||
30 | */ | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "C" { | ||
34 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
35 | } | ||
36 | #endif | ||
37 | #endif | ||
38 | |||
39 | |||
40 | /** | ||
41 | * GNS zone transfer | ||
42 | */ | ||
43 | #define GNUNET_GNSRECORD_TYPE_PKEY 65536 | ||
44 | |||
45 | /** | ||
46 | * GNS nick names | ||
47 | */ | ||
48 | #define GNUNET_GNSRECORD_TYPE_NICK 65537 | ||
49 | |||
50 | /** | ||
51 | * legacy hostnames | ||
52 | */ | ||
53 | #define GNUNET_GNSRECORD_TYPE_LEHO 65538 | ||
54 | |||
55 | /** | ||
56 | * VPN resolution | ||
57 | */ | ||
58 | #define GNUNET_GNSRECORD_TYPE_VPN 65539 | ||
59 | |||
60 | /** | ||
61 | * Delegation to DNS | ||
62 | */ | ||
63 | #define GNUNET_GNSRECORD_TYPE_GNS2DNS 65540 | ||
64 | |||
65 | /** | ||
66 | * Boxed records (see TLSA/SRV handling in GNS) | ||
67 | */ | ||
68 | #define GNUNET_GNSRECORD_TYPE_BOX 65541 | ||
69 | |||
70 | /** | ||
71 | * social place for SecuShare | ||
72 | */ | ||
73 | #define GNUNET_GNSRECORD_TYPE_PLACE 65542 | ||
74 | |||
75 | /** | ||
76 | * Endpoint for conversation | ||
77 | */ | ||
78 | #define GNUNET_GNSRECORD_TYPE_PHONE 65543 | ||
79 | |||
80 | /** | ||
81 | * identity attribute | ||
82 | */ | ||
83 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE 65544 | ||
84 | |||
85 | /** | ||
86 | * local ticket reference | ||
87 | */ | ||
88 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET 65545 | ||
89 | |||
90 | /** | ||
91 | * For ABD policies | ||
92 | */ | ||
93 | #define GNUNET_GNSRECORD_TYPE_DELEGATE 65548 | ||
94 | |||
95 | /** | ||
96 | * For ABD reverse lookups | ||
97 | */ | ||
98 | #define GNUNET_GNSRECORD_TYPE_ATTRIBUTE 65549 | ||
99 | |||
100 | /** | ||
101 | * for reclaim records | ||
102 | */ | ||
103 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF 65550 | ||
104 | |||
105 | /** | ||
106 | * For reclaim OIDC client names. | ||
107 | */ | ||
108 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT 65552 | ||
109 | |||
110 | /** | ||
111 | * Used reclaimID OIDC client redirect URIs. | ||
112 | */ | ||
113 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553 | ||
114 | |||
115 | /** | ||
116 | * Record type for an attribute attestation (e.g. JWT). | ||
117 | */ | ||
118 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL 65554 | ||
119 | |||
120 | /** | ||
121 | * Record type for a presentation of a credential. | ||
122 | */ | ||
123 | #define GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION 65555 | ||
124 | |||
125 | /** | ||
126 | * Record type for EDKEY zone delegations. | ||
127 | */ | ||
128 | #define GNUNET_GNSRECORD_TYPE_EDKEY 65556 | ||
129 | |||
130 | /** | ||
131 | * Encoding for Robust Immutable Storage (ERIS) binary read capability | ||
132 | */ | ||
133 | #define GNUNET_GNSRECORD_TYPE_ERIS_READ_CAPABILITY 65557 | ||
134 | |||
135 | /** | ||
136 | * Record type to share an entry of a messenger room | ||
137 | */ | ||
138 | #define GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY 65558 | ||
139 | |||
140 | |||
141 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
142 | { | ||
143 | #endif | ||
144 | #ifdef __cplusplus | ||
145 | } | ||
146 | #endif | ||
147 | |||
148 | #endif | ||
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h index 73b51252e..5640209a6 100644 --- a/src/include/gnunet_block_lib.h +++ b/src/include/gnunet_block_lib.h | |||
@@ -43,6 +43,8 @@ extern "C" | |||
43 | 43 | ||
44 | /** | 44 | /** |
45 | * Blocks in the datastore and the datacache must have a unique type. | 45 | * Blocks in the datastore and the datacache must have a unique type. |
46 | * | ||
47 | * TODO: move to GANA! | ||
46 | */ | 48 | */ |
47 | enum GNUNET_BLOCK_Type | 49 | enum GNUNET_BLOCK_Type |
48 | { | 50 | { |
@@ -155,6 +157,7 @@ enum GNUNET_BLOCK_Type | |||
155 | 157 | ||
156 | /** | 158 | /** |
157 | * Flags that can be set to control the evaluation. | 159 | * Flags that can be set to control the evaluation. |
160 | * @deprecated | ||
158 | */ | 161 | */ |
159 | enum GNUNET_BLOCK_EvaluationOptions | 162 | enum GNUNET_BLOCK_EvaluationOptions |
160 | { | 163 | { |
@@ -173,6 +176,7 @@ enum GNUNET_BLOCK_EvaluationOptions | |||
173 | 176 | ||
174 | /** | 177 | /** |
175 | * Possible ways for how a block may relate to a query. | 178 | * Possible ways for how a block may relate to a query. |
179 | * @deprecated | ||
176 | */ | 180 | */ |
177 | enum GNUNET_BLOCK_EvaluationResult | 181 | enum GNUNET_BLOCK_EvaluationResult |
178 | { | 182 | { |
@@ -221,6 +225,44 @@ enum GNUNET_BLOCK_EvaluationResult | |||
221 | 225 | ||
222 | 226 | ||
223 | /** | 227 | /** |
228 | * Possible ways for how a block may relate to a query. | ||
229 | */ | ||
230 | enum GNUNET_BLOCK_ReplyEvaluationResult | ||
231 | { | ||
232 | /** | ||
233 | * Valid result, but suppressed because it is a duplicate. | ||
234 | */ | ||
235 | GNUNET_BLOCK_REPLY_OK_DUPLICATE = 0, | ||
236 | |||
237 | /** | ||
238 | * Valid result, and there may be more. | ||
239 | */ | ||
240 | GNUNET_BLOCK_REPLY_OK_MORE = 1, | ||
241 | |||
242 | /** | ||
243 | * Last possible valid result. | ||
244 | */ | ||
245 | GNUNET_BLOCK_REPLY_OK_LAST = 2, | ||
246 | |||
247 | /** | ||
248 | * Specified block type not supported by any plugin. | ||
249 | */ | ||
250 | GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED = -1, | ||
251 | |||
252 | /** | ||
253 | * Block does not match query (invalid result) | ||
254 | */ | ||
255 | GNUNET_BLOCK_REPLY_INVALID = -2, | ||
256 | |||
257 | /** | ||
258 | * Block does not match xquery (valid result, not relevant for the request) | ||
259 | */ | ||
260 | GNUNET_BLOCK_REPLY_IRRELEVANT = -3, | ||
261 | |||
262 | }; | ||
263 | |||
264 | |||
265 | /** | ||
224 | * Handle to an initialized block library. | 266 | * Handle to an initialized block library. |
225 | */ | 267 | */ |
226 | struct GNUNET_BLOCK_Context; | 268 | struct GNUNET_BLOCK_Context; |
@@ -297,7 +339,7 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, | |||
297 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not | 339 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not |
298 | * supported, #GNUNET_SYSERR on error | 340 | * supported, #GNUNET_SYSERR on error |
299 | */ | 341 | */ |
300 | int | 342 | enum GNUNET_GenericReturnValue |
301 | GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, | 343 | GNUNET_BLOCK_group_serialize (struct GNUNET_BLOCK_Group *bg, |
302 | uint32_t *nonce, | 344 | uint32_t *nonce, |
303 | void **raw_data, | 345 | void **raw_data, |
@@ -330,6 +372,7 @@ GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg); | |||
330 | * @param reply_block response to validate | 372 | * @param reply_block response to validate |
331 | * @param reply_block_size number of bytes in @a reply_block | 373 | * @param reply_block_size number of bytes in @a reply_block |
332 | * @return characterization of result | 374 | * @return characterization of result |
375 | * @deprecated | ||
333 | */ | 376 | */ |
334 | enum GNUNET_BLOCK_EvaluationResult | 377 | enum GNUNET_BLOCK_EvaluationResult |
335 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | 378 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, |
@@ -344,6 +387,70 @@ GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | |||
344 | 387 | ||
345 | 388 | ||
346 | /** | 389 | /** |
390 | * Function called to validate a reply. | ||
391 | * Also checks the query key against the block contents | ||
392 | * as it would be done with the #GNUNET_BLOCK_get_key() function. | ||
393 | * | ||
394 | * @param ctx block contxt | ||
395 | * @param type block type | ||
396 | * @param group block group to use for evaluation | ||
397 | * @param query original query (hash) | ||
398 | * @param xquery extrended query data (can be NULL, depending on type) | ||
399 | * @param xquery_size number of bytes in @a xquery | ||
400 | * @param reply_block response to validate | ||
401 | * @param reply_block_size number of bytes in @a reply_block | ||
402 | * @return characterization of result | ||
403 | */ | ||
404 | enum GNUNET_BLOCK_ReplyEvaluationResult | ||
405 | GNUNET_BLOCK_check_reply (struct GNUNET_BLOCK_Context *ctx, | ||
406 | enum GNUNET_BLOCK_Type type, | ||
407 | struct GNUNET_BLOCK_Group *group, | ||
408 | const struct GNUNET_HashCode *query, | ||
409 | const void *xquery, | ||
410 | size_t xquery_size, | ||
411 | const void *reply_block, | ||
412 | size_t reply_block_size); | ||
413 | |||
414 | |||
415 | /** | ||
416 | * Function called to validate a request. | ||
417 | * | ||
418 | * @param ctx block contxt | ||
419 | * @param type block type | ||
420 | * @param query original query (hash) | ||
421 | * @param xquery extrended query data (can be NULL, depending on type) | ||
422 | * @param xquery_size number of bytes in @a xquery | ||
423 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, | ||
424 | * #GNUNET_SYSERR if @a type is not supported | ||
425 | */ | ||
426 | enum GNUNET_GenericReturnValue | ||
427 | GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, | ||
428 | enum GNUNET_BLOCK_Type type, | ||
429 | const struct GNUNET_HashCode *query, | ||
430 | const void *xquery, | ||
431 | size_t xquery_size); | ||
432 | |||
433 | |||
434 | /** | ||
435 | * Function called to validate a block. | ||
436 | * | ||
437 | * @param ctx block contxt | ||
438 | * @param type block type | ||
439 | * @param query query key (hash) | ||
440 | * @param block payload to put | ||
441 | * @param block_size number of bytes in @a block | ||
442 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, | ||
443 | * #GNUNET_SYSERR if @a type is not supported | ||
444 | */ | ||
445 | enum GNUNET_GenericReturnValue | ||
446 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | ||
447 | enum GNUNET_BLOCK_Type type, | ||
448 | const struct GNUNET_HashCode *query, | ||
449 | const void *block, | ||
450 | size_t block_size); | ||
451 | |||
452 | |||
453 | /** | ||
347 | * Function called to obtain the key for a block. | 454 | * Function called to obtain the key for a block. |
348 | * | 455 | * |
349 | * @param ctx block context | 456 | * @param ctx block context |
@@ -356,7 +463,7 @@ GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | |||
356 | * #GNUNET_SYSERR if type not supported | 463 | * #GNUNET_SYSERR if type not supported |
357 | * (or if extracting a key from a block of this type does not work) | 464 | * (or if extracting a key from a block of this type does not work) |
358 | */ | 465 | */ |
359 | int | 466 | enum GNUNET_GenericReturnValue |
360 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | 467 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, |
361 | enum GNUNET_BLOCK_Type type, | 468 | enum GNUNET_BLOCK_Type type, |
362 | const void *block, | 469 | const void *block, |
@@ -375,7 +482,7 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | |||
375 | * @param seen_results_count number of entries in @a seen_results | 482 | * @param seen_results_count number of entries in @a seen_results |
376 | * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success | 483 | * @return #GNUNET_SYSERR if not supported, #GNUNET_OK on success |
377 | */ | 484 | */ |
378 | int | 485 | enum GNUNET_GenericReturnValue |
379 | GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, | 486 | GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, |
380 | const struct GNUNET_HashCode *seen_results, | 487 | const struct GNUNET_HashCode *seen_results, |
381 | unsigned int seen_results_count); | 488 | unsigned int seen_results_count); |
@@ -393,7 +500,7 @@ GNUNET_BLOCK_group_set_seen (struct GNUNET_BLOCK_Group *bg, | |||
393 | * #GNUNET_NO if merge failed due to different nonce | 500 | * #GNUNET_NO if merge failed due to different nonce |
394 | * #GNUNET_SYSERR if merging is not supported | 501 | * #GNUNET_SYSERR if merging is not supported |
395 | */ | 502 | */ |
396 | int | 503 | enum GNUNET_GenericReturnValue |
397 | GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1, | 504 | GNUNET_BLOCK_group_merge (struct GNUNET_BLOCK_Group *bg1, |
398 | struct GNUNET_BLOCK_Group *bg2); | 505 | struct GNUNET_BLOCK_Group *bg2); |
399 | 506 | ||
diff --git a/src/include/gnunet_block_plugin.h b/src/include/gnunet_block_plugin.h index ee237ac03..2c9a3839d 100644 --- a/src/include/gnunet_block_plugin.h +++ b/src/include/gnunet_block_plugin.h | |||
@@ -48,9 +48,9 @@ | |||
48 | * @param seen_results_count number of entries in @a seen_results | 48 | * @param seen_results_count number of entries in @a seen_results |
49 | */ | 49 | */ |
50 | typedef void | 50 | typedef void |
51 | (*GNUNET_BLOCK_GroupMarkSeenFunction)(struct GNUNET_BLOCK_Group *bg, | 51 | (*GNUNET_BLOCK_GroupMarkSeenFunction)( |
52 | const struct | 52 | struct GNUNET_BLOCK_Group *bg, |
53 | GNUNET_HashCode *seen_results, | 53 | const struct GNUNET_HashCode *seen_results, |
54 | unsigned int seen_results_count); | 54 | unsigned int seen_results_count); |
55 | 55 | ||
56 | 56 | ||
@@ -63,7 +63,7 @@ typedef void | |||
63 | * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus | 63 | * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus |
64 | * we failed. | 64 | * we failed. |
65 | */ | 65 | */ |
66 | typedef int | 66 | typedef enum GNUNET_GenericReturnValue |
67 | (*GNUNET_BLOCK_GroupMergeFunction)(struct GNUNET_BLOCK_Group *bg1, | 67 | (*GNUNET_BLOCK_GroupMergeFunction)(struct GNUNET_BLOCK_Group *bg1, |
68 | const struct GNUNET_BLOCK_Group *bg2); | 68 | const struct GNUNET_BLOCK_Group *bg2); |
69 | 69 | ||
@@ -78,7 +78,7 @@ typedef int | |||
78 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not | 78 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not |
79 | * supported, #GNUNET_SYSERR on error | 79 | * supported, #GNUNET_SYSERR on error |
80 | */ | 80 | */ |
81 | typedef int | 81 | typedef enum GNUNET_GenericReturnValue |
82 | (*GNUNET_BLOCK_GroupSerializeFunction)(struct GNUNET_BLOCK_Group *bg, | 82 | (*GNUNET_BLOCK_GroupSerializeFunction)(struct GNUNET_BLOCK_Group *bg, |
83 | uint32_t *nonce, | 83 | uint32_t *nonce, |
84 | void **raw_data, | 84 | void **raw_data, |
@@ -180,6 +180,7 @@ typedef struct GNUNET_BLOCK_Group * | |||
180 | * @param reply_block response to validate | 180 | * @param reply_block response to validate |
181 | * @param reply_block_size number of bytes in @a reply_block | 181 | * @param reply_block_size number of bytes in @a reply_block |
182 | * @return characterization of result | 182 | * @return characterization of result |
183 | * @deprecated | ||
183 | */ | 184 | */ |
184 | typedef enum GNUNET_BLOCK_EvaluationResult | 185 | typedef enum GNUNET_BLOCK_EvaluationResult |
185 | (*GNUNET_BLOCK_EvaluationFunction)(void *cls, | 186 | (*GNUNET_BLOCK_EvaluationFunction)(void *cls, |
@@ -195,19 +196,83 @@ typedef enum GNUNET_BLOCK_EvaluationResult | |||
195 | 196 | ||
196 | 197 | ||
197 | /** | 198 | /** |
199 | * Function called to validate a query. | ||
200 | * | ||
201 | * @param cls closure | ||
202 | * @param ctx block context | ||
203 | * @param type block type | ||
204 | * @param query original query (hash) | ||
205 | * @param xquery extrended query data (can be NULL, depending on type) | ||
206 | * @param xquery_size number of bytes in @a xquery | ||
207 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
208 | */ | ||
209 | typedef enum GNUNET_GenericReturnValue | ||
210 | (*GNUNET_BLOCK_QueryEvaluationFunction)(void *cls, | ||
211 | enum GNUNET_BLOCK_Type type, | ||
212 | const struct GNUNET_HashCode *query, | ||
213 | const void *xquery, | ||
214 | size_t xquery_size); | ||
215 | |||
216 | |||
217 | /** | ||
218 | * Function called to validate a block for storage. | ||
219 | * | ||
220 | * @param cls closure | ||
221 | * @param type block type | ||
222 | * @param query key for the block (hash), must match exactly | ||
223 | * @param block block data to validate | ||
224 | * @param block_size number of bytes in @a block | ||
225 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
226 | */ | ||
227 | typedef enum GNUNET_GenericReturnValue | ||
228 | (*GNUNET_BLOCK_BlockEvaluationFunction)(void *cls, | ||
229 | enum GNUNET_BLOCK_Type type, | ||
230 | const struct GNUNET_HashCode *query, | ||
231 | const void *block, | ||
232 | size_t block_size); | ||
233 | |||
234 | |||
235 | /** | ||
236 | * Function called to validate a reply to a request. Note that it is assumed | ||
237 | * that the reply has already been matched to the key (and signatures checked) | ||
238 | * as it would be done with the GetKeyFunction and the | ||
239 | * BlockEvaluationFunction. | ||
240 | * | ||
241 | * @param cls closure | ||
242 | * @param type block type | ||
243 | * @param group which block group to use for evaluation | ||
244 | * @param query original query (hash) | ||
245 | * @param xquery extrended query data (can be NULL, depending on type) | ||
246 | * @param xquery_size number of bytes in @a xquery | ||
247 | * @param reply_block response to validate | ||
248 | * @param reply_block_size number of bytes in @a reply_block | ||
249 | * @return characterization of result | ||
250 | */ | ||
251 | typedef enum GNUNET_BLOCK_ReplyEvaluationResult | ||
252 | (*GNUNET_BLOCK_ReplyEvaluationFunction)(void *cls, | ||
253 | enum GNUNET_BLOCK_Type type, | ||
254 | struct GNUNET_BLOCK_Group *group, | ||
255 | const struct GNUNET_HashCode *query, | ||
256 | const void *xquery, | ||
257 | size_t xquery_size, | ||
258 | const void *reply_block, | ||
259 | size_t reply_block_size); | ||
260 | |||
261 | |||
262 | /** | ||
198 | * Function called to obtain the key for a block. | 263 | * Function called to obtain the key for a block. |
199 | * | 264 | * |
200 | * @param cls closure | 265 | * @param cls closure |
201 | * @param type block type | 266 | * @param type block type |
202 | * @param block block to get the key for | 267 | * @param block block to get the key for |
203 | * @param block_size number of bytes in @a block | 268 | * @param block_size number of bytes in @a block |
204 | * @param key set to the key (query) for the given block | 269 | * @param[out] key set to the key (query) for the given block |
205 | * @return #GNUNET_YES on success, | 270 | * @return #GNUNET_YES on success, |
206 | * #GNUNET_NO if the block is malformed | 271 | * #GNUNET_NO if the block is malformed |
207 | * #GNUNET_SYSERR if type not supported | 272 | * #GNUNET_SYSERR if type not supported |
208 | * (or if extracting a key from a block of this type does not work) | 273 | * (or if extracting a key from a block of this type does not work) |
209 | */ | 274 | */ |
210 | typedef int | 275 | typedef enum GNUNET_GenericReturnValue |
211 | (*GNUNET_BLOCK_GetKeyFunction) (void *cls, | 276 | (*GNUNET_BLOCK_GetKeyFunction) (void *cls, |
212 | enum GNUNET_BLOCK_Type type, | 277 | enum GNUNET_BLOCK_Type type, |
213 | const void *block, | 278 | const void *block, |
@@ -234,6 +299,8 @@ struct GNUNET_BLOCK_PluginFunctions | |||
234 | /** | 299 | /** |
235 | * Main function of a block plugin. Allows us to check if a | 300 | * Main function of a block plugin. Allows us to check if a |
236 | * block matches a query. | 301 | * block matches a query. |
302 | * | ||
303 | * @param deprecated | ||
237 | */ | 304 | */ |
238 | GNUNET_BLOCK_EvaluationFunction evaluate; | 305 | GNUNET_BLOCK_EvaluationFunction evaluate; |
239 | 306 | ||
@@ -247,6 +314,22 @@ struct GNUNET_BLOCK_PluginFunctions | |||
247 | * context (i.e. to detect duplicates). | 314 | * context (i.e. to detect duplicates). |
248 | */ | 315 | */ |
249 | GNUNET_BLOCK_GroupCreateFunction create_group; | 316 | GNUNET_BLOCK_GroupCreateFunction create_group; |
317 | |||
318 | /** | ||
319 | * Check that a query is well-formed. | ||
320 | */ | ||
321 | GNUNET_BLOCK_QueryEvaluationFunction check_query; | ||
322 | |||
323 | /** | ||
324 | * Check that a block is well-formed. | ||
325 | */ | ||
326 | GNUNET_BLOCK_BlockEvaluationFunction check_block; | ||
327 | |||
328 | /** | ||
329 | * Check that a reply block matches a query. | ||
330 | */ | ||
331 | GNUNET_BLOCK_ReplyEvaluationFunction check_reply; | ||
332 | |||
250 | }; | 333 | }; |
251 | 334 | ||
252 | #endif | 335 | #endif |
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 9166f822b..1ab135d80 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -50,6 +50,7 @@ extern "C" { | |||
50 | #endif | 50 | #endif |
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | #include <stdbool.h> | ||
53 | #include <sodium.h> | 54 | #include <sodium.h> |
54 | 55 | ||
55 | /** | 56 | /** |
@@ -1037,61 +1038,38 @@ GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a, | |||
1037 | 1038 | ||
1038 | 1039 | ||
1039 | /** | 1040 | /** |
1040 | * @ingroup hash | 1041 | * Count the number of leading 0 bits in @a h. |
1041 | * Convert a hashcode into a key. | ||
1042 | * | 1042 | * |
1043 | * @param hc hash code that serves to generate the key | 1043 | * @param h a hash |
1044 | * @param skey set to a valid session key | 1044 | * @return number of leading 0 bits in @a h |
1045 | * @param iv set to a valid initialization vector | ||
1046 | */ | 1045 | */ |
1047 | void | 1046 | unsigned int |
1048 | GNUNET_CRYPTO_hash_to_aes_key ( | 1047 | GNUNET_CRYPTO_hash_count_leading_zeros (const struct GNUNET_HashCode *h); |
1049 | const struct GNUNET_HashCode *hc, | ||
1050 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | ||
1051 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv); | ||
1052 | 1048 | ||
1053 | 1049 | ||
1054 | /** | 1050 | /** |
1055 | * @ingroup hash | 1051 | * Count the number of tailing 0 bits in @a h. |
1056 | * Obtain a bit from a hashcode. | ||
1057 | * | 1052 | * |
1058 | * @param code the `struct GNUNET_HashCode` to index bit-wise | 1053 | * @param h a hash |
1059 | * @param bit index into the hashcode, [0...159] where 0 is the leftmost bit | 1054 | * @return number of tailing 0 bits in @a h |
1060 | * (bytes in code interpreted big endian) | ||
1061 | * @return Bit \a bit from hashcode \a code, -1 for invalid index | ||
1062 | */ | ||
1063 | int | ||
1064 | GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code, | ||
1065 | unsigned int bit); | ||
1066 | |||
1067 | |||
1068 | /** | ||
1069 | * Obtain a bit from a hashcode. | ||
1070 | * @param code the GNUNET_CRYPTO_hash to index bit-wise | ||
1071 | * @param bit index into the hashcode, [0...511] where 0 is the rightmost bit | ||
1072 | * (bytes in code interpreted little endian) | ||
1073 | * @return Bit \a bit from hashcode \a code, -1 for invalid index | ||
1074 | */ | 1055 | */ |
1075 | int | 1056 | unsigned int |
1076 | GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code, | 1057 | GNUNET_CRYPTO_hash_count_tailing_zeros (const struct GNUNET_HashCode *h); |
1077 | unsigned int bit); | ||
1078 | 1058 | ||
1079 | 1059 | ||
1080 | /** | 1060 | /** |
1081 | * @ingroup hash | 1061 | * @ingroup hash |
1082 | * Determine how many low order bits match in two | 1062 | * Convert a hashcode into a key. |
1083 | * `struct GNUNET_HashCodes`. e.g. - 010011 and 011111 share | ||
1084 | * the first two lowest order bits, and therefore the | ||
1085 | * return value is two (NOT XOR distance, nor how many | ||
1086 | * bits match absolutely!). | ||
1087 | * | 1063 | * |
1088 | * @param first the first hashcode | 1064 | * @param hc hash code that serves to generate the key |
1089 | * @param second the hashcode to compare first to | 1065 | * @param skey set to a valid session key |
1090 | * @return the number of bits that match | 1066 | * @param iv set to a valid initialization vector |
1091 | */ | 1067 | */ |
1092 | unsigned int | 1068 | void |
1093 | GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first, | 1069 | GNUNET_CRYPTO_hash_to_aes_key ( |
1094 | const struct GNUNET_HashCode *second); | 1070 | const struct GNUNET_HashCode *hc, |
1071 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | ||
1072 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv); | ||
1095 | 1073 | ||
1096 | 1074 | ||
1097 | /** | 1075 | /** |
@@ -2606,7 +2584,6 @@ void | |||
2606 | GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | 2584 | GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, |
2607 | struct GNUNET_CRYPTO_CsRPublic *r_pub); | 2585 | struct GNUNET_CRYPTO_CsRPublic *r_pub); |
2608 | 2586 | ||
2609 | |||
2610 | /** | 2587 | /** |
2611 | * Derives new random blinding factors. | 2588 | * Derives new random blinding factors. |
2612 | * In original papers blinding factors are generated randomly | 2589 | * In original papers blinding factors are generated randomly |
@@ -2614,13 +2591,12 @@ GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | |||
2614 | * To ensure unpredictability a new nonce has to be used. | 2591 | * To ensure unpredictability a new nonce has to be used. |
2615 | * Uses HKDF internally | 2592 | * Uses HKDF internally |
2616 | * | 2593 | * |
2617 | * @param secret is secret to derive blinding factors | 2594 | * @param blind_seed is the blinding seed to derive blinding factors |
2618 | * @param secret_len secret length | ||
2619 | * @param[out] bs array containing the two derived blinding secrets | 2595 | * @param[out] bs array containing the two derived blinding secrets |
2620 | */ | 2596 | */ |
2621 | void | 2597 | void |
2622 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const void *secret, | 2598 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct |
2623 | size_t secret_len, | 2599 | GNUNET_CRYPTO_CsNonce *blind_seed, |
2624 | struct GNUNET_CRYPTO_CsBlindingSecret | 2600 | struct GNUNET_CRYPTO_CsBlindingSecret |
2625 | bs[2]); | 2601 | bs[2]); |
2626 | 2602 | ||
diff --git a/src/include/gnunet_datacache_lib.h b/src/include/gnunet_datacache_lib.h index 40885803b..519c36bb4 100644 --- a/src/include/gnunet_datacache_lib.h +++ b/src/include/gnunet_datacache_lib.h | |||
@@ -146,20 +146,6 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
146 | 146 | ||
147 | 147 | ||
148 | /** | 148 | /** |
149 | * Obtain a random element from the datacache. | ||
150 | * | ||
151 | * @param h handle to the datacache | ||
152 | * @param iter maybe NULL (to just count) | ||
153 | * @param iter_cls closure for @a iter | ||
154 | * @return the number of results found (zero or 1) | ||
155 | */ | ||
156 | unsigned int | ||
157 | GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h, | ||
158 | GNUNET_DATACACHE_Iterator iter, | ||
159 | void *iter_cls); | ||
160 | |||
161 | |||
162 | /** | ||
163 | * Iterate over the results that are "close" to a particular key in | 149 | * Iterate over the results that are "close" to a particular key in |
164 | * the datacache. "close" is defined as numerically larger than @a | 150 | * the datacache. "close" is defined as numerically larger than @a |
165 | * key (when interpreted as a circular address space), with small | 151 | * key (when interpreted as a circular address space), with small |
diff --git a/src/include/gnunet_datacache_plugin.h b/src/include/gnunet_datacache_plugin.h index d7fa8fde0..5d5cac12c 100644 --- a/src/include/gnunet_datacache_plugin.h +++ b/src/include/gnunet_datacache_plugin.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2006, 2009, 2015 GNUnet e.V. | 3 | Copyright (C) 2006, 2009, 2015, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -115,15 +115,17 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
115 | * @param path_info a path through the network | 115 | * @param path_info a path through the network |
116 | * @return 0 if duplicate, -1 on error, number of bytes used otherwise | 116 | * @return 0 if duplicate, -1 on error, number of bytes used otherwise |
117 | */ | 117 | */ |
118 | ssize_t (*put) (void *cls, | 118 | ssize_t |
119 | const struct GNUNET_HashCode *key, | 119 | (*put) (void *cls, |
120 | uint32_t xor_distance, | 120 | const struct GNUNET_HashCode *key, |
121 | size_t size, | 121 | uint32_t xor_distance, |
122 | const char *data, | 122 | size_t size, |
123 | enum GNUNET_BLOCK_Type type, | 123 | const char *data, |
124 | struct GNUNET_TIME_Absolute discard_time, | 124 | enum GNUNET_BLOCK_Type type, |
125 | unsigned int path_info_len, | 125 | struct GNUNET_TIME_Absolute discard_time, |
126 | const struct GNUNET_PeerIdentity *path_info); | 126 | unsigned int path_info_len, |
127 | const struct GNUNET_PeerIdentity *path_info); | ||
128 | |||
127 | 129 | ||
128 | /** | 130 | /** |
129 | * Iterate over the results for a particular key | 131 | * Iterate over the results for a particular key |
@@ -136,11 +138,13 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
136 | * @param iter_cls closure for @a iter | 138 | * @param iter_cls closure for @a iter |
137 | * @return the number of results found | 139 | * @return the number of results found |
138 | */ | 140 | */ |
139 | unsigned int (*get) (void *cls, | 141 | unsigned int |
140 | const struct GNUNET_HashCode *key, | 142 | (*get) (void *cls, |
141 | enum GNUNET_BLOCK_Type type, | 143 | const struct GNUNET_HashCode *key, |
142 | GNUNET_DATACACHE_Iterator iter, | 144 | enum GNUNET_BLOCK_Type type, |
143 | void *iter_cls); | 145 | GNUNET_DATACACHE_Iterator iter, |
146 | void *iter_cls); | ||
147 | |||
144 | 148 | ||
145 | /** | 149 | /** |
146 | * Delete the entry with the lowest expiration value | 150 | * Delete the entry with the lowest expiration value |
@@ -149,19 +153,8 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
149 | * @param cls closure (internal context for the plugin) | 153 | * @param cls closure (internal context for the plugin) |
150 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 154 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
151 | */ | 155 | */ |
152 | int (*del) (void *cls); | 156 | enum GNUNET_GenericReturnValue |
153 | 157 | (*del)(void *cls); | |
154 | /** | ||
155 | * Return a random value from the datastore. | ||
156 | * | ||
157 | * @param cls closure (internal context for the plugin) | ||
158 | * @param iter maybe NULL (to just count) | ||
159 | * @param iter_cls closure for @a iter | ||
160 | * @return the number of results found (zero or one) | ||
161 | */ | ||
162 | unsigned int (*get_random) (void *cls, | ||
163 | GNUNET_DATACACHE_Iterator iter, | ||
164 | void *iter_cls); | ||
165 | 158 | ||
166 | 159 | ||
167 | /** | 160 | /** |
@@ -177,11 +170,12 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
177 | * @param iter_cls closure for @a iter | 170 | * @param iter_cls closure for @a iter |
178 | * @return the number of results found | 171 | * @return the number of results found |
179 | */ | 172 | */ |
180 | unsigned int (*get_closest) (void *cls, | 173 | unsigned int |
181 | const struct GNUNET_HashCode *key, | 174 | (*get_closest) (void *cls, |
182 | unsigned int num_results, | 175 | const struct GNUNET_HashCode *key, |
183 | GNUNET_DATACACHE_Iterator iter, | 176 | unsigned int num_results, |
184 | void *iter_cls); | 177 | GNUNET_DATACACHE_Iterator iter, |
178 | void *iter_cls); | ||
185 | }; | 179 | }; |
186 | 180 | ||
187 | 181 | ||
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index d4a4ed7d2..160beffdd 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h | |||
@@ -56,6 +56,12 @@ extern "C" | |||
56 | 56 | ||
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Maximum allowed replication level for all requests. | ||
60 | */ | ||
61 | #define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL 16 | ||
62 | |||
63 | |||
64 | /** | ||
59 | * Connection to the DHT service. | 65 | * Connection to the DHT service. |
60 | */ | 66 | */ |
61 | struct GNUNET_DHT_Handle; | 67 | struct GNUNET_DHT_Handle; |
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h index 731be4159..259d648dd 100644 --- a/src/include/gnunet_getopt_lib.h +++ b/src/include/gnunet_getopt_lib.h | |||
@@ -378,6 +378,24 @@ GNUNET_GETOPT_option_absolute_time (char shortName, | |||
378 | 378 | ||
379 | 379 | ||
380 | /** | 380 | /** |
381 | * Allow user to specify a `struct GNUNET_TIME_Timestamp` | ||
382 | * (using human-readable "fancy" time). | ||
383 | * | ||
384 | * @param shortName short name of the option | ||
385 | * @param name long name of the option | ||
386 | * @param argumentHelp help text for the option argument | ||
387 | * @param description long help text for the option | ||
388 | * @param[out] val set to the time specified at the command line | ||
389 | */ | ||
390 | struct GNUNET_GETOPT_CommandLineOption | ||
391 | GNUNET_GETOPT_option_timestamp (char shortName, | ||
392 | const char *name, | ||
393 | const char *argumentHelp, | ||
394 | const char *description, | ||
395 | struct GNUNET_TIME_Timestamp *val); | ||
396 | |||
397 | |||
398 | /** | ||
381 | * Increment @a val each time the option flag is given by one. | 399 | * Increment @a val each time the option flag is given by one. |
382 | * | 400 | * |
383 | * @param shortName short name of the option | 401 | * @param shortName short name of the option |
diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h index c123983e2..e40a741bf 100644 --- a/src/include/gnunet_identity_service.h +++ b/src/include/gnunet_identity_service.h | |||
@@ -82,6 +82,8 @@ struct GNUNET_IDENTITY_Handle; | |||
82 | */ | 82 | */ |
83 | struct GNUNET_IDENTITY_Ego; | 83 | struct GNUNET_IDENTITY_Ego; |
84 | 84 | ||
85 | // FIXME: these types are NOT packed, | ||
86 | // NOT 64-bit aligned, but used in messages!!?? | ||
85 | 87 | ||
86 | /** | 88 | /** |
87 | * A private key for an identity as per LSD0001. | 89 | * A private key for an identity as per LSD0001. |
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 5ef4592e5..7d101196c 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -304,25 +304,25 @@ GNUNET_JSON_spec_boolean (const char *name, | |||
304 | /* ************ GNUnet-specific parser specifications ******************* */ | 304 | /* ************ GNUnet-specific parser specifications ******************* */ |
305 | 305 | ||
306 | /** | 306 | /** |
307 | * Absolute time. | 307 | * Timestamp. |
308 | * | 308 | * |
309 | * @param name name of the JSON field | 309 | * @param name name of the JSON field |
310 | * @param[out] at where to store the absolute time found under @a name | 310 | * @param[out] at where to store the absolute time found under @a name |
311 | */ | 311 | */ |
312 | struct GNUNET_JSON_Specification | 312 | struct GNUNET_JSON_Specification |
313 | GNUNET_JSON_spec_absolute_time (const char *name, | 313 | GNUNET_JSON_spec_timestamp (const char *name, |
314 | struct GNUNET_TIME_Absolute *at); | 314 | struct GNUNET_TIME_Timestamp *t); |
315 | 315 | ||
316 | 316 | ||
317 | /** | 317 | /** |
318 | * Absolute time in network byte order. | 318 | * Timestamp in network byte order. |
319 | * | 319 | * |
320 | * @param name name of the JSON field | 320 | * @param name name of the JSON field |
321 | * @param[out] at where to store the absolute time found under @a name | 321 | * @param[out] tn where to store the absolute time found under @a name |
322 | */ | 322 | */ |
323 | struct GNUNET_JSON_Specification | 323 | struct GNUNET_JSON_Specification |
324 | GNUNET_JSON_spec_absolute_time_nbo (const char *name, | 324 | GNUNET_JSON_spec_timestamp_nbo (const char *name, |
325 | struct GNUNET_TIME_AbsoluteNBO *at); | 325 | struct GNUNET_TIME_TimestampNBO *tn); |
326 | 326 | ||
327 | 327 | ||
328 | /** | 328 | /** |
@@ -385,23 +385,23 @@ GNUNET_JSON_from_data (const void *data, size_t size); | |||
385 | 385 | ||
386 | 386 | ||
387 | /** | 387 | /** |
388 | * Convert absolute timestamp to a json string. | 388 | * Convert timestamp to a json string. |
389 | * | 389 | * |
390 | * @param stamp the time stamp | 390 | * @param stamp the time stamp |
391 | * @return a json string with the timestamp in @a stamp | 391 | * @return a json string with the timestamp in @a stamp |
392 | */ | 392 | */ |
393 | json_t * | 393 | json_t * |
394 | GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp); | 394 | GNUNET_JSON_from_timestamp (struct GNUNET_TIME_Timestamp stamp); |
395 | 395 | ||
396 | 396 | ||
397 | /** | 397 | /** |
398 | * Convert absolute timestamp to a json string. | 398 | * Convert timestamp to a json string. |
399 | * | 399 | * |
400 | * @param stamp the time stamp | 400 | * @param stamp the time stamp |
401 | * @return a json string with the timestamp in @a stamp | 401 | * @return a json string with the timestamp in @a stamp |
402 | */ | 402 | */ |
403 | json_t * | 403 | json_t * |
404 | GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp); | 404 | GNUNET_JSON_from_timestamp_nbo (struct GNUNET_TIME_TimestampNBO stamp); |
405 | 405 | ||
406 | 406 | ||
407 | /** | 407 | /** |
@@ -747,30 +747,30 @@ GNUNET_JSON_pack_data_varsize (const char *name, | |||
747 | 747 | ||
748 | /** | 748 | /** |
749 | * Generate packer instruction for a JSON field of type | 749 | * Generate packer instruction for a JSON field of type |
750 | * absolute time. | 750 | * timestamp. |
751 | * | 751 | * |
752 | * @param name name of the field to add to the object | 752 | * @param name name of the field to add to the object |
753 | * @param at absolute time to pack, a value of 0 is only | 753 | * @param at timestamp pack, a value of 0 is only |
754 | * allowed with #GNUNET_JSON_pack_allow_null()! | 754 | * allowed with #GNUNET_JSON_pack_allow_null()! |
755 | * @return json pack specification | 755 | * @return json pack specification |
756 | */ | 756 | */ |
757 | struct GNUNET_JSON_PackSpec | 757 | struct GNUNET_JSON_PackSpec |
758 | GNUNET_JSON_pack_time_abs (const char *name, | 758 | GNUNET_JSON_pack_timestamp (const char *name, |
759 | struct GNUNET_TIME_Absolute at); | 759 | struct GNUNET_TIME_Timestamp at); |
760 | 760 | ||
761 | 761 | ||
762 | /** | 762 | /** |
763 | * Generate packer instruction for a JSON field of type | 763 | * Generate packer instruction for a JSON field of type |
764 | * absolute time in network byte order. | 764 | * timestamp in network byte order. |
765 | * | 765 | * |
766 | * @param name name of the field to add to the object | 766 | * @param name name of the field to add to the object |
767 | * @param at absolute time to pack, a value of 0 is only | 767 | * @param at timestamp to pack, a value of 0 is only |
768 | * allowed with #GNUNET_JSON_pack_allow_null()! | 768 | * allowed with #GNUNET_JSON_pack_allow_null()! |
769 | * @return json pack specification | 769 | * @return json pack specification |
770 | */ | 770 | */ |
771 | struct GNUNET_JSON_PackSpec | 771 | struct GNUNET_JSON_PackSpec |
772 | GNUNET_JSON_pack_time_abs_nbo (const char *name, | 772 | GNUNET_JSON_pack_timestamp_nbo (const char *name, |
773 | struct GNUNET_TIME_AbsoluteNBO at); | 773 | struct GNUNET_TIME_TimestampNBO at); |
774 | 774 | ||
775 | 775 | ||
776 | /** | 776 | /** |
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 05d373f88..f7bf59212 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -96,7 +96,11 @@ struct GNUNET_PQ_QueryParam | |||
96 | */ | 96 | */ |
97 | #define GNUNET_PQ_query_param_end \ | 97 | #define GNUNET_PQ_query_param_end \ |
98 | { \ | 98 | { \ |
99 | NULL, NULL, NULL, 0, 0 \ | 99 | .conv = NULL, \ |
100 | .conv_cls = NULL, \ | ||
101 | .data = NULL, \ | ||
102 | .size = 0, \ | ||
103 | .num_params = 0 \ | ||
100 | } | 104 | } |
101 | 105 | ||
102 | 106 | ||
@@ -200,6 +204,17 @@ GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | |||
200 | 204 | ||
201 | 205 | ||
202 | /** | 206 | /** |
207 | * Generate query parameter for a timestamp. | ||
208 | * The database must store a 64-bit integer. | ||
209 | * | ||
210 | * @param x pointer to the query parameter to pass | ||
211 | * @return query parameter to use | ||
212 | */ | ||
213 | struct GNUNET_PQ_QueryParam | ||
214 | GNUNET_PQ_query_param_timestamp (const struct GNUNET_TIME_Timestamp *x); | ||
215 | |||
216 | |||
217 | /** | ||
203 | * Generate query parameter for an absolute time value. | 218 | * Generate query parameter for an absolute time value. |
204 | * The database must store a 64-bit integer. | 219 | * The database must store a 64-bit integer. |
205 | * | 220 | * |
@@ -212,6 +227,18 @@ GNUNET_PQ_query_param_absolute_time_nbo ( | |||
212 | 227 | ||
213 | 228 | ||
214 | /** | 229 | /** |
230 | * Generate query parameter for a timestamp in NBO. | ||
231 | * The database must store a 64-bit integer. | ||
232 | * | ||
233 | * @param x pointer to the query parameter to pass | ||
234 | * @return query parameter to use | ||
235 | */ | ||
236 | struct GNUNET_PQ_QueryParam | ||
237 | GNUNET_PQ_query_param_timestamp_nbo ( | ||
238 | const struct GNUNET_TIME_TimestampNBO *t); | ||
239 | |||
240 | |||
241 | /** | ||
215 | * Generate query parameter for an uint16_t in host byte order. | 242 | * Generate query parameter for an uint16_t in host byte order. |
216 | * | 243 | * |
217 | * @param x pointer to the query parameter to pass | 244 | * @param x pointer to the query parameter to pass |
@@ -472,6 +499,18 @@ GNUNET_PQ_result_spec_absolute_time (const char *name, | |||
472 | 499 | ||
473 | 500 | ||
474 | /** | 501 | /** |
502 | * Timestamp expected. | ||
503 | * | ||
504 | * @param name name of the field in the table | ||
505 | * @param[out] t where to store the result | ||
506 | * @return array entry for the result specification to use | ||
507 | */ | ||
508 | struct GNUNET_PQ_ResultSpec | ||
509 | GNUNET_PQ_result_spec_timestamp (const char *name, | ||
510 | struct GNUNET_TIME_Timestamp *t); | ||
511 | |||
512 | |||
513 | /** | ||
475 | * Relative time expected. | 514 | * Relative time expected. |
476 | * | 515 | * |
477 | * @param name name of the field in the table | 516 | * @param name name of the field in the table |
@@ -496,6 +535,18 @@ GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, | |||
496 | 535 | ||
497 | 536 | ||
498 | /** | 537 | /** |
538 | * Timestamp expected. | ||
539 | * | ||
540 | * @param name name of the field in the table | ||
541 | * @param[out] tn where to store the result | ||
542 | * @return array entry for the result specification to use | ||
543 | */ | ||
544 | struct GNUNET_PQ_ResultSpec | ||
545 | GNUNET_PQ_result_spec_timestamp_nbo (const char *name, | ||
546 | struct GNUNET_TIME_TimestampNBO *tn); | ||
547 | |||
548 | |||
549 | /** | ||
499 | * uint16_t expected. | 550 | * uint16_t expected. |
500 | * | 551 | * |
501 | * @param name name of the field in the table | 552 | * @param name name of the field in the table |
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h deleted file mode 100644 index 7c0c1d104..000000000 --- a/src/include/gnunet_signatures.h +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Christian Grothoff | ||
23 | * | ||
24 | * @file | ||
25 | * Constants for network signatures | ||
26 | * | ||
27 | * @defgroup signatures Network signature definitions | ||
28 | * @{ | ||
29 | */ | ||
30 | |||
31 | #ifndef GNUNET_SIGNATURES_H | ||
32 | #define GNUNET_SIGNATURES_H | ||
33 | |||
34 | #ifdef __cplusplus | ||
35 | extern "C" | ||
36 | { | ||
37 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
38 | } | ||
39 | #endif | ||
40 | #endif | ||
41 | |||
42 | /** | ||
43 | * Test signature, not valid for anything other than writing | ||
44 | * a test. (Note that the signature verification code will | ||
45 | * accept this value). | ||
46 | */ | ||
47 | #define GNUNET_SIGNATURE_PURPOSE_TEST 0 | ||
48 | |||
49 | /** | ||
50 | * Signature for confirming that this peer uses a particular address. | ||
51 | */ | ||
52 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN 1 | ||
53 | |||
54 | /** | ||
55 | * Signature for confirming that this peer intends to disconnect. | ||
56 | */ | ||
57 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DISCONNECT 2 | ||
58 | |||
59 | /** | ||
60 | * Signature for confirming a key revocation. | ||
61 | */ | ||
62 | #define GNUNET_SIGNATURE_PURPOSE_REVOCATION 3 | ||
63 | |||
64 | /** | ||
65 | * Signature for a namespace/pseudonym advertisement (by | ||
66 | * the namespace owner). | ||
67 | */ | ||
68 | #define GNUNET_SIGNATURE_PURPOSE_NAMESPACE_ADVERTISEMENT 4 | ||
69 | |||
70 | /** | ||
71 | * Signature by which a peer affirms that it is | ||
72 | * providing a certain bit of content (used | ||
73 | * in LOCation URIs). | ||
74 | */ | ||
75 | #define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT 5 | ||
76 | |||
77 | /** | ||
78 | * Obsolete, legacy value. | ||
79 | */ | ||
80 | #define GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK 6 | ||
81 | |||
82 | /** | ||
83 | * Obsolete, legacy value. | ||
84 | */ | ||
85 | #define GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK 7 | ||
86 | |||
87 | /** | ||
88 | * Obsolete, legacy value. | ||
89 | */ | ||
90 | #define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK 8 | ||
91 | |||
92 | /** | ||
93 | * Obsolete, legacy value. | ||
94 | */ | ||
95 | #define GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG 9 | ||
96 | |||
97 | /** | ||
98 | * | ||
99 | */ | ||
100 | #define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 10 | ||
101 | |||
102 | /** | ||
103 | * Signature of an GNUNET_DNS_Advertisement | ||
104 | */ | ||
105 | #define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD 11 | ||
106 | |||
107 | /** | ||
108 | * Signature of a chat message. | ||
109 | */ | ||
110 | #define GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE 12 | ||
111 | |||
112 | /** | ||
113 | * Signature of confirmation receipt for a chat message. | ||
114 | */ | ||
115 | #define GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT 13 | ||
116 | |||
117 | /** | ||
118 | * Signature of a network size estimate message. | ||
119 | */ | ||
120 | #define GNUNET_SIGNATURE_PURPOSE_NSE_SEND 14 | ||
121 | |||
122 | /** | ||
123 | * Signature of a gnunet naming system record block | ||
124 | */ | ||
125 | #define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN 15 | ||
126 | |||
127 | /** | ||
128 | * Purpose is to set a session key. | ||
129 | */ | ||
130 | #define GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY 16 | ||
131 | |||
132 | /** | ||
133 | * UBlock Signature, done using DSS, not ECC | ||
134 | */ | ||
135 | #define GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK 17 | ||
136 | |||
137 | /** | ||
138 | * Accept state in regex DFA. Peer affirms that | ||
139 | * it offers the matching service. | ||
140 | */ | ||
141 | #define GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT 18 | ||
142 | |||
143 | /** | ||
144 | * Signature of a multicast message sent by the origin. | ||
145 | */ | ||
146 | #define GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE 19 | ||
147 | |||
148 | /** | ||
149 | * Signature of a conversation ring. | ||
150 | */ | ||
151 | #define GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING 20 | ||
152 | |||
153 | /** | ||
154 | * Signature for the first round of distributed key generation. | ||
155 | */ | ||
156 | #define GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1 21 | ||
157 | |||
158 | /** | ||
159 | * Signature for the second round of distributed key generation. | ||
160 | */ | ||
161 | #define GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2 22 | ||
162 | |||
163 | /** | ||
164 | * Signature for cooperatice decryption. | ||
165 | */ | ||
166 | #define GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION 23 | ||
167 | |||
168 | /** | ||
169 | * Signature of a multicast request sent by a member. | ||
170 | */ | ||
171 | #define GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST 24 | ||
172 | |||
173 | /** | ||
174 | * Signature for a sensor anomaly report message. | ||
175 | */ | ||
176 | #define GNUNET_SIGNATURE_PURPOSE_SENSOR_ANOMALY_REPORT 25 | ||
177 | |||
178 | /** | ||
179 | * Signature for a GNUid Token | ||
180 | */ | ||
181 | #define GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN 26 | ||
182 | |||
183 | /** | ||
184 | * Signature for a GNUid Ticket | ||
185 | */ | ||
186 | #define GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN 27 | ||
187 | |||
188 | /** | ||
189 | * Signature for a GNUnet credential | ||
190 | */ | ||
191 | #define GNUNET_SIGNATURE_PURPOSE_DELEGATE 28 | ||
192 | |||
193 | /** | ||
194 | * Signature by a peer affirming that this is one of its | ||
195 | * addresses (for the given time period). | ||
196 | */ | ||
197 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS 29 | ||
198 | |||
199 | /** | ||
200 | * Signature by a peer affirming that the given ephemeral | ||
201 | * key is currently in use by that peer's transport service. | ||
202 | */ | ||
203 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL 30 | ||
204 | |||
205 | /** | ||
206 | * Signature used by TCP communicator handshake, | ||
207 | */ | ||
208 | #define GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE 31 | ||
209 | |||
210 | /** | ||
211 | * Signature used by TCP communicator rekey. | ||
212 | */ | ||
213 | #define GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY 32 | ||
214 | |||
215 | /** | ||
216 | * Signature used by UDP communicator handshake | ||
217 | */ | ||
218 | #define GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE 33 | ||
219 | |||
220 | /** | ||
221 | * Signature used by UDP broadcasts. | ||
222 | */ | ||
223 | #define GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST 34 | ||
224 | |||
225 | /** | ||
226 | * Signature by a peer affirming that it received a | ||
227 | * challenge (and stating how long it expects the | ||
228 | * address on which the challenge was received to | ||
229 | * remain valid). | ||
230 | */ | ||
231 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE 35 | ||
232 | |||
233 | /** | ||
234 | * Signature by a peer affirming that it is on a DV path. | ||
235 | */ | ||
236 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP 36 | ||
237 | |||
238 | /** | ||
239 | * Signature by a peer affirming that it originated the | ||
240 | * DV path. | ||
241 | */ | ||
242 | #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37 | ||
243 | |||
244 | /** | ||
245 | * Signature by a peer that like to create a connection. | ||
246 | */ | ||
247 | #define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR 38 | ||
248 | |||
249 | /** | ||
250 | * Signature by a peer sending back the nonce received at initial handshake. | ||
251 | */ | ||
252 | #define GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK 39 | ||
253 | |||
254 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
255 | { | ||
256 | #endif | ||
257 | #ifdef __cplusplus | ||
258 | } | ||
259 | #endif | ||
260 | |||
261 | /* ifndef GNUNET_SIGNATURES_H */ | ||
262 | #endif | ||
263 | |||
264 | /** @} */ /* end of group */ | ||
265 | |||
266 | /* end of gnunet_signatures.h */ | ||
diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h index 21ce5b393..e89ded07e 100644 --- a/src/include/gnunet_sq_lib.h +++ b/src/include/gnunet_sq_lib.h | |||
@@ -40,7 +40,7 @@ | |||
40 | * so immediately suitable for passing to `sqlite3_bind`-functions. | 40 | * so immediately suitable for passing to `sqlite3_bind`-functions. |
41 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | 41 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success |
42 | */ | 42 | */ |
43 | typedef int | 43 | typedef enum GNUNET_GenericReturnValue |
44 | (*GNUNET_SQ_QueryConverter)(void *cls, | 44 | (*GNUNET_SQ_QueryConverter)(void *cls, |
45 | const void *data, | 45 | const void *data, |
46 | size_t data_len, | 46 | size_t data_len, |
@@ -156,8 +156,8 @@ GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | |||
156 | * @param x pointer to the query parameter to pass | 156 | * @param x pointer to the query parameter to pass |
157 | */ | 157 | */ |
158 | struct GNUNET_SQ_QueryParam | 158 | struct GNUNET_SQ_QueryParam |
159 | GNUNET_SQ_query_param_absolute_time_nbo (const struct | 159 | GNUNET_SQ_query_param_absolute_time_nbo ( |
160 | GNUNET_TIME_AbsoluteNBO *x); | 160 | const struct GNUNET_TIME_AbsoluteNBO *x); |
161 | 161 | ||
162 | 162 | ||
163 | /** | 163 | /** |
@@ -222,7 +222,7 @@ GNUNET_SQ_reset (sqlite3 *dbh, | |||
222 | * #GNUNET_YES if all results could be extracted | 222 | * #GNUNET_YES if all results could be extracted |
223 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | 223 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) |
224 | */ | 224 | */ |
225 | typedef int | 225 | typedef enum GNUNET_GenericReturnValue |
226 | (*GNUNET_SQ_ResultConverter)(void *cls, | 226 | (*GNUNET_SQ_ResultConverter)(void *cls, |
227 | sqlite3_stmt *result, | 227 | sqlite3_stmt *result, |
228 | unsigned int column, | 228 | unsigned int column, |
@@ -436,7 +436,7 @@ GNUNET_SQ_result_spec_uint64 (uint64_t *u64); | |||
436 | * #GNUNET_OK if all results could be extracted | 436 | * #GNUNET_OK if all results could be extracted |
437 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | 437 | * #GNUNET_SYSERR if a result was invalid (non-existing field) |
438 | */ | 438 | */ |
439 | int | 439 | enum GNUNET_GenericReturnValue |
440 | GNUNET_SQ_extract_result (sqlite3_stmt *result, | 440 | GNUNET_SQ_extract_result (sqlite3_stmt *result, |
441 | struct GNUNET_SQ_ResultSpec *rs); | 441 | struct GNUNET_SQ_ResultSpec *rs); |
442 | 442 | ||
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 977c2ead7..2e0c720ee 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -76,7 +76,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | |||
76 | * @param rtime set to the relative time | 76 | * @param rtime set to the relative time |
77 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 77 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
78 | */ | 78 | */ |
79 | int | 79 | enum GNUNET_GenericReturnValue |
80 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | 80 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, |
81 | struct GNUNET_TIME_Relative *rtime); | 81 | struct GNUNET_TIME_Relative *rtime); |
82 | 82 | ||
@@ -91,12 +91,27 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | |||
91 | * @param atime set to the absolute time | 91 | * @param atime set to the absolute time |
92 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 92 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
93 | */ | 93 | */ |
94 | int | 94 | enum GNUNET_GenericReturnValue |
95 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | 95 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, |
96 | struct GNUNET_TIME_Absolute *atime); | 96 | struct GNUNET_TIME_Absolute *atime); |
97 | 97 | ||
98 | 98 | ||
99 | /** | 99 | /** |
100 | * @ingroup time | ||
101 | * Convert a given fancy human-readable time to our internal | ||
102 | * representation. The human-readable time is expected to be | ||
103 | * in local time, whereas the returned value will be in UTC. | ||
104 | * | ||
105 | * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S) | ||
106 | * @param atime set to the absolute time | ||
107 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
108 | */ | ||
109 | enum GNUNET_GenericReturnValue | ||
110 | GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, | ||
111 | struct GNUNET_TIME_Timestamp *atime); | ||
112 | |||
113 | |||
114 | /** | ||
100 | * Convert a given filesize into a fancy human-readable format. | 115 | * Convert a given filesize into a fancy human-readable format. |
101 | * | 116 | * |
102 | * @param size number of bytes | 117 | * @param size number of bytes |
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h index 26b442066..b14439462 100644 --- a/src/include/gnunet_time_lib.h +++ b/src/include/gnunet_time_lib.h | |||
@@ -54,6 +54,17 @@ struct GNUNET_TIME_Absolute | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * Rounded time for timestamps used by GNUnet, in seconds. | ||
58 | */ | ||
59 | struct GNUNET_TIME_Timestamp | ||
60 | { | ||
61 | /** | ||
62 | * The actual value. Must be round number in seconds. | ||
63 | */ | ||
64 | struct GNUNET_TIME_Absolute abs_time; | ||
65 | }; | ||
66 | |||
67 | /** | ||
57 | * Time for relative time used by GNUnet, in microseconds. | 68 | * Time for relative time used by GNUnet, in microseconds. |
58 | * Always positive, so we can only refer to future time. | 69 | * Always positive, so we can only refer to future time. |
59 | */ | 70 | */ |
@@ -89,17 +100,34 @@ struct GNUNET_TIME_AbsoluteNBO | |||
89 | */ | 100 | */ |
90 | uint64_t abs_value_us__ GNUNET_PACKED; | 101 | uint64_t abs_value_us__ GNUNET_PACKED; |
91 | }; | 102 | }; |
103 | |||
104 | /** | ||
105 | * Time for timestamps used by GNUnet, in seconds and in network byte order. | ||
106 | */ | ||
107 | struct GNUNET_TIME_TimestampNBO | ||
108 | { | ||
109 | /** | ||
110 | * The actual value. Must be round number in seconds. | ||
111 | */ | ||
112 | struct GNUNET_TIME_AbsoluteNBO abs_time_nbo; | ||
113 | }; | ||
114 | |||
92 | GNUNET_NETWORK_STRUCT_END | 115 | GNUNET_NETWORK_STRUCT_END |
93 | 116 | ||
94 | /** | 117 | /** |
95 | * Relative time zero. | 118 | * Relative time zero. |
96 | */ | 119 | */ |
97 | #define GNUNET_TIME_UNIT_ZERO GNUNET_TIME_relative_get_zero_ () | 120 | #define GNUNET_TIME_UNIT_ZERO ((struct GNUNET_TIME_Relative){0}) |
98 | 121 | ||
99 | /** | 122 | /** |
100 | * Absolute time zero. | 123 | * Absolute time zero. |
101 | */ | 124 | */ |
102 | #define GNUNET_TIME_UNIT_ZERO_ABS GNUNET_TIME_absolute_get_zero_ () | 125 | #define GNUNET_TIME_UNIT_ZERO_ABS ((struct GNUNET_TIME_Absolute){0}) |
126 | |||
127 | /** | ||
128 | * Timestamp of zero. | ||
129 | */ | ||
130 | #define GNUNET_TIME_UNIT_ZERO_TS ((struct GNUNET_TIME_Timestamp){{0}}) | ||
103 | 131 | ||
104 | /** | 132 | /** |
105 | * One microsecond, our basic time unit. | 133 | * One microsecond, our basic time unit. |
@@ -154,13 +182,22 @@ GNUNET_NETWORK_STRUCT_END | |||
154 | * Constant used to specify "forever". This constant | 182 | * Constant used to specify "forever". This constant |
155 | * will be treated specially in all time operations. | 183 | * will be treated specially in all time operations. |
156 | */ | 184 | */ |
157 | #define GNUNET_TIME_UNIT_FOREVER_REL GNUNET_TIME_relative_get_forever_ () | 185 | #define GNUNET_TIME_UNIT_FOREVER_REL \ |
186 | ((struct GNUNET_TIME_Relative){UINT64_MAX}) | ||
158 | 187 | ||
159 | /** | 188 | /** |
160 | * Constant used to specify "forever". This constant | 189 | * Constant used to specify "forever". This constant |
161 | * will be treated specially in all time operations. | 190 | * will be treated specially in all time operations. |
162 | */ | 191 | */ |
163 | #define GNUNET_TIME_UNIT_FOREVER_ABS GNUNET_TIME_absolute_get_forever_ () | 192 | #define GNUNET_TIME_UNIT_FOREVER_ABS \ |
193 | ((struct GNUNET_TIME_Absolute){UINT64_MAX}) | ||
194 | |||
195 | /** | ||
196 | * Constant used to specify "forever". This constant | ||
197 | * will be treated specially in all time operations. | ||
198 | */ | ||
199 | #define GNUNET_TIME_UNIT_FOREVER_TS \ | ||
200 | ((struct GNUNET_TIME_Timestamp){{UINT64_MAX}}) | ||
164 | 201 | ||
165 | 202 | ||
166 | /** | 203 | /** |
@@ -183,6 +220,47 @@ GNUNET_NETWORK_STRUCT_END | |||
183 | 220 | ||
184 | 221 | ||
185 | /** | 222 | /** |
223 | * Convert @a ts to human-readable timestamp. | ||
224 | * Note that the returned value will be overwritten if this function | ||
225 | * is called again. | ||
226 | * | ||
227 | * @param ts the timestamp to convert | ||
228 | * @return statically allocated string, will change on the next call | ||
229 | */ | ||
230 | const char * | ||
231 | GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts); | ||
232 | |||
233 | |||
234 | /** | ||
235 | * @ingroup time | ||
236 | * Like `asctime`, except for GNUnet time. Converts a GNUnet internal | ||
237 | * absolute time (which is in UTC) to a string in local time. | ||
238 | * Note that the returned value will be overwritten if this function | ||
239 | * is called again. | ||
240 | * | ||
241 | * @param t the absolute time to convert | ||
242 | * @return timestamp in human-readable form in local time | ||
243 | */ | ||
244 | const char * | ||
245 | GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute ts); | ||
246 | |||
247 | |||
248 | /** | ||
249 | * @ingroup time | ||
250 | * Give relative time in human-readable fancy format. | ||
251 | * This is one of the very few calls in the entire API that is | ||
252 | * NOT reentrant! | ||
253 | * | ||
254 | * @param delta time in milli seconds | ||
255 | * @param do_round are we allowed to round a bit? | ||
256 | * @return string in human-readable form | ||
257 | */ | ||
258 | const char * | ||
259 | GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta, | ||
260 | bool do_round); | ||
261 | |||
262 | |||
263 | /** | ||
186 | * Randomized exponential back-off, starting at 1 ms | 264 | * Randomized exponential back-off, starting at 1 ms |
187 | * and going up by a factor of 2+r, where 0 <= r <= 0.5, up | 265 | * and going up by a factor of 2+r, where 0 <= r <= 0.5, up |
188 | * to a maximum of the given threshold. | 266 | * to a maximum of the given threshold. |
@@ -192,8 +270,8 @@ GNUNET_NETWORK_STRUCT_END | |||
192 | * @return the next backoff time | 270 | * @return the next backoff time |
193 | */ | 271 | */ |
194 | struct GNUNET_TIME_Relative | 272 | struct GNUNET_TIME_Relative |
195 | GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, struct | 273 | GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, |
196 | GNUNET_TIME_Relative threshold); | 274 | struct GNUNET_TIME_Relative threshold); |
197 | 275 | ||
198 | 276 | ||
199 | /** | 277 | /** |
@@ -290,27 +368,69 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel); | |||
290 | 368 | ||
291 | 369 | ||
292 | /** | 370 | /** |
293 | * Round a time value so that it is suitable for transmission | 371 | * Convert relative time to a timestamp in the |
294 | * via JSON encodings. | 372 | * future. |
373 | * | ||
374 | * @param rel relative time to convert | ||
375 | * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow) | ||
376 | */ | ||
377 | struct GNUNET_TIME_Timestamp | ||
378 | GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel); | ||
379 | |||
380 | |||
381 | /** | ||
382 | * Round an absolute time to a timestamp. | ||
295 | * | 383 | * |
296 | * @param at time to round | 384 | * @param at time to round |
297 | * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if | 385 | * @return the result |
298 | * it was just now rounded | ||
299 | */ | 386 | */ |
300 | int | 387 | struct GNUNET_TIME_Timestamp |
301 | GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at); | 388 | GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at); |
302 | 389 | ||
303 | 390 | ||
304 | /** | 391 | /** |
305 | * Round a time value so that it is suitable for transmission | 392 | * Get timestamp representing the current time. |
306 | * via JSON encodings. | ||
307 | * | 393 | * |
308 | * @param rt time to round | 394 | * @return current time, rounded down to seconds |
309 | * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if | ||
310 | * it was just now rounded | ||
311 | */ | 395 | */ |
312 | int | 396 | struct GNUNET_TIME_Timestamp |
313 | GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt); | 397 | GNUNET_TIME_timestamp_get (void); |
398 | |||
399 | |||
400 | /** | ||
401 | * Compare two absolute times. | ||
402 | * | ||
403 | * @param t1 first time | ||
404 | * @param op compare operator | ||
405 | * @param t2 second time | ||
406 | * @return true if @a t1 @a op @a t2 | ||
407 | */ | ||
408 | #define GNUNET_TIME_absolute_cmp(t1,op,t2) \ | ||
409 | ((void) (1 op 2), (t1).abs_value_us op (t2).abs_value_us) | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Compare two timestamps | ||
414 | * | ||
415 | * @param t1 first timestamp | ||
416 | * @param op compare operator | ||
417 | * @param t2 second timestamp | ||
418 | * @return true if @a t1 @a op @a t2 | ||
419 | */ | ||
420 | #define GNUNET_TIME_timestamp_cmp(t1,op,t2) \ | ||
421 | GNUNET_TIME_absolute_cmp ((t1).abs_time,op,(t2).abs_time) | ||
422 | |||
423 | |||
424 | /** | ||
425 | * Compare two relative times. | ||
426 | * | ||
427 | * @param t1 first time | ||
428 | * @param op compare operator | ||
429 | * @param t2 second time | ||
430 | * @return true if @a t1 @a op @a t2 | ||
431 | */ | ||
432 | #define GNUNET_TIME_relative_cmp(t1,op,t2) \ | ||
433 | ((void) (1 op 2), (t1).rel_value_us op (t2).rel_value_us) | ||
314 | 434 | ||
315 | 435 | ||
316 | /** | 436 | /** |
@@ -362,6 +482,30 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, | |||
362 | 482 | ||
363 | 483 | ||
364 | /** | 484 | /** |
485 | * Return the maximum of two timestamps. | ||
486 | * | ||
487 | * @param t1 first timestamp | ||
488 | * @param t2 other timestamp | ||
489 | * @return timestamp that is smaller | ||
490 | */ | ||
491 | struct GNUNET_TIME_Timestamp | ||
492 | GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1, | ||
493 | struct GNUNET_TIME_Timestamp t2); | ||
494 | |||
495 | |||
496 | /** | ||
497 | * Return the minimum of two timestamps. | ||
498 | * | ||
499 | * @param t1 first timestamp | ||
500 | * @param t2 other timestamp | ||
501 | * @return timestamp that is smaller | ||
502 | */ | ||
503 | struct GNUNET_TIME_Timestamp | ||
504 | GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1, | ||
505 | struct GNUNET_TIME_Timestamp t2); | ||
506 | |||
507 | |||
508 | /** | ||
365 | * Given a timestamp in the future, how much time | 509 | * Given a timestamp in the future, how much time |
366 | * remains until then? | 510 | * remains until then? |
367 | * | 511 | * |
@@ -530,6 +674,16 @@ GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a); | |||
530 | 674 | ||
531 | 675 | ||
532 | /** | 676 | /** |
677 | * Convert timestamp to network byte order. | ||
678 | * | ||
679 | * @param t time to convert | ||
680 | * @return converted time value | ||
681 | */ | ||
682 | struct GNUNET_TIME_TimestampNBO | ||
683 | GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t); | ||
684 | |||
685 | |||
686 | /** | ||
533 | * Convert milliseconds after the UNIX epoch to absolute time. | 687 | * Convert milliseconds after the UNIX epoch to absolute time. |
534 | * | 688 | * |
535 | * @param ms_after_epoch millisecond timestamp to convert | 689 | * @param ms_after_epoch millisecond timestamp to convert |
@@ -558,6 +712,15 @@ GNUNET_TIME_absolute_is_past (struct GNUNET_TIME_Absolute abs); | |||
558 | 712 | ||
559 | 713 | ||
560 | /** | 714 | /** |
715 | * Test if @a abs is truly zero. | ||
716 | * | ||
717 | * @return true if it is. | ||
718 | */ | ||
719 | bool | ||
720 | GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs); | ||
721 | |||
722 | |||
723 | /** | ||
561 | * Test if @a abs is truly in the future (excluding now). | 724 | * Test if @a abs is truly in the future (excluding now). |
562 | * | 725 | * |
563 | * @return true if it is. | 726 | * @return true if it is. |
@@ -595,6 +758,15 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch); | |||
595 | 758 | ||
596 | 759 | ||
597 | /** | 760 | /** |
761 | * Convert seconds after the UNIX epoch to timestamp. | ||
762 | * | ||
763 | * @param s_after_epoch seconds after epoch to convert | ||
764 | * @return converted time value | ||
765 | */struct GNUNET_TIME_Timestamp | ||
766 | GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch); | ||
767 | |||
768 | |||
769 | /** | ||
598 | * Convert absolute time from network byte order. | 770 | * Convert absolute time from network byte order. |
599 | * | 771 | * |
600 | * @param a time to convert | 772 | * @param a time to convert |
@@ -605,6 +777,16 @@ GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a); | |||
605 | 777 | ||
606 | 778 | ||
607 | /** | 779 | /** |
780 | * Convert timestamp from network byte order. | ||
781 | * | ||
782 | * @param tn time to convert | ||
783 | * @return converted time value | ||
784 | */ | ||
785 | struct GNUNET_TIME_Timestamp | ||
786 | GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn); | ||
787 | |||
788 | |||
789 | /** | ||
608 | * Set the timestamp offset for this instance. | 790 | * Set the timestamp offset for this instance. |
609 | * | 791 | * |
610 | * @param offset the offset to skew the locale time by | 792 | * @param offset the offset to skew the locale time by |
diff --git a/src/json/json_generator.c b/src/json/json_generator.c index 0c513ca9d..5421b9527 100644 --- a/src/json/json_generator.c +++ b/src/json/json_generator.c | |||
@@ -27,14 +27,6 @@ | |||
27 | #include "gnunet_json_lib.h" | 27 | #include "gnunet_json_lib.h" |
28 | 28 | ||
29 | 29 | ||
30 | /** | ||
31 | * Convert binary data to a JSON string | ||
32 | * with the base32crockford encoding. | ||
33 | * | ||
34 | * @param data binary data | ||
35 | * @param size size of @a data in bytes | ||
36 | * @return json string that encodes @a data | ||
37 | */ | ||
38 | json_t * | 30 | json_t * |
39 | GNUNET_JSON_from_data (const void *data, | 31 | GNUNET_JSON_from_data (const void *data, |
40 | size_t size) | 32 | size_t size) |
@@ -57,30 +49,30 @@ GNUNET_JSON_from_data (const void *data, | |||
57 | } | 49 | } |
58 | 50 | ||
59 | 51 | ||
60 | /** | ||
61 | * Convert absolute timestamp to a json string. | ||
62 | * | ||
63 | * @param stamp the time stamp | ||
64 | * @return a json string with the timestamp in @a stamp | ||
65 | */ | ||
66 | json_t * | 52 | json_t * |
67 | GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp) | 53 | GNUNET_JSON_from_timestamp (struct GNUNET_TIME_Timestamp stamp) |
68 | { | 54 | { |
69 | json_t *j; | 55 | json_t *j; |
70 | 56 | ||
71 | GNUNET_assert (GNUNET_OK == | ||
72 | GNUNET_TIME_round_abs (&stamp)); | ||
73 | |||
74 | j = json_object (); | 57 | j = json_object (); |
75 | if (NULL == j) | 58 | if (NULL == j) |
76 | { | 59 | { |
77 | GNUNET_break (0); | 60 | GNUNET_break (0); |
78 | return NULL; | 61 | return NULL; |
79 | } | 62 | } |
80 | if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 63 | if (GNUNET_TIME_absolute_is_never (stamp.abs_time)) |
81 | { | 64 | { |
82 | if (0 != | 65 | if (0 != |
83 | json_object_set_new (j, | 66 | json_object_set_new (j, |
67 | "t_s", | ||
68 | json_string ("never"))) | ||
69 | { | ||
70 | GNUNET_break (0); | ||
71 | json_decref (j); | ||
72 | return NULL; | ||
73 | } | ||
74 | if (0 != | ||
75 | json_object_set_new (j, | ||
84 | "t_ms", | 76 | "t_ms", |
85 | json_string ("never"))) | 77 | json_string ("never"))) |
86 | { | 78 | { |
@@ -90,11 +82,29 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp) | |||
90 | } | 82 | } |
91 | return j; | 83 | return j; |
92 | } | 84 | } |
85 | GNUNET_assert ( | ||
86 | 0 == | ||
87 | (stamp.abs_time.abs_value_us | ||
88 | % GNUNET_TIME_UNIT_SECONDS.rel_value_us)); | ||
93 | if (0 != | 89 | if (0 != |
94 | json_object_set_new (j, | 90 | json_object_set_new ( |
95 | "t_ms", | 91 | j, |
96 | json_integer ((json_int_t) (stamp.abs_value_us | 92 | "t_s", |
97 | / 1000LL)))) | 93 | json_integer ( |
94 | (json_int_t) (stamp.abs_time.abs_value_us | ||
95 | / GNUNET_TIME_UNIT_SECONDS.rel_value_us)))) | ||
96 | { | ||
97 | GNUNET_break (0); | ||
98 | json_decref (j); | ||
99 | return NULL; | ||
100 | } | ||
101 | if (0 != | ||
102 | json_object_set_new ( | ||
103 | j, | ||
104 | "t_ms", | ||
105 | json_integer ( | ||
106 | (json_int_t) (stamp.abs_time.abs_value_us | ||
107 | / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us)))) | ||
98 | { | 108 | { |
99 | GNUNET_break (0); | 109 | GNUNET_break (0); |
100 | json_decref (j); | 110 | json_decref (j); |
@@ -104,43 +114,37 @@ GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp) | |||
104 | } | 114 | } |
105 | 115 | ||
106 | 116 | ||
107 | /** | ||
108 | * Convert absolute timestamp to a json string. | ||
109 | * | ||
110 | * @param stamp the time stamp | ||
111 | * @return a json string with the timestamp in @a stamp | ||
112 | */ | ||
113 | json_t * | 117 | json_t * |
114 | GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp) | 118 | GNUNET_JSON_from_timestamp_nbo (struct GNUNET_TIME_TimestampNBO stamp) |
115 | { | 119 | { |
116 | return GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (stamp)); | 120 | return GNUNET_JSON_from_timestamp (GNUNET_TIME_timestamp_ntoh (stamp)); |
117 | } | 121 | } |
118 | 122 | ||
119 | 123 | ||
120 | /** | ||
121 | * Convert relative timestamp to a json string. | ||
122 | * | ||
123 | * @param stamp the time stamp | ||
124 | * @return a json string with the timestamp in @a stamp | ||
125 | */ | ||
126 | json_t * | 124 | json_t * |
127 | GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp) | 125 | GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp) |
128 | { | 126 | { |
129 | json_t *j; | 127 | json_t *j; |
130 | 128 | ||
131 | GNUNET_assert (GNUNET_OK == | ||
132 | GNUNET_TIME_round_rel (&stamp)); | ||
133 | |||
134 | j = json_object (); | 129 | j = json_object (); |
135 | if (NULL == j) | 130 | if (NULL == j) |
136 | { | 131 | { |
137 | GNUNET_break (0); | 132 | GNUNET_break (0); |
138 | return NULL; | 133 | return NULL; |
139 | } | 134 | } |
140 | if (stamp.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 135 | if (GNUNET_TIME_relative_is_forever (stamp)) |
141 | { | 136 | { |
142 | if (0 != | 137 | if (0 != |
143 | json_object_set_new (j, | 138 | json_object_set_new (j, |
139 | "d_us", | ||
140 | json_string ("forever"))) | ||
141 | { | ||
142 | GNUNET_break (0); | ||
143 | json_decref (j); | ||
144 | return NULL; | ||
145 | } | ||
146 | if (0 != | ||
147 | json_object_set_new (j, | ||
144 | "d_ms", | 148 | "d_ms", |
145 | json_string ("forever"))) | 149 | json_string ("forever"))) |
146 | { | 150 | { |
@@ -150,11 +154,27 @@ GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp) | |||
150 | } | 154 | } |
151 | return j; | 155 | return j; |
152 | } | 156 | } |
157 | if (stamp.rel_value_us >= (1LLU << 53)) | ||
158 | { | ||
159 | /* value is larger than allowed */ | ||
160 | GNUNET_break (0); | ||
161 | return NULL; | ||
162 | } | ||
153 | if (0 != | 163 | if (0 != |
154 | json_object_set_new (j, | 164 | json_object_set_new ( |
155 | "d_ms", | 165 | j, |
156 | json_integer ((json_int_t) (stamp.rel_value_us | 166 | "d_us", |
157 | / 1000LL)))) | 167 | json_integer ((json_int_t) stamp.rel_value_us))) |
168 | { | ||
169 | GNUNET_break (0); | ||
170 | json_decref (j); | ||
171 | return NULL; | ||
172 | } | ||
173 | if (0 != | ||
174 | json_object_set_new ( | ||
175 | j, | ||
176 | "d_ms", | ||
177 | json_integer (((json_int_t) stamp.rel_value_us)/1000LL))) | ||
158 | { | 178 | { |
159 | GNUNET_break (0); | 179 | GNUNET_break (0); |
160 | json_decref (j); | 180 | json_decref (j); |
@@ -164,12 +184,6 @@ GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp) | |||
164 | } | 184 | } |
165 | 185 | ||
166 | 186 | ||
167 | /** | ||
168 | * Convert RSA public key to JSON. | ||
169 | * | ||
170 | * @param pk public key to convert | ||
171 | * @return corresponding JSON encoding | ||
172 | */ | ||
173 | json_t * | 187 | json_t * |
174 | GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk) | 188 | GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk) |
175 | { | 189 | { |
@@ -186,12 +200,6 @@ GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk) | |||
186 | } | 200 | } |
187 | 201 | ||
188 | 202 | ||
189 | /** | ||
190 | * Convert RSA signature to JSON. | ||
191 | * | ||
192 | * @param sig signature to convert | ||
193 | * @return corresponding JSON encoding | ||
194 | */ | ||
195 | json_t * | 203 | json_t * |
196 | GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig) | 204 | GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig) |
197 | { | 205 | { |
diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 3a11f205c..c0513c529 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c | |||
@@ -49,7 +49,7 @@ GNUNET_JSON_spec_end () | |||
49 | * @param[out] spec where to write the data | 49 | * @param[out] spec where to write the data |
50 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 50 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
51 | */ | 51 | */ |
52 | static int | 52 | static enum GNUNET_GenericReturnValue |
53 | parse_fixed_data (void *cls, | 53 | parse_fixed_data (void *cls, |
54 | json_t *root, | 54 | json_t *root, |
55 | struct GNUNET_JSON_Specification *spec) | 55 | struct GNUNET_JSON_Specification *spec) |
@@ -579,19 +579,20 @@ GNUNET_JSON_spec_int64 (const char *name, | |||
579 | /* ************ GNUnet-specific parser specifications ******************* */ | 579 | /* ************ GNUnet-specific parser specifications ******************* */ |
580 | 580 | ||
581 | /** | 581 | /** |
582 | * Parse given JSON object to absolute time. | 582 | * Parse given JSON object to a timestamp. |
583 | * | 583 | * |
584 | * @param cls closure, NULL | 584 | * @param cls closure, NULL |
585 | * @param root the json object representing data | 585 | * @param root the json object representing data |
586 | * @param[out] spec where to write the data | 586 | * @param[out] spec where to write the data |
587 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 587 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
588 | */ | 588 | */ |
589 | static int | 589 | static enum GNUNET_GenericReturnValue |
590 | parse_abs_time (void *cls, | 590 | parse_timestamp (void *cls, |
591 | json_t *root, | 591 | json_t *root, |
592 | struct GNUNET_JSON_Specification *spec) | 592 | struct GNUNET_JSON_Specification *spec) |
593 | { | 593 | { |
594 | struct GNUNET_TIME_Absolute *abs = spec->ptr; | 594 | struct GNUNET_TIME_Timestamp *ts = spec->ptr; |
595 | json_t *json_t_s; | ||
595 | json_t *json_t_ms; | 596 | json_t *json_t_ms; |
596 | unsigned long long int tval; | 597 | unsigned long long int tval; |
597 | 598 | ||
@@ -600,13 +601,49 @@ parse_abs_time (void *cls, | |||
600 | GNUNET_break_op (0); | 601 | GNUNET_break_op (0); |
601 | return GNUNET_SYSERR; | 602 | return GNUNET_SYSERR; |
602 | } | 603 | } |
603 | json_t_ms = json_object_get (root, "t_ms"); | 604 | json_t_s = json_object_get (root, |
605 | "t_s"); | ||
606 | if (json_is_integer (json_t_s)) | ||
607 | { | ||
608 | tval = json_integer_value (json_t_s); | ||
609 | /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ | ||
610 | ts->abs_time.abs_value_us | ||
611 | = tval * GNUNET_TIME_UNIT_SECONDS.rel_value_us; | ||
612 | if (ts->abs_time.abs_value_us | ||
613 | / GNUNET_TIME_UNIT_SECONDS.rel_value_us | ||
614 | != tval) | ||
615 | { | ||
616 | /* Integer overflow */ | ||
617 | GNUNET_break_op (0); | ||
618 | return GNUNET_SYSERR; | ||
619 | } | ||
620 | return GNUNET_OK; | ||
621 | } | ||
622 | if (json_is_string (json_t_s)) | ||
623 | { | ||
624 | const char *val; | ||
625 | |||
626 | val = json_string_value (json_t_s); | ||
627 | if ((0 == strcasecmp (val, | ||
628 | "never"))) | ||
629 | { | ||
630 | ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
631 | return GNUNET_OK; | ||
632 | } | ||
633 | GNUNET_break_op (0); | ||
634 | return GNUNET_SYSERR; | ||
635 | } | ||
636 | json_t_ms = json_object_get (root, | ||
637 | "t_ms"); | ||
604 | if (json_is_integer (json_t_ms)) | 638 | if (json_is_integer (json_t_ms)) |
605 | { | 639 | { |
606 | tval = json_integer_value (json_t_ms); | 640 | tval = json_integer_value (json_t_ms); |
607 | /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ | 641 | GNUNET_break_op (0 == tval % 1000); |
608 | abs->abs_value_us = tval * GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; | 642 | tval -= tval % 1000; |
609 | if ((abs->abs_value_us) | 643 | /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ |
644 | ts->abs_time.abs_value_us | ||
645 | = tval * GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; | ||
646 | if (ts->abs_time.abs_value_us | ||
610 | / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us | 647 | / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us |
611 | != tval) | 648 | != tval) |
612 | { | 649 | { |
@@ -621,9 +658,10 @@ parse_abs_time (void *cls, | |||
621 | const char *val; | 658 | const char *val; |
622 | 659 | ||
623 | val = json_string_value (json_t_ms); | 660 | val = json_string_value (json_t_ms); |
624 | if ((0 == strcasecmp (val, "never"))) | 661 | if ((0 == strcasecmp (val, |
662 | "never"))) | ||
625 | { | 663 | { |
626 | *abs = GNUNET_TIME_UNIT_FOREVER_ABS; | 664 | ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS; |
627 | return GNUNET_OK; | 665 | return GNUNET_OK; |
628 | } | 666 | } |
629 | GNUNET_break_op (0); | 667 | GNUNET_break_op (0); |
@@ -635,17 +673,14 @@ parse_abs_time (void *cls, | |||
635 | 673 | ||
636 | 674 | ||
637 | struct GNUNET_JSON_Specification | 675 | struct GNUNET_JSON_Specification |
638 | GNUNET_JSON_spec_absolute_time (const char *name, | 676 | GNUNET_JSON_spec_timestamp (const char *name, |
639 | struct GNUNET_TIME_Absolute *at) | 677 | struct GNUNET_TIME_Timestamp *t) |
640 | { | 678 | { |
641 | struct GNUNET_JSON_Specification ret = { | 679 | struct GNUNET_JSON_Specification ret = { |
642 | .parser = &parse_abs_time, | 680 | .parser = &parse_timestamp, |
643 | .cleaner = NULL, | ||
644 | .cls = NULL, | ||
645 | .field = name, | 681 | .field = name, |
646 | .ptr = at, | 682 | .ptr = t, |
647 | .ptr_size = sizeof(struct GNUNET_TIME_Absolute), | 683 | .ptr_size = sizeof(struct GNUNET_TIME_Timestamp) |
648 | .size_ptr = NULL | ||
649 | }; | 684 | }; |
650 | 685 | ||
651 | return ret; | 686 | return ret; |
@@ -660,40 +695,37 @@ GNUNET_JSON_spec_absolute_time (const char *name, | |||
660 | * @param[out] spec where to write the data | 695 | * @param[out] spec where to write the data |
661 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 696 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
662 | */ | 697 | */ |
663 | static int | 698 | static enum GNUNET_GenericReturnValue |
664 | parse_abs_time_nbo (void *cls, | 699 | parse_timestamp_nbo (void *cls, |
665 | json_t *root, | 700 | json_t *root, |
666 | struct GNUNET_JSON_Specification *spec) | 701 | struct GNUNET_JSON_Specification *spec) |
667 | { | 702 | { |
668 | struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr; | 703 | struct GNUNET_TIME_TimestampNBO *ts = spec->ptr; |
669 | struct GNUNET_TIME_Absolute a; | 704 | struct GNUNET_TIME_Timestamp a; |
670 | struct GNUNET_JSON_Specification ispec; | 705 | struct GNUNET_JSON_Specification ispec; |
671 | 706 | ||
672 | ispec = *spec; | 707 | ispec = *spec; |
673 | ispec.parser = &parse_abs_time; | 708 | ispec.parser = &parse_timestamp; |
674 | ispec.ptr = &a; | 709 | ispec.ptr = &a; |
675 | if (GNUNET_OK != | 710 | if (GNUNET_OK != |
676 | parse_abs_time (NULL, | 711 | parse_timestamp (NULL, |
677 | root, | 712 | root, |
678 | &ispec)) | 713 | &ispec)) |
679 | return GNUNET_SYSERR; | 714 | return GNUNET_SYSERR; |
680 | *abs = GNUNET_TIME_absolute_hton (a); | 715 | *ts = GNUNET_TIME_timestamp_hton (a); |
681 | return GNUNET_OK; | 716 | return GNUNET_OK; |
682 | } | 717 | } |
683 | 718 | ||
684 | 719 | ||
685 | struct GNUNET_JSON_Specification | 720 | struct GNUNET_JSON_Specification |
686 | GNUNET_JSON_spec_absolute_time_nbo (const char *name, | 721 | GNUNET_JSON_spec_timestamp_nbo (const char *name, |
687 | struct GNUNET_TIME_AbsoluteNBO *at) | 722 | struct GNUNET_TIME_TimestampNBO *at) |
688 | { | 723 | { |
689 | struct GNUNET_JSON_Specification ret = { | 724 | struct GNUNET_JSON_Specification ret = { |
690 | .parser = &parse_abs_time_nbo, | 725 | .parser = &parse_timestamp_nbo, |
691 | .cleaner = NULL, | ||
692 | .cls = NULL, | ||
693 | .field = name, | 726 | .field = name, |
694 | .ptr = at, | 727 | .ptr = at, |
695 | .ptr_size = sizeof(struct GNUNET_TIME_AbsoluteNBO), | 728 | .ptr_size = sizeof(struct GNUNET_TIME_TimestampNBO) |
696 | .size_ptr = NULL | ||
697 | }; | 729 | }; |
698 | 730 | ||
699 | return ret; | 731 | return ret; |
@@ -708,12 +740,13 @@ GNUNET_JSON_spec_absolute_time_nbo (const char *name, | |||
708 | * @param[out] spec where to write the data | 740 | * @param[out] spec where to write the data |
709 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 741 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
710 | */ | 742 | */ |
711 | static int | 743 | static enum GNUNET_GenericReturnValue |
712 | parse_rel_time (void *cls, | 744 | parse_rel_time (void *cls, |
713 | json_t *root, | 745 | json_t *root, |
714 | struct GNUNET_JSON_Specification *spec) | 746 | struct GNUNET_JSON_Specification *spec) |
715 | { | 747 | { |
716 | struct GNUNET_TIME_Relative *rel = spec->ptr; | 748 | struct GNUNET_TIME_Relative *rel = spec->ptr; |
749 | json_t *json_d_us; | ||
717 | json_t *json_d_ms; | 750 | json_t *json_d_ms; |
718 | unsigned long long int tval; | 751 | unsigned long long int tval; |
719 | 752 | ||
@@ -722,25 +755,52 @@ parse_rel_time (void *cls, | |||
722 | GNUNET_break_op (0); | 755 | GNUNET_break_op (0); |
723 | return GNUNET_SYSERR; | 756 | return GNUNET_SYSERR; |
724 | } | 757 | } |
725 | json_d_ms = json_object_get (root, "d_ms"); | 758 | json_d_us = json_object_get (root, |
726 | if (json_is_integer (json_d_ms)) | 759 | "d_us"); |
760 | if (json_is_integer (json_d_us)) | ||
727 | { | 761 | { |
728 | tval = json_integer_value (json_d_ms); | 762 | tval = json_integer_value (json_d_us); |
729 | /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ | 763 | if (tval >= (1LLU << 53)) |
730 | rel->rel_value_us = tval * 1000LL; | ||
731 | if ((rel->rel_value_us) / 1000LL != tval) | ||
732 | { | 764 | { |
733 | /* Integer overflow */ | 765 | /* value is larger than allowed */ |
734 | GNUNET_break_op (0); | 766 | GNUNET_break_op (0); |
735 | return GNUNET_SYSERR; | 767 | return GNUNET_SYSERR; |
736 | } | 768 | } |
769 | rel->rel_value_us = tval; | ||
770 | return GNUNET_OK; | ||
771 | } | ||
772 | if (json_is_string (json_d_us)) | ||
773 | { | ||
774 | const char *val; | ||
775 | |||
776 | val = json_string_value (json_d_us); | ||
777 | if ((0 == strcasecmp (val, | ||
778 | "forever"))) | ||
779 | { | ||
780 | *rel = GNUNET_TIME_UNIT_FOREVER_REL; | ||
781 | return GNUNET_OK; | ||
782 | } | ||
783 | GNUNET_break_op (0); | ||
784 | return GNUNET_SYSERR; | ||
785 | } | ||
786 | |||
787 | json_d_ms = json_object_get (root, | ||
788 | "d_ms"); | ||
789 | if (json_is_integer (json_d_ms)) | ||
790 | { | ||
791 | tval = json_integer_value (json_d_ms); | ||
792 | *rel = GNUNET_TIME_relative_multiply ( | ||
793 | GNUNET_TIME_UNIT_MILLISECONDS, | ||
794 | tval); | ||
737 | return GNUNET_OK; | 795 | return GNUNET_OK; |
738 | } | 796 | } |
739 | if (json_is_string (json_d_ms)) | 797 | if (json_is_string (json_d_ms)) |
740 | { | 798 | { |
741 | const char *val; | 799 | const char *val; |
800 | |||
742 | val = json_string_value (json_d_ms); | 801 | val = json_string_value (json_d_ms); |
743 | if ((0 == strcasecmp (val, "forever"))) | 802 | if ((0 == strcasecmp (val, |
803 | "forever"))) | ||
744 | { | 804 | { |
745 | *rel = GNUNET_TIME_UNIT_FOREVER_REL; | 805 | *rel = GNUNET_TIME_UNIT_FOREVER_REL; |
746 | return GNUNET_OK; | 806 | return GNUNET_OK; |
@@ -759,12 +819,9 @@ GNUNET_JSON_spec_relative_time (const char *name, | |||
759 | { | 819 | { |
760 | struct GNUNET_JSON_Specification ret = { | 820 | struct GNUNET_JSON_Specification ret = { |
761 | .parser = &parse_rel_time, | 821 | .parser = &parse_rel_time, |
762 | .cleaner = NULL, | ||
763 | .cls = NULL, | ||
764 | .field = name, | 822 | .field = name, |
765 | .ptr = rt, | 823 | .ptr = rt, |
766 | .ptr_size = sizeof(struct GNUNET_TIME_Relative), | 824 | .ptr_size = sizeof(struct GNUNET_TIME_Relative) |
767 | .size_ptr = NULL | ||
768 | }; | 825 | }; |
769 | 826 | ||
770 | return ret; | 827 | return ret; |
@@ -779,7 +836,7 @@ GNUNET_JSON_spec_relative_time (const char *name, | |||
779 | * @param[out] spec where to write the data | 836 | * @param[out] spec where to write the data |
780 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 837 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
781 | */ | 838 | */ |
782 | static int | 839 | static enum GNUNET_GenericReturnValue |
783 | parse_rsa_public_key (void *cls, | 840 | parse_rsa_public_key (void *cls, |
784 | json_t *root, | 841 | json_t *root, |
785 | struct GNUNET_JSON_Specification *spec) | 842 | struct GNUNET_JSON_Specification *spec) |
@@ -864,7 +921,7 @@ GNUNET_JSON_spec_rsa_public_key (const char *name, | |||
864 | * @param[out] spec where to write the data | 921 | * @param[out] spec where to write the data |
865 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 922 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
866 | */ | 923 | */ |
867 | static int | 924 | static enum GNUNET_GenericReturnValue |
868 | parse_rsa_signature (void *cls, | 925 | parse_rsa_signature (void *cls, |
869 | json_t *root, | 926 | json_t *root, |
870 | struct GNUNET_JSON_Specification *spec) | 927 | struct GNUNET_JSON_Specification *spec) |
@@ -952,7 +1009,7 @@ GNUNET_JSON_spec_rsa_signature (const char *name, | |||
952 | * @param[out] spec where to write the data | 1009 | * @param[out] spec where to write the data |
953 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error | 1010 | * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error |
954 | */ | 1011 | */ |
955 | static int | 1012 | static enum GNUNET_GenericReturnValue |
956 | parse_boolean (void *cls, | 1013 | parse_boolean (void *cls, |
957 | json_t *root, | 1014 | json_t *root, |
958 | struct GNUNET_JSON_Specification *spec) | 1015 | struct GNUNET_JSON_Specification *spec) |
diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 92f8b4535..296f56104 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c | |||
@@ -245,16 +245,16 @@ GNUNET_JSON_pack_data_varsize (const char *name, | |||
245 | 245 | ||
246 | 246 | ||
247 | struct GNUNET_JSON_PackSpec | 247 | struct GNUNET_JSON_PackSpec |
248 | GNUNET_JSON_pack_time_abs (const char *name, | 248 | GNUNET_JSON_pack_timestamp (const char *name, |
249 | struct GNUNET_TIME_Absolute at) | 249 | struct GNUNET_TIME_Timestamp t) |
250 | { | 250 | { |
251 | struct GNUNET_JSON_PackSpec ps = { | 251 | struct GNUNET_JSON_PackSpec ps = { |
252 | .field_name = name | 252 | .field_name = name |
253 | }; | 253 | }; |
254 | 254 | ||
255 | if (0 != at.abs_value_us) | 255 | if (! GNUNET_TIME_absolute_is_zero (t.abs_time)) |
256 | { | 256 | { |
257 | ps.object = GNUNET_JSON_from_time_abs (at); | 257 | ps.object = GNUNET_JSON_from_timestamp (t); |
258 | GNUNET_assert (NULL != ps.object); | 258 | GNUNET_assert (NULL != ps.object); |
259 | } | 259 | } |
260 | else | 260 | else |
@@ -266,11 +266,11 @@ GNUNET_JSON_pack_time_abs (const char *name, | |||
266 | 266 | ||
267 | 267 | ||
268 | struct GNUNET_JSON_PackSpec | 268 | struct GNUNET_JSON_PackSpec |
269 | GNUNET_JSON_pack_time_abs_nbo (const char *name, | 269 | GNUNET_JSON_pack_timestamp_nbo (const char *name, |
270 | struct GNUNET_TIME_AbsoluteNBO at) | 270 | struct GNUNET_TIME_TimestampNBO at) |
271 | { | 271 | { |
272 | return GNUNET_JSON_pack_time_abs (name, | 272 | return GNUNET_JSON_pack_timestamp (name, |
273 | GNUNET_TIME_absolute_ntoh (at)); | 273 | GNUNET_TIME_timestamp_ntoh (at)); |
274 | } | 274 | } |
275 | 275 | ||
276 | 276 | ||
diff --git a/src/json/test_json.c b/src/json/test_json.c index 4485a37a4..d6c372cf3 100644 --- a/src/json/test_json.c +++ b/src/json/test_json.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2015, 2016 GNUnet e.V. | 3 | (C) 2015, 2016, 2021 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -34,33 +34,44 @@ | |||
34 | * @return 0 on success | 34 | * @return 0 on success |
35 | */ | 35 | */ |
36 | static int | 36 | static int |
37 | test_abs_time () | 37 | test_timestamp (void) |
38 | { | 38 | { |
39 | json_t *j; | 39 | json_t *j; |
40 | struct GNUNET_TIME_Absolute a1; | 40 | struct GNUNET_TIME_Absolute a1; |
41 | struct GNUNET_TIME_Absolute a2; | 41 | struct GNUNET_TIME_Timestamp t1; |
42 | struct GNUNET_JSON_Specification s1[] = { GNUNET_JSON_spec_absolute_time ( | 42 | struct GNUNET_TIME_Timestamp t2; |
43 | NULL, | 43 | struct GNUNET_JSON_Specification s1[] = { |
44 | &a2), | 44 | GNUNET_JSON_spec_timestamp (NULL, |
45 | GNUNET_JSON_spec_end () }; | 45 | &t2), |
46 | struct GNUNET_JSON_Specification s2[] = { GNUNET_JSON_spec_absolute_time ( | 46 | GNUNET_JSON_spec_end () |
47 | NULL, | 47 | }; |
48 | &a2), | 48 | struct GNUNET_JSON_Specification s2[] = { |
49 | GNUNET_JSON_spec_end () }; | 49 | GNUNET_JSON_spec_timestamp (NULL, |
50 | &t2), | ||
51 | GNUNET_JSON_spec_end () | ||
52 | }; | ||
50 | 53 | ||
51 | a1 = GNUNET_TIME_absolute_get (); | 54 | a1 = GNUNET_TIME_absolute_get (); |
52 | GNUNET_TIME_round_abs (&a1); | 55 | t1 = GNUNET_TIME_absolute_to_timestamp (a1); |
53 | j = GNUNET_JSON_from_time_abs (a1); | 56 | j = GNUNET_JSON_from_timestamp (t1); |
54 | GNUNET_assert (NULL != j); | 57 | GNUNET_assert (NULL != j); |
55 | GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (j, s1, NULL, NULL)); | 58 | GNUNET_assert (GNUNET_OK == |
56 | GNUNET_assert (a1.abs_value_us == a2.abs_value_us); | 59 | GNUNET_JSON_parse (j, |
60 | s1, | ||
61 | NULL, | ||
62 | NULL)); | ||
63 | GNUNET_assert (GNUNET_TIME_timestamp_cmp (t1, ==, t2)); | ||
57 | json_decref (j); | 64 | json_decref (j); |
58 | 65 | ||
59 | a1 = GNUNET_TIME_UNIT_FOREVER_ABS; | 66 | a1 = GNUNET_TIME_UNIT_FOREVER_ABS; |
60 | j = GNUNET_JSON_from_time_abs (a1); | 67 | j = GNUNET_JSON_from_timestamp (t1); |
61 | GNUNET_assert (NULL != j); | 68 | GNUNET_assert (NULL != j); |
62 | GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (j, s2, NULL, NULL)); | 69 | GNUNET_assert (GNUNET_OK == |
63 | GNUNET_assert (a1.abs_value_us == a2.abs_value_us); | 70 | GNUNET_JSON_parse (j, |
71 | s2, | ||
72 | NULL, | ||
73 | NULL)); | ||
74 | GNUNET_assert (GNUNET_TIME_timestamp_cmp (t1, ==, t2)); | ||
64 | json_decref (j); | 75 | json_decref (j); |
65 | return 0; | 76 | return 0; |
66 | } | 77 | } |
@@ -72,19 +83,21 @@ test_abs_time () | |||
72 | * @return 0 on success | 83 | * @return 0 on success |
73 | */ | 84 | */ |
74 | static int | 85 | static int |
75 | test_rel_time () | 86 | test_rel_time (void) |
76 | { | 87 | { |
77 | json_t *j; | 88 | json_t *j; |
78 | struct GNUNET_TIME_Relative r1; | 89 | struct GNUNET_TIME_Relative r1; |
79 | struct GNUNET_TIME_Relative r2; | 90 | struct GNUNET_TIME_Relative r2; |
80 | struct GNUNET_JSON_Specification s1[] = { GNUNET_JSON_spec_relative_time ( | 91 | struct GNUNET_JSON_Specification s1[] = { |
81 | NULL, | 92 | GNUNET_JSON_spec_relative_time (NULL, |
82 | &r2), | 93 | &r2), |
83 | GNUNET_JSON_spec_end () }; | 94 | GNUNET_JSON_spec_end () |
84 | struct GNUNET_JSON_Specification s2[] = { GNUNET_JSON_spec_relative_time ( | 95 | }; |
85 | NULL, | 96 | struct GNUNET_JSON_Specification s2[] = { |
86 | &r2), | 97 | GNUNET_JSON_spec_relative_time (NULL, |
87 | GNUNET_JSON_spec_end () }; | 98 | &r2), |
99 | GNUNET_JSON_spec_end () | ||
100 | }; | ||
88 | 101 | ||
89 | r1 = GNUNET_TIME_UNIT_SECONDS; | 102 | r1 = GNUNET_TIME_UNIT_SECONDS; |
90 | j = GNUNET_JSON_from_time_rel (r1); | 103 | j = GNUNET_JSON_from_time_rel (r1); |
@@ -211,7 +224,7 @@ int | |||
211 | main (int argc, const char *const argv[]) | 224 | main (int argc, const char *const argv[]) |
212 | { | 225 | { |
213 | GNUNET_log_setup ("test-json", "WARNING", NULL); | 226 | GNUNET_log_setup ("test-json", "WARNING", NULL); |
214 | if (0 != test_abs_time ()) | 227 | if (0 != test_timestamp ()) |
215 | return 1; | 228 | return 1; |
216 | if (0 != test_rel_time ()) | 229 | if (0 != test_rel_time ()) |
217 | return 1; | 230 | return 1; |
diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c index a37b1b10b..6b3ffe638 100644 --- a/src/messenger/messenger_api.c +++ b/src/messenger/messenger_api.c | |||
@@ -253,7 +253,7 @@ handle_recv_message (void *cls, | |||
253 | store, context, sender | 253 | store, context, sender |
254 | ); | 254 | ); |
255 | 255 | ||
256 | handle_room_message (room, contact, &message, hash); | 256 | contact = handle_room_message (room, contact, &message, hash); |
257 | 257 | ||
258 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message(room, hash); | 258 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message(room, hash); |
259 | 259 | ||
diff --git a/src/namestore/gnunet-namestore-fcfsd.c b/src/namestore/gnunet-namestore-fcfsd.c index 7ec9db156..5b13e50ff 100644 --- a/src/namestore/gnunet-namestore-fcfsd.c +++ b/src/namestore/gnunet-namestore-fcfsd.c | |||
@@ -789,7 +789,11 @@ create_response (void *cls, | |||
789 | "message", _ ("unable to process submitted data"), | 789 | "message", _ ("unable to process submitted data"), |
790 | NULL); | 790 | NULL); |
791 | rd->body_length = strlen (rd->body); | 791 | rd->body_length = strlen (rd->body); |
792 | #ifdef MHD_HTTP_CONTENT_TOO_LARGE | ||
793 | rd->code = MHD_HTTP_CONTENT_TOO_LARGE; | ||
794 | #else | ||
792 | rd->code = MHD_HTTP_PAYLOAD_TOO_LARGE; | 795 | rd->code = MHD_HTTP_PAYLOAD_TOO_LARGE; |
796 | #endif | ||
793 | return MHD_YES; | 797 | return MHD_YES; |
794 | case GNUNET_JSON_PR_JSON_INVALID: | 798 | case GNUNET_JSON_PR_JSON_INVALID: |
795 | rd->body = make_json ("error", "true", | 799 | rd->body = make_json ("error", "true", |
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c index 972b3a79d..56014752d 100644 --- a/src/nse/gnunet-service-nse.c +++ b/src/nse/gnunet-service-nse.c | |||
@@ -505,12 +505,18 @@ get_matching_bits (struct GNUNET_TIME_Absolute timestamp, | |||
505 | { | 505 | { |
506 | struct GNUNET_HashCode timestamp_hash; | 506 | struct GNUNET_HashCode timestamp_hash; |
507 | struct GNUNET_HashCode pid_hash; | 507 | struct GNUNET_HashCode pid_hash; |
508 | struct GNUNET_HashCode xor; | ||
508 | 509 | ||
509 | GNUNET_CRYPTO_hash (×tamp.abs_value_us, | 510 | GNUNET_CRYPTO_hash (×tamp.abs_value_us, |
510 | sizeof(timestamp.abs_value_us), | 511 | sizeof(timestamp.abs_value_us), |
511 | ×tamp_hash); | 512 | ×tamp_hash); |
512 | GNUNET_CRYPTO_hash (id, sizeof(struct GNUNET_PeerIdentity), &pid_hash); | 513 | GNUNET_CRYPTO_hash (id, |
513 | return GNUNET_CRYPTO_hash_matching_bits (×tamp_hash, &pid_hash); | 514 | sizeof(struct GNUNET_PeerIdentity), |
515 | &pid_hash); | ||
516 | GNUNET_CRYPTO_hash_xor (&pid_hash, | ||
517 | ×tamp_hash, | ||
518 | &xor); | ||
519 | return GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | ||
514 | } | 520 | } |
515 | 521 | ||
516 | 522 | ||
@@ -774,24 +780,6 @@ update_flood_message (void *cls) | |||
774 | 780 | ||
775 | 781 | ||
776 | /** | 782 | /** |
777 | * Count the leading zeroes in hash. | ||
778 | * | ||
779 | * @param hash to count leading zeros in | ||
780 | * @return the number of leading zero bits. | ||
781 | */ | ||
782 | static unsigned int | ||
783 | count_leading_zeroes (const struct GNUNET_HashCode *hash) | ||
784 | { | ||
785 | unsigned int hash_count; | ||
786 | |||
787 | hash_count = 0; | ||
788 | while (0 == GNUNET_CRYPTO_hash_get_bit_ltr (hash, hash_count)) | ||
789 | hash_count++; | ||
790 | return hash_count; | ||
791 | } | ||
792 | |||
793 | |||
794 | /** | ||
795 | * Check whether the given public key and integer are a valid proof of | 783 | * Check whether the given public key and integer are a valid proof of |
796 | * work. | 784 | * work. |
797 | * | 785 | * |
@@ -799,7 +787,7 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash) | |||
799 | * @param val the integer | 787 | * @param val the integer |
800 | * @return #GNUNET_YES if valid, #GNUNET_NO if not | 788 | * @return #GNUNET_YES if valid, #GNUNET_NO if not |
801 | */ | 789 | */ |
802 | static int | 790 | static enum GNUNET_GenericReturnValue |
803 | check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, | 791 | check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, |
804 | uint64_t val) | 792 | uint64_t val) |
805 | { | 793 | { |
@@ -815,8 +803,10 @@ check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, | |||
815 | buf, | 803 | buf, |
816 | sizeof(buf), | 804 | sizeof(buf), |
817 | &result); | 805 | &result); |
818 | return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES | 806 | return (GNUNET_CRYPTO_hash_count_leading_zeros (&result) >= |
819 | : GNUNET_NO; | 807 | nse_work_required) |
808 | ? GNUNET_YES | ||
809 | : GNUNET_NO; | ||
820 | } | 810 | } |
821 | 811 | ||
822 | 812 | ||
@@ -877,7 +867,8 @@ find_proof (void *cls) | |||
877 | buf, | 867 | buf, |
878 | sizeof(buf), | 868 | sizeof(buf), |
879 | &result); | 869 | &result); |
880 | if (nse_work_required <= count_leading_zeroes (&result)) | 870 | if (nse_work_required <= |
871 | GNUNET_CRYPTO_hash_count_leading_zeros (&result)) | ||
881 | { | 872 | { |
882 | my_proof = counter; | 873 | my_proof = counter; |
883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index a63d5f14e..5fea994ef 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c | |||
@@ -122,6 +122,7 @@ GNUNET_PQ_connect2 (const char *config_str, | |||
122 | GNUNET_PQ_reconnect (db); | 122 | GNUNET_PQ_reconnect (db); |
123 | if (NULL == db->conn) | 123 | if (NULL == db->conn) |
124 | { | 124 | { |
125 | GNUNET_CONTAINER_multishortmap_destroy (db->channel_map); | ||
125 | GNUNET_free (db->load_path); | 126 | GNUNET_free (db->load_path); |
126 | GNUNET_free (db->config_str); | 127 | GNUNET_free (db->config_str); |
127 | GNUNET_free (db); | 128 | GNUNET_free (db); |
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 78c324512..ce8ce8f87 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c | |||
@@ -70,7 +70,8 @@ struct GNUNET_PQ_QueryParam | |||
70 | GNUNET_PQ_query_param_null (void) | 70 | GNUNET_PQ_query_param_null (void) |
71 | { | 71 | { |
72 | struct GNUNET_PQ_QueryParam res = { | 72 | struct GNUNET_PQ_QueryParam res = { |
73 | &qconv_null, NULL, NULL, 0, 1 | 73 | .conv = &qconv_null, |
74 | .num_params = 1 | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | return res; | 77 | return res; |
@@ -192,7 +193,10 @@ struct GNUNET_PQ_QueryParam | |||
192 | GNUNET_PQ_query_param_uint16 (const uint16_t *x) | 193 | GNUNET_PQ_query_param_uint16 (const uint16_t *x) |
193 | { | 194 | { |
194 | struct GNUNET_PQ_QueryParam res = { | 195 | struct GNUNET_PQ_QueryParam res = { |
195 | &qconv_uint16, NULL, x, sizeof(*x), 1 | 196 | .conv = &qconv_uint16, |
197 | .data = x, | ||
198 | .size = sizeof(*x), | ||
199 | .num_params = 1 | ||
196 | }; | 200 | }; |
197 | 201 | ||
198 | return res; | 202 | return res; |
@@ -246,7 +250,10 @@ struct GNUNET_PQ_QueryParam | |||
246 | GNUNET_PQ_query_param_uint32 (const uint32_t *x) | 250 | GNUNET_PQ_query_param_uint32 (const uint32_t *x) |
247 | { | 251 | { |
248 | struct GNUNET_PQ_QueryParam res = { | 252 | struct GNUNET_PQ_QueryParam res = { |
249 | &qconv_uint32, NULL, x, sizeof(*x), 1 | 253 | .conv = &qconv_uint32, |
254 | .data = x, | ||
255 | .size = sizeof(*x), | ||
256 | .num_params = 1 | ||
250 | }; | 257 | }; |
251 | 258 | ||
252 | return res; | 259 | return res; |
@@ -300,7 +307,10 @@ struct GNUNET_PQ_QueryParam | |||
300 | GNUNET_PQ_query_param_uint64 (const uint64_t *x) | 307 | GNUNET_PQ_query_param_uint64 (const uint64_t *x) |
301 | { | 308 | { |
302 | struct GNUNET_PQ_QueryParam res = { | 309 | struct GNUNET_PQ_QueryParam res = { |
303 | &qconv_uint64, NULL, x, sizeof(*x), 1 | 310 | .conv = &qconv_uint64, |
311 | .data = x, | ||
312 | .size = sizeof(*x), | ||
313 | .num_params = 1 | ||
304 | }; | 314 | }; |
305 | 315 | ||
306 | return res; | 316 | return res; |
@@ -350,11 +360,13 @@ qconv_rsa_public_key (void *cls, | |||
350 | 360 | ||
351 | 361 | ||
352 | struct GNUNET_PQ_QueryParam | 362 | struct GNUNET_PQ_QueryParam |
353 | GNUNET_PQ_query_param_rsa_public_key (const struct | 363 | GNUNET_PQ_query_param_rsa_public_key ( |
354 | GNUNET_CRYPTO_RsaPublicKey *x) | 364 | const struct GNUNET_CRYPTO_RsaPublicKey *x) |
355 | { | 365 | { |
356 | struct GNUNET_PQ_QueryParam res = { | 366 | struct GNUNET_PQ_QueryParam res = { |
357 | &qconv_rsa_public_key, NULL, (x), 0, 1 | 367 | .conv = &qconv_rsa_public_key, |
368 | .data = x, | ||
369 | .num_params = 1 | ||
358 | }; | 370 | }; |
359 | 371 | ||
360 | return res; | 372 | return res; |
@@ -407,7 +419,9 @@ struct GNUNET_PQ_QueryParam | |||
407 | GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | 419 | GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) |
408 | { | 420 | { |
409 | struct GNUNET_PQ_QueryParam res = { | 421 | struct GNUNET_PQ_QueryParam res = { |
410 | &qconv_rsa_signature, NULL, (x), 0, 1 | 422 | .conv = &qconv_rsa_signature, |
423 | .data = x, | ||
424 | .num_params = 1 | ||
411 | }; | 425 | }; |
412 | 426 | ||
413 | return res; | 427 | return res; |
@@ -463,7 +477,10 @@ struct GNUNET_PQ_QueryParam | |||
463 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) | 477 | GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) |
464 | { | 478 | { |
465 | struct GNUNET_PQ_QueryParam res = { | 479 | struct GNUNET_PQ_QueryParam res = { |
466 | &qconv_rel_time, NULL, x, sizeof(*x), 1 | 480 | .conv = &qconv_rel_time, |
481 | .data = x, | ||
482 | .size = sizeof(*x), | ||
483 | .num_params = 1 | ||
467 | }; | 484 | }; |
468 | 485 | ||
469 | return res; | 486 | return res; |
@@ -519,7 +536,10 @@ struct GNUNET_PQ_QueryParam | |||
519 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) | 536 | GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) |
520 | { | 537 | { |
521 | struct GNUNET_PQ_QueryParam res = { | 538 | struct GNUNET_PQ_QueryParam res = { |
522 | &qconv_abs_time, NULL, x, sizeof(*x), 1 | 539 | .conv = &qconv_abs_time, |
540 | .data = x, | ||
541 | .size = sizeof(*x), | ||
542 | .num_params = 1 | ||
523 | }; | 543 | }; |
524 | 544 | ||
525 | return res; | 545 | return res; |
@@ -534,4 +554,19 @@ GNUNET_PQ_query_param_absolute_time_nbo ( | |||
534 | } | 554 | } |
535 | 555 | ||
536 | 556 | ||
557 | struct GNUNET_PQ_QueryParam | ||
558 | GNUNET_PQ_query_param_timestamp (const struct GNUNET_TIME_Timestamp *x) | ||
559 | { | ||
560 | return GNUNET_PQ_query_param_absolute_time (&x->abs_time); | ||
561 | } | ||
562 | |||
563 | |||
564 | struct GNUNET_PQ_QueryParam | ||
565 | GNUNET_PQ_query_param_timestamp_nbo ( | ||
566 | const struct GNUNET_TIME_TimestampNBO *x) | ||
567 | { | ||
568 | return GNUNET_PQ_query_param_absolute_time_nbo (&x->abs_time_nbo); | ||
569 | } | ||
570 | |||
571 | |||
537 | /* end of pq_query_helper.c */ | 572 | /* end of pq_query_helper.c */ |
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 4057772ec..2c11f5202 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c | |||
@@ -757,6 +757,148 @@ GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, | |||
757 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | 757 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) |
758 | */ | 758 | */ |
759 | static enum GNUNET_GenericReturnValue | 759 | static enum GNUNET_GenericReturnValue |
760 | extract_timestamp (void *cls, | ||
761 | PGresult *result, | ||
762 | int row, | ||
763 | const char *fname, | ||
764 | size_t *dst_size, | ||
765 | void *dst) | ||
766 | { | ||
767 | struct GNUNET_TIME_Timestamp *udst = dst; | ||
768 | struct GNUNET_TIME_Absolute abs; | ||
769 | const int64_t *res; | ||
770 | int fnum; | ||
771 | |||
772 | (void) cls; | ||
773 | fnum = PQfnumber (result, | ||
774 | fname); | ||
775 | if (fnum < 0) | ||
776 | { | ||
777 | GNUNET_break (0); | ||
778 | return GNUNET_SYSERR; | ||
779 | } | ||
780 | if (PQgetisnull (result, | ||
781 | row, | ||
782 | fnum)) | ||
783 | return GNUNET_NO; | ||
784 | GNUNET_assert (NULL != dst); | ||
785 | if (sizeof(struct GNUNET_TIME_Absolute) != *dst_size) | ||
786 | { | ||
787 | GNUNET_break (0); | ||
788 | return GNUNET_SYSERR; | ||
789 | } | ||
790 | if (sizeof(int64_t) != | ||
791 | PQgetlength (result, | ||
792 | row, | ||
793 | fnum)) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | res = (int64_t *) PQgetvalue (result, | ||
799 | row, | ||
800 | fnum); | ||
801 | if (INT64_MAX == GNUNET_ntohll ((uint64_t) *res)) | ||
802 | { | ||
803 | abs = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
804 | } | ||
805 | else | ||
806 | { | ||
807 | abs.abs_value_us = GNUNET_ntohll ((uint64_t) *res); | ||
808 | if (0 != abs.abs_value_us % GNUNET_TIME_UNIT_SECONDS.rel_value_us) | ||
809 | { | ||
810 | /* timestamps must be multiple of seconds! */ | ||
811 | GNUNET_break (0); | ||
812 | return GNUNET_SYSERR; | ||
813 | } | ||
814 | } | ||
815 | udst->abs_time = abs; | ||
816 | return GNUNET_OK; | ||
817 | } | ||
818 | |||
819 | |||
820 | struct GNUNET_PQ_ResultSpec | ||
821 | GNUNET_PQ_result_spec_timestamp (const char *name, | ||
822 | struct GNUNET_TIME_Timestamp *at) | ||
823 | { | ||
824 | struct GNUNET_PQ_ResultSpec res = { | ||
825 | .conv = &extract_timestamp, | ||
826 | .dst = (void *) at, | ||
827 | .dst_size = sizeof(*at), | ||
828 | .fname = name | ||
829 | }; | ||
830 | |||
831 | return res; | ||
832 | } | ||
833 | |||
834 | |||
835 | /** | ||
836 | * Extract data from a Postgres database @a result at row @a row. | ||
837 | * | ||
838 | * @param cls closure | ||
839 | * @param result where to extract data from | ||
840 | * @param int row to extract data from | ||
841 | * @param fname name (or prefix) of the fields to extract from | ||
842 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
843 | * @param[out] dst where to store the result | ||
844 | * @return | ||
845 | * #GNUNET_YES if all results could be extracted | ||
846 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
847 | */ | ||
848 | static enum GNUNET_GenericReturnValue | ||
849 | extract_timestamp_nbo (void *cls, | ||
850 | PGresult *result, | ||
851 | int row, | ||
852 | const char *fname, | ||
853 | size_t *dst_size, | ||
854 | void *dst) | ||
855 | { | ||
856 | struct GNUNET_TIME_TimestampNBO *udst = dst; | ||
857 | struct GNUNET_TIME_Timestamp t; | ||
858 | enum GNUNET_GenericReturnValue r; | ||
859 | |||
860 | r = extract_timestamp (NULL, | ||
861 | result, | ||
862 | row, | ||
863 | fname, | ||
864 | dst_size, | ||
865 | &t); | ||
866 | if (GNUNET_OK != r) | ||
867 | return r; | ||
868 | *udst = GNUNET_TIME_timestamp_hton (t); | ||
869 | return r; | ||
870 | } | ||
871 | |||
872 | |||
873 | struct GNUNET_PQ_ResultSpec | ||
874 | GNUNET_PQ_result_spec_timestamp_nbo (const char *name, | ||
875 | struct GNUNET_TIME_TimestampNBO *at) | ||
876 | { | ||
877 | struct GNUNET_PQ_ResultSpec res = { | ||
878 | .conv = &extract_timestamp_nbo, | ||
879 | .dst = (void *) at, | ||
880 | .dst_size = sizeof(*at), | ||
881 | .fname = name | ||
882 | }; | ||
883 | |||
884 | return res; | ||
885 | } | ||
886 | |||
887 | |||
888 | /** | ||
889 | * Extract data from a Postgres database @a result at row @a row. | ||
890 | * | ||
891 | * @param cls closure | ||
892 | * @param result where to extract data from | ||
893 | * @param int row to extract data from | ||
894 | * @param fname name (or prefix) of the fields to extract from | ||
895 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
896 | * @param[out] dst where to store the result | ||
897 | * @return | ||
898 | * #GNUNET_YES if all results could be extracted | ||
899 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
900 | */ | ||
901 | static enum GNUNET_GenericReturnValue | ||
760 | extract_uint16 (void *cls, | 902 | extract_uint16 (void *cls, |
761 | PGresult *result, | 903 | PGresult *result, |
762 | int row, | 904 | int row, |
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index ad897493f..0953830ab 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -329,6 +329,222 @@ block_plugin_regex_evaluate (void *cls, | |||
329 | 329 | ||
330 | 330 | ||
331 | /** | 331 | /** |
332 | * Function called to validate a query. | ||
333 | * | ||
334 | * @param cls closure | ||
335 | * @param ctx block context | ||
336 | * @param type block type | ||
337 | * @param query original query (hash) | ||
338 | * @param xquery extrended query data (can be NULL, depending on type) | ||
339 | * @param xquery_size number of bytes in @a xquery | ||
340 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
341 | */ | ||
342 | static enum GNUNET_GenericReturnValue | ||
343 | block_plugin_regex_check_query (void *cls, | ||
344 | enum GNUNET_BLOCK_Type type, | ||
345 | const struct GNUNET_HashCode *query, | ||
346 | const void *xquery, | ||
347 | size_t xquery_size) | ||
348 | { | ||
349 | switch (type) | ||
350 | { | ||
351 | case GNUNET_BLOCK_TYPE_REGEX: | ||
352 | if (0 != xquery_size) | ||
353 | { | ||
354 | const char *s; | ||
355 | |||
356 | s = (const char *) xquery; | ||
357 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
358 | { | ||
359 | GNUNET_break_op (0); | ||
360 | return GNUNET_NO; | ||
361 | } | ||
362 | } | ||
363 | return GNUNET_OK; | ||
364 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
365 | if (0 != xquery_size) | ||
366 | { | ||
367 | GNUNET_break_op (0); | ||
368 | return GNUNET_NO; | ||
369 | } | ||
370 | return GNUNET_OK; | ||
371 | default: | ||
372 | GNUNET_break (0); | ||
373 | return GNUNET_SYSERR; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Function called to validate a block for storage. | ||
380 | * | ||
381 | * @param cls closure | ||
382 | * @param type block type | ||
383 | * @param query key for the block (hash), must match exactly | ||
384 | * @param block block data to validate | ||
385 | * @param block_size number of bytes in @a block | ||
386 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
387 | */ | ||
388 | static enum GNUNET_GenericReturnValue | ||
389 | block_plugin_regex_check_block (void *cls, | ||
390 | enum GNUNET_BLOCK_Type type, | ||
391 | const struct GNUNET_HashCode *query, | ||
392 | const void *block, | ||
393 | size_t block_size) | ||
394 | { | ||
395 | switch (type) | ||
396 | { | ||
397 | case GNUNET_BLOCK_TYPE_REGEX: | ||
398 | if (GNUNET_SYSERR == | ||
399 | REGEX_BLOCK_check (block, | ||
400 | block_size, | ||
401 | query, | ||
402 | NULL)) | ||
403 | return GNUNET_NO; | ||
404 | return GNUNET_OK; | ||
405 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
406 | { | ||
407 | const struct RegexAcceptBlock *rba; | ||
408 | |||
409 | if (sizeof(struct RegexAcceptBlock) != block_size) | ||
410 | { | ||
411 | GNUNET_break_op (0); | ||
412 | return GNUNET_NO; | ||
413 | } | ||
414 | rba = block; | ||
415 | if (ntohl (rba->purpose.size) != | ||
416 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
417 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
418 | + sizeof(struct GNUNET_HashCode)) | ||
419 | { | ||
420 | GNUNET_break_op (0); | ||
421 | return GNUNET_NO; | ||
422 | } | ||
423 | if (GNUNET_TIME_absolute_is_past (GNUNET_TIME_absolute_ntoh ( | ||
424 | rba->expiration_time))) | ||
425 | { | ||
426 | return GNUNET_NO; | ||
427 | } | ||
428 | if (GNUNET_OK != | ||
429 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT, | ||
430 | &rba->purpose, | ||
431 | &rba->signature, | ||
432 | &rba->peer.public_key)) | ||
433 | { | ||
434 | GNUNET_break_op (0); | ||
435 | return GNUNET_NO; | ||
436 | } | ||
437 | return GNUNET_OK; | ||
438 | } | ||
439 | default: | ||
440 | GNUNET_break (0); | ||
441 | return GNUNET_SYSERR; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Function called to validate a reply to a request. Note that it is assumed | ||
448 | * that the reply has already been matched to the key (and signatures checked) | ||
449 | * as it would be done with the GetKeyFunction and the | ||
450 | * BlockEvaluationFunction. | ||
451 | * | ||
452 | * @param cls closure | ||
453 | * @param type block type | ||
454 | * @param group which block group to use for evaluation | ||
455 | * @param query original query (hash) | ||
456 | * @param xquery extrended query data (can be NULL, depending on type) | ||
457 | * @param xquery_size number of bytes in @a xquery | ||
458 | * @param reply_block response to validate | ||
459 | * @param reply_block_size number of bytes in @a reply_block | ||
460 | * @return characterization of result | ||
461 | */ | ||
462 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
463 | block_plugin_regex_check_reply ( | ||
464 | void *cls, | ||
465 | enum GNUNET_BLOCK_Type type, | ||
466 | struct GNUNET_BLOCK_Group *group, | ||
467 | const struct GNUNET_HashCode *query, | ||
468 | const void *xquery, | ||
469 | size_t xquery_size, | ||
470 | const void *reply_block, | ||
471 | size_t reply_block_size) | ||
472 | { | ||
473 | struct GNUNET_HashCode chash; | ||
474 | |||
475 | switch (type) | ||
476 | { | ||
477 | case GNUNET_BLOCK_TYPE_REGEX: | ||
478 | if (0 != xquery_size) | ||
479 | { | ||
480 | const char *s; | ||
481 | |||
482 | s = (const char *) xquery; | ||
483 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
484 | { | ||
485 | /* Technically, the query is invalid ... */ | ||
486 | GNUNET_break (0); | ||
487 | return GNUNET_BLOCK_REPLY_INVALID; | ||
488 | } | ||
489 | } | ||
490 | switch (REGEX_BLOCK_check (reply_block, | ||
491 | reply_block_size, | ||
492 | query, | ||
493 | xquery)) | ||
494 | { | ||
495 | case GNUNET_SYSERR: | ||
496 | GNUNET_break_op (0); | ||
497 | return GNUNET_BLOCK_REPLY_INVALID; | ||
498 | case GNUNET_NO: | ||
499 | /* xquery mismatch, can happen */ | ||
500 | return GNUNET_BLOCK_REPLY_IRRELEVANT; | ||
501 | default: | ||
502 | break; | ||
503 | } | ||
504 | GNUNET_CRYPTO_hash (reply_block, | ||
505 | reply_block_size, | ||
506 | &chash); | ||
507 | if (GNUNET_YES == | ||
508 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
509 | &chash)) | ||
510 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
511 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
512 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
513 | { | ||
514 | const struct RegexAcceptBlock *rba; | ||
515 | |||
516 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | ||
517 | { | ||
518 | GNUNET_break_op (0); | ||
519 | return GNUNET_BLOCK_REPLY_INVALID; | ||
520 | } | ||
521 | rba = reply_block; | ||
522 | if (ntohl (rba->purpose.size) != | ||
523 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
524 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
525 | + sizeof(struct GNUNET_HashCode)) | ||
526 | { | ||
527 | GNUNET_break_op (0); | ||
528 | return GNUNET_BLOCK_REPLY_INVALID; | ||
529 | } | ||
530 | GNUNET_CRYPTO_hash (reply_block, | ||
531 | reply_block_size, | ||
532 | &chash); | ||
533 | if (GNUNET_YES == | ||
534 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
535 | &chash)) | ||
536 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
537 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
538 | } | ||
539 | default: | ||
540 | GNUNET_break (0); | ||
541 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
542 | } | ||
543 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
544 | } | ||
545 | |||
546 | |||
547 | /** | ||
332 | * Function called to obtain the key for a block. | 548 | * Function called to obtain the key for a block. |
333 | * | 549 | * |
334 | * @param cls closure | 550 | * @param cls closure |
@@ -339,7 +555,7 @@ block_plugin_regex_evaluate (void *cls, | |||
339 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 555 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
340 | * (or if extracting a key from a block of this type does not work) | 556 | * (or if extracting a key from a block of this type does not work) |
341 | */ | 557 | */ |
342 | static int | 558 | static enum GNUNET_GenericReturnValue |
343 | block_plugin_regex_get_key (void *cls, | 559 | block_plugin_regex_get_key (void *cls, |
344 | enum GNUNET_BLOCK_Type type, | 560 | enum GNUNET_BLOCK_Type type, |
345 | const void *block, | 561 | const void *block, |
@@ -350,14 +566,14 @@ block_plugin_regex_get_key (void *cls, | |||
350 | { | 566 | { |
351 | case GNUNET_BLOCK_TYPE_REGEX: | 567 | case GNUNET_BLOCK_TYPE_REGEX: |
352 | if (GNUNET_OK != | 568 | if (GNUNET_OK != |
353 | REGEX_BLOCK_get_key (block, block_size, | 569 | REGEX_BLOCK_get_key (block, |
570 | block_size, | ||
354 | key)) | 571 | key)) |
355 | { | 572 | { |
356 | GNUNET_break_op (0); | 573 | GNUNET_break_op (0); |
357 | return GNUNET_NO; | 574 | return GNUNET_NO; |
358 | } | 575 | } |
359 | return GNUNET_OK; | 576 | return GNUNET_OK; |
360 | |||
361 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | 577 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: |
362 | if (sizeof(struct RegexAcceptBlock) != block_size) | 578 | if (sizeof(struct RegexAcceptBlock) != block_size) |
363 | { | 579 | { |
@@ -366,7 +582,6 @@ block_plugin_regex_get_key (void *cls, | |||
366 | } | 582 | } |
367 | *key = ((struct RegexAcceptBlock *) block)->key; | 583 | *key = ((struct RegexAcceptBlock *) block)->key; |
368 | return GNUNET_OK; | 584 | return GNUNET_OK; |
369 | |||
370 | default: | 585 | default: |
371 | GNUNET_break (0); | 586 | GNUNET_break (0); |
372 | return GNUNET_SYSERR; | 587 | return GNUNET_SYSERR; |
@@ -380,7 +595,7 @@ block_plugin_regex_get_key (void *cls, | |||
380 | void * | 595 | void * |
381 | libgnunet_plugin_block_regex_init (void *cls) | 596 | libgnunet_plugin_block_regex_init (void *cls) |
382 | { | 597 | { |
383 | static enum GNUNET_BLOCK_Type types[] = { | 598 | static const enum GNUNET_BLOCK_Type types[] = { |
384 | GNUNET_BLOCK_TYPE_REGEX, | 599 | GNUNET_BLOCK_TYPE_REGEX, |
385 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT, | 600 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT, |
386 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 601 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
@@ -390,6 +605,9 @@ libgnunet_plugin_block_regex_init (void *cls) | |||
390 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 605 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
391 | api->evaluate = &block_plugin_regex_evaluate; | 606 | api->evaluate = &block_plugin_regex_evaluate; |
392 | api->get_key = &block_plugin_regex_get_key; | 607 | api->get_key = &block_plugin_regex_get_key; |
608 | api->check_query = &block_plugin_regex_check_query; | ||
609 | api->check_block = &block_plugin_regex_check_block; | ||
610 | api->check_reply = &block_plugin_regex_check_reply; | ||
393 | api->create_group = &block_plugin_regex_create_group; | 611 | api->create_group = &block_plugin_regex_create_group; |
394 | api->types = types; | 612 | api->types = types; |
395 | return api; | 613 | return api; |
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index 5fe0ade98..4494ade83 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c | |||
@@ -169,14 +169,16 @@ new_peer_entry (const struct GNUNET_PeerIdentity *peer) | |||
169 | * @return #GNUNET_YES if the message is verified | 169 | * @return #GNUNET_YES if the message is verified |
170 | * #GNUNET_NO if the key/signature don't verify | 170 | * #GNUNET_NO if the key/signature don't verify |
171 | */ | 171 | */ |
172 | static int | 172 | static enum GNUNET_GenericReturnValue |
173 | verify_revoke_message (const struct RevokeMessage *rm) | 173 | verify_revoke_message (const struct RevokeMessage *rm) |
174 | { | 174 | { |
175 | struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; | 175 | const struct GNUNET_REVOCATION_PowP *pow |
176 | if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow, | 176 | = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; |
177 | (unsigned | 177 | |
178 | int) revocation_work_required, | 178 | if (GNUNET_YES != |
179 | epoch_duration)) | 179 | GNUNET_REVOCATION_check_pow (pow, |
180 | (unsigned int) revocation_work_required, | ||
181 | epoch_duration)) | ||
180 | { | 182 | { |
181 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 183 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
182 | "Proof of work invalid!\n"); | 184 | "Proof of work invalid!\n"); |
@@ -263,7 +265,7 @@ handle_query_message (void *cls, | |||
263 | * @param value our `struct PeerEntry` for the neighbour | 265 | * @param value our `struct PeerEntry` for the neighbour |
264 | * @return #GNUNET_OK (continue to iterate) | 266 | * @return #GNUNET_OK (continue to iterate) |
265 | */ | 267 | */ |
266 | static int | 268 | static enum GNUNET_GenericReturnValue |
267 | do_flood (void *cls, | 269 | do_flood (void *cls, |
268 | const struct GNUNET_PeerIdentity *target, | 270 | const struct GNUNET_PeerIdentity *target, |
269 | void *value) | 271 | void *value) |
@@ -278,10 +280,12 @@ do_flood (void *cls, | |||
278 | but we have no direct CORE | 280 | but we have no direct CORE |
279 | connection for flooding */ | 281 | connection for flooding */ |
280 | e = GNUNET_MQ_msg_extra (cp, | 282 | e = GNUNET_MQ_msg_extra (cp, |
281 | htonl (rm->pow_size), | 283 | htonl (rm->pow_size), |
282 | GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); | 284 | GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); |
283 | *cp = *rm; | 285 | *cp = *rm; |
284 | memcpy (&cp[1], &rm[1], htonl (rm->pow_size)); | 286 | memcpy (&cp[1], |
287 | &rm[1], | ||
288 | htonl (rm->pow_size)); | ||
285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 289 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
286 | "Flooding revocation to `%s'\n", | 290 | "Flooding revocation to `%s'\n", |
287 | GNUNET_i2s (target)); | 291 | GNUNET_i2s (target)); |
@@ -300,17 +304,18 @@ do_flood (void *cls, | |||
300 | * @return #GNUNET_OK on success, #GNUNET_NO if we encountered an error, | 304 | * @return #GNUNET_OK on success, #GNUNET_NO if we encountered an error, |
301 | * #GNUNET_SYSERR if the message was malformed | 305 | * #GNUNET_SYSERR if the message was malformed |
302 | */ | 306 | */ |
303 | static int | 307 | static enum GNUNET_GenericReturnValue |
304 | publicize_rm (const struct RevokeMessage *rm) | 308 | publicize_rm (const struct RevokeMessage *rm) |
305 | { | 309 | { |
306 | struct RevokeMessage *cp; | 310 | struct RevokeMessage *cp; |
307 | struct GNUNET_HashCode hc; | 311 | struct GNUNET_HashCode hc; |
308 | struct GNUNET_SETU_Element e; | 312 | struct GNUNET_SETU_Element e; |
309 | ssize_t pklen; | 313 | ssize_t pklen; |
310 | const struct GNUNET_IDENTITY_PublicKey *pk; | 314 | const struct GNUNET_REVOCATION_PowP *pow |
315 | = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; | ||
316 | const struct GNUNET_IDENTITY_PublicKey *pk | ||
317 | = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; | ||
311 | 318 | ||
312 | struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; | ||
313 | pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; | ||
314 | pklen = GNUNET_IDENTITY_key_get_length (pk); | 319 | pklen = GNUNET_IDENTITY_key_get_length (pk); |
315 | if (0 > pklen) | 320 | if (0 > pklen) |
316 | { | 321 | { |
diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c index da5882d59..3beae60bb 100644 --- a/src/revocation/plugin_block_revocation.c +++ b/src/revocation/plugin_block_revocation.c | |||
@@ -34,19 +34,6 @@ | |||
34 | #define DEBUG_REVOCATION GNUNET_EXTRA_LOGGING | 34 | #define DEBUG_REVOCATION GNUNET_EXTRA_LOGGING |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Number of bits we set per entry in the bloomfilter. | ||
38 | * Do not change! | ||
39 | */ | ||
40 | #define BLOOMFILTER_K 16 | ||
41 | |||
42 | |||
43 | /** | ||
44 | * How big is the BF we use for DHT blocks? | ||
45 | */ | ||
46 | #define REVOCATION_BF_SIZE 8 | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Context used inside the plugin. | 37 | * Context used inside the plugin. |
51 | */ | 38 | */ |
52 | struct InternalContext | 39 | struct InternalContext |
@@ -57,54 +44,6 @@ struct InternalContext | |||
57 | 44 | ||
58 | 45 | ||
59 | /** | 46 | /** |
60 | * Create a new block group. | ||
61 | * | ||
62 | * @param ctx block context in which the block group is created | ||
63 | * @param type type of the block for which we are creating the group | ||
64 | * @param nonce random value used to seed the group creation | ||
65 | * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh | ||
66 | * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh | ||
67 | * @param va variable arguments specific to @a type | ||
68 | * @return block group handle, NULL if block groups are not supported | ||
69 | * by this @a type of block (this is not an error) | ||
70 | */ | ||
71 | static struct GNUNET_BLOCK_Group * | ||
72 | block_plugin_revocation_create_group (void *cls, | ||
73 | enum GNUNET_BLOCK_Type type, | ||
74 | uint32_t nonce, | ||
75 | const void *raw_data, | ||
76 | size_t raw_data_size, | ||
77 | va_list va) | ||
78 | { | ||
79 | unsigned int bf_size; | ||
80 | const char *guard; | ||
81 | |||
82 | guard = va_arg (va, const char *); | ||
83 | if (0 == strcmp (guard, | ||
84 | "seen-set-size")) | ||
85 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned | ||
86 | int), | ||
87 | BLOOMFILTER_K); | ||
88 | else if (0 == strcmp (guard, | ||
89 | "filter-size")) | ||
90 | bf_size = va_arg (va, unsigned int); | ||
91 | else | ||
92 | { | ||
93 | GNUNET_break (0); | ||
94 | bf_size = REVOCATION_BF_SIZE; | ||
95 | } | ||
96 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
97 | return GNUNET_BLOCK_GROUP_bf_create (cls, | ||
98 | bf_size, | ||
99 | BLOOMFILTER_K, | ||
100 | type, | ||
101 | nonce, | ||
102 | raw_data, | ||
103 | raw_data_size); | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Function called to validate a reply or a request. For | 47 | * Function called to validate a reply or a request. For |
109 | * request evaluation, simply pass "NULL" for the reply_block. | 48 | * request evaluation, simply pass "NULL" for the reply_block. |
110 | * | 49 | * |
@@ -133,7 +72,6 @@ block_plugin_revocation_evaluate (void *cls, | |||
133 | size_t reply_block_size) | 72 | size_t reply_block_size) |
134 | { | 73 | { |
135 | struct InternalContext *ic = cls; | 74 | struct InternalContext *ic = cls; |
136 | struct GNUNET_HashCode chash; | ||
137 | ssize_t pklen; | 75 | ssize_t pklen; |
138 | const struct RevokeMessage *rm = reply_block; | 76 | const struct RevokeMessage *rm = reply_block; |
139 | 77 | ||
@@ -160,14 +98,134 @@ block_plugin_revocation_evaluate (void *cls, | |||
160 | GNUNET_break_op (0); | 98 | GNUNET_break_op (0); |
161 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | 99 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
162 | } | 100 | } |
163 | GNUNET_CRYPTO_hash (pk, | 101 | return GNUNET_BLOCK_EVALUATION_OK_LAST; |
164 | pklen, | 102 | } |
165 | &chash); | 103 | |
166 | if (GNUNET_YES == | 104 | |
167 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | 105 | /** |
168 | &chash)) | 106 | * Function called to validate a query. |
169 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | 107 | * |
170 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 108 | * @param cls closure |
109 | * @param ctx block context | ||
110 | * @param type block type | ||
111 | * @param query original query (hash) | ||
112 | * @param xquery extrended query data (can be NULL, depending on type) | ||
113 | * @param xquery_size number of bytes in @a xquery | ||
114 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
115 | */ | ||
116 | static enum GNUNET_GenericReturnValue | ||
117 | block_plugin_revocation_check_query (void *cls, | ||
118 | enum GNUNET_BLOCK_Type type, | ||
119 | const struct GNUNET_HashCode *query, | ||
120 | const void *xquery, | ||
121 | size_t xquery_size) | ||
122 | { | ||
123 | (void) cls; | ||
124 | (void) query; | ||
125 | (void) xquery; | ||
126 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | ||
127 | return GNUNET_SYSERR; | ||
128 | if (0 != xquery_size) | ||
129 | return GNUNET_NO; | ||
130 | return GNUNET_OK; | ||
131 | } | ||
132 | |||
133 | |||
134 | /** | ||
135 | * Function called to validate a block for storage. | ||
136 | * | ||
137 | * @param cls closure | ||
138 | * @param type block type | ||
139 | * @param query key for the block (hash), must match exactly | ||
140 | * @param block block data to validate | ||
141 | * @param block_size number of bytes in @a block | ||
142 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
143 | */ | ||
144 | static enum GNUNET_GenericReturnValue | ||
145 | block_plugin_revocation_check_block (void *cls, | ||
146 | enum GNUNET_BLOCK_Type type, | ||
147 | const struct GNUNET_HashCode *query, | ||
148 | const void *block, | ||
149 | size_t block_size) | ||
150 | { | ||
151 | struct InternalContext *ic = cls; | ||
152 | const struct RevokeMessage *rm = block; | ||
153 | const struct GNUNET_REVOCATION_PowP *pow | ||
154 | = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; | ||
155 | struct GNUNET_IDENTITY_PublicKey pk; | ||
156 | ssize_t pklen; | ||
157 | size_t left; | ||
158 | |||
159 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | ||
160 | return GNUNET_SYSERR; | ||
161 | if (block_size < sizeof(*rm) + sizeof(*pow)) | ||
162 | { | ||
163 | GNUNET_break_op (0); | ||
164 | return GNUNET_NO; | ||
165 | } | ||
166 | if (block_size != sizeof(*rm) + ntohl (rm->pow_size)) | ||
167 | { | ||
168 | GNUNET_break_op (0); | ||
169 | return GNUNET_NO; | ||
170 | } | ||
171 | left = block_size - sizeof (*rm) - sizeof (*pow); | ||
172 | pklen = GNUNET_IDENTITY_read_key_from_buffer (&pk, | ||
173 | &pow[1], | ||
174 | left); | ||
175 | if (0 > pklen) | ||
176 | { | ||
177 | GNUNET_break_op (0); | ||
178 | return GNUNET_NO; | ||
179 | } | ||
180 | if (GNUNET_YES != | ||
181 | GNUNET_REVOCATION_check_pow (pow, | ||
182 | ic->matching_bits, | ||
183 | ic->epoch_duration)) | ||
184 | { | ||
185 | GNUNET_break_op (0); | ||
186 | return GNUNET_NO; | ||
187 | } | ||
188 | return GNUNET_OK; | ||
189 | } | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Function called to validate a reply to a request. Note that it is assumed | ||
194 | * that the reply has already been matched to the key (and signatures checked) | ||
195 | * as it would be done with the GetKeyFunction and the | ||
196 | * BlockEvaluationFunction. | ||
197 | * | ||
198 | * @param cls closure | ||
199 | * @param type block type | ||
200 | * @param group which block group to use for evaluation | ||
201 | * @param query original query (hash) | ||
202 | * @param xquery extrended query data (can be NULL, depending on type) | ||
203 | * @param xquery_size number of bytes in @a xquery | ||
204 | * @param reply_block response to validate | ||
205 | * @param reply_block_size number of bytes in @a reply_block | ||
206 | * @return characterization of result | ||
207 | */ | ||
208 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
209 | block_plugin_revocation_check_reply ( | ||
210 | void *cls, | ||
211 | enum GNUNET_BLOCK_Type type, | ||
212 | struct GNUNET_BLOCK_Group *group, | ||
213 | const struct GNUNET_HashCode *query, | ||
214 | const void *xquery, | ||
215 | size_t xquery_size, | ||
216 | const void *reply_block, | ||
217 | size_t reply_block_size) | ||
218 | { | ||
219 | (void) cls; | ||
220 | (void) group; | ||
221 | (void) query; | ||
222 | (void) xquery; | ||
223 | (void) xquery_size; | ||
224 | (void) reply_block; | ||
225 | (void) reply_block_size; | ||
226 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | ||
227 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
228 | return GNUNET_BLOCK_REPLY_OK_LAST; | ||
171 | } | 229 | } |
172 | 230 | ||
173 | 231 | ||
@@ -182,7 +240,7 @@ block_plugin_revocation_evaluate (void *cls, | |||
182 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 240 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
183 | * (or if extracting a key from a block of this type does not work) | 241 | * (or if extracting a key from a block of this type does not work) |
184 | */ | 242 | */ |
185 | static int | 243 | static enum GNUNET_GenericReturnValue |
186 | block_plugin_revocation_get_key (void *cls, | 244 | block_plugin_revocation_get_key (void *cls, |
187 | enum GNUNET_BLOCK_Type type, | 245 | enum GNUNET_BLOCK_Type type, |
188 | const void *block, | 246 | const void *block, |
@@ -190,24 +248,35 @@ block_plugin_revocation_get_key (void *cls, | |||
190 | struct GNUNET_HashCode *key) | 248 | struct GNUNET_HashCode *key) |
191 | { | 249 | { |
192 | const struct RevokeMessage *rm = block; | 250 | const struct RevokeMessage *rm = block; |
193 | ssize_t ksize; | 251 | const struct GNUNET_REVOCATION_PowP *pow |
252 | = (const struct GNUNET_REVOCATION_PowP *) &rm[1]; | ||
253 | struct GNUNET_IDENTITY_PublicKey pk; | ||
254 | ssize_t pklen; | ||
255 | size_t left; | ||
194 | 256 | ||
195 | if (block_size <= sizeof(*rm)) | 257 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) |
258 | return GNUNET_SYSERR; | ||
259 | if (block_size < sizeof(*rm) + sizeof(*pow)) | ||
196 | { | 260 | { |
197 | GNUNET_break_op (0); | 261 | GNUNET_break_op (0); |
198 | return GNUNET_SYSERR; | 262 | return GNUNET_NO; |
199 | } | 263 | } |
200 | struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; | 264 | if (block_size != sizeof(*rm) + ntohl (rm->pow_size)) |
201 | const struct GNUNET_IDENTITY_PublicKey *pk; | ||
202 | pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; | ||
203 | ksize = GNUNET_IDENTITY_key_get_length (pk); | ||
204 | if (0 > ksize) | ||
205 | { | 265 | { |
206 | GNUNET_break_op (0); | 266 | GNUNET_break_op (0); |
207 | return GNUNET_SYSERR; | 267 | return GNUNET_NO; |
208 | } | 268 | } |
209 | GNUNET_CRYPTO_hash (pk, | 269 | left = block_size - sizeof (*rm) - sizeof (*pow); |
210 | ksize, | 270 | pklen = GNUNET_IDENTITY_read_key_from_buffer (&pk, |
271 | &pow[1], | ||
272 | left); | ||
273 | if (0 > pklen) | ||
274 | { | ||
275 | GNUNET_break_op (0); | ||
276 | return GNUNET_NO; | ||
277 | } | ||
278 | GNUNET_CRYPTO_hash (&pow[1], | ||
279 | pklen, | ||
211 | key); | 280 | key); |
212 | return GNUNET_OK; | 281 | return GNUNET_OK; |
213 | } | 282 | } |
@@ -221,8 +290,8 @@ block_plugin_revocation_get_key (void *cls, | |||
221 | void * | 290 | void * |
222 | libgnunet_plugin_block_revocation_init (void *cls) | 291 | libgnunet_plugin_block_revocation_init (void *cls) |
223 | { | 292 | { |
224 | static enum GNUNET_BLOCK_Type types[] = { | 293 | static const enum GNUNET_BLOCK_Type types[] = { |
225 | GNUNET_BLOCK_TYPE_REVOCATION, | 294 | GNUNET_BLOCK_TYPE_REVOCATION, |
226 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 295 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
227 | }; | 296 | }; |
228 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 297 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
@@ -247,7 +316,10 @@ libgnunet_plugin_block_revocation_init (void *cls) | |||
247 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 316 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
248 | api->evaluate = &block_plugin_revocation_evaluate; | 317 | api->evaluate = &block_plugin_revocation_evaluate; |
249 | api->get_key = &block_plugin_revocation_get_key; | 318 | api->get_key = &block_plugin_revocation_get_key; |
250 | api->create_group = &block_plugin_revocation_create_group; | 319 | api->check_query = &block_plugin_revocation_check_query; |
320 | api->check_block = &block_plugin_revocation_check_block; | ||
321 | api->check_reply = &block_plugin_revocation_check_reply; | ||
322 | api->create_group = NULL; | ||
251 | api->types = types; | 323 | api->types = types; |
252 | ic = GNUNET_new (struct InternalContext); | 324 | ic = GNUNET_new (struct InternalContext); |
253 | ic->matching_bits = (unsigned int) matching_bits; | 325 | ic->matching_bits = (unsigned int) matching_bits; |
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index f2b95bafa..d5bd53e56 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c | |||
@@ -53,7 +53,7 @@ struct GNUNET_REVOCATION_Query | |||
53 | 53 | ||
54 | /** | 54 | /** |
55 | * Helper struct that holds a found pow nonce | 55 | * Helper struct that holds a found pow nonce |
56 | * and the corresponding number of leading zeroes. | 56 | * and the corresponding number of leading zeros. |
57 | */ | 57 | */ |
58 | struct BestPow | 58 | struct BestPow |
59 | { | 59 | { |
@@ -389,27 +389,10 @@ GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h) | |||
389 | 389 | ||
390 | 390 | ||
391 | /** | 391 | /** |
392 | * Count the leading zeroes in hash. | ||
393 | * | ||
394 | * @param hash to count leading zeros in | ||
395 | * @return the number of leading zero bits. | ||
396 | */ | ||
397 | static unsigned int | ||
398 | count_leading_zeroes (const struct GNUNET_HashCode *hash) | ||
399 | { | ||
400 | unsigned int hash_count; | ||
401 | hash_count = 0; | ||
402 | while ((0 == GNUNET_CRYPTO_hash_get_bit_ltr (hash, hash_count))) | ||
403 | hash_count++; | ||
404 | return hash_count; | ||
405 | } | ||
406 | |||
407 | |||
408 | /** | ||
409 | * Calculate the average zeros in the pows. | 392 | * Calculate the average zeros in the pows. |
410 | * | 393 | * |
411 | * @param ph the PowHandle | 394 | * @param ph the PowHandle |
412 | * @return the average number of zeroes. | 395 | * @return the average number of zeros. |
413 | */ | 396 | */ |
414 | static unsigned int | 397 | static unsigned int |
415 | calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph) | 398 | calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph) |
@@ -535,7 +518,7 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, | |||
535 | buf, | 518 | buf, |
536 | sizeof(buf), | 519 | sizeof(buf), |
537 | &result); | 520 | &result); |
538 | tmp_score = count_leading_zeroes (&result); | 521 | tmp_score = GNUNET_CRYPTO_hash_count_leading_zeros (&result); |
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 522 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
540 | "Score %u with %" PRIu64 " (#%u)\n", | 523 | "Score %u with %" PRIu64 " (#%u)\n", |
541 | tmp_score, pow_val, i); | 524 | tmp_score, pow_val, i); |
@@ -732,7 +715,7 @@ GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc) | |||
732 | buf, | 715 | buf, |
733 | sizeof(buf), | 716 | sizeof(buf), |
734 | &result); | 717 | &result); |
735 | zeros = count_leading_zeroes (&result); | 718 | zeros = GNUNET_CRYPTO_hash_count_leading_zeros (&result); |
736 | for (unsigned int i = 0; i < POW_COUNT; i++) | 719 | for (unsigned int i = 0; i < POW_COUNT; i++) |
737 | { | 720 | { |
738 | if (pc->best[i].bits < zeros) | 721 | if (pc->best[i].bits < zeros) |
diff --git a/src/set/plugin_block_set_test.c b/src/set/plugin_block_set_test.c index 1de086092..3d66831bb 100644 --- a/src/set/plugin_block_set_test.c +++ b/src/set/plugin_block_set_test.c | |||
@@ -66,6 +66,87 @@ block_plugin_set_test_evaluate (void *cls, | |||
66 | 66 | ||
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Function called to validate a query. | ||
70 | * | ||
71 | * @param cls closure | ||
72 | * @param ctx block context | ||
73 | * @param type block type | ||
74 | * @param query original query (hash) | ||
75 | * @param xquery extrended query data (can be NULL, depending on type) | ||
76 | * @param xquery_size number of bytes in @a xquery | ||
77 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
78 | */ | ||
79 | static enum GNUNET_GenericReturnValue | ||
80 | block_plugin_set_test_check_query (void *cls, | ||
81 | enum GNUNET_BLOCK_Type type, | ||
82 | const struct GNUNET_HashCode *query, | ||
83 | const void *xquery, | ||
84 | size_t xquery_size) | ||
85 | { | ||
86 | return GNUNET_OK; | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Function called to validate a block for storage. | ||
92 | * | ||
93 | * @param cls closure | ||
94 | * @param type block type | ||
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | ||
97 | * @param block_size number of bytes in @a block | ||
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
99 | */ | ||
100 | static enum GNUNET_GenericReturnValue | ||
101 | block_plugin_set_test_check_block (void *cls, | ||
102 | enum GNUNET_BLOCK_Type type, | ||
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | ||
105 | size_t block_size) | ||
106 | { | ||
107 | if ((NULL == block) || | ||
108 | (0 == block_size) || | ||
109 | (0 != ((char *) block)[0])) | ||
110 | return GNUNET_SYSERR; | ||
111 | return GNUNET_OK; | ||
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Function called to validate a reply to a request. Note that it is assumed | ||
117 | * that the reply has already been matched to the key (and signatures checked) | ||
118 | * as it would be done with the GetKeyFunction and the | ||
119 | * BlockEvaluationFunction. | ||
120 | * | ||
121 | * @param cls closure | ||
122 | * @param type block type | ||
123 | * @param group which block group to use for evaluation | ||
124 | * @param query original query (hash) | ||
125 | * @param xquery extrended query data (can be NULL, depending on type) | ||
126 | * @param xquery_size number of bytes in @a xquery | ||
127 | * @param reply_block response to validate | ||
128 | * @param reply_block_size number of bytes in @a reply_block | ||
129 | * @return characterization of result | ||
130 | */ | ||
131 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
132 | block_plugin_set_test_check_reply (void *cls, | ||
133 | enum GNUNET_BLOCK_Type type, | ||
134 | struct GNUNET_BLOCK_Group *group, | ||
135 | const struct GNUNET_HashCode *query, | ||
136 | const void *xquery, | ||
137 | size_t xquery_size, | ||
138 | const void *reply_block, | ||
139 | size_t reply_block_size) | ||
140 | { | ||
141 | if ((NULL == reply_block) || | ||
142 | (0 == reply_block_size) || | ||
143 | (0 != ((char *) reply_block)[0])) | ||
144 | return GNUNET_BLOCK_REPLY_INVALID; | ||
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
69 | * Function called to obtain the key for a block. | 150 | * Function called to obtain the key for a block. |
70 | * | 151 | * |
71 | * @param cls closure | 152 | * @param cls closure |
@@ -76,7 +157,7 @@ block_plugin_set_test_evaluate (void *cls, | |||
76 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 157 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
77 | * (or if extracting a key from a block of this type does not work) | 158 | * (or if extracting a key from a block of this type does not work) |
78 | */ | 159 | */ |
79 | static int | 160 | static enum GNUNET_GenericReturnValue |
80 | block_plugin_set_test_get_key (void *cls, | 161 | block_plugin_set_test_get_key (void *cls, |
81 | enum GNUNET_BLOCK_Type type, | 162 | enum GNUNET_BLOCK_Type type, |
82 | const void *block, | 163 | const void *block, |
@@ -93,7 +174,7 @@ block_plugin_set_test_get_key (void *cls, | |||
93 | void * | 174 | void * |
94 | libgnunet_plugin_block_set_test_init (void *cls) | 175 | libgnunet_plugin_block_set_test_init (void *cls) |
95 | { | 176 | { |
96 | static enum GNUNET_BLOCK_Type types[] = { | 177 | static const enum GNUNET_BLOCK_Type types[] = { |
97 | GNUNET_BLOCK_TYPE_SET_TEST, | 178 | GNUNET_BLOCK_TYPE_SET_TEST, |
98 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 179 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
99 | }; | 180 | }; |
@@ -102,6 +183,9 @@ libgnunet_plugin_block_set_test_init (void *cls) | |||
102 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
103 | api->evaluate = &block_plugin_set_test_evaluate; | 184 | api->evaluate = &block_plugin_set_test_evaluate; |
104 | api->get_key = &block_plugin_set_test_get_key; | 185 | api->get_key = &block_plugin_set_test_get_key; |
186 | api->check_query = &block_plugin_set_test_check_query; | ||
187 | api->check_block = &block_plugin_set_test_check_block; | ||
188 | api->check_reply = &block_plugin_set_test_check_reply; | ||
105 | api->types = types; | 189 | api->types = types; |
106 | return api; | 190 | return api; |
107 | } | 191 | } |
diff --git a/src/seti/plugin_block_seti_test.c b/src/seti/plugin_block_seti_test.c index 55cf31bea..af86e1af6 100644 --- a/src/seti/plugin_block_seti_test.c +++ b/src/seti/plugin_block_seti_test.c | |||
@@ -66,6 +66,87 @@ block_plugin_seti_test_evaluate (void *cls, | |||
66 | 66 | ||
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Function called to validate a query. | ||
70 | * | ||
71 | * @param cls closure | ||
72 | * @param ctx block context | ||
73 | * @param type block type | ||
74 | * @param query original query (hash) | ||
75 | * @param xquery extrended query data (can be NULL, depending on type) | ||
76 | * @param xquery_size number of bytes in @a xquery | ||
77 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
78 | */ | ||
79 | static enum GNUNET_GenericReturnValue | ||
80 | block_plugin_seti_test_check_query (void *cls, | ||
81 | enum GNUNET_BLOCK_Type type, | ||
82 | const struct GNUNET_HashCode *query, | ||
83 | const void *xquery, | ||
84 | size_t xquery_size) | ||
85 | { | ||
86 | return GNUNET_OK; | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Function called to validate a block for storage. | ||
92 | * | ||
93 | * @param cls closure | ||
94 | * @param type block type | ||
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | ||
97 | * @param block_size number of bytes in @a block | ||
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
99 | */ | ||
100 | static enum GNUNET_GenericReturnValue | ||
101 | block_plugin_seti_test_check_block (void *cls, | ||
102 | enum GNUNET_BLOCK_Type type, | ||
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | ||
105 | size_t block_size) | ||
106 | { | ||
107 | if ((NULL == block) || | ||
108 | (0 == block_size) || | ||
109 | (0 != ((char *) block)[0])) | ||
110 | return GNUNET_SYSERR; | ||
111 | return GNUNET_OK; | ||
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Function called to validate a reply to a request. Note that it is assumed | ||
117 | * that the reply has already been matched to the key (and signatures checked) | ||
118 | * as it would be done with the GetKeyFunction and the | ||
119 | * BlockEvaluationFunction. | ||
120 | * | ||
121 | * @param cls closure | ||
122 | * @param type block type | ||
123 | * @param group which block group to use for evaluation | ||
124 | * @param query original query (hash) | ||
125 | * @param xquery extrended query data (can be NULL, depending on type) | ||
126 | * @param xquery_size number of bytes in @a xquery | ||
127 | * @param reply_block response to validate | ||
128 | * @param reply_block_size number of bytes in @a reply_block | ||
129 | * @return characterization of result | ||
130 | */ | ||
131 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
132 | block_plugin_seti_test_check_reply (void *cls, | ||
133 | enum GNUNET_BLOCK_Type type, | ||
134 | struct GNUNET_BLOCK_Group *group, | ||
135 | const struct GNUNET_HashCode *query, | ||
136 | const void *xquery, | ||
137 | size_t xquery_size, | ||
138 | const void *reply_block, | ||
139 | size_t reply_block_size) | ||
140 | { | ||
141 | if ( (NULL == reply_block) || | ||
142 | (0 == reply_block_size) || | ||
143 | (0 != ((char *) reply_block)[0]) ) | ||
144 | return GNUNET_BLOCK_REPLY_INVALID; | ||
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
69 | * Function called to obtain the key for a block. | 150 | * Function called to obtain the key for a block. |
70 | * | 151 | * |
71 | * @param cls closure | 152 | * @param cls closure |
@@ -76,7 +157,7 @@ block_plugin_seti_test_evaluate (void *cls, | |||
76 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 157 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
77 | * (or if extracting a key from a block of this type does not work) | 158 | * (or if extracting a key from a block of this type does not work) |
78 | */ | 159 | */ |
79 | static int | 160 | static enum GNUNET_GenericReturnValue |
80 | block_plugin_seti_test_get_key (void *cls, | 161 | block_plugin_seti_test_get_key (void *cls, |
81 | enum GNUNET_BLOCK_Type type, | 162 | enum GNUNET_BLOCK_Type type, |
82 | const void *block, | 163 | const void *block, |
@@ -102,6 +183,9 @@ libgnunet_plugin_block_seti_test_init (void *cls) | |||
102 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
103 | api->evaluate = &block_plugin_seti_test_evaluate; | 184 | api->evaluate = &block_plugin_seti_test_evaluate; |
104 | api->get_key = &block_plugin_seti_test_get_key; | 185 | api->get_key = &block_plugin_seti_test_get_key; |
186 | api->check_query = &block_plugin_seti_test_check_query; | ||
187 | api->check_block = &block_plugin_seti_test_check_block; | ||
188 | api->check_reply = &block_plugin_seti_test_check_reply; | ||
105 | api->types = types; | 189 | api->types = types; |
106 | return api; | 190 | return api; |
107 | } | 191 | } |
diff --git a/src/setu/plugin_block_setu_test.c b/src/setu/plugin_block_setu_test.c index fd0c8a680..9872bba39 100644 --- a/src/setu/plugin_block_setu_test.c +++ b/src/setu/plugin_block_setu_test.c | |||
@@ -66,6 +66,87 @@ block_plugin_setu_test_evaluate (void *cls, | |||
66 | 66 | ||
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Function called to validate a query. | ||
70 | * | ||
71 | * @param cls closure | ||
72 | * @param ctx block context | ||
73 | * @param type block type | ||
74 | * @param query original query (hash) | ||
75 | * @param xquery extrended query data (can be NULL, depending on type) | ||
76 | * @param xquery_size number of bytes in @a xquery | ||
77 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
78 | */ | ||
79 | static enum GNUNET_GenericReturnValue | ||
80 | block_plugin_setu_test_check_query (void *cls, | ||
81 | enum GNUNET_BLOCK_Type type, | ||
82 | const struct GNUNET_HashCode *query, | ||
83 | const void *xquery, | ||
84 | size_t xquery_size) | ||
85 | { | ||
86 | return GNUNET_OK; | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Function called to validate a block for storage. | ||
92 | * | ||
93 | * @param cls closure | ||
94 | * @param type block type | ||
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | ||
97 | * @param block_size number of bytes in @a block | ||
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
99 | */ | ||
100 | static enum GNUNET_GenericReturnValue | ||
101 | block_plugin_setu_test_check_block (void *cls, | ||
102 | enum GNUNET_BLOCK_Type type, | ||
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | ||
105 | size_t block_size) | ||
106 | { | ||
107 | if ( (NULL == block) || | ||
108 | (0 == block_size) || | ||
109 | (0 != ((char *) block)[0]) ) | ||
110 | return GNUNET_SYSERR; | ||
111 | return GNUNET_OK; | ||
112 | } | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Function called to validate a reply to a request. Note that it is assumed | ||
117 | * that the reply has already been matched to the key (and signatures checked) | ||
118 | * as it would be done with the GetKeyFunction and the | ||
119 | * BlockEvaluationFunction. | ||
120 | * | ||
121 | * @param cls closure | ||
122 | * @param type block type | ||
123 | * @param group which block group to use for evaluation | ||
124 | * @param query original query (hash) | ||
125 | * @param xquery extrended query data (can be NULL, depending on type) | ||
126 | * @param xquery_size number of bytes in @a xquery | ||
127 | * @param reply_block response to validate | ||
128 | * @param reply_block_size number of bytes in @a reply_block | ||
129 | * @return characterization of result | ||
130 | */ | ||
131 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
132 | block_plugin_setu_test_check_reply (void *cls, | ||
133 | enum GNUNET_BLOCK_Type type, | ||
134 | struct GNUNET_BLOCK_Group *group, | ||
135 | const struct GNUNET_HashCode *query, | ||
136 | const void *xquery, | ||
137 | size_t xquery_size, | ||
138 | const void *reply_block, | ||
139 | size_t reply_block_size) | ||
140 | { | ||
141 | if ( (NULL == reply_block) || | ||
142 | (0 == reply_block_size) || | ||
143 | (0 != ((char *) reply_block)[0]) ) | ||
144 | return GNUNET_BLOCK_REPLY_INVALID; | ||
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
69 | * Function called to obtain the key for a block. | 150 | * Function called to obtain the key for a block. |
70 | * | 151 | * |
71 | * @param cls closure | 152 | * @param cls closure |
@@ -76,7 +157,7 @@ block_plugin_setu_test_evaluate (void *cls, | |||
76 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 157 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
77 | * (or if extracting a key from a block of this type does not work) | 158 | * (or if extracting a key from a block of this type does not work) |
78 | */ | 159 | */ |
79 | static int | 160 | static enum GNUNET_GenericReturnValue |
80 | block_plugin_setu_test_get_key (void *cls, | 161 | block_plugin_setu_test_get_key (void *cls, |
81 | enum GNUNET_BLOCK_Type type, | 162 | enum GNUNET_BLOCK_Type type, |
82 | const void *block, | 163 | const void *block, |
@@ -102,6 +183,9 @@ libgnunet_plugin_block_setu_test_init (void *cls) | |||
102 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
103 | api->evaluate = &block_plugin_setu_test_evaluate; | 184 | api->evaluate = &block_plugin_setu_test_evaluate; |
104 | api->get_key = &block_plugin_setu_test_get_key; | 185 | api->get_key = &block_plugin_setu_test_get_key; |
186 | api->check_query = &block_plugin_setu_test_check_query; | ||
187 | api->check_block = &block_plugin_setu_test_check_block; | ||
188 | api->check_reply = &block_plugin_setu_test_check_reply; | ||
105 | api->types = types; | 189 | api->types = types; |
106 | return api; | 190 | return api; |
107 | } | 191 | } |
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index 2a5e33e2b..3bfdeaa90 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -115,7 +115,7 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
115 | struct TcpHandshakeSignature | 115 | struct TcpHandshakeSignature |
116 | { | 116 | { |
117 | /** | 117 | /** |
118 | * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE | 118 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE |
119 | */ | 119 | */ |
120 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 120 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
121 | 121 | ||
@@ -153,7 +153,7 @@ struct TcpHandshakeSignature | |||
153 | struct TcpHandshakeAckSignature | 153 | struct TcpHandshakeAckSignature |
154 | { | 154 | { |
155 | /** | 155 | /** |
156 | * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK | 156 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK |
157 | */ | 157 | */ |
158 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 158 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
159 | 159 | ||
@@ -190,7 +190,7 @@ struct TCPConfirmation | |||
190 | struct GNUNET_PeerIdentity sender; | 190 | struct GNUNET_PeerIdentity sender; |
191 | 191 | ||
192 | /** | 192 | /** |
193 | * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE | 193 | * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE |
194 | */ | 194 | */ |
195 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | 195 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; |
196 | 196 | ||
@@ -225,7 +225,7 @@ struct TCPConfirmationAck | |||
225 | struct GNUNET_PeerIdentity sender; | 225 | struct GNUNET_PeerIdentity sender; |
226 | 226 | ||
227 | /** | 227 | /** |
228 | * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK | 228 | * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK |
229 | */ | 229 | */ |
230 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | 230 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; |
231 | 231 | ||
@@ -297,7 +297,7 @@ struct TCPRekey | |||
297 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral; | 297 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral; |
298 | 298 | ||
299 | /** | 299 | /** |
300 | * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY | 300 | * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY |
301 | */ | 301 | */ |
302 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | 302 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; |
303 | 303 | ||
@@ -315,7 +315,7 @@ struct TCPRekey | |||
315 | struct TcpRekeySignature | 315 | struct TcpRekeySignature |
316 | { | 316 | { |
317 | /** | 317 | /** |
318 | * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY | 318 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY |
319 | */ | 319 | */ |
320 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 320 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
321 | 321 | ||
@@ -1313,7 +1313,7 @@ do_rekey (struct Queue *queue, const struct TCPRekey *rekey) | |||
1313 | { | 1313 | { |
1314 | struct TcpRekeySignature thp; | 1314 | struct TcpRekeySignature thp; |
1315 | 1315 | ||
1316 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY); | 1316 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY); |
1317 | thp.purpose.size = htonl (sizeof(thp)); | 1317 | thp.purpose.size = htonl (sizeof(thp)); |
1318 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1318 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1319 | "do_rekey size %u\n", | 1319 | "do_rekey size %u\n", |
@@ -1340,7 +1340,7 @@ do_rekey (struct Queue *queue, const struct TCPRekey *rekey) | |||
1340 | GNUNET_TIME_absolute_ntoh (thp.monotonic_time))); | 1340 | GNUNET_TIME_absolute_ntoh (thp.monotonic_time))); |
1341 | GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp))); | 1341 | GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp))); |
1342 | if (GNUNET_OK != | 1342 | if (GNUNET_OK != |
1343 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY, | 1343 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY, |
1344 | &thp, | 1344 | &thp, |
1345 | &rekey->sender_sig, | 1345 | &rekey->sender_sig, |
1346 | &queue->target.public_key)) | 1346 | &queue->target.public_key)) |
@@ -1464,7 +1464,7 @@ send_challenge (struct ChallengeNonceP challenge, struct Queue *queue) | |||
1464 | tca.monotonic_time = | 1464 | tca.monotonic_time = |
1465 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | 1465 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); |
1466 | thas.purpose.purpose = htonl ( | 1466 | thas.purpose.purpose = htonl ( |
1467 | GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK); | 1467 | GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK); |
1468 | thas.purpose.size = htonl (sizeof(thas)); | 1468 | thas.purpose.size = htonl (sizeof(thas)); |
1469 | thas.sender = my_identity; | 1469 | thas.sender = my_identity; |
1470 | thas.receiver = queue->target; | 1470 | thas.receiver = queue->target; |
@@ -1527,7 +1527,7 @@ inject_rekey (struct Queue *queue) | |||
1527 | GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral); | 1527 | GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral); |
1528 | rekey.monotonic_time = | 1528 | rekey.monotonic_time = |
1529 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | 1529 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); |
1530 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY); | 1530 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY); |
1531 | thp.purpose.size = htonl (sizeof(thp)); | 1531 | thp.purpose.size = htonl (sizeof(thp)); |
1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1533 | "inject_rekey size %u\n", | 1533 | "inject_rekey size %u\n", |
@@ -1725,7 +1725,7 @@ try_handle_plaintext (struct Queue *queue) | |||
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | thas.purpose.purpose = htonl ( | 1727 | thas.purpose.purpose = htonl ( |
1728 | GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK); | 1728 | GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK); |
1729 | thas.purpose.size = htonl (sizeof(thas)); | 1729 | thas.purpose.size = htonl (sizeof(thas)); |
1730 | thas.sender = tca->sender; | 1730 | thas.sender = tca->sender; |
1731 | thas.receiver = my_identity; | 1731 | thas.receiver = my_identity; |
@@ -1733,7 +1733,7 @@ try_handle_plaintext (struct Queue *queue) | |||
1733 | thas.challenge = tca->challenge; | 1733 | thas.challenge = tca->challenge; |
1734 | 1734 | ||
1735 | if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify ( | 1735 | if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify ( |
1736 | GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE_ACK, | 1736 | GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK, |
1737 | &thas, | 1737 | &thas, |
1738 | &tca->sender_sig, | 1738 | &tca->sender_sig, |
1739 | &tca->sender.public_key)) | 1739 | &tca->sender.public_key)) |
@@ -2472,7 +2472,7 @@ transmit_kx (struct Queue *queue, | |||
2472 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | 2472 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, |
2473 | &tc.challenge, | 2473 | &tc.challenge, |
2474 | sizeof(tc.challenge)); | 2474 | sizeof(tc.challenge)); |
2475 | ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE); | 2475 | ths.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE); |
2476 | ths.purpose.size = htonl (sizeof(ths)); | 2476 | ths.purpose.size = htonl (sizeof(ths)); |
2477 | ths.sender = my_identity; | 2477 | ths.sender = my_identity; |
2478 | ths.receiver = queue->target; | 2478 | ths.receiver = queue->target; |
@@ -2625,7 +2625,7 @@ decrypt_and_check_tc (struct Queue *queue, | |||
2625 | sizeof(*tc), | 2625 | sizeof(*tc), |
2626 | &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)], | 2626 | &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)], |
2627 | sizeof(*tc))); | 2627 | sizeof(*tc))); |
2628 | ths.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE); | 2628 | ths.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE); |
2629 | ths.purpose.size = htonl (sizeof(ths)); | 2629 | ths.purpose.size = htonl (sizeof(ths)); |
2630 | ths.sender = tc->sender; | 2630 | ths.sender = tc->sender; |
2631 | ths.receiver = my_identity; | 2631 | ths.receiver = my_identity; |
@@ -2633,7 +2633,7 @@ decrypt_and_check_tc (struct Queue *queue, | |||
2633 | ths.monotonic_time = tc->monotonic_time; | 2633 | ths.monotonic_time = tc->monotonic_time; |
2634 | ths.challenge = tc->challenge; | 2634 | ths.challenge = tc->challenge; |
2635 | ret = GNUNET_CRYPTO_eddsa_verify ( | 2635 | ret = GNUNET_CRYPTO_eddsa_verify ( |
2636 | GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE, | 2636 | GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE, |
2637 | &ths, | 2637 | &ths, |
2638 | &tc->sender_sig, | 2638 | &tc->sender_sig, |
2639 | &tc->sender.public_key); | 2639 | &tc->sender.public_key); |
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 201e94e80..b6edff485 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -164,7 +164,7 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
164 | struct UdpHandshakeSignature | 164 | struct UdpHandshakeSignature |
165 | { | 165 | { |
166 | /** | 166 | /** |
167 | * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE | 167 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE |
168 | */ | 168 | */ |
169 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 169 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
170 | 170 | ||
@@ -227,7 +227,7 @@ struct UDPConfirmation | |||
227 | struct GNUNET_PeerIdentity sender; | 227 | struct GNUNET_PeerIdentity sender; |
228 | 228 | ||
229 | /** | 229 | /** |
230 | * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE | 230 | * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE |
231 | */ | 231 | */ |
232 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | 232 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; |
233 | 233 | ||
@@ -284,7 +284,7 @@ struct UDPAck | |||
284 | struct UdpBroadcastSignature | 284 | struct UdpBroadcastSignature |
285 | { | 285 | { |
286 | /** | 286 | /** |
287 | * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST | 287 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST |
288 | */ | 288 | */ |
289 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | 289 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; |
290 | 290 | ||
@@ -315,7 +315,7 @@ struct UDPBroadcast | |||
315 | 315 | ||
316 | /** | 316 | /** |
317 | * Sender's signature of type | 317 | * Sender's signature of type |
318 | * #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST | 318 | * #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST |
319 | */ | 319 | */ |
320 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | 320 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; |
321 | }; | 321 | }; |
@@ -2202,14 +2202,14 @@ verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, | |||
2202 | { | 2202 | { |
2203 | struct UdpHandshakeSignature uhs; | 2203 | struct UdpHandshakeSignature uhs; |
2204 | 2204 | ||
2205 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE); | 2205 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE); |
2206 | uhs.purpose.size = htonl (sizeof(uhs)); | 2206 | uhs.purpose.size = htonl (sizeof(uhs)); |
2207 | uhs.sender = uc->sender; | 2207 | uhs.sender = uc->sender; |
2208 | uhs.receiver = my_identity; | 2208 | uhs.receiver = my_identity; |
2209 | uhs.ephemeral = *ephemeral; | 2209 | uhs.ephemeral = *ephemeral; |
2210 | uhs.monotonic_time = uc->monotonic_time; | 2210 | uhs.monotonic_time = uc->monotonic_time; |
2211 | return GNUNET_CRYPTO_eddsa_verify ( | 2211 | return GNUNET_CRYPTO_eddsa_verify ( |
2212 | GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, | 2212 | GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, |
2213 | &uhs, | 2213 | &uhs, |
2214 | &uc->sender_sig, | 2214 | &uc->sender_sig, |
2215 | &uc->sender.public_key); | 2215 | &uc->sender.public_key); |
@@ -2350,7 +2350,7 @@ sock_read (void *cls) | |||
2350 | "received UDPBroadcast from %s\n", | 2350 | "received UDPBroadcast from %s\n", |
2351 | GNUNET_a2s ((const struct sockaddr *) addr_verify, salen)); | 2351 | GNUNET_a2s ((const struct sockaddr *) addr_verify, salen)); |
2352 | ub = (const struct UDPBroadcast *) buf; | 2352 | ub = (const struct UDPBroadcast *) buf; |
2353 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST); | 2353 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST); |
2354 | uhs.purpose.size = htonl (sizeof(uhs)); | 2354 | uhs.purpose.size = htonl (sizeof(uhs)); |
2355 | uhs.sender = ub->sender; | 2355 | uhs.sender = ub->sender; |
2356 | sender = ub->sender; | 2356 | sender = ub->sender; |
@@ -2366,7 +2366,7 @@ sock_read (void *cls) | |||
2366 | GNUNET_i2s (&sender)); | 2366 | GNUNET_i2s (&sender)); |
2367 | GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen, &uhs.h_address); | 2367 | GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen, &uhs.h_address); |
2368 | if (GNUNET_OK == | 2368 | if (GNUNET_OK == |
2369 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST, | 2369 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, |
2370 | &uhs, | 2370 | &uhs, |
2371 | &ub->sender_sig, | 2371 | &ub->sender_sig, |
2372 | &ub->sender.public_key)) | 2372 | &ub->sender.public_key)) |
@@ -2699,7 +2699,7 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, | |||
2699 | uc.sender = my_identity; | 2699 | uc.sender = my_identity; |
2700 | uc.monotonic_time = | 2700 | uc.monotonic_time = |
2701 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | 2701 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); |
2702 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE); | 2702 | uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE); |
2703 | uhs.purpose.size = htonl (sizeof(uhs)); | 2703 | uhs.purpose.size = htonl (sizeof(uhs)); |
2704 | uhs.sender = my_identity; | 2704 | uhs.sender = my_identity; |
2705 | uhs.receiver = receiver->target; | 2705 | uhs.receiver = receiver->target; |
@@ -3644,7 +3644,7 @@ iface_proc (void *cls, | |||
3644 | bi->salen = addrlen; | 3644 | bi->salen = addrlen; |
3645 | bi->found = GNUNET_YES; | 3645 | bi->found = GNUNET_YES; |
3646 | bi->bcm.sender = my_identity; | 3646 | bi->bcm.sender = my_identity; |
3647 | ubs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST); | 3647 | ubs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST); |
3648 | ubs.purpose.size = htonl (sizeof(ubs)); | 3648 | ubs.purpose.size = htonl (sizeof(ubs)); |
3649 | ubs.sender = my_identity; | 3649 | ubs.sender = my_identity; |
3650 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3650 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 9fda40f51..406d42b1e 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -144,7 +144,7 @@ libgnunetutil_la_LIBADD = \ | |||
144 | 144 | ||
145 | libgnunetutil_la_LDFLAGS = \ | 145 | libgnunetutil_la_LDFLAGS = \ |
146 | $(GN_LIB_LDFLAGS) \ | 146 | $(GN_LIB_LDFLAGS) \ |
147 | -version-info 14:0:0 | 147 | -version-info 15:0:0 |
148 | 148 | ||
149 | GNUNET_ECC = gnunet-ecc | 149 | GNUNET_ECC = gnunet-ecc |
150 | GNUNET_SCRYPT = gnunet-scrypt | 150 | GNUNET_SCRYPT = gnunet-scrypt |
diff --git a/src/util/crypto_cs.c b/src/util/crypto_cs.c index 5c441b669..c89ba5d83 100644 --- a/src/util/crypto_cs.c +++ b/src/util/crypto_cs.c | |||
@@ -147,8 +147,8 @@ GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | |||
147 | * @param[out] bs array containing the two derived blinding secrets | 147 | * @param[out] bs array containing the two derived blinding secrets |
148 | */ | 148 | */ |
149 | void | 149 | void |
150 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const void *secret, | 150 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct |
151 | size_t secret_len, | 151 | GNUNET_CRYPTO_CsNonce *blind_seed, |
152 | struct GNUNET_CRYPTO_CsBlindingSecret | 152 | struct GNUNET_CRYPTO_CsBlindingSecret |
153 | bs[2]) | 153 | bs[2]) |
154 | { | 154 | { |
@@ -161,8 +161,8 @@ GNUNET_CRYPTO_cs_blinding_secrets_derive (const void *secret, | |||
161 | GCRY_MD_SHA256, | 161 | GCRY_MD_SHA256, |
162 | "alphabeta", | 162 | "alphabeta", |
163 | strlen ("alphabeta"), | 163 | strlen ("alphabeta"), |
164 | secret, | 164 | blind_seed, |
165 | secret_len, | 165 | sizeof(*blind_seed), |
166 | NULL, | 166 | NULL, |
167 | 0)); | 167 | 0)); |
168 | map_to_scalar_subgroup (&bs[0].alpha); | 168 | map_to_scalar_subgroup (&bs[0].alpha); |
diff --git a/src/util/crypto_ecc_setup.c b/src/util/crypto_ecc_setup.c index f7cd8c6d9..21ce48eef 100644 --- a/src/util/crypto_ecc_setup.c +++ b/src/util/crypto_ecc_setup.c | |||
@@ -134,8 +134,10 @@ read_from_file (const char *filename, | |||
134 | * @param filename name of file to use to store the key | 134 | * @param filename name of file to use to store the key |
135 | * @param do_create should a file be created? | 135 | * @param do_create should a file be created? |
136 | * @param[out] pkey set to the private key from @a filename on success | 136 | * @param[out] pkey set to the private key from @a filename on success |
137 | * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but | 137 | * @return - #GNUNET_OK on success, |
138 | * we found an existing file, #GNUNET_SYSERR on failure | 138 | * - #GNUNET_NO if @a do_create was set but we found an existing file, |
139 | * - #GNUNET_SYSERR on failure _or_ if the file didn't exist and @a | ||
140 | * do_create was not set | ||
139 | */ | 141 | */ |
140 | enum GNUNET_GenericReturnValue | 142 | enum GNUNET_GenericReturnValue |
141 | GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, | 143 | GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, |
@@ -152,6 +154,11 @@ GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, | |||
152 | /* file existed, report that we didn't create it... */ | 154 | /* file existed, report that we didn't create it... */ |
153 | return (do_create) ? GNUNET_NO : GNUNET_OK; | 155 | return (do_create) ? GNUNET_NO : GNUNET_OK; |
154 | } | 156 | } |
157 | else if (! do_create) | ||
158 | { | ||
159 | return GNUNET_SYSERR; | ||
160 | } | ||
161 | |||
155 | GNUNET_CRYPTO_eddsa_key_create (pkey); | 162 | GNUNET_CRYPTO_eddsa_key_create (pkey); |
156 | ret = GNUNET_DISK_fn_write (filename, | 163 | ret = GNUNET_DISK_fn_write (filename, |
157 | pkey, | 164 | pkey, |
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index d62ec8012..dcd46e5f9 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c | |||
@@ -135,18 +135,22 @@ GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a, | |||
135 | const struct GNUNET_HashCode *b, | 135 | const struct GNUNET_HashCode *b, |
136 | struct GNUNET_HashCode *result) | 136 | struct GNUNET_HashCode *result) |
137 | { | 137 | { |
138 | for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; | 138 | const unsigned long long *lla = (const unsigned long long *) a; |
139 | i >= 0; | 139 | const unsigned long long *llb = (const unsigned long long *) b; |
140 | i--) | 140 | unsigned long long *llr = (unsigned long long *) result; |
141 | result->bits[i] = a->bits[i] ^ b->bits[i]; | 141 | |
142 | GNUNET_static_assert (8 == sizeof (unsigned long long)); | ||
143 | GNUNET_static_assert (0 == sizeof (*a) % sizeof (unsigned long long)); | ||
144 | for (int i = sizeof (*result) / sizeof (*llr) - 1; i>=0; i--) | ||
145 | llr[i] = lla[i] ^ llb[i]; | ||
142 | } | 146 | } |
143 | 147 | ||
144 | 148 | ||
145 | void | 149 | void |
146 | GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc, | 150 | GNUNET_CRYPTO_hash_to_aes_key ( |
147 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | 151 | const struct GNUNET_HashCode *hc, |
148 | struct | 152 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, |
149 | GNUNET_CRYPTO_SymmetricInitializationVector *iv) | 153 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) |
150 | { | 154 | { |
151 | GNUNET_assert (GNUNET_YES == | 155 | GNUNET_assert (GNUNET_YES == |
152 | GNUNET_CRYPTO_kdf ( | 156 | GNUNET_CRYPTO_kdf ( |
@@ -167,33 +171,47 @@ GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc, | |||
167 | } | 171 | } |
168 | 172 | ||
169 | 173 | ||
170 | int | 174 | unsigned int |
171 | GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code, | 175 | GNUNET_CRYPTO_hash_count_leading_zeros (const struct GNUNET_HashCode *h) |
172 | unsigned int bit) | ||
173 | { | 176 | { |
174 | GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode)); | 177 | const unsigned long long *llp = (const unsigned long long *) h; |
175 | return (((unsigned char *) code)[bit >> 3] & (128 >> (bit & 7))) > 0; | 178 | unsigned int ret = 0; |
176 | } | 179 | unsigned int i; |
177 | |||
178 | 180 | ||
179 | int | 181 | GNUNET_static_assert (8 == sizeof (unsigned long long)); |
180 | GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code, | 182 | GNUNET_static_assert (0 == sizeof (*h) % sizeof (unsigned long long)); |
181 | unsigned int bit) | 183 | for (i = 0; i<sizeof (*h) / sizeof (*llp); i++) |
182 | { | 184 | { |
183 | GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode)); | 185 | if (0LLU != llp[i]) |
184 | return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0; | 186 | break; |
187 | ret += sizeof (*llp) * 8; | ||
188 | } | ||
189 | if (ret == 8 * sizeof (*h)) | ||
190 | return ret; | ||
191 | ret += __builtin_clzll (GNUNET_ntohll ((uint64_t) llp[i])); | ||
192 | return ret; | ||
185 | } | 193 | } |
186 | 194 | ||
187 | 195 | ||
188 | unsigned int | 196 | unsigned int |
189 | GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first, | 197 | GNUNET_CRYPTO_hash_count_tailing_zeros (const struct GNUNET_HashCode *h) |
190 | const struct GNUNET_HashCode *second) | ||
191 | { | 198 | { |
192 | for (unsigned int i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++) | 199 | const unsigned long long *llp = (const unsigned long long *) h; |
193 | if (GNUNET_CRYPTO_hash_get_bit_rtl (first, i) != | 200 | unsigned int ret = 0; |
194 | GNUNET_CRYPTO_hash_get_bit_rtl (second, i)) | 201 | int i; |
195 | return i; | 202 | |
196 | return sizeof(struct GNUNET_HashCode) * 8; | 203 | GNUNET_static_assert (8 == sizeof (unsigned long long)); |
204 | GNUNET_static_assert (0 == sizeof (*h) % sizeof (unsigned long long)); | ||
205 | for (i = sizeof (*h) / sizeof (*llp) - 1; i>=0; i--) | ||
206 | { | ||
207 | if (0LLU != llp[i]) | ||
208 | break; | ||
209 | ret += sizeof (*llp) * 8; | ||
210 | } | ||
211 | if (ret == 8 * sizeof (*h)) | ||
212 | return ret; | ||
213 | ret += __builtin_ctzll (GNUNET_ntohll ((uint64_t) llp[i])); | ||
214 | return ret; | ||
197 | } | 215 | } |
198 | 216 | ||
199 | 217 | ||
@@ -224,18 +242,19 @@ GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1, | |||
224 | const struct GNUNET_HashCode *h2, | 242 | const struct GNUNET_HashCode *h2, |
225 | const struct GNUNET_HashCode *target) | 243 | const struct GNUNET_HashCode *target) |
226 | { | 244 | { |
227 | unsigned int d1; | 245 | const unsigned long long *l1 = (const unsigned long long *) h1; |
228 | unsigned int d2; | 246 | const unsigned long long *l2 = (const unsigned long long *) h2; |
247 | const unsigned long long *t = (const unsigned long long *) target; | ||
229 | 248 | ||
230 | for (ssize_t i = sizeof(struct GNUNET_HashCode) / sizeof(unsigned int) - 1; | 249 | GNUNET_static_assert (0 == sizeof (*h1) % sizeof (*l1)); |
231 | i >= 0; | 250 | for (size_t i = 0; i < sizeof(*h1) / sizeof(*l1); i++) |
232 | i--) | ||
233 | { | 251 | { |
234 | d1 = ((unsigned int *) h1)[i] ^ ((unsigned int *) target)[i]; | 252 | unsigned long long x1 = l1[i] ^ t[i]; |
235 | d2 = ((unsigned int *) h2)[i] ^ ((unsigned int *) target)[i]; | 253 | unsigned long long x2 = l2[i] ^ t[i]; |
236 | if (d1 > d2) | 254 | |
255 | if (x1 > x2) | ||
237 | return 1; | 256 | return 1; |
238 | else if (d1 < d2) | 257 | if (x1 < x2) |
239 | return -1; | 258 | return -1; |
240 | } | 259 | } |
241 | return 0; | 260 | return 0; |
@@ -243,25 +262,30 @@ GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1, | |||
243 | 262 | ||
244 | 263 | ||
245 | void | 264 | void |
246 | GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key, | 265 | GNUNET_CRYPTO_hmac_derive_key ( |
247 | const struct | 266 | struct GNUNET_CRYPTO_AuthKey *key, |
248 | GNUNET_CRYPTO_SymmetricSessionKey *rkey, | 267 | const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, |
249 | const void *salt, size_t salt_len, ...) | 268 | const void *salt, size_t salt_len, |
269 | ...) | ||
250 | { | 270 | { |
251 | va_list argp; | 271 | va_list argp; |
252 | 272 | ||
253 | va_start (argp, salt_len); | 273 | va_start (argp, |
254 | GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp); | 274 | salt_len); |
275 | GNUNET_CRYPTO_hmac_derive_key_v (key, | ||
276 | rkey, | ||
277 | salt, salt_len, | ||
278 | argp); | ||
255 | va_end (argp); | 279 | va_end (argp); |
256 | } | 280 | } |
257 | 281 | ||
258 | 282 | ||
259 | void | 283 | void |
260 | GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key, | 284 | GNUNET_CRYPTO_hmac_derive_key_v ( |
261 | const struct | 285 | struct GNUNET_CRYPTO_AuthKey *key, |
262 | GNUNET_CRYPTO_SymmetricSessionKey *rkey, | 286 | const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, |
263 | const void *salt, size_t salt_len, | 287 | const void *salt, size_t salt_len, |
264 | va_list argp) | 288 | va_list argp) |
265 | { | 289 | { |
266 | GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key), | 290 | GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key), |
267 | salt, salt_len, | 291 | salt, salt_len, |
@@ -283,7 +307,9 @@ GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len, | |||
283 | { | 307 | { |
284 | once = 1; | 308 | once = 1; |
285 | GNUNET_assert (GPG_ERR_NO_ERROR == | 309 | GNUNET_assert (GPG_ERR_NO_ERROR == |
286 | gcry_md_open (&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC)); | 310 | gcry_md_open (&md, |
311 | GCRY_MD_SHA512, | ||
312 | GCRY_MD_FLAG_HMAC)); | ||
287 | } | 313 | } |
288 | else | 314 | else |
289 | { | 315 | { |
@@ -323,15 +349,12 @@ GNUNET_CRYPTO_hash_context_start () | |||
323 | struct GNUNET_HashContext *hc; | 349 | struct GNUNET_HashContext *hc; |
324 | 350 | ||
325 | BENCHMARK_START (hash_context_start); | 351 | BENCHMARK_START (hash_context_start); |
326 | |||
327 | hc = GNUNET_new (struct GNUNET_HashContext); | 352 | hc = GNUNET_new (struct GNUNET_HashContext); |
328 | GNUNET_assert (0 == | 353 | GNUNET_assert (0 == |
329 | gcry_md_open (&hc->hd, | 354 | gcry_md_open (&hc->hd, |
330 | GCRY_MD_SHA512, | 355 | GCRY_MD_SHA512, |
331 | 0)); | 356 | 0)); |
332 | |||
333 | BENCHMARK_END (hash_context_start); | 357 | BENCHMARK_END (hash_context_start); |
334 | |||
335 | return hc; | 358 | return hc; |
336 | } | 359 | } |
337 | 360 | ||
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c index 592875531..917aa440b 100644 --- a/src/util/getopt_helpers.c +++ b/src/util/getopt_helpers.c | |||
@@ -38,7 +38,7 @@ | |||
38 | * @param value not used (NULL) | 38 | * @param value not used (NULL) |
39 | * @return #GNUNET_NO (do not continue, not an error) | 39 | * @return #GNUNET_NO (do not continue, not an error) |
40 | */ | 40 | */ |
41 | static int | 41 | static enum GNUNET_GenericReturnValue |
42 | print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 42 | print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
43 | void *scls, | 43 | void *scls, |
44 | const char *option, | 44 | const char *option, |
@@ -53,12 +53,6 @@ print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
53 | } | 53 | } |
54 | 54 | ||
55 | 55 | ||
56 | /** | ||
57 | * Define the option to print the version of | ||
58 | * the application (-v option) | ||
59 | * | ||
60 | * @param version string with the version number | ||
61 | */ | ||
62 | struct GNUNET_GETOPT_CommandLineOption | 56 | struct GNUNET_GETOPT_CommandLineOption |
63 | GNUNET_GETOPT_option_version (const char *version) | 57 | GNUNET_GETOPT_option_version (const char *version) |
64 | { | 58 | { |
@@ -90,7 +84,7 @@ GNUNET_GETOPT_option_version (const char *version) | |||
90 | * @param value not used (NULL) | 84 | * @param value not used (NULL) |
91 | * @return #GNUNET_NO (do not continue, not an error) | 85 | * @return #GNUNET_NO (do not continue, not an error) |
92 | */ | 86 | */ |
93 | static int | 87 | static enum GNUNET_GenericReturnValue |
94 | format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 88 | format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
95 | void *scls, | 89 | void *scls, |
96 | const char *option, | 90 | const char *option, |
@@ -192,12 +186,6 @@ OUTER: | |||
192 | } | 186 | } |
193 | 187 | ||
194 | 188 | ||
195 | /** | ||
196 | * Defining the option to print the command line | ||
197 | * help text (-h option). | ||
198 | * | ||
199 | * @param about string with brief description of the application | ||
200 | */ | ||
201 | struct GNUNET_GETOPT_CommandLineOption | 189 | struct GNUNET_GETOPT_CommandLineOption |
202 | GNUNET_GETOPT_option_help (const char *about) | 190 | GNUNET_GETOPT_option_help (const char *about) |
203 | { | 191 | { |
@@ -229,7 +217,7 @@ GNUNET_GETOPT_option_help (const char *about) | |||
229 | * @param value not used (NULL) | 217 | * @param value not used (NULL) |
230 | * @return #GNUNET_OK | 218 | * @return #GNUNET_OK |
231 | */ | 219 | */ |
232 | static int | 220 | static enum GNUNET_GenericReturnValue |
233 | increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 221 | increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
234 | void *scls, | 222 | void *scls, |
235 | const char *option, | 223 | const char *option, |
@@ -245,15 +233,6 @@ increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
245 | } | 233 | } |
246 | 234 | ||
247 | 235 | ||
248 | /** | ||
249 | * Increment @a val each time the option flag is given by one. | ||
250 | * | ||
251 | * @param shortName short name of the option | ||
252 | * @param name long name of the option | ||
253 | * @param argumentHelp help text for the option argument | ||
254 | * @param description long help text for the option | ||
255 | * @param[out] val increment by 1 each time the option is present | ||
256 | */ | ||
257 | struct GNUNET_GETOPT_CommandLineOption | 236 | struct GNUNET_GETOPT_CommandLineOption |
258 | GNUNET_GETOPT_option_increment_uint (char shortName, | 237 | GNUNET_GETOPT_option_increment_uint (char shortName, |
259 | const char *name, | 238 | const char *name, |
@@ -272,12 +251,6 @@ GNUNET_GETOPT_option_increment_uint (char shortName, | |||
272 | } | 251 | } |
273 | 252 | ||
274 | 253 | ||
275 | /** | ||
276 | * Define the '-V' verbosity option. Using the option more | ||
277 | * than once increments @a level each time. | ||
278 | * | ||
279 | * @param[out] level set to the verbosity level | ||
280 | */ | ||
281 | struct GNUNET_GETOPT_CommandLineOption | 254 | struct GNUNET_GETOPT_CommandLineOption |
282 | GNUNET_GETOPT_option_verbose (unsigned int *level) | 255 | GNUNET_GETOPT_option_verbose (unsigned int *level) |
283 | { | 256 | { |
@@ -308,7 +281,7 @@ GNUNET_GETOPT_option_verbose (unsigned int *level) | |||
308 | * @param value not used (NULL) | 281 | * @param value not used (NULL) |
309 | * @return #GNUNET_OK | 282 | * @return #GNUNET_OK |
310 | */ | 283 | */ |
311 | static int | 284 | static enum GNUNET_GenericReturnValue |
312 | set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 285 | set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
313 | void *scls, | 286 | void *scls, |
314 | const char *option, | 287 | const char *option, |
@@ -324,16 +297,6 @@ set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
324 | } | 297 | } |
325 | 298 | ||
326 | 299 | ||
327 | /** | ||
328 | * Allow user to specify a flag (which internally means setting | ||
329 | * an integer to 1/#GNUNET_YES/#GNUNET_OK. | ||
330 | * | ||
331 | * @param shortName short name of the option | ||
332 | * @param name long name of the option | ||
333 | * @param argumentHelp help text for the option argument | ||
334 | * @param description long help text for the option | ||
335 | * @param[out] val set to 1 if the option is present | ||
336 | */ | ||
337 | struct GNUNET_GETOPT_CommandLineOption | 300 | struct GNUNET_GETOPT_CommandLineOption |
338 | GNUNET_GETOPT_option_flag (char shortName, | 301 | GNUNET_GETOPT_option_flag (char shortName, |
339 | const char *name, | 302 | const char *name, |
@@ -366,7 +329,7 @@ GNUNET_GETOPT_option_flag (char shortName, | |||
366 | * @param value actual value of the option (a string) | 329 | * @param value actual value of the option (a string) |
367 | * @return #GNUNET_OK | 330 | * @return #GNUNET_OK |
368 | */ | 331 | */ |
369 | static int | 332 | static enum GNUNET_GenericReturnValue |
370 | set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 333 | set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
371 | void *scls, | 334 | void *scls, |
372 | const char *option, | 335 | const char *option, |
@@ -383,15 +346,6 @@ set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
383 | } | 346 | } |
384 | 347 | ||
385 | 348 | ||
386 | /** | ||
387 | * Allow user to specify a string. | ||
388 | * | ||
389 | * @param shortName short name of the option | ||
390 | * @param name long name of the option | ||
391 | * @param argumentHelp help text for the option argument | ||
392 | * @param description long help text for the option | ||
393 | * @param[out] str set to the string | ||
394 | */ | ||
395 | struct GNUNET_GETOPT_CommandLineOption | 349 | struct GNUNET_GETOPT_CommandLineOption |
396 | GNUNET_GETOPT_option_string (char shortName, | 350 | GNUNET_GETOPT_option_string (char shortName, |
397 | const char *name, | 351 | const char *name, |
@@ -413,12 +367,6 @@ GNUNET_GETOPT_option_string (char shortName, | |||
413 | } | 367 | } |
414 | 368 | ||
415 | 369 | ||
416 | /** | ||
417 | * Define the '-L' log level option. Note that we do not check | ||
418 | * that the log level is valid here. | ||
419 | * | ||
420 | * @param[out] level set to the log level | ||
421 | */ | ||
422 | struct GNUNET_GETOPT_CommandLineOption | 370 | struct GNUNET_GETOPT_CommandLineOption |
423 | GNUNET_GETOPT_option_loglevel (char **level) | 371 | GNUNET_GETOPT_option_loglevel (char **level) |
424 | { | 372 | { |
@@ -447,7 +395,7 @@ GNUNET_GETOPT_option_loglevel (char **level) | |||
447 | * @param value actual value of the option (a string) | 395 | * @param value actual value of the option (a string) |
448 | * @return #GNUNET_OK | 396 | * @return #GNUNET_OK |
449 | */ | 397 | */ |
450 | static int | 398 | static enum GNUNET_GenericReturnValue |
451 | set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 399 | set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
452 | void *scls, | 400 | void *scls, |
453 | const char *option, | 401 | const char *option, |
@@ -464,15 +412,6 @@ set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
464 | } | 412 | } |
465 | 413 | ||
466 | 414 | ||
467 | /** | ||
468 | * Allow user to specify a filename (automatically path expanded). | ||
469 | * | ||
470 | * @param shortName short name of the option | ||
471 | * @param name long name of the option | ||
472 | * @param argumentHelp help text for the option argument | ||
473 | * @param description long help text for the option | ||
474 | * @param[out] str set to the string | ||
475 | */ | ||
476 | struct GNUNET_GETOPT_CommandLineOption | 415 | struct GNUNET_GETOPT_CommandLineOption |
477 | GNUNET_GETOPT_option_filename (char shortName, | 416 | GNUNET_GETOPT_option_filename (char shortName, |
478 | const char *name, | 417 | const char *name, |
@@ -494,11 +433,6 @@ GNUNET_GETOPT_option_filename (char shortName, | |||
494 | } | 433 | } |
495 | 434 | ||
496 | 435 | ||
497 | /** | ||
498 | * Allow user to specify log file name (-l option) | ||
499 | * | ||
500 | * @param[out] logfn set to the name of the logfile | ||
501 | */ | ||
502 | struct GNUNET_GETOPT_CommandLineOption | 436 | struct GNUNET_GETOPT_CommandLineOption |
503 | GNUNET_GETOPT_option_logfile (char **logfn) | 437 | GNUNET_GETOPT_option_logfile (char **logfn) |
504 | { | 438 | { |
@@ -517,11 +451,6 @@ GNUNET_GETOPT_option_logfile (char **logfn) | |||
517 | } | 451 | } |
518 | 452 | ||
519 | 453 | ||
520 | /** | ||
521 | * Allow user to specify configuration file name (-c option) | ||
522 | * | ||
523 | * @param[out] fn set to the name of the configuration file | ||
524 | */ | ||
525 | struct GNUNET_GETOPT_CommandLineOption | 454 | struct GNUNET_GETOPT_CommandLineOption |
526 | GNUNET_GETOPT_option_cfgfile (char **fn) | 455 | GNUNET_GETOPT_option_cfgfile (char **fn) |
527 | { | 456 | { |
@@ -552,7 +481,7 @@ GNUNET_GETOPT_option_cfgfile (char **fn) | |||
552 | * @param value actual value of the option as a string. | 481 | * @param value actual value of the option as a string. |
553 | * @return #GNUNET_OK if parsing the value worked | 482 | * @return #GNUNET_OK if parsing the value worked |
554 | */ | 483 | */ |
555 | static int | 484 | static enum GNUNET_GenericReturnValue |
556 | set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 485 | set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
557 | void *scls, | 486 | void *scls, |
558 | const char *option, | 487 | const char *option, |
@@ -573,15 +502,6 @@ set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
573 | } | 502 | } |
574 | 503 | ||
575 | 504 | ||
576 | /** | ||
577 | * Allow user to specify an `unsigned long long` | ||
578 | * | ||
579 | * @param shortName short name of the option | ||
580 | * @param name long name of the option | ||
581 | * @param argumentHelp help text for the option argument | ||
582 | * @param description long help text for the option | ||
583 | * @param[out] val set to the value specified at the command line | ||
584 | */ | ||
585 | struct GNUNET_GETOPT_CommandLineOption | 505 | struct GNUNET_GETOPT_CommandLineOption |
586 | GNUNET_GETOPT_option_ulong (char shortName, | 506 | GNUNET_GETOPT_option_ulong (char shortName, |
587 | const char *name, | 507 | const char *name, |
@@ -616,7 +536,7 @@ GNUNET_GETOPT_option_ulong (char shortName, | |||
616 | * @param value actual value of the option as a string. | 536 | * @param value actual value of the option as a string. |
617 | * @return #GNUNET_OK if parsing the value worked | 537 | * @return #GNUNET_OK if parsing the value worked |
618 | */ | 538 | */ |
619 | static int | 539 | static enum GNUNET_GenericReturnValue |
620 | set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 540 | set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
621 | void *scls, | 541 | void *scls, |
622 | const char *option, | 542 | const char *option, |
@@ -664,15 +584,6 @@ set_timetravel_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
664 | } | 584 | } |
665 | 585 | ||
666 | 586 | ||
667 | /** | ||
668 | * Allow user to specify a `long long` with an offset to add to the current | ||
669 | * system time to construct the time seen by the application. Used for | ||
670 | * debugging / testing. | ||
671 | * | ||
672 | * @param shortName short name of the option | ||
673 | * @param name long name of the option | ||
674 | * @param[out] val set to the time specified at the command line | ||
675 | */ | ||
676 | struct GNUNET_GETOPT_CommandLineOption | 587 | struct GNUNET_GETOPT_CommandLineOption |
677 | GNUNET_GETOPT_option_timetravel (char shortName, | 588 | GNUNET_GETOPT_option_timetravel (char shortName, |
678 | const char *name) | 589 | const char *name) |
@@ -684,8 +595,7 @@ GNUNET_GETOPT_option_timetravel (char shortName, | |||
684 | .description = _ ( | 595 | .description = _ ( |
685 | "modify system time by given offset (for debugging/testing only)"), | 596 | "modify system time by given offset (for debugging/testing only)"), |
686 | .require_argument = 1, | 597 | .require_argument = 1, |
687 | .processor = | 598 | .processor = &set_timetravel_time |
688 | &set_timetravel_time | ||
689 | }; | 599 | }; |
690 | 600 | ||
691 | return clo; | 601 | return clo; |
@@ -705,7 +615,7 @@ GNUNET_GETOPT_option_timetravel (char shortName, | |||
705 | * @param value actual value of the option as a string. | 615 | * @param value actual value of the option as a string. |
706 | * @return #GNUNET_OK if parsing the value worked | 616 | * @return #GNUNET_OK if parsing the value worked |
707 | */ | 617 | */ |
708 | static int | 618 | static enum GNUNET_GenericReturnValue |
709 | set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 619 | set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
710 | void *scls, | 620 | void *scls, |
711 | const char *option, | 621 | const char *option, |
@@ -725,16 +635,6 @@ set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
725 | } | 635 | } |
726 | 636 | ||
727 | 637 | ||
728 | /** | ||
729 | * Allow user to specify a `struct GNUNET_TIME_Relative` | ||
730 | * (using human-readable "fancy" time). | ||
731 | * | ||
732 | * @param shortName short name of the option | ||
733 | * @param name long name of the option | ||
734 | * @param argumentHelp help text for the option argument | ||
735 | * @param description long help text for the option | ||
736 | * @param[out] val set to the time specified at the command line | ||
737 | */ | ||
738 | struct GNUNET_GETOPT_CommandLineOption | 638 | struct GNUNET_GETOPT_CommandLineOption |
739 | GNUNET_GETOPT_option_relative_time (char shortName, | 639 | GNUNET_GETOPT_option_relative_time (char shortName, |
740 | const char *name, | 640 | const char *name, |
@@ -748,8 +648,7 @@ GNUNET_GETOPT_option_relative_time (char shortName, | |||
748 | .argumentHelp = argumentHelp, | 648 | .argumentHelp = argumentHelp, |
749 | .description = description, | 649 | .description = description, |
750 | .require_argument = 1, | 650 | .require_argument = 1, |
751 | .processor = | 651 | .processor = &set_relative_time, |
752 | &set_relative_time, | ||
753 | .scls = (void *) val | 652 | .scls = (void *) val |
754 | }; | 653 | }; |
755 | 654 | ||
@@ -770,7 +669,7 @@ GNUNET_GETOPT_option_relative_time (char shortName, | |||
770 | * @param value actual value of the option as a string. | 669 | * @param value actual value of the option as a string. |
771 | * @return #GNUNET_OK if parsing the value worked | 670 | * @return #GNUNET_OK if parsing the value worked |
772 | */ | 671 | */ |
773 | static int | 672 | static enum GNUNET_GenericReturnValue |
774 | set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 673 | set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
775 | void *scls, | 674 | void *scls, |
776 | const char *option, | 675 | const char *option, |
@@ -790,16 +689,6 @@ set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
790 | } | 689 | } |
791 | 690 | ||
792 | 691 | ||
793 | /** | ||
794 | * Allow user to specify a `struct GNUNET_TIME_Absolute` | ||
795 | * (using human-readable "fancy" time). | ||
796 | * | ||
797 | * @param shortName short name of the option | ||
798 | * @param name long name of the option | ||
799 | * @param argumentHelp help text for the option argument | ||
800 | * @param description long help text for the option | ||
801 | * @param[out] val set to the time specified at the command line | ||
802 | */ | ||
803 | struct GNUNET_GETOPT_CommandLineOption | 692 | struct GNUNET_GETOPT_CommandLineOption |
804 | GNUNET_GETOPT_option_absolute_time (char shortName, | 693 | GNUNET_GETOPT_option_absolute_time (char shortName, |
805 | const char *name, | 694 | const char *name, |
@@ -813,8 +702,71 @@ GNUNET_GETOPT_option_absolute_time (char shortName, | |||
813 | .argumentHelp = argumentHelp, | 702 | .argumentHelp = argumentHelp, |
814 | .description = description, | 703 | .description = description, |
815 | .require_argument = 1, | 704 | .require_argument = 1, |
816 | .processor = | 705 | .processor = &set_absolute_time, |
817 | &set_absolute_time, | 706 | .scls = (void *) val |
707 | }; | ||
708 | |||
709 | return clo; | ||
710 | } | ||
711 | |||
712 | |||
713 | /** | ||
714 | * Set an option of type 'struct GNUNET_TIME_Timestamp' from the command line. | ||
715 | * A pointer to this function should be passed as part of the | ||
716 | * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options | ||
717 | * of this type. It should be followed by a pointer to a value of | ||
718 | * type 'struct GNUNET_TIME_Absolute'. | ||
719 | * | ||
720 | * @param ctx command line processing context | ||
721 | * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`) | ||
722 | * @param option name of the option | ||
723 | * @param value actual value of the option as a string. | ||
724 | * @return #GNUNET_OK if parsing the value worked | ||
725 | */ | ||
726 | static enum GNUNET_GenericReturnValue | ||
727 | set_timestamp (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
728 | void *scls, | ||
729 | const char *option, | ||
730 | const char *value) | ||
731 | { | ||
732 | struct GNUNET_TIME_Timestamp *t = scls; | ||
733 | struct GNUNET_TIME_Absolute abs; | ||
734 | |||
735 | (void) ctx; | ||
736 | if (GNUNET_OK != | ||
737 | GNUNET_STRINGS_fancy_time_to_absolute (value, | ||
738 | &abs)) | ||
739 | { | ||
740 | fprintf (stderr, | ||
741 | _ ("You must pass a timestamp to the `%s' option.\n"), | ||
742 | option); | ||
743 | return GNUNET_SYSERR; | ||
744 | } | ||
745 | if (0 != abs.abs_value_us % GNUNET_TIME_UNIT_SECONDS.rel_value_us) | ||
746 | { | ||
747 | fprintf (stderr, | ||
748 | _ ("The maximum precision allowed for timestamps is seconds.\n")); | ||
749 | return GNUNET_SYSERR; | ||
750 | } | ||
751 | t->abs_time = abs; | ||
752 | return GNUNET_OK; | ||
753 | } | ||
754 | |||
755 | |||
756 | struct GNUNET_GETOPT_CommandLineOption | ||
757 | GNUNET_GETOPT_option_timestamp (char shortName, | ||
758 | const char *name, | ||
759 | const char *argumentHelp, | ||
760 | const char *description, | ||
761 | struct GNUNET_TIME_Timestamp *val) | ||
762 | { | ||
763 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
764 | .shortName = shortName, | ||
765 | .name = name, | ||
766 | .argumentHelp = argumentHelp, | ||
767 | .description = description, | ||
768 | .require_argument = 1, | ||
769 | .processor = &set_timestamp, | ||
818 | .scls = (void *) val | 770 | .scls = (void *) val |
819 | }; | 771 | }; |
820 | 772 | ||
@@ -835,7 +787,7 @@ GNUNET_GETOPT_option_absolute_time (char shortName, | |||
835 | * @param value actual value of the option as a string. | 787 | * @param value actual value of the option as a string. |
836 | * @return #GNUNET_OK if parsing the value worked | 788 | * @return #GNUNET_OK if parsing the value worked |
837 | */ | 789 | */ |
838 | static int | 790 | static enum GNUNET_GenericReturnValue |
839 | set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 791 | set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
840 | void *scls, | 792 | void *scls, |
841 | const char *option, | 793 | const char *option, |
@@ -864,15 +816,6 @@ set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
864 | } | 816 | } |
865 | 817 | ||
866 | 818 | ||
867 | /** | ||
868 | * Allow user to specify an unsigned integer. | ||
869 | * | ||
870 | * @param shortName short name of the option | ||
871 | * @param name long name of the option | ||
872 | * @param argumentHelp help text for the option argument | ||
873 | * @param description long help text for the option | ||
874 | * @param[out] val set to the value specified at the command line | ||
875 | */ | ||
876 | struct GNUNET_GETOPT_CommandLineOption | 819 | struct GNUNET_GETOPT_CommandLineOption |
877 | GNUNET_GETOPT_option_uint (char shortName, | 820 | GNUNET_GETOPT_option_uint (char shortName, |
878 | const char *name, | 821 | const char *name, |
@@ -907,7 +850,7 @@ GNUNET_GETOPT_option_uint (char shortName, | |||
907 | * @param value actual value of the option as a string. | 850 | * @param value actual value of the option as a string. |
908 | * @return #GNUNET_OK if parsing the value worked | 851 | * @return #GNUNET_OK if parsing the value worked |
909 | */ | 852 | */ |
910 | static int | 853 | static enum GNUNET_GenericReturnValue |
911 | set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 854 | set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
912 | void *scls, | 855 | void *scls, |
913 | const char *option, | 856 | const char *option, |
@@ -938,15 +881,6 @@ set_uint16 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
938 | } | 881 | } |
939 | 882 | ||
940 | 883 | ||
941 | /** | ||
942 | * Allow user to specify an uint16_t. | ||
943 | * | ||
944 | * @param shortName short name of the option | ||
945 | * @param name long name of the option | ||
946 | * @param argumentHelp help text for the option argument | ||
947 | * @param description long help text for the option | ||
948 | * @param[out] val set to the value specified at the command line | ||
949 | */ | ||
950 | struct GNUNET_GETOPT_CommandLineOption | 884 | struct GNUNET_GETOPT_CommandLineOption |
951 | GNUNET_GETOPT_option_uint16 (char shortName, | 885 | GNUNET_GETOPT_option_uint16 (char shortName, |
952 | const char *name, | 886 | const char *name, |
@@ -998,7 +932,7 @@ struct Base32Context | |||
998 | * @param value actual value of the option as a string. | 932 | * @param value actual value of the option as a string. |
999 | * @return #GNUNET_OK if parsing the value worked | 933 | * @return #GNUNET_OK if parsing the value worked |
1000 | */ | 934 | */ |
1001 | static int | 935 | static enum GNUNET_GenericReturnValue |
1002 | set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | 936 | set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, |
1003 | void *scls, | 937 | void *scls, |
1004 | const char *option, | 938 | const char *option, |
@@ -1036,17 +970,6 @@ free_bc (void *cls) | |||
1036 | } | 970 | } |
1037 | 971 | ||
1038 | 972 | ||
1039 | /** | ||
1040 | * Allow user to specify a binary value using Crockford | ||
1041 | * Base32 encoding. | ||
1042 | * | ||
1043 | * @param shortName short name of the option | ||
1044 | * @param name long name of the option | ||
1045 | * @param argumentHelp help text for the option argument | ||
1046 | * @param description long help text for the option | ||
1047 | * @param[out] val binary value decoded from Crockford Base32-encoded argument | ||
1048 | * @param val_size size of @a val in bytes | ||
1049 | */ | ||
1050 | struct GNUNET_GETOPT_CommandLineOption | 973 | struct GNUNET_GETOPT_CommandLineOption |
1051 | GNUNET_GETOPT_option_base32_fixed_size (char shortName, | 974 | GNUNET_GETOPT_option_base32_fixed_size (char shortName, |
1052 | const char *name, | 975 | const char *name, |
@@ -1073,12 +996,6 @@ GNUNET_GETOPT_option_base32_fixed_size (char shortName, | |||
1073 | } | 996 | } |
1074 | 997 | ||
1075 | 998 | ||
1076 | /** | ||
1077 | * Make the given option mandatory. | ||
1078 | * | ||
1079 | * @param opt option to modify | ||
1080 | * @return @a opt with the mandatory flag set. | ||
1081 | */ | ||
1082 | struct GNUNET_GETOPT_CommandLineOption | 999 | struct GNUNET_GETOPT_CommandLineOption |
1083 | GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt) | 1000 | GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt) |
1084 | { | 1001 | { |
@@ -1087,12 +1004,6 @@ GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt) | |||
1087 | } | 1004 | } |
1088 | 1005 | ||
1089 | 1006 | ||
1090 | /** | ||
1091 | * Make the given option mutually exclusive with other options. | ||
1092 | * | ||
1093 | * @param opt option to modify | ||
1094 | * @return @a opt with the exclusive flag set. | ||
1095 | */ | ||
1096 | struct GNUNET_GETOPT_CommandLineOption | 1007 | struct GNUNET_GETOPT_CommandLineOption |
1097 | GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt) | 1008 | GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt) |
1098 | { | 1009 | { |
diff --git a/src/util/gnunet-scrypt.c b/src/util/gnunet-scrypt.c index fe8b6769f..ad46e3f39 100644 --- a/src/util/gnunet-scrypt.c +++ b/src/util/gnunet-scrypt.c | |||
@@ -78,24 +78,6 @@ shutdown_task (void *cls) | |||
78 | 78 | ||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * Count the leading zeroes in hash. | ||
82 | * | ||
83 | * @param hash to count leading zeros in | ||
84 | * @return the number of leading zero bits. | ||
85 | */ | ||
86 | static unsigned int | ||
87 | count_leading_zeroes (const struct GNUNET_HashCode *hash) | ||
88 | { | ||
89 | unsigned int hash_count; | ||
90 | |||
91 | hash_count = 0; | ||
92 | while (0 == GNUNET_CRYPTO_hash_get_bit_ltr (hash, hash_count)) | ||
93 | hash_count++; | ||
94 | return hash_count; | ||
95 | } | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Find our proof of work. | 81 | * Find our proof of work. |
100 | * | 82 | * |
101 | * @param cls closure (unused) | 83 | * @param cls closure (unused) |
@@ -131,7 +113,8 @@ find_proof (void *cls) | |||
131 | buf, | 113 | buf, |
132 | sizeof(buf), | 114 | sizeof(buf), |
133 | &result); | 115 | &result); |
134 | if (nse_work_required <= count_leading_zeroes (&result)) | 116 | if (nse_work_required <= |
117 | GNUNET_CRYPTO_hash_count_leading_zeros (&result)) | ||
135 | { | 118 | { |
136 | proof = counter; | 119 | proof = counter; |
137 | fprintf (stdout, | 120 | fprintf (stdout, |
diff --git a/src/util/perf_crypto_cs.c b/src/util/perf_crypto_cs.c index a8c72052b..54c9c8e0e 100644 --- a/src/util/perf_crypto_cs.c +++ b/src/util/perf_crypto_cs.c | |||
@@ -103,8 +103,6 @@ eval () | |||
103 | for (i = 0; i < ITER; i++) | 103 | for (i = 0; i < ITER; i++) |
104 | { | 104 | { |
105 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce, | 105 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce, |
106 | sizeof(struct | ||
107 | GNUNET_CRYPTO_CsNonce), | ||
108 | bs); | 106 | bs); |
109 | } | 107 | } |
110 | printf ("10x derive blinding secrets took %s\n", | 108 | printf ("10x derive blinding secrets took %s\n", |
@@ -167,9 +165,9 @@ eval () | |||
167 | for (i = 0; i < ITER; i++) | 165 | for (i = 0; i < ITER; i++) |
168 | { | 166 | { |
169 | GNUNET_CRYPTO_cs_verify (&sig, | 167 | GNUNET_CRYPTO_cs_verify (&sig, |
170 | &pub, | 168 | &pub, |
171 | message, | 169 | message, |
172 | message_len); | 170 | message_len); |
173 | } | 171 | } |
174 | printf ("10x verifying signatures took %s\n", | 172 | printf ("10x verifying signatures took %s\n", |
175 | GNUNET_STRINGS_relative_time_to_string ( | 173 | GNUNET_STRINGS_relative_time_to_string ( |
diff --git a/src/util/perf_crypto_rsa.c b/src/util/perf_crypto_rsa.c index aba61786f..a3e041bdf 100644 --- a/src/util/perf_crypto_rsa.c +++ b/src/util/perf_crypto_rsa.c | |||
@@ -203,6 +203,7 @@ main (int argc, char *argv[]) | |||
203 | { | 203 | { |
204 | eval (1024); | 204 | eval (1024); |
205 | eval (2048); | 205 | eval (2048); |
206 | eval (3072); | ||
206 | /* eval (4096); */ | 207 | /* eval (4096); */ |
207 | return 0; | 208 | return 0; |
208 | } | 209 | } |
diff --git a/src/util/strings.c b/src/util/strings.c index 673915888..db672da87 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -201,7 +201,7 @@ struct ConversionTable | |||
201 | * @param output where to store the result | 201 | * @param output where to store the result |
202 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 202 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
203 | */ | 203 | */ |
204 | static int | 204 | static enum GNUNET_GenericReturnValue |
205 | convert_with_table (const char *input, | 205 | convert_with_table (const char *input, |
206 | const struct ConversionTable *table, | 206 | const struct ConversionTable *table, |
207 | unsigned long long *output) | 207 | unsigned long long *output) |
@@ -256,7 +256,7 @@ convert_with_table (const char *input, | |||
256 | } | 256 | } |
257 | 257 | ||
258 | 258 | ||
259 | int | 259 | enum GNUNET_GenericReturnValue |
260 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | 260 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, |
261 | unsigned long long *size) | 261 | unsigned long long *size) |
262 | { | 262 | { |
@@ -280,7 +280,7 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | |||
280 | } | 280 | } |
281 | 281 | ||
282 | 282 | ||
283 | int | 283 | enum GNUNET_GenericReturnValue |
284 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | 284 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, |
285 | struct GNUNET_TIME_Relative *rtime) | 285 | struct GNUNET_TIME_Relative *rtime) |
286 | { | 286 | { |
@@ -322,7 +322,7 @@ GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, | |||
322 | } | 322 | } |
323 | 323 | ||
324 | 324 | ||
325 | int | 325 | enum GNUNET_GenericReturnValue |
326 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | 326 | GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, |
327 | struct GNUNET_TIME_Absolute *atime) | 327 | struct GNUNET_TIME_Absolute *atime) |
328 | { | 328 | { |
@@ -354,6 +354,15 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, | |||
354 | } | 354 | } |
355 | 355 | ||
356 | 356 | ||
357 | enum GNUNET_GenericReturnValue | ||
358 | GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, | ||
359 | struct GNUNET_TIME_Timestamp *atime) | ||
360 | { | ||
361 | return GNUNET_STRINGS_fancy_time_to_absolute (fancy_time, | ||
362 | &atime->abs_time); | ||
363 | } | ||
364 | |||
365 | |||
357 | char * | 366 | char * |
358 | GNUNET_STRINGS_conv (const char *input, | 367 | GNUNET_STRINGS_conv (const char *input, |
359 | size_t len, | 368 | size_t len, |
@@ -607,7 +616,7 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) | |||
607 | time_t tt; | 616 | time_t tt; |
608 | struct tm *tp; | 617 | struct tm *tp; |
609 | 618 | ||
610 | if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 619 | if (GNUNET_TIME_absolute_is_never (t)) |
611 | return "end of time"; | 620 | return "end of time"; |
612 | tt = t.abs_value_us / 1000LL / 1000LL; | 621 | tt = t.abs_value_us / 1000LL / 1000LL; |
613 | tp = localtime (&tt); | 622 | tp = localtime (&tt); |
@@ -616,7 +625,8 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) | |||
616 | * As for msvcrt, use the wide variant, which always returns utf16 | 625 | * As for msvcrt, use the wide variant, which always returns utf16 |
617 | * (otherwise we'd have to detect current codepage or use W32API character | 626 | * (otherwise we'd have to detect current codepage or use W32API character |
618 | * set conversion routines to convert to UTF8). | 627 | * set conversion routines to convert to UTF8). |
619 | */strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp); | 628 | */ |
629 | strftime (buf, sizeof(buf), "%a %b %d %H:%M:%S %Y", tp); | ||
620 | 630 | ||
621 | return buf; | 631 | return buf; |
622 | } | 632 | } |
diff --git a/src/util/test_crypto_cs.c b/src/util/test_crypto_cs.c index 2978fec0a..d3406516e 100644 --- a/src/util/test_crypto_cs.c +++ b/src/util/test_crypto_cs.c | |||
@@ -148,8 +148,7 @@ test_generate_rpublic (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | |||
148 | 148 | ||
149 | 149 | ||
150 | void | 150 | void |
151 | test_derive_blindingsecrets (const void *secret, | 151 | test_derive_blindingsecrets (const struct GNUNET_CRYPTO_CsNonce *blind_seed, |
152 | size_t secret_len, | ||
153 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]) | 152 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]) |
154 | { | 153 | { |
155 | /* TEST 1 | 154 | /* TEST 1 |
@@ -159,7 +158,7 @@ test_derive_blindingsecrets (const void *secret, | |||
159 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 158 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) |
160 | * 2); | 159 | * 2); |
161 | 160 | ||
162 | GNUNET_CRYPTO_cs_blinding_secrets_derive (secret, secret_len, bs); | 161 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); |
163 | 162 | ||
164 | GNUNET_assert (0 != memcmp (&other_bs[0], | 163 | GNUNET_assert (0 != memcmp (&other_bs[0], |
165 | &bs[0], | 164 | &bs[0], |
@@ -173,7 +172,7 @@ test_derive_blindingsecrets (const void *secret, | |||
173 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 172 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) |
174 | * 2); | 173 | * 2); |
175 | for (int i = 0; i<ITER; i++) { | 174 | for (int i = 0; i<ITER; i++) { |
176 | GNUNET_CRYPTO_cs_blinding_secrets_derive (secret, secret_len, bs); | 175 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); |
177 | GNUNET_assert (0 == memcmp (&other_bs[0], | 176 | GNUNET_assert (0 == memcmp (&other_bs[0], |
178 | &bs[0], | 177 | &bs[0], |
179 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 178 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) |
@@ -493,8 +492,7 @@ main (int argc, | |||
493 | // generate blinding secrets | 492 | // generate blinding secrets |
494 | struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2]; | 493 | struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2]; |
495 | test_derive_blindingsecrets (&nonce, | 494 | test_derive_blindingsecrets (&nonce, |
496 | sizeof(nonce), | 495 | blindingsecrets); |
497 | blindingsecrets); | ||
498 | 496 | ||
499 | // calculate blinded c's | 497 | // calculate blinded c's |
500 | struct GNUNET_CRYPTO_CsC blinded_cs[2]; | 498 | struct GNUNET_CRYPTO_CsC blinded_cs[2]; |
diff --git a/src/util/test_crypto_eddsa.c b/src/util/test_crypto_eddsa.c index 10d6a4e91..459619ff2 100644 --- a/src/util/test_crypto_eddsa.c +++ b/src/util/test_crypto_eddsa.c | |||
@@ -216,12 +216,16 @@ testCreateFromFile (void) | |||
216 | struct GNUNET_CRYPTO_EddsaPublicKey p1; | 216 | struct GNUNET_CRYPTO_EddsaPublicKey p1; |
217 | struct GNUNET_CRYPTO_EddsaPublicKey p2; | 217 | struct GNUNET_CRYPTO_EddsaPublicKey p2; |
218 | 218 | ||
219 | GNUNET_assert (0 <= | 219 | /* do_create == GNUNET_YES and non-existing file MUST return GNUNET_YES */ |
220 | GNUNET_assert (0 == unlink (KEYFILE) || ENOENT == errno); | ||
221 | GNUNET_assert (GNUNET_YES == | ||
220 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, | 222 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, |
221 | GNUNET_YES, | 223 | GNUNET_YES, |
222 | &key)); | 224 | &key)); |
223 | GNUNET_CRYPTO_eddsa_key_get_public (&key, | 225 | GNUNET_CRYPTO_eddsa_key_get_public (&key, |
224 | &p1); | 226 | &p1); |
227 | |||
228 | /* do_create == GNUNET_YES and _existing_ file MUST return GNUNET_NO */ | ||
225 | GNUNET_assert (GNUNET_NO == | 229 | GNUNET_assert (GNUNET_NO == |
226 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, | 230 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, |
227 | GNUNET_YES, | 231 | GNUNET_YES, |
@@ -231,16 +235,13 @@ testCreateFromFile (void) | |||
231 | GNUNET_assert (0 == | 235 | GNUNET_assert (0 == |
232 | GNUNET_memcmp (&p1, | 236 | GNUNET_memcmp (&p1, |
233 | &p2)); | 237 | &p2)); |
238 | |||
239 | /* do_create == GNUNET_NO and non-existing file MUST return GNUNET_SYSERR */ | ||
234 | GNUNET_assert (0 == unlink (KEYFILE)); | 240 | GNUNET_assert (0 == unlink (KEYFILE)); |
235 | GNUNET_assert (GNUNET_OK == | 241 | GNUNET_assert (GNUNET_SYSERR == |
236 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, | 242 | GNUNET_CRYPTO_eddsa_key_from_file (KEYFILE, |
237 | GNUNET_NO, | 243 | GNUNET_NO, |
238 | &key)); | 244 | &key)); |
239 | GNUNET_CRYPTO_eddsa_key_get_public (&key, | ||
240 | &p2); | ||
241 | GNUNET_assert (0 != | ||
242 | GNUNET_memcmp (&p1, | ||
243 | &p2)); | ||
244 | return GNUNET_OK; | 245 | return GNUNET_OK; |
245 | } | 246 | } |
246 | 247 | ||
@@ -299,7 +300,6 @@ main (int argc, char *argv[]) | |||
299 | failure_count++; | 300 | failure_count++; |
300 | if (GNUNET_OK != testCreateFromFile ()) | 301 | if (GNUNET_OK != testCreateFromFile ()) |
301 | failure_count++; | 302 | failure_count++; |
302 | GNUNET_assert (0 == unlink (KEYFILE)); | ||
303 | perf_keygen (); | 303 | perf_keygen (); |
304 | 304 | ||
305 | if (0 != failure_count) | 305 | if (0 != failure_count) |
diff --git a/src/util/test_crypto_hash.c b/src/util/test_crypto_hash.c index d22e1f5d3..8241676da 100644 --- a/src/util/test_crypto_hash.c +++ b/src/util/test_crypto_hash.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2002, 2003, 2004, 2006, 2009 GNUnet e.V. | 3 | Copyright (C) 2002, 2003, 2004, 2006, 2009, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -37,25 +37,29 @@ test (int number) | |||
37 | struct GNUNET_HashCode h2; | 37 | struct GNUNET_HashCode h2; |
38 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; | 38 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; |
39 | 39 | ||
40 | memset (&h1, number, sizeof(struct GNUNET_HashCode)); | 40 | memset (&h1, |
41 | GNUNET_CRYPTO_hash_to_enc (&h1, &enc); | 41 | number, |
42 | if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &h2)) | 42 | sizeof(struct GNUNET_HashCode)); |
43 | GNUNET_CRYPTO_hash_to_enc (&h1, | ||
44 | &enc); | ||
45 | if (GNUNET_OK != | ||
46 | GNUNET_CRYPTO_hash_from_string ((char *) &enc, | ||
47 | &h2)) | ||
43 | { | 48 | { |
44 | printf ("enc2hash failed!\n"); | 49 | printf ("enc2hash failed!\n"); |
45 | return 1; | 50 | return 1; |
46 | } | 51 | } |
47 | if (0 != memcmp (&h1, &h2, sizeof(struct GNUNET_HashCode))) | 52 | if (0 != GNUNET_memcmp (&h1, |
53 | &h2)) | ||
48 | return 1; | 54 | return 1; |
49 | return 0; | 55 | return 0; |
50 | } | 56 | } |
51 | 57 | ||
52 | 58 | ||
53 | static int | 59 | static int |
54 | testEncoding () | 60 | test_encoding (void) |
55 | { | 61 | { |
56 | int i; | 62 | for (int i = 0; i < 255; i++) |
57 | |||
58 | for (i = 0; i < 255; i++) | ||
59 | if (0 != test (i)) | 63 | if (0 != test (i)) |
60 | return 1; | 64 | return 1; |
61 | return 0; | 65 | return 0; |
@@ -63,7 +67,7 @@ testEncoding () | |||
63 | 67 | ||
64 | 68 | ||
65 | static int | 69 | static int |
66 | testArithmetic () | 70 | test_arithmetic (void) |
67 | { | 71 | { |
68 | struct GNUNET_HashCode h1; | 72 | struct GNUNET_HashCode h1; |
69 | struct GNUNET_HashCode h2; | 73 | struct GNUNET_HashCode h2; |
@@ -72,49 +76,80 @@ testArithmetic () | |||
72 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 76 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; |
73 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 77 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
74 | 78 | ||
75 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &h1); | 79 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, |
76 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &h2); | 80 | &h1); |
77 | if (GNUNET_CRYPTO_hash_distance_u32 (&h1, &h2) != | 81 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, |
78 | GNUNET_CRYPTO_hash_distance_u32 (&h2, &h1)) | 82 | &h2); |
79 | return 1; | 83 | if (GNUNET_CRYPTO_hash_distance_u32 (&h1, |
80 | GNUNET_CRYPTO_hash_difference (&h1, &h2, &d); | 84 | &h2) != |
81 | GNUNET_CRYPTO_hash_sum (&h1, &d, &s); | 85 | GNUNET_CRYPTO_hash_distance_u32 (&h2, |
82 | if (0 != GNUNET_CRYPTO_hash_cmp (&s, &h2)) | 86 | &h1)) |
83 | return 1; | ||
84 | GNUNET_CRYPTO_hash_xor (&h1, &h2, &d); | ||
85 | GNUNET_CRYPTO_hash_xor (&h1, &d, &s); | ||
86 | if (0 != GNUNET_CRYPTO_hash_cmp (&s, &h2)) | ||
87 | return 1; | 87 | return 1; |
88 | if (0 != GNUNET_CRYPTO_hash_xorcmp (&s, &h2, &h1)) | 88 | GNUNET_CRYPTO_hash_difference (&h1, |
89 | &h2, | ||
90 | &d); | ||
91 | GNUNET_CRYPTO_hash_sum (&h1, | ||
92 | &d, | ||
93 | &s); | ||
94 | if (0 != | ||
95 | GNUNET_CRYPTO_hash_cmp (&s, | ||
96 | &h2)) | ||
89 | return 1; | 97 | return 1; |
90 | if (-1 != GNUNET_CRYPTO_hash_xorcmp (&h1, &h2, &h1)) | 98 | GNUNET_CRYPTO_hash_xor (&h1, |
99 | &h2, | ||
100 | &d); | ||
101 | GNUNET_CRYPTO_hash_xor (&h1, | ||
102 | &d, | ||
103 | &s); | ||
104 | if (0 != | ||
105 | GNUNET_CRYPTO_hash_cmp (&s, | ||
106 | &h2)) | ||
91 | return 1; | 107 | return 1; |
92 | if (1 != GNUNET_CRYPTO_hash_xorcmp (&h1, &h2, &h2)) | 108 | if (0 != |
109 | GNUNET_CRYPTO_hash_xorcmp (&s, | ||
110 | &h2, | ||
111 | &h1)) | ||
93 | return 1; | 112 | return 1; |
94 | memset (&d, 0x40, sizeof(d)); | 113 | if (-1 != |
95 | if (0 != GNUNET_CRYPTO_hash_get_bit_rtl (&d, 3)) | 114 | GNUNET_CRYPTO_hash_xorcmp (&h1, |
115 | &h2, | ||
116 | &h1)) | ||
96 | return 1; | 117 | return 1; |
97 | if (1 != GNUNET_CRYPTO_hash_get_bit_rtl (&d, 6)) | 118 | if (1 != |
119 | GNUNET_CRYPTO_hash_xorcmp (&h1, | ||
120 | &h2, | ||
121 | &h2)) | ||
98 | return 1; | 122 | return 1; |
99 | memset (&d, 0x02, sizeof(d)); | 123 | memset (&d, |
100 | if (0 != GNUNET_CRYPTO_hash_get_bit_ltr (&d, 3)) | 124 | 0, |
101 | return 1; | 125 | sizeof(d)); |
102 | if (1 != GNUNET_CRYPTO_hash_get_bit_ltr (&d, 6)) | 126 | GNUNET_CRYPTO_hash_to_aes_key (&d, |
103 | return 1; | 127 | &skey, |
104 | memset (&d, 0, sizeof(d)); | 128 | &iv); |
105 | GNUNET_CRYPTO_hash_to_aes_key (&d, &skey, &iv); | 129 | memset (&h1, |
130 | 0, | ||
131 | sizeof (h1)); | ||
132 | h1.bits[1] = htonl (0x00200000); /* 32 + 8 + 2 = 42 MSB bits cleared */ | ||
133 | GNUNET_assert (42 == | ||
134 | GNUNET_CRYPTO_hash_count_leading_zeros (&h1)); | ||
135 | GNUNET_assert (512 - 42 - 1 == | ||
136 | GNUNET_CRYPTO_hash_count_tailing_zeros (&h1)); | ||
106 | return 0; | 137 | return 0; |
107 | } | 138 | } |
108 | 139 | ||
109 | 140 | ||
110 | static void | 141 | static void |
111 | finished_task (void *cls, const struct GNUNET_HashCode *res) | 142 | finished_task (void *cls, |
143 | const struct GNUNET_HashCode *res) | ||
112 | { | 144 | { |
113 | int *ret = cls; | 145 | int *ret = cls; |
114 | struct GNUNET_HashCode want; | 146 | struct GNUNET_HashCode want; |
115 | 147 | ||
116 | GNUNET_CRYPTO_hash (block, sizeof(block), &want); | 148 | GNUNET_CRYPTO_hash (block, |
117 | if (0 != memcmp (res, &want, sizeof(want))) | 149 | sizeof(block), |
150 | &want); | ||
151 | if (0 != GNUNET_memcmp (res, | ||
152 | &want)) | ||
118 | *ret = 2; | 153 | *ret = 2; |
119 | else | 154 | else |
120 | *ret = 0; | 155 | *ret = 0; |
@@ -126,43 +161,57 @@ file_hasher (void *cls) | |||
126 | { | 161 | { |
127 | GNUNET_assert (NULL != | 162 | GNUNET_assert (NULL != |
128 | GNUNET_CRYPTO_hash_file (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 163 | GNUNET_CRYPTO_hash_file (GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
129 | FILENAME, 1024, &finished_task, cls)); | 164 | FILENAME, |
165 | 1024, | ||
166 | &finished_task, | ||
167 | cls)); | ||
130 | } | 168 | } |
131 | 169 | ||
132 | 170 | ||
133 | static int | 171 | static int |
134 | testFileHash () | 172 | test_file_hash (void) |
135 | { | 173 | { |
136 | int ret; | 174 | int ret; |
137 | FILE *f; | 175 | FILE *f; |
138 | 176 | ||
139 | memset (block, 42, sizeof(block) / 2); | 177 | memset (block, |
140 | memset (&block[sizeof(block) / 2], 43, sizeof(block) / 2); | 178 | 42, |
179 | sizeof(block) / 2); | ||
180 | memset (&block[sizeof(block) / 2], | ||
181 | 43, | ||
182 | sizeof(block) / 2); | ||
141 | GNUNET_assert (NULL != (f = fopen (FILENAME, "w+"))); | 183 | GNUNET_assert (NULL != (f = fopen (FILENAME, "w+"))); |
142 | GNUNET_break (sizeof(block) == fwrite (block, 1, sizeof(block), f)); | 184 | GNUNET_break (sizeof(block) == |
185 | fwrite (block, | ||
186 | 1, | ||
187 | sizeof(block), | ||
188 | f)); | ||
143 | GNUNET_break (0 == fclose (f)); | 189 | GNUNET_break (0 == fclose (f)); |
144 | ret = 1; | 190 | ret = 1; |
145 | GNUNET_SCHEDULER_run (&file_hasher, &ret); | 191 | GNUNET_SCHEDULER_run (&file_hasher, |
192 | &ret); | ||
146 | GNUNET_break (0 == unlink (FILENAME)); | 193 | GNUNET_break (0 == unlink (FILENAME)); |
147 | return ret; | 194 | return ret; |
148 | } | 195 | } |
149 | 196 | ||
150 | 197 | ||
151 | int | 198 | int |
152 | main (int argc, char *argv[]) | 199 | main (int argc, |
200 | char *argv[]) | ||
153 | { | 201 | { |
154 | int failureCount = 0; | 202 | int failureCount = 0; |
155 | int i; | 203 | |
156 | 204 | GNUNET_log_setup ("test-crypto-hash", | |
157 | GNUNET_log_setup ("test-crypto-hash", "WARNING", NULL); | 205 | "WARNING", |
158 | for (i = 0; i < 10; i++) | 206 | NULL); |
159 | failureCount += testEncoding (); | 207 | for (int i = 0; i < 10; i++) |
160 | failureCount += testArithmetic (); | 208 | failureCount += test_encoding (); |
161 | failureCount += testFileHash (); | 209 | failureCount += test_arithmetic (); |
162 | if (failureCount != 0) | 210 | failureCount += test_file_hash (); |
211 | if (0 != failureCount) | ||
163 | return 1; | 212 | return 1; |
164 | return 0; | 213 | return 0; |
165 | } | 214 | } |
166 | 215 | ||
167 | 216 | ||
168 | /* end of hashingtest.c */ | 217 | /* end of test_crypto_hash.c */ |
diff --git a/src/util/time.c b/src/util/time.c index 144e1b401..83b39b4e8 100644 --- a/src/util/time.c +++ b/src/util/time.c | |||
@@ -58,27 +58,35 @@ GNUNET_TIME_get_offset () | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | int | 61 | struct GNUNET_TIME_Timestamp |
62 | GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at) | 62 | GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at) |
63 | { | 63 | { |
64 | if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 64 | struct GNUNET_TIME_Timestamp ts; |
65 | return GNUNET_OK; | 65 | |
66 | if (0 == at->abs_value_us % 1000000) | 66 | if (GNUNET_TIME_absolute_is_never (at)) |
67 | return GNUNET_OK; | 67 | return GNUNET_TIME_UNIT_FOREVER_TS; |
68 | at->abs_value_us -= at->abs_value_us % 1000000; | 68 | ts.abs_time.abs_value_us = at.abs_value_us - at.abs_value_us % 1000000; |
69 | return GNUNET_NO; | 69 | return ts; |
70 | } | ||
71 | |||
72 | |||
73 | struct GNUNET_TIME_TimestampNBO | ||
74 | GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t) | ||
75 | { | ||
76 | struct GNUNET_TIME_TimestampNBO tn; | ||
77 | |||
78 | tn.abs_time_nbo = GNUNET_TIME_absolute_hton (t.abs_time); | ||
79 | return tn; | ||
70 | } | 80 | } |
71 | 81 | ||
72 | 82 | ||
73 | int | 83 | struct GNUNET_TIME_Timestamp |
74 | GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt) | 84 | GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn) |
75 | { | 85 | { |
76 | if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 86 | struct GNUNET_TIME_Timestamp t; |
77 | return GNUNET_OK; | 87 | |
78 | if (0 == rt->rel_value_us % 1000000) | 88 | t.abs_time = GNUNET_TIME_absolute_ntoh (tn.abs_time_nbo); |
79 | return GNUNET_OK; | 89 | return t; |
80 | rt->rel_value_us -= rt->rel_value_us % 1000000; | ||
81 | return GNUNET_NO; | ||
82 | } | 90 | } |
83 | 91 | ||
84 | 92 | ||
@@ -96,6 +104,14 @@ GNUNET_TIME_absolute_get () | |||
96 | } | 104 | } |
97 | 105 | ||
98 | 106 | ||
107 | struct GNUNET_TIME_Timestamp | ||
108 | GNUNET_TIME_timestamp_get () | ||
109 | { | ||
110 | return GNUNET_TIME_absolute_to_timestamp ( | ||
111 | GNUNET_TIME_absolute_get ()); | ||
112 | } | ||
113 | |||
114 | |||
99 | struct GNUNET_TIME_Relative | 115 | struct GNUNET_TIME_Relative |
100 | GNUNET_TIME_relative_get_zero_ () | 116 | GNUNET_TIME_relative_get_zero_ () |
101 | { | 117 | { |
@@ -177,12 +193,114 @@ GNUNET_TIME_absolute_get_forever_ () | |||
177 | } | 193 | } |
178 | 194 | ||
179 | 195 | ||
196 | const char * | ||
197 | GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts) | ||
198 | { | ||
199 | static GNUNET_THREAD_LOCAL char buf[255]; | ||
200 | time_t tt; | ||
201 | struct tm *tp; | ||
202 | |||
203 | if (GNUNET_TIME_absolute_is_never (ts.abs_time)) | ||
204 | return "end of time"; | ||
205 | tt = ts.abs_time.abs_value_us / 1000LL / 1000LL; | ||
206 | tp = localtime (&tt); | ||
207 | /* This is hacky, but i don't know a way to detect libc character encoding. | ||
208 | * Just expect utf8 from glibc these days. | ||
209 | * As for msvcrt, use the wide variant, which always returns utf16 | ||
210 | * (otherwise we'd have to detect current codepage or use W32API character | ||
211 | * set conversion routines to convert to UTF8). | ||
212 | */ | ||
213 | strftime (buf, | ||
214 | sizeof(buf), | ||
215 | "%a %b %d %H:%M:%S %Y", | ||
216 | tp); | ||
217 | return buf; | ||
218 | } | ||
219 | |||
220 | |||
221 | const char * | ||
222 | GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute t) | ||
223 | { | ||
224 | static GNUNET_THREAD_LOCAL char buf[255]; | ||
225 | time_t tt; | ||
226 | struct tm *tp; | ||
227 | |||
228 | if (GNUNET_TIME_absolute_is_never (t)) | ||
229 | return "end of time"; | ||
230 | tt = t.abs_value_us / 1000LL / 1000LL; | ||
231 | tp = localtime (&tt); | ||
232 | /* This is hacky, but i don't know a way to detect libc character encoding. | ||
233 | * Just expect utf8 from glibc these days. | ||
234 | * As for msvcrt, use the wide variant, which always returns utf16 | ||
235 | * (otherwise we'd have to detect current codepage or use W32API character | ||
236 | * set conversion routines to convert to UTF8). | ||
237 | */ | ||
238 | strftime (buf, | ||
239 | sizeof(buf), | ||
240 | "%a %b %d %H:%M:%S %Y", | ||
241 | tp); | ||
242 | return buf; | ||
243 | } | ||
244 | |||
245 | |||
246 | const char * | ||
247 | GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta, | ||
248 | bool do_round) | ||
249 | { | ||
250 | static GNUNET_THREAD_LOCAL char buf[128]; | ||
251 | const char *unit = /* time unit */ "µs"; | ||
252 | uint64_t dval = delta.rel_value_us; | ||
253 | |||
254 | if (GNUNET_TIME_relative_is_forever (delta)) | ||
255 | return "forever"; | ||
256 | if (0 == delta.rel_value_us) | ||
257 | return "0 ms"; | ||
258 | if ( ((GNUNET_YES == do_round) && | ||
259 | (dval > 5 * 1000)) || | ||
260 | (0 == (dval % 1000))) | ||
261 | { | ||
262 | dval = dval / 1000; | ||
263 | unit = /* time unit */ "ms"; | ||
264 | if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000))) | ||
265 | { | ||
266 | dval = dval / 1000; | ||
267 | unit = /* time unit */ "s"; | ||
268 | if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) | ||
269 | { | ||
270 | dval = dval / 60; | ||
271 | unit = /* time unit */ "m"; | ||
272 | if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) | ||
273 | { | ||
274 | dval = dval / 60; | ||
275 | unit = /* time unit */ "h"; | ||
276 | if (((GNUNET_YES == do_round) && (dval > 5 * 24)) || | ||
277 | (0 == (dval % 24))) | ||
278 | { | ||
279 | dval = dval / 24; | ||
280 | if (1 == dval) | ||
281 | unit = /* time unit */ "day"; | ||
282 | else | ||
283 | unit = /* time unit */ "days"; | ||
284 | } | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | GNUNET_snprintf (buf, | ||
290 | sizeof(buf), | ||
291 | "%llu %s", | ||
292 | (unsigned long long) dval, | ||
293 | unit); | ||
294 | return buf; | ||
295 | } | ||
296 | |||
297 | |||
180 | struct GNUNET_TIME_Absolute | 298 | struct GNUNET_TIME_Absolute |
181 | GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) | 299 | GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) |
182 | { | 300 | { |
183 | struct GNUNET_TIME_Absolute ret; | 301 | struct GNUNET_TIME_Absolute ret; |
184 | 302 | ||
185 | if (rel.rel_value_us == UINT64_MAX) | 303 | if (GNUNET_TIME_relative_is_forever (rel)) |
186 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 304 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
187 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 305 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
188 | 306 | ||
@@ -196,6 +314,14 @@ GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel) | |||
196 | } | 314 | } |
197 | 315 | ||
198 | 316 | ||
317 | struct GNUNET_TIME_Timestamp | ||
318 | GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel) | ||
319 | { | ||
320 | return GNUNET_TIME_absolute_to_timestamp ( | ||
321 | GNUNET_TIME_relative_to_absolute (rel)); | ||
322 | } | ||
323 | |||
324 | |||
199 | struct GNUNET_TIME_Relative | 325 | struct GNUNET_TIME_Relative |
200 | GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, | 326 | GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, |
201 | struct GNUNET_TIME_Relative t2) | 327 | struct GNUNET_TIME_Relative t2) |
@@ -228,12 +354,28 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, | |||
228 | } | 354 | } |
229 | 355 | ||
230 | 356 | ||
357 | struct GNUNET_TIME_Timestamp | ||
358 | GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1, | ||
359 | struct GNUNET_TIME_Timestamp t2) | ||
360 | { | ||
361 | return (t1.abs_time.abs_value_us > t2.abs_time.abs_value_us) ? t1 : t2; | ||
362 | } | ||
363 | |||
364 | |||
365 | struct GNUNET_TIME_Timestamp | ||
366 | GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1, | ||
367 | struct GNUNET_TIME_Timestamp t2) | ||
368 | { | ||
369 | return (t1.abs_time.abs_value_us < t2.abs_time.abs_value_us) ? t1 : t2; | ||
370 | } | ||
371 | |||
372 | |||
231 | struct GNUNET_TIME_Relative | 373 | struct GNUNET_TIME_Relative |
232 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) | 374 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) |
233 | { | 375 | { |
234 | struct GNUNET_TIME_Relative ret; | 376 | struct GNUNET_TIME_Relative ret; |
235 | 377 | ||
236 | if (future.abs_value_us == UINT64_MAX) | 378 | if (GNUNET_TIME_absolute_is_never (future)) |
237 | return GNUNET_TIME_UNIT_FOREVER_REL; | 379 | return GNUNET_TIME_UNIT_FOREVER_REL; |
238 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 380 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
239 | 381 | ||
@@ -250,7 +392,7 @@ GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start, | |||
250 | { | 392 | { |
251 | struct GNUNET_TIME_Relative ret; | 393 | struct GNUNET_TIME_Relative ret; |
252 | 394 | ||
253 | if (end.abs_value_us == UINT64_MAX) | 395 | if (GNUNET_TIME_absolute_is_never (end)) |
254 | return GNUNET_TIME_UNIT_FOREVER_REL; | 396 | return GNUNET_TIME_UNIT_FOREVER_REL; |
255 | if (end.abs_value_us < start.abs_value_us) | 397 | if (end.abs_value_us < start.abs_value_us) |
256 | return GNUNET_TIME_UNIT_ZERO; | 398 | return GNUNET_TIME_UNIT_ZERO; |
@@ -279,8 +421,8 @@ GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start, | |||
279 | { | 421 | { |
280 | struct GNUNET_TIME_Absolute ret; | 422 | struct GNUNET_TIME_Absolute ret; |
281 | 423 | ||
282 | if ((start.abs_value_us == UINT64_MAX) || | 424 | if (GNUNET_TIME_absolute_is_never (start) || |
283 | (duration.rel_value_us == UINT64_MAX)) | 425 | GNUNET_TIME_relative_is_forever (duration)) |
284 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 426 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
285 | if (start.abs_value_us + duration.rel_value_us < start.abs_value_us) | 427 | if (start.abs_value_us + duration.rel_value_us < start.abs_value_us) |
286 | { | 428 | { |
@@ -300,7 +442,7 @@ GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start, | |||
300 | 442 | ||
301 | if (start.abs_value_us <= duration.rel_value_us) | 443 | if (start.abs_value_us <= duration.rel_value_us) |
302 | return GNUNET_TIME_UNIT_ZERO_ABS; | 444 | return GNUNET_TIME_UNIT_ZERO_ABS; |
303 | if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) | 445 | if (GNUNET_TIME_absolute_is_never (start)) |
304 | return GNUNET_TIME_UNIT_FOREVER_ABS; | 446 | return GNUNET_TIME_UNIT_FOREVER_ABS; |
305 | ret.abs_value_us = start.abs_value_us - duration.rel_value_us; | 447 | ret.abs_value_us = start.abs_value_us - duration.rel_value_us; |
306 | return ret; | 448 | return ret; |
@@ -315,7 +457,7 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, | |||
315 | 457 | ||
316 | if (0 == factor) | 458 | if (0 == factor) |
317 | return GNUNET_TIME_UNIT_ZERO; | 459 | return GNUNET_TIME_UNIT_ZERO; |
318 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 460 | if (GNUNET_TIME_relative_is_forever (rel)) |
319 | return GNUNET_TIME_UNIT_FOREVER_REL; | 461 | return GNUNET_TIME_UNIT_FOREVER_REL; |
320 | ret.rel_value_us = rel.rel_value_us * factor; | 462 | ret.rel_value_us = rel.rel_value_us * factor; |
321 | if (ret.rel_value_us / factor != rel.rel_value_us) | 463 | if (ret.rel_value_us / factor != rel.rel_value_us) |
@@ -328,7 +470,8 @@ GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, | |||
328 | 470 | ||
329 | 471 | ||
330 | struct GNUNET_TIME_Relative | 472 | struct GNUNET_TIME_Relative |
331 | relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor) | 473 | relative_multiply_double (struct GNUNET_TIME_Relative rel, |
474 | double factor) | ||
332 | { | 475 | { |
333 | struct GNUNET_TIME_Relative out; | 476 | struct GNUNET_TIME_Relative out; |
334 | double m; | 477 | double m; |
@@ -337,7 +480,7 @@ relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor) | |||
337 | 480 | ||
338 | if (0 == factor) | 481 | if (0 == factor) |
339 | return GNUNET_TIME_UNIT_ZERO; | 482 | return GNUNET_TIME_UNIT_ZERO; |
340 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 483 | if (GNUNET_TIME_relative_is_forever (rel)) |
341 | return GNUNET_TIME_UNIT_FOREVER_REL; | 484 | return GNUNET_TIME_UNIT_FOREVER_REL; |
342 | 485 | ||
343 | m = ((double) rel.rel_value_us) * factor; | 486 | m = ((double) rel.rel_value_us) * factor; |
@@ -361,7 +504,7 @@ GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel, | |||
361 | 504 | ||
362 | if (0 == factor) | 505 | if (0 == factor) |
363 | return GNUNET_TIME_UNIT_ZERO; | 506 | return GNUNET_TIME_UNIT_ZERO; |
364 | if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 507 | if (GNUNET_TIME_relative_is_forever (rel)) |
365 | return GNUNET_TIME_UNIT_FOREVER_REL; | 508 | return GNUNET_TIME_UNIT_FOREVER_REL; |
366 | ret.rel_value_us = rel.rel_value_us * factor; | 509 | ret.rel_value_us = rel.rel_value_us * factor; |
367 | if (ret.rel_value_us / factor != rel.rel_value_us) | 510 | if (ret.rel_value_us / factor != rel.rel_value_us) |
@@ -379,7 +522,7 @@ GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel, | |||
379 | struct GNUNET_TIME_Relative ret; | 522 | struct GNUNET_TIME_Relative ret; |
380 | 523 | ||
381 | if ((0 == factor) || | 524 | if ((0 == factor) || |
382 | (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)) | 525 | (GNUNET_TIME_relative_is_forever (rel))) |
383 | return GNUNET_TIME_UNIT_FOREVER_REL; | 526 | return GNUNET_TIME_UNIT_FOREVER_REL; |
384 | ret.rel_value_us = rel.rel_value_us / factor; | 527 | ret.rel_value_us = rel.rel_value_us / factor; |
385 | return ret; | 528 | return ret; |
@@ -538,6 +681,20 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch) | |||
538 | } | 681 | } |
539 | 682 | ||
540 | 683 | ||
684 | struct GNUNET_TIME_Timestamp | ||
685 | GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch) | ||
686 | { | ||
687 | struct GNUNET_TIME_Timestamp ret; | ||
688 | |||
689 | ret.abs_time.abs_value_us | ||
690 | = GNUNET_TIME_UNIT_SECONDS.rel_value_us * s_after_epoch; | ||
691 | if (ret.abs_time.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us | ||
692 | != s_after_epoch) | ||
693 | ret = GNUNET_TIME_UNIT_FOREVER_TS; | ||
694 | return ret; | ||
695 | } | ||
696 | |||
697 | |||
541 | struct GNUNET_TIME_Absolute | 698 | struct GNUNET_TIME_Absolute |
542 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) | 699 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) |
543 | { | 700 | { |
@@ -645,6 +802,13 @@ GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, | |||
645 | } | 802 | } |
646 | 803 | ||
647 | 804 | ||
805 | bool | ||
806 | GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs) | ||
807 | { | ||
808 | return 0 == abs.abs_value_us; | ||
809 | } | ||
810 | |||
811 | |||
648 | struct GNUNET_TIME_Relative | 812 | struct GNUNET_TIME_Relative |
649 | GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r) | 813 | GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r) |
650 | { | 814 | { |