diff options
author | t3sserakt <t3ss@posteo.de> | 2022-03-17 15:12:06 +0100 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2022-03-17 15:12:06 +0100 |
commit | 8d41efc36bec5bc5ec29278a365d5a63d7349084 (patch) | |
tree | 99177b1b5400df5ae7180c2af1f47408cace1034 /src | |
parent | 95a1edacccd9b3bf769a144a12d41946d0ac25dc (diff) | |
parent | ea4a5dd6ca3d62f852b5c2de94071b7fc8f0544c (diff) | |
download | gnunet-8d41efc36bec5bc5ec29278a365d5a63d7349084.tar.gz gnunet-8d41efc36bec5bc5ec29278a365d5a63d7349084.zip |
Merge branch 'master' of ssh://git.gnunet.org/gnunet
Diffstat (limited to 'src')
152 files changed, 7779 insertions, 4549 deletions
diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in index 4abddd99c..2c65869dd 100644 --- a/src/ats/ats.conf.in +++ b/src/ats/ats.conf.in | |||
@@ -15,8 +15,8 @@ MODE = proportional | |||
15 | # IMPORTANT: Do not lower those quotas below 10 MiB | 15 | # IMPORTANT: Do not lower those quotas below 10 MiB |
16 | # Or your peer may not bootstrap correctly. | 16 | # Or your peer may not bootstrap correctly. |
17 | # Network specific inbound/outbound quotas | 17 | # Network specific inbound/outbound quotas |
18 | UNSPECIFIED_QUOTA_IN = 10 MiB | 18 | UNSPECIFIED_QUOTA_IN = unlimited |
19 | UNSPECIFIED_QUOTA_OUT = 10 MiB | 19 | UNSPECIFIED_QUOTA_OUT = unlimited |
20 | # LOOPBACK | 20 | # LOOPBACK |
21 | LOOPBACK_QUOTA_IN = unlimited | 21 | LOOPBACK_QUOTA_IN = unlimited |
22 | LOOPBACK_QUOTA_OUT = unlimited | 22 | LOOPBACK_QUOTA_OUT = unlimited |
@@ -27,8 +27,8 @@ LAN_QUOTA_OUT = unlimited | |||
27 | WAN_QUOTA_IN = 10 MiB | 27 | WAN_QUOTA_IN = 10 MiB |
28 | WAN_QUOTA_OUT = 10 MiB | 28 | WAN_QUOTA_OUT = 10 MiB |
29 | # WLAN | 29 | # WLAN |
30 | WLAN_QUOTA_IN = 10 MiB | 30 | WLAN_QUOTA_IN = unlimited |
31 | WLAN_QUOTA_OUT = 10 MiB | 31 | WLAN_QUOTA_OUT = unlimited |
32 | # BLUETOOTH | 32 | # BLUETOOTH |
33 | BLUETOOTH_QUOTA_IN = 10 MiB | 33 | BLUETOOTH_QUOTA_IN = 10 MiB |
34 | BLUETOOTH_QUOTA_OUT = 10 MiB | 34 | BLUETOOTH_QUOTA_OUT = 10 MiB |
@@ -38,7 +38,7 @@ BLUETOOTH_QUOTA_OUT = 10 MiB | |||
38 | # How proportional to preferences is bandwidth distribution in a network | 38 | # How proportional to preferences is bandwidth distribution in a network |
39 | # 1.0: Fair with respect to addresses without preferences | 39 | # 1.0: Fair with respect to addresses without preferences |
40 | # > 1.0: The bigger, the more respect is paid to preferences | 40 | # > 1.0: The bigger, the more respect is paid to preferences |
41 | PROP_PROPORTIONALITY_FACTOR = 2.00 | 41 | PROP_PROPORTIONALITY_FACTOR = 10.00 |
42 | # Should we stick to existing connections are prefer to switch? | 42 | # Should we stick to existing connections or prefer to switch? |
43 | # [1.0...2.0], lower value prefers to switch, bigger value is more tolerant | 43 | # [1.0...2.0], lower value prefers to switch, bigger value is more tolerant |
44 | PROP_STABILITY_FACTOR = 1.25 | 44 | PROP_STABILITY_FACTOR = 1.25 |
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c index 25b963532..ba7994686 100644 --- a/src/ats/gnunet-ats-solver-eval.c +++ b/src/ats/gnunet-ats-solver-eval.c | |||
@@ -442,7 +442,7 @@ GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int | |||
442 | } | 442 | } |
443 | } | 443 | } |
444 | 444 | ||
445 | cleanup: | 445 | cleanup: |
446 | next = lf_head; | 446 | next = lf_head; |
447 | for (cur = next; NULL != cur; cur = next) | 447 | for (cur = next; NULL != cur; cur = next) |
448 | { | 448 | { |
@@ -1414,7 +1414,8 @@ load_op_add_address (struct GNUNET_ATS_TEST_Operation *o, | |||
1414 | } | 1414 | } |
1415 | else | 1415 | else |
1416 | { | 1416 | { |
1417 | GNUNET_STRINGS_utf8_toupper (op_network, op_network); | 1417 | GNUNET_break (GNUNET_OK == GNUNET_STRINGS_utf8_toupper (op_network, |
1418 | op_network)); | ||
1418 | if (0 == strcmp (op_network, "UNSPECIFIED")) | 1419 | if (0 == strcmp (op_network, "UNSPECIFIED")) |
1419 | { | 1420 | { |
1420 | o->address_network = GNUNET_NT_UNSPECIFIED; | 1421 | o->address_network = GNUNET_NT_UNSPECIFIED; |
diff --git a/src/block/bg_bf.c b/src/block/bg_bf.c index ae8ee0e51..601f605a2 100644 --- a/src/block/bg_bf.c +++ b/src/block/bg_bf.c | |||
@@ -61,7 +61,7 @@ struct BfGroupInternals | |||
61 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not | 61 | * @return #GNUNET_OK on success, #GNUNET_NO if serialization is not |
62 | * supported, #GNUNET_SYSERR on error | 62 | * supported, #GNUNET_SYSERR on error |
63 | */ | 63 | */ |
64 | static int | 64 | static enum GNUNET_GenericReturnValue |
65 | bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg, | 65 | bf_group_serialize_cb (struct GNUNET_BLOCK_Group *bg, |
66 | uint32_t *nonce, | 66 | uint32_t *nonce, |
67 | void **raw_data, | 67 | void **raw_data, |
@@ -124,7 +124,7 @@ bf_group_mark_seen_cb (struct GNUNET_BLOCK_Group *bg, | |||
124 | * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus | 124 | * @return #GNUNET_OK on success, #GNUNET_NO if the nonces were different and thus |
125 | * we failed. | 125 | * we failed. |
126 | */ | 126 | */ |
127 | static int | 127 | static enum GNUNET_GenericReturnValue |
128 | bf_group_merge_cb (struct GNUNET_BLOCK_Group *bg1, | 128 | bf_group_merge_cb (struct GNUNET_BLOCK_Group *bg1, |
129 | const struct GNUNET_BLOCK_Group *bg2) | 129 | const struct GNUNET_BLOCK_Group *bg2) |
130 | { | 130 | { |
diff --git a/src/block/block.c b/src/block/block.c index 5824946f7..2e3c1dc70 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, 2021 GNUnet e.V. | 3 | Copyright (C) 2010, 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 |
@@ -255,35 +255,6 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, | |||
255 | } | 255 | } |
256 | 256 | ||
257 | 257 | ||
258 | enum GNUNET_BLOCK_EvaluationResult | ||
259 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | ||
260 | enum GNUNET_BLOCK_Type type, | ||
261 | struct GNUNET_BLOCK_Group *group, | ||
262 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
263 | const struct GNUNET_HashCode *query, | ||
264 | const void *xquery, | ||
265 | size_t xquery_size, | ||
266 | const void *reply_block, | ||
267 | size_t reply_block_size) | ||
268 | { | ||
269 | struct GNUNET_BLOCK_PluginFunctions *plugin = find_plugin (ctx, | ||
270 | type); | ||
271 | |||
272 | if (NULL == plugin) | ||
273 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
274 | return plugin->evaluate (plugin->cls, | ||
275 | ctx, | ||
276 | type, | ||
277 | group, | ||
278 | eo, | ||
279 | query, | ||
280 | xquery, | ||
281 | xquery_size, | ||
282 | reply_block, | ||
283 | reply_block_size); | ||
284 | } | ||
285 | |||
286 | |||
287 | enum GNUNET_GenericReturnValue | 258 | enum GNUNET_GenericReturnValue |
288 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | 259 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, |
289 | enum GNUNET_BLOCK_Type type, | 260 | enum GNUNET_BLOCK_Type type, |
@@ -327,7 +298,6 @@ GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, | |||
327 | enum GNUNET_GenericReturnValue | 298 | enum GNUNET_GenericReturnValue |
328 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | 299 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, |
329 | enum GNUNET_BLOCK_Type type, | 300 | enum GNUNET_BLOCK_Type type, |
330 | const struct GNUNET_HashCode *query, | ||
331 | const void *block, | 301 | const void *block, |
332 | size_t block_size) | 302 | size_t block_size) |
333 | { | 303 | { |
@@ -338,7 +308,6 @@ GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | |||
338 | return GNUNET_SYSERR; | 308 | return GNUNET_SYSERR; |
339 | return plugin->check_block (plugin->cls, | 309 | return plugin->check_block (plugin->cls, |
340 | type, | 310 | type, |
341 | query, | ||
342 | block, | 311 | block, |
343 | block_size); | 312 | block_size); |
344 | } | 313 | } |
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c index 13d9adfda..dcaf1afaa 100644 --- a/src/block/plugin_block_template.c +++ b/src/block/plugin_block_template.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 GNUnet e.V. | 3 | Copyright (C) 2010, 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 |
@@ -92,49 +92,6 @@ block_plugin_template_create_group (void *cls, | |||
92 | 92 | ||
93 | 93 | ||
94 | /** | 94 | /** |
95 | * Function called to validate a reply or a request. For | ||
96 | * request evaluation, simply pass "NULL" for the reply_block. | ||
97 | * | ||
98 | * @param cls closure | ||
99 | * @param ctx context | ||
100 | * @param type block type | ||
101 | * @param group block group to use | ||
102 | * @param eo control flags | ||
103 | * @param query original query (hash) | ||
104 | * @param xquery extrended query data (can be NULL, depending on type) | ||
105 | * @param xquery_size number of bytes in xquery | ||
106 | * @param reply_block response to validate | ||
107 | * @param reply_block_size number of bytes in reply block | ||
108 | * @return characterization of result | ||
109 | */ | ||
110 | static enum GNUNET_BLOCK_EvaluationResult | ||
111 | block_plugin_template_evaluate (void *cls, | ||
112 | struct GNUNET_BLOCK_Context *ctx, | ||
113 | enum GNUNET_BLOCK_Type type, | ||
114 | struct GNUNET_BLOCK_Group *group, | ||
115 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
116 | const struct GNUNET_HashCode *query, | ||
117 | const void *xquery, | ||
118 | size_t xquery_size, | ||
119 | const void *reply_block, | ||
120 | size_t reply_block_size) | ||
121 | { | ||
122 | struct GNUNET_HashCode chash; | ||
123 | |||
124 | if (NULL == reply_block) | ||
125 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
126 | GNUNET_CRYPTO_hash (reply_block, | ||
127 | reply_block_size, | ||
128 | &chash); | ||
129 | if (GNUNET_YES == | ||
130 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
131 | &chash)) | ||
132 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
133 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
134 | } | ||
135 | |||
136 | |||
137 | /** | ||
138 | * Function called to validate a query. | 95 | * Function called to validate a query. |
139 | * | 96 | * |
140 | * @param cls closure | 97 | * @param cls closure |
@@ -143,16 +100,16 @@ block_plugin_template_evaluate (void *cls, | |||
143 | * @param query original query (hash) | 100 | * @param query original query (hash) |
144 | * @param xquery extrended query data (can be NULL, depending on type) | 101 | * @param xquery extrended query data (can be NULL, depending on type) |
145 | * @param xquery_size number of bytes in @a xquery | 102 | * @param xquery_size number of bytes in @a xquery |
146 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | 103 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not, #GNUNET_SYSERR if not supported |
147 | */ | 104 | */ |
148 | static enum GNUNET_GenericReturnValue | 105 | static enum GNUNET_GenericReturnValue |
149 | block_plugin_template_check_query (void *cls, | 106 | block_plugin_template_check_query (void *cls, |
150 | enum GNUNET_BLOCK_Type type, | 107 | enum GNUNET_BLOCK_Type type, |
151 | const struct GNUNET_HashCode *query, | 108 | const struct GNUNET_HashCode *query, |
152 | const void *xquery, | 109 | const void *xquery, |
153 | size_t xquery_size) | 110 | size_t xquery_size) |
154 | { | 111 | { |
155 | return GNUNET_OK; | 112 | return GNUNET_SYSERR; |
156 | } | 113 | } |
157 | 114 | ||
158 | 115 | ||
@@ -161,19 +118,17 @@ block_plugin_template_check_query (void *cls, | |||
161 | * | 118 | * |
162 | * @param cls closure | 119 | * @param cls closure |
163 | * @param type block type | 120 | * @param type block type |
164 | * @param query key for the block (hash), must match exactly | ||
165 | * @param block block data to validate | 121 | * @param block block data to validate |
166 | * @param block_size number of bytes in @a block | 122 | * @param block_size number of bytes in @a block |
167 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 123 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, #GNUNET_SYSERR if not supported |
168 | */ | 124 | */ |
169 | static enum GNUNET_GenericReturnValue | 125 | static enum GNUNET_GenericReturnValue |
170 | block_plugin_template_check_block (void *cls, | 126 | block_plugin_template_check_block (void *cls, |
171 | enum GNUNET_BLOCK_Type type, | 127 | enum GNUNET_BLOCK_Type type, |
172 | const struct GNUNET_HashCode *query, | ||
173 | const void *block, | 128 | const void *block, |
174 | size_t block_size) | 129 | size_t block_size) |
175 | { | 130 | { |
176 | return GNUNET_OK; | 131 | return GNUNET_SYSERR; |
177 | } | 132 | } |
178 | 133 | ||
179 | 134 | ||
@@ -195,16 +150,16 @@ block_plugin_template_check_block (void *cls, | |||
195 | */ | 150 | */ |
196 | static enum GNUNET_BLOCK_ReplyEvaluationResult | 151 | static enum GNUNET_BLOCK_ReplyEvaluationResult |
197 | block_plugin_template_check_reply ( | 152 | block_plugin_template_check_reply ( |
198 | void *cls, | 153 | void *cls, |
199 | enum GNUNET_BLOCK_Type type, | 154 | enum GNUNET_BLOCK_Type type, |
200 | struct GNUNET_BLOCK_Group *group, | 155 | struct GNUNET_BLOCK_Group *group, |
201 | const struct GNUNET_HashCode *query, | 156 | const struct GNUNET_HashCode *query, |
202 | const void *xquery, | 157 | const void *xquery, |
203 | size_t xquery_size, | 158 | size_t xquery_size, |
204 | const void *reply_block, | 159 | const void *reply_block, |
205 | size_t reply_block_size) | 160 | size_t reply_block_size) |
206 | { | 161 | { |
207 | return GNUNET_BLOCK_REPLY_OK_MORE; | 162 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
208 | } | 163 | } |
209 | 164 | ||
210 | 165 | ||
@@ -245,7 +200,6 @@ libgnunet_plugin_block_template_init (void *cls) | |||
245 | struct GNUNET_BLOCK_PluginFunctions *api; | 200 | struct GNUNET_BLOCK_PluginFunctions *api; |
246 | 201 | ||
247 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 202 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
248 | api->evaluate = &block_plugin_template_evaluate; | ||
249 | api->get_key = &block_plugin_template_get_key; | 203 | api->get_key = &block_plugin_template_get_key; |
250 | api->check_query = &block_plugin_template_check_query; | 204 | api->check_query = &block_plugin_template_check_query; |
251 | api->check_block = &block_plugin_template_check_block; | 205 | api->check_block = &block_plugin_template_check_block; |
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c index fd643c4dc..05d379387 100644 --- a/src/block/plugin_block_test.c +++ b/src/block/plugin_block_test.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 GNUnet e.V. | 3 | Copyright (C) 2010, 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 |
@@ -90,59 +90,6 @@ block_plugin_test_create_group (void *cls, | |||
90 | 90 | ||
91 | 91 | ||
92 | /** | 92 | /** |
93 | * Function called to validate a reply or a request. For | ||
94 | * request evaluation, simply pass "NULL" for the reply_block. | ||
95 | * | ||
96 | * @param cls closure | ||
97 | * @param ctx block context | ||
98 | * @param type block type | ||
99 | * @param group group to check against | ||
100 | * @param eo control flags | ||
101 | * @param query original query (hash) | ||
102 | * @param xquery extrended query data (can be NULL, depending on type) | ||
103 | * @param xquery_size number of bytes in @a xquery | ||
104 | * @param reply_block response to validate | ||
105 | * @param reply_block_size number of bytes in @a reply_block | ||
106 | * @return characterization of result | ||
107 | */ | ||
108 | static enum GNUNET_BLOCK_EvaluationResult | ||
109 | block_plugin_test_evaluate (void *cls, | ||
110 | struct GNUNET_BLOCK_Context *ctx, | ||
111 | enum GNUNET_BLOCK_Type type, | ||
112 | struct GNUNET_BLOCK_Group *group, | ||
113 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
114 | const struct GNUNET_HashCode *query, | ||
115 | const void *xquery, | ||
116 | size_t xquery_size, | ||
117 | const void *reply_block, | ||
118 | size_t reply_block_size) | ||
119 | { | ||
120 | struct GNUNET_HashCode chash; | ||
121 | |||
122 | if (GNUNET_BLOCK_TYPE_TEST != type) | ||
123 | { | ||
124 | GNUNET_break (0); | ||
125 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
126 | } | ||
127 | if (0 != xquery_size) | ||
128 | { | ||
129 | GNUNET_break_op (0); | ||
130 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
131 | } | ||
132 | if (NULL == reply_block) | ||
133 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
134 | GNUNET_CRYPTO_hash (reply_block, | ||
135 | reply_block_size, | ||
136 | &chash); | ||
137 | if (GNUNET_YES == | ||
138 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
139 | &chash)) | ||
140 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
141 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
142 | } | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Function called to validate a query. | 93 | * Function called to validate a query. |
147 | * | 94 | * |
148 | * @param cls closure | 95 | * @param cls closure |
@@ -151,15 +98,18 @@ block_plugin_test_evaluate (void *cls, | |||
151 | * @param query original query (hash) | 98 | * @param query original query (hash) |
152 | * @param xquery extrended query data (can be NULL, depending on type) | 99 | * @param xquery extrended query data (can be NULL, depending on type) |
153 | * @param xquery_size number of bytes in @a xquery | 100 | * @param xquery_size number of bytes in @a xquery |
154 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | 101 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not, #GNUNET_SYSERR if @a type is not supported |
155 | */ | 102 | */ |
156 | static enum GNUNET_GenericReturnValue | 103 | static enum GNUNET_GenericReturnValue |
157 | block_plugin_test_check_query (void *cls, | 104 | block_plugin_test_check_query (void *cls, |
158 | enum GNUNET_BLOCK_Type type, | 105 | enum GNUNET_BLOCK_Type type, |
159 | const struct GNUNET_HashCode *query, | 106 | const struct GNUNET_HashCode *query, |
160 | const void *xquery, | 107 | const void *xquery, |
161 | size_t xquery_size) | 108 | size_t xquery_size) |
162 | { | 109 | { |
110 | (void) cls; | ||
111 | (void) query; | ||
112 | (void) xquery; | ||
163 | if (GNUNET_BLOCK_TYPE_TEST != type) | 113 | if (GNUNET_BLOCK_TYPE_TEST != type) |
164 | { | 114 | { |
165 | GNUNET_break (0); | 115 | GNUNET_break (0); |
@@ -168,9 +118,9 @@ block_plugin_test_check_query (void *cls, | |||
168 | if (0 != xquery_size) | 118 | if (0 != xquery_size) |
169 | { | 119 | { |
170 | GNUNET_break_op (0); | 120 | GNUNET_break_op (0); |
171 | return GNUNET_SYSERR; | 121 | return GNUNET_NO; |
172 | } | 122 | } |
173 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | 123 | return GNUNET_OK; |
174 | } | 124 | } |
175 | 125 | ||
176 | 126 | ||
@@ -179,18 +129,19 @@ block_plugin_test_check_query (void *cls, | |||
179 | * | 129 | * |
180 | * @param cls closure | 130 | * @param cls closure |
181 | * @param type block type | 131 | * @param type block type |
182 | * @param query key for the block (hash), must match exactly | ||
183 | * @param block block data to validate | 132 | * @param block block data to validate |
184 | * @param block_size number of bytes in @a block | 133 | * @param block_size number of bytes in @a block |
185 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 134 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, #GNUNET_SYSERR if @a type is not supported |
186 | */ | 135 | */ |
187 | static enum GNUNET_GenericReturnValue | 136 | static enum GNUNET_GenericReturnValue |
188 | block_plugin_test_check_block (void *cls, | 137 | block_plugin_test_check_block (void *cls, |
189 | enum GNUNET_BLOCK_Type type, | 138 | enum GNUNET_BLOCK_Type type, |
190 | const struct GNUNET_HashCode *query, | 139 | const void *block, |
191 | const void *block, | 140 | size_t block_size) |
192 | size_t block_size) | ||
193 | { | 141 | { |
142 | (void) cls; | ||
143 | (void) block; | ||
144 | (void) block_size; | ||
194 | if (GNUNET_BLOCK_TYPE_TEST != type) | 145 | if (GNUNET_BLOCK_TYPE_TEST != type) |
195 | { | 146 | { |
196 | GNUNET_break (0); | 147 | GNUNET_break (0); |
@@ -218,16 +169,20 @@ block_plugin_test_check_block (void *cls, | |||
218 | */ | 169 | */ |
219 | static enum GNUNET_BLOCK_ReplyEvaluationResult | 170 | static enum GNUNET_BLOCK_ReplyEvaluationResult |
220 | block_plugin_test_check_reply (void *cls, | 171 | block_plugin_test_check_reply (void *cls, |
221 | enum GNUNET_BLOCK_Type type, | 172 | enum GNUNET_BLOCK_Type type, |
222 | struct GNUNET_BLOCK_Group *group, | 173 | struct GNUNET_BLOCK_Group *group, |
223 | const struct GNUNET_HashCode *query, | 174 | const struct GNUNET_HashCode *query, |
224 | const void *xquery, | 175 | const void *xquery, |
225 | size_t xquery_size, | 176 | size_t xquery_size, |
226 | const void *reply_block, | 177 | const void *reply_block, |
227 | size_t reply_block_size) | 178 | size_t reply_block_size) |
228 | { | 179 | { |
229 | struct GNUNET_HashCode chash; | 180 | struct GNUNET_HashCode chash; |
230 | 181 | ||
182 | (void) cls; | ||
183 | (void) query; | ||
184 | (void) xquery; | ||
185 | (void) xquery_size; | ||
231 | if (GNUNET_BLOCK_TYPE_TEST != type) | 186 | if (GNUNET_BLOCK_TYPE_TEST != type) |
232 | { | 187 | { |
233 | GNUNET_break (0); | 188 | GNUNET_break (0); |
@@ -252,8 +207,7 @@ block_plugin_test_check_reply (void *cls, | |||
252 | * @param block block to get the key for | 207 | * @param block block to get the key for |
253 | * @param block_size number of bytes in @a block | 208 | * @param block_size number of bytes in @a block |
254 | * @param key set to the key (query) for the given block | 209 | * @param key set to the key (query) for the given block |
255 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 210 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported, #GNUNET_NO 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) | ||
257 | */ | 211 | */ |
258 | static enum GNUNET_GenericReturnValue | 212 | static enum GNUNET_GenericReturnValue |
259 | block_plugin_test_get_key (void *cls, | 213 | block_plugin_test_get_key (void *cls, |
@@ -262,9 +216,16 @@ block_plugin_test_get_key (void *cls, | |||
262 | size_t block_size, | 216 | size_t block_size, |
263 | struct GNUNET_HashCode *key) | 217 | struct GNUNET_HashCode *key) |
264 | { | 218 | { |
265 | /* always fails since there is no fixed relationship between | 219 | (void) cls; |
266 | * keys and values for test values */ | 220 | (void) block; |
267 | return GNUNET_SYSERR; | 221 | (void) block_size; |
222 | (void) key; | ||
223 | if (GNUNET_BLOCK_TYPE_TEST != type) | ||
224 | { | ||
225 | GNUNET_break (0); | ||
226 | return GNUNET_SYSERR; | ||
227 | } | ||
228 | return GNUNET_NO; | ||
268 | } | 229 | } |
269 | 230 | ||
270 | 231 | ||
@@ -284,7 +245,6 @@ libgnunet_plugin_block_test_init (void *cls) | |||
284 | struct GNUNET_BLOCK_PluginFunctions *api; | 245 | struct GNUNET_BLOCK_PluginFunctions *api; |
285 | 246 | ||
286 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 247 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
287 | api->evaluate = &block_plugin_test_evaluate; | ||
288 | api->get_key = &block_plugin_test_get_key; | 248 | api->get_key = &block_plugin_test_get_key; |
289 | api->check_query = &block_plugin_test_check_query; | 249 | api->check_query = &block_plugin_test_check_query; |
290 | api->check_block = &block_plugin_test_check_block; | 250 | api->check_block = &block_plugin_test_check_block; |
diff --git a/src/consensus/plugin_block_consensus.c b/src/consensus/plugin_block_consensus.c index 430a2c0cb..f30b9b0d7 100644 --- a/src/consensus/plugin_block_consensus.c +++ b/src/consensus/plugin_block_consensus.c | |||
@@ -47,57 +47,6 @@ struct BlockContext | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | 49 | ||
50 | /** | ||
51 | * Function called to validate a reply or a request. For | ||
52 | * request evaluation, simply pass "NULL" for the reply_block. | ||
53 | * | ||
54 | * @param cls closure | ||
55 | * @param ctx context | ||
56 | * @param type block type | ||
57 | * @param group block group to use | ||
58 | * @param eo control flags | ||
59 | * @param query original query (hash) | ||
60 | * @param xquery extrended query data (can be NULL, depending on type) | ||
61 | * @param xquery_size number of bytes in xquery | ||
62 | * @param reply_block response to validate | ||
63 | * @param reply_block_size number of bytes in reply block | ||
64 | * @return characterization of result | ||
65 | */ | ||
66 | static enum GNUNET_BLOCK_EvaluationResult | ||
67 | block_plugin_consensus_evaluate (void *cls, | ||
68 | struct GNUNET_BLOCK_Context *ctx, | ||
69 | enum GNUNET_BLOCK_Type type, | ||
70 | struct GNUNET_BLOCK_Group *group, | ||
71 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
72 | const struct GNUNET_HashCode *query, | ||
73 | const void *xquery, | ||
74 | size_t xquery_size, | ||
75 | const void *reply_block, | ||
76 | size_t reply_block_size) | ||
77 | { | ||
78 | struct BlockContext *bctx = cls; | ||
79 | const struct ConsensusElement *ce = reply_block; | ||
80 | |||
81 | if (reply_block_size < sizeof(struct ConsensusElement)) | ||
82 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
83 | if ( (0 != ce->marker) || | ||
84 | (0 == ce->payload_type) ) | ||
85 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
86 | |||
87 | if (NULL == bctx->bc) | ||
88 | bctx->bc = GNUNET_BLOCK_context_create (bctx->cfg); | ||
89 | return GNUNET_BLOCK_evaluate (bctx->bc, | ||
90 | type, | ||
91 | group, | ||
92 | eo, | ||
93 | query, | ||
94 | xquery, | ||
95 | xquery_size, | ||
96 | &ce[1], | ||
97 | reply_block_size | ||
98 | - sizeof(struct ConsensusElement)); | ||
99 | } | ||
100 | |||
101 | 50 | ||
102 | /** | 51 | /** |
103 | * Function called to validate a query. | 52 | * Function called to validate a query. |
@@ -128,7 +77,6 @@ block_plugin_consensus_check_query (void *cls, | |||
128 | * | 77 | * |
129 | * @param cls closure | 78 | * @param cls closure |
130 | * @param type block type | 79 | * @param type block type |
131 | * @param query key for the block (hash), must match exactly | ||
132 | * @param block block data to validate | 80 | * @param block block data to validate |
133 | * @param block_size number of bytes in @a block | 81 | * @param block_size number of bytes in @a block |
134 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 82 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -136,7 +84,6 @@ block_plugin_consensus_check_query (void *cls, | |||
136 | static enum GNUNET_GenericReturnValue | 84 | static enum GNUNET_GenericReturnValue |
137 | block_plugin_consensus_check_block (void *cls, | 85 | block_plugin_consensus_check_block (void *cls, |
138 | enum GNUNET_BLOCK_Type type, | 86 | enum GNUNET_BLOCK_Type type, |
139 | const struct GNUNET_HashCode *query, | ||
140 | const void *block, | 87 | const void *block, |
141 | size_t block_size) | 88 | size_t block_size) |
142 | { | 89 | { |
@@ -144,7 +91,10 @@ block_plugin_consensus_check_block (void *cls, | |||
144 | const struct ConsensusElement *ce = block; | 91 | const struct ConsensusElement *ce = block; |
145 | 92 | ||
146 | if (block_size < sizeof(*ce)) | 93 | if (block_size < sizeof(*ce)) |
94 | { | ||
95 | GNUNET_break_op (0); | ||
147 | return GNUNET_NO; | 96 | return GNUNET_NO; |
97 | } | ||
148 | if ( (0 != ce->marker) || | 98 | if ( (0 != ce->marker) || |
149 | (0 == ce->payload_type) ) | 99 | (0 == ce->payload_type) ) |
150 | return GNUNET_OK; | 100 | return GNUNET_OK; |
@@ -152,7 +102,6 @@ block_plugin_consensus_check_block (void *cls, | |||
152 | ctx->bc = GNUNET_BLOCK_context_create (ctx->cfg); | 102 | ctx->bc = GNUNET_BLOCK_context_create (ctx->cfg); |
153 | return GNUNET_BLOCK_check_block (ctx->bc, | 103 | return GNUNET_BLOCK_check_block (ctx->bc, |
154 | ntohl (ce->payload_type), | 104 | ntohl (ce->payload_type), |
155 | query, | ||
156 | &ce[1], | 105 | &ce[1], |
157 | block_size - sizeof(*ce)); | 106 | block_size - sizeof(*ce)); |
158 | } | 107 | } |
@@ -188,8 +137,7 @@ block_plugin_consensus_check_reply ( | |||
188 | struct BlockContext *ctx = cls; | 137 | struct BlockContext *ctx = cls; |
189 | const struct ConsensusElement *ce = reply_block; | 138 | const struct ConsensusElement *ce = reply_block; |
190 | 139 | ||
191 | if (reply_block_size < sizeof(struct ConsensusElement)) | 140 | GNUNET_assert (reply_block_size >= sizeof(struct ConsensusElement)); |
192 | return GNUNET_NO; | ||
193 | if ( (0 != ce->marker) || | 141 | if ( (0 != ce->marker) || |
194 | (0 == ce->payload_type) ) | 142 | (0 == ce->payload_type) ) |
195 | return GNUNET_BLOCK_REPLY_OK_MORE; | 143 | return GNUNET_BLOCK_REPLY_OK_MORE; |
@@ -246,7 +194,6 @@ libgnunet_plugin_block_consensus_init (void *cls) | |||
246 | ctx->cfg = cfg; | 194 | ctx->cfg = cfg; |
247 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 195 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
248 | api->cls = ctx; | 196 | api->cls = ctx; |
249 | api->evaluate = &block_plugin_consensus_evaluate; | ||
250 | api->get_key = &block_plugin_consensus_get_key; | 197 | api->get_key = &block_plugin_consensus_get_key; |
251 | api->check_query = &block_plugin_consensus_check_query; | 198 | api->check_query = &block_plugin_consensus_check_query; |
252 | api->check_block = &block_plugin_consensus_check_block; | 199 | api->check_block = &block_plugin_consensus_check_block; |
diff --git a/src/consensus/test_consensus.conf b/src/consensus/test_consensus.conf index 67b366405..df7fb6861 100644 --- a/src/consensus/test_consensus.conf +++ b/src/consensus/test_consensus.conf | |||
@@ -3,7 +3,7 @@ GNUNET_TEST_HOME = $GNUNET_TMP/test-consensus/ | |||
3 | 3 | ||
4 | [consensus] | 4 | [consensus] |
5 | #OPTIONS = -L INFO | 5 | #OPTIONS = -L INFO |
6 | BINARY = gnunet-service-evil-consensus | 6 | BINARY = gnunet-service-consensus |
7 | 7 | ||
8 | #PREFIX = valgrind | 8 | #PREFIX = valgrind |
9 | 9 | ||
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c index 944a99aad..761ab801f 100644 --- a/src/datacache/datacache.c +++ b/src/datacache/datacache.c | |||
@@ -114,11 +114,11 @@ env_delete_notify (void *cls, | |||
114 | h->utilization -= size; | 114 | h->utilization -= size; |
115 | GNUNET_CONTAINER_bloomfilter_remove (h->filter, key); | 115 | GNUNET_CONTAINER_bloomfilter_remove (h->filter, key); |
116 | GNUNET_STATISTICS_update (h->stats, | 116 | GNUNET_STATISTICS_update (h->stats, |
117 | gettext_noop ("# bytes stored"), | 117 | "# bytes stored", |
118 | -(long long) size, | 118 | -(long long) size, |
119 | GNUNET_NO); | 119 | GNUNET_NO); |
120 | GNUNET_STATISTICS_update (h->stats, | 120 | GNUNET_STATISTICS_update (h->stats, |
121 | gettext_noop ("# items stored"), | 121 | "# items stored", |
122 | -1, | 122 | -1, |
123 | GNUNET_NO); | 123 | GNUNET_NO); |
124 | } | 124 | } |
@@ -136,15 +136,25 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
136 | const struct GNUNET_OS_ProjectData *pd; | 136 | const struct GNUNET_OS_ProjectData *pd; |
137 | 137 | ||
138 | if (GNUNET_OK != | 138 | if (GNUNET_OK != |
139 | GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", "a)) | 139 | GNUNET_CONFIGURATION_get_value_size (cfg, |
140 | section, | ||
141 | "QUOTA", | ||
142 | "a)) | ||
140 | { | 143 | { |
141 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "QUOTA"); | 144 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
145 | section, | ||
146 | "QUOTA"); | ||
142 | return NULL; | 147 | return NULL; |
143 | } | 148 | } |
144 | if (GNUNET_OK != | 149 | if (GNUNET_OK != |
145 | GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name)) | 150 | GNUNET_CONFIGURATION_get_value_string (cfg, |
151 | section, | ||
152 | "DATABASE", | ||
153 | &name)) | ||
146 | { | 154 | { |
147 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, section, "DATABASE"); | 155 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
156 | section, | ||
157 | "DATABASE"); | ||
148 | return NULL; | 158 | return NULL; |
149 | } | 159 | } |
150 | bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ | 160 | bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ |
@@ -152,10 +162,14 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
152 | ret = GNUNET_new (struct GNUNET_DATACACHE_Handle); | 162 | ret = GNUNET_new (struct GNUNET_DATACACHE_Handle); |
153 | 163 | ||
154 | if (GNUNET_YES != | 164 | if (GNUNET_YES != |
155 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF")) | 165 | GNUNET_CONFIGURATION_get_value_yesno (cfg, |
166 | section, | ||
167 | "DISABLE_BF")) | ||
156 | { | 168 | { |
157 | if (GNUNET_YES != | 169 | if (GNUNET_YES != |
158 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC")) | 170 | GNUNET_CONFIGURATION_get_value_yesno (cfg, |
171 | section, | ||
172 | "DISABLE_BF_RC")) | ||
159 | { | 173 | { |
160 | ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); | 174 | ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); |
161 | } | 175 | } |
@@ -174,7 +188,8 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
174 | 5); /* approx. 3% false positives at max use */ | 188 | 5); /* approx. 3% false positives at max use */ |
175 | } | 189 | } |
176 | } | 190 | } |
177 | ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); | 191 | ret->stats = GNUNET_STATISTICS_create ("datacache", |
192 | cfg); | ||
178 | ret->section = GNUNET_strdup (section); | 193 | ret->section = GNUNET_strdup (section); |
179 | ret->env.cfg = cfg; | 194 | ret->env.cfg = cfg; |
180 | ret->env.delete_notify = &env_delete_notify; | 195 | ret->env.delete_notify = &env_delete_notify; |
@@ -182,25 +197,31 @@ GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
182 | ret->env.cls = ret; | 197 | ret->env.cls = ret; |
183 | ret->env.delete_notify = &env_delete_notify; | 198 | ret->env.delete_notify = &env_delete_notify; |
184 | ret->env.quota = quota; | 199 | ret->env.quota = quota; |
185 | LOG (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' datacache plugin\n"), name); | 200 | LOG (GNUNET_ERROR_TYPE_INFO, |
186 | GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name); | 201 | "Loading `%s' datacache plugin\n", |
202 | name); | ||
203 | GNUNET_asprintf (&libname, | ||
204 | "libgnunet_plugin_datacache_%s", | ||
205 | name); | ||
187 | ret->short_name = name; | 206 | ret->short_name = name; |
188 | ret->lib_name = libname; | 207 | ret->lib_name = libname; |
189 | /* Load the plugin within GNUnet's default context */ | 208 | /* Load the plugin within GNUnet's default context */ |
190 | pd = GNUNET_OS_project_data_get (); | 209 | pd = GNUNET_OS_project_data_get (); |
191 | GNUNET_OS_init (GNUNET_OS_project_data_default ()); | 210 | GNUNET_OS_init (GNUNET_OS_project_data_default ()); |
192 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); | 211 | ret->api = GNUNET_PLUGIN_load (libname, |
212 | &ret->env); | ||
193 | GNUNET_OS_init (pd); | 213 | GNUNET_OS_init (pd); |
194 | if (NULL == ret->api) | 214 | if (NULL == ret->api) |
195 | { | 215 | { |
196 | /* Try to load the plugin within the application's context | 216 | /* Try to load the plugin within the application's context |
197 | This normally happens when the application is not GNUnet itself but a | 217 | This normally happens when the application is not GNUnet itself but a |
198 | third party; inside GNUnet this is effectively a double failure. */ | 218 | third party; inside GNUnet this is effectively a double failure. */ |
199 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); | 219 | ret->api = GNUNET_PLUGIN_load (libname, |
220 | &ret->env); | ||
200 | if (NULL == ret->api) | 221 | if (NULL == ret->api) |
201 | { | 222 | { |
202 | LOG (GNUNET_ERROR_TYPE_ERROR, | 223 | LOG (GNUNET_ERROR_TYPE_ERROR, |
203 | _ ("Failed to load datacache plugin for `%s'\n"), | 224 | "Failed to load datacache plugin for `%s'\n", |
204 | name); | 225 | name); |
205 | GNUNET_DATACACHE_destroy (ret); | 226 | GNUNET_DATACACHE_destroy (ret); |
206 | return NULL; | 227 | return NULL; |
@@ -216,7 +237,9 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h) | |||
216 | if (NULL != h->filter) | 237 | if (NULL != h->filter) |
217 | GNUNET_CONTAINER_bloomfilter_free (h->filter); | 238 | GNUNET_CONTAINER_bloomfilter_free (h->filter); |
218 | if (NULL != h->api) | 239 | if (NULL != h->api) |
219 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api)); | 240 | GNUNET_break (NULL == |
241 | GNUNET_PLUGIN_unload (h->lib_name, | ||
242 | h->api)); | ||
220 | GNUNET_free (h->lib_name); | 243 | GNUNET_free (h->lib_name); |
221 | GNUNET_free (h->short_name); | 244 | GNUNET_free (h->short_name); |
222 | GNUNET_free (h->section); | 245 | GNUNET_free (h->section); |
@@ -270,17 +293,19 @@ GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h, | |||
270 | "Stored data under key `%s' in cache\n", | 293 | "Stored data under key `%s' in cache\n", |
271 | GNUNET_h2s (key)); | 294 | GNUNET_h2s (key)); |
272 | if (NULL != h->filter) | 295 | if (NULL != h->filter) |
273 | GNUNET_CONTAINER_bloomfilter_add (h->filter, key); | 296 | GNUNET_CONTAINER_bloomfilter_add (h->filter, |
297 | key); | ||
274 | GNUNET_STATISTICS_update (h->stats, | 298 | GNUNET_STATISTICS_update (h->stats, |
275 | gettext_noop ("# bytes stored"), | 299 | "# bytes stored", |
276 | used, | 300 | used, |
277 | GNUNET_NO); | 301 | GNUNET_NO); |
278 | GNUNET_STATISTICS_update (h->stats, | 302 | GNUNET_STATISTICS_update (h->stats, |
279 | gettext_noop ("# items stored"), | 303 | "# items stored", |
280 | 1, | 304 | 1, |
281 | GNUNET_NO); | 305 | GNUNET_NO); |
282 | while (h->utilization + used > h->env.quota) | 306 | while (h->utilization + used > h->env.quota) |
283 | GNUNET_assert (GNUNET_OK == h->api->del (h->api->cls)); | 307 | GNUNET_assert (GNUNET_OK == |
308 | h->api->del (h->api->cls)); | ||
284 | h->utilization += used; | 309 | h->utilization += used; |
285 | return GNUNET_OK; | 310 | return GNUNET_OK; |
286 | } | 311 | } |
@@ -294,18 +319,18 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
294 | void *iter_cls) | 319 | void *iter_cls) |
295 | { | 320 | { |
296 | GNUNET_STATISTICS_update (h->stats, | 321 | GNUNET_STATISTICS_update (h->stats, |
297 | gettext_noop ("# requests received"), | 322 | "# requests received", |
298 | 1, | 323 | 1, |
299 | GNUNET_NO); | 324 | GNUNET_NO); |
300 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 325 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
301 | "Processing request for key `%s'\n", | 326 | "Processing request for key `%s'\n", |
302 | GNUNET_h2s (key)); | 327 | GNUNET_h2s (key)); |
303 | if ((NULL != h->filter) && | 328 | if ((NULL != h->filter) && |
304 | (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key))) | 329 | (GNUNET_OK != |
330 | GNUNET_CONTAINER_bloomfilter_test (h->filter, key))) | ||
305 | { | 331 | { |
306 | GNUNET_STATISTICS_update (h->stats, | 332 | GNUNET_STATISTICS_update (h->stats, |
307 | gettext_noop ( | 333 | "# requests filtered by bloom filter", |
308 | "# requests filtered by bloom filter"), | ||
309 | 1, | 334 | 1, |
310 | GNUNET_NO); | 335 | GNUNET_NO); |
311 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 336 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -313,26 +338,33 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
313 | GNUNET_h2s (key)); | 338 | GNUNET_h2s (key)); |
314 | return 0; /* can not be present */ | 339 | return 0; /* can not be present */ |
315 | } | 340 | } |
316 | return h->api->get (h->api->cls, key, type, iter, iter_cls); | 341 | return h->api->get (h->api->cls, |
342 | key, | ||
343 | type, | ||
344 | iter, iter_cls); | ||
317 | } | 345 | } |
318 | 346 | ||
319 | 347 | ||
320 | unsigned int | 348 | unsigned int |
321 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, | 349 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, |
322 | const struct GNUNET_HashCode *key, | 350 | const struct GNUNET_HashCode *key, |
351 | enum GNUNET_BLOCK_Type type, | ||
323 | unsigned int num_results, | 352 | unsigned int num_results, |
324 | GNUNET_DATACACHE_Iterator iter, | 353 | GNUNET_DATACACHE_Iterator iter, |
325 | void *iter_cls) | 354 | void *iter_cls) |
326 | { | 355 | { |
327 | GNUNET_STATISTICS_update (h->stats, | 356 | GNUNET_STATISTICS_update (h->stats, |
328 | gettext_noop ( | 357 | "# proximity search requests received", |
329 | "# proximity search requests received"), | ||
330 | 1, | 358 | 1, |
331 | GNUNET_NO); | 359 | GNUNET_NO); |
332 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 360 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
333 | "Processing proximity search at `%s'\n", | 361 | "Processing proximity search at `%s'\n", |
334 | GNUNET_h2s (key)); | 362 | GNUNET_h2s (key)); |
335 | return h->api->get_closest (h->api->cls, key, num_results, iter, iter_cls); | 363 | return h->api->get_closest (h->api->cls, |
364 | key, | ||
365 | type, | ||
366 | num_results, | ||
367 | iter, iter_cls); | ||
336 | } | 368 | } |
337 | 369 | ||
338 | 370 | ||
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c index fbd3aea9a..5b50468a5 100644 --- a/src/datacache/plugin_datacache_heap.c +++ b/src/datacache/plugin_datacache_heap.c | |||
@@ -158,7 +158,7 @@ struct PutContext | |||
158 | * @param value an existing value | 158 | * @param value an existing value |
159 | * @return #GNUNET_YES if not found (to continue to iterate) | 159 | * @return #GNUNET_YES if not found (to continue to iterate) |
160 | */ | 160 | */ |
161 | static int | 161 | static enum GNUNET_GenericReturnValue |
162 | put_cb (void *cls, | 162 | put_cb (void *cls, |
163 | const struct GNUNET_HashCode *key, | 163 | const struct GNUNET_HashCode *key, |
164 | void *value) | 164 | void *value) |
@@ -224,15 +224,20 @@ heap_plugin_put (void *cls, | |||
224 | { | 224 | { |
225 | struct Plugin *plugin = cls; | 225 | struct Plugin *plugin = cls; |
226 | struct Value *val; | 226 | struct Value *val; |
227 | struct PutContext put_ctx; | 227 | struct PutContext put_ctx = { |
228 | 228 | .data = data, | |
229 | put_ctx.found = GNUNET_NO; | 229 | .size = size, |
230 | put_ctx.data = data; | 230 | .path_info = path_info, |
231 | put_ctx.size = size; | 231 | .path_info_len = path_info_len, |
232 | put_ctx.path_info = path_info; | 232 | .discard_time = discard_time, |
233 | put_ctx.path_info_len = path_info_len; | 233 | .type = type |
234 | put_ctx.discard_time = discard_time; | 234 | }; |
235 | put_ctx.type = type; | 235 | |
236 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
237 | "Storing %u bytes under key %s with path length %u\n", | ||
238 | (unsigned int) size, | ||
239 | GNUNET_h2s (key), | ||
240 | path_info_len); | ||
236 | GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map, | 241 | GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map, |
237 | key, | 242 | key, |
238 | &put_cb, | 243 | &put_cb, |
@@ -313,12 +318,25 @@ get_cb (void *cls, | |||
313 | struct Value *val = value; | 318 | struct Value *val = value; |
314 | int ret; | 319 | int ret; |
315 | 320 | ||
316 | if ((get_ctx->type != val->type) && | 321 | if ( (get_ctx->type != val->type) && |
317 | (GNUNET_BLOCK_TYPE_ANY != get_ctx->type)) | 322 | (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) ) |
323 | { | ||
324 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
325 | "Result for key %s does not match block type %d\n", | ||
326 | GNUNET_h2s (key), | ||
327 | get_ctx->type); | ||
318 | return GNUNET_OK; | 328 | return GNUNET_OK; |
319 | if (0 == | 329 | } |
320 | GNUNET_TIME_absolute_get_remaining (val->discard_time).rel_value_us) | 330 | if (GNUNET_TIME_absolute_is_past (val->discard_time)) |
331 | { | ||
332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
333 | "Result for key %s is expired\n", | ||
334 | GNUNET_h2s (key)); | ||
321 | return GNUNET_OK; | 335 | return GNUNET_OK; |
336 | } | ||
337 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
338 | "Found result for key %s\n", | ||
339 | GNUNET_h2s (key)); | ||
322 | if (NULL != get_ctx->iter) | 340 | if (NULL != get_ctx->iter) |
323 | ret = get_ctx->iter (get_ctx->iter_cls, | 341 | ret = get_ctx->iter (get_ctx->iter_cls, |
324 | key, | 342 | key, |
@@ -409,13 +427,16 @@ struct GetClosestContext | |||
409 | { | 427 | { |
410 | struct Value **values; | 428 | struct Value **values; |
411 | 429 | ||
430 | const struct GNUNET_HashCode *key; | ||
431 | |||
432 | enum GNUNET_BLOCK_Type type; | ||
433 | |||
412 | unsigned int num_results; | 434 | unsigned int num_results; |
413 | 435 | ||
414 | const struct GNUNET_HashCode *key; | ||
415 | }; | 436 | }; |
416 | 437 | ||
417 | 438 | ||
418 | static int | 439 | static enum GNUNET_GenericReturnValue |
419 | find_closest (void *cls, | 440 | find_closest (void *cls, |
420 | const struct GNUNET_HashCode *key, | 441 | const struct GNUNET_HashCode *key, |
421 | void *value) | 442 | void *value) |
@@ -427,6 +448,9 @@ find_closest (void *cls, | |||
427 | if (1 != GNUNET_CRYPTO_hash_cmp (key, | 448 | if (1 != GNUNET_CRYPTO_hash_cmp (key, |
428 | gcc->key)) | 449 | gcc->key)) |
429 | return GNUNET_OK; /* useless */ | 450 | return GNUNET_OK; /* useless */ |
451 | if ( (val->type != gcc->type) && | ||
452 | (GNUNET_BLOCK_TYPE_ANY != gcc->type) ) | ||
453 | return GNUNET_OK; /* useless */ | ||
430 | j = gcc->num_results; | 454 | j = gcc->num_results; |
431 | for (unsigned int i = 0; i < gcc->num_results; i++) | 455 | for (unsigned int i = 0; i < gcc->num_results; i++) |
432 | { | 456 | { |
@@ -435,8 +459,9 @@ find_closest (void *cls, | |||
435 | j = i; | 459 | j = i; |
436 | break; | 460 | break; |
437 | } | 461 | } |
438 | if (1 == GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key, | 462 | if (1 == |
439 | key)) | 463 | GNUNET_CRYPTO_hash_cmp (&gcc->values[i]->key, |
464 | key)) | ||
440 | { | 465 | { |
441 | j = i; | 466 | j = i; |
442 | break; | 467 | break; |
@@ -457,6 +482,7 @@ find_closest (void *cls, | |||
457 | * | 482 | * |
458 | * @param cls closure (internal context for the plugin) | 483 | * @param cls closure (internal context for the plugin) |
459 | * @param key area of the keyspace to look into | 484 | * @param key area of the keyspace to look into |
485 | * @param type desired block type for the replies | ||
460 | * @param num_results number of results that should be returned to @a iter | 486 | * @param num_results number of results that should be returned to @a iter |
461 | * @param iter maybe NULL (to just count) | 487 | * @param iter maybe NULL (to just count) |
462 | * @param iter_cls closure for @a iter | 488 | * @param iter_cls closure for @a iter |
@@ -465,6 +491,7 @@ find_closest (void *cls, | |||
465 | static unsigned int | 491 | static unsigned int |
466 | heap_plugin_get_closest (void *cls, | 492 | heap_plugin_get_closest (void *cls, |
467 | const struct GNUNET_HashCode *key, | 493 | const struct GNUNET_HashCode *key, |
494 | enum GNUNET_BLOCK_Type type, | ||
468 | unsigned int num_results, | 495 | unsigned int num_results, |
469 | GNUNET_DATACACHE_Iterator iter, | 496 | GNUNET_DATACACHE_Iterator iter, |
470 | void *iter_cls) | 497 | void *iter_cls) |
@@ -473,14 +500,15 @@ heap_plugin_get_closest (void *cls, | |||
473 | struct Value *values[num_results]; | 500 | struct Value *values[num_results]; |
474 | struct GetClosestContext gcc = { | 501 | struct GetClosestContext gcc = { |
475 | .values = values, | 502 | .values = values, |
476 | .num_results = num_results, | 503 | .type = type, |
504 | .num_results = num_results * 2, | ||
477 | .key = key | 505 | .key = key |
478 | }; | 506 | }; |
479 | 507 | ||
480 | GNUNET_CONTAINER_multihashmap_iterate (plugin->map, | 508 | GNUNET_CONTAINER_multihashmap_iterate (plugin->map, |
481 | &find_closest, | 509 | &find_closest, |
482 | &gcc); | 510 | &gcc); |
483 | for (unsigned int i = 0; i < num_results; i++) | 511 | for (unsigned int i = 0; i < num_results * 2; i++) |
484 | { | 512 | { |
485 | if (NULL == values[i]) | 513 | if (NULL == values[i]) |
486 | return i; | 514 | return i; |
@@ -493,7 +521,7 @@ heap_plugin_get_closest (void *cls, | |||
493 | values[i]->path_info_len, | 521 | values[i]->path_info_len, |
494 | values[i]->path_info); | 522 | values[i]->path_info); |
495 | } | 523 | } |
496 | return num_results; | 524 | return num_results * 2; |
497 | } | 525 | } |
498 | 526 | ||
499 | 527 | ||
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 6a44c44a5..1a83cda86 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c | |||
@@ -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, 2010, 2012, 2015, 2017, 2018 GNUnet e.V. | 3 | Copyright (C) 2006, 2009, 2010, 2012, 2015, 2017, 2018, 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 |
@@ -109,9 +109,20 @@ init_connection (struct Plugin *plugin) | |||
109 | " ORDER BY prox ASC, discard_time ASC LIMIT 1", | 109 | " ORDER BY prox ASC, discard_time ASC LIMIT 1", |
110 | 0), | 110 | 0), |
111 | GNUNET_PQ_make_prepare ("get_closest", | 111 | GNUNET_PQ_make_prepare ("get_closest", |
112 | "SELECT discard_time,type,value,path,key FROM gn011dc " | 112 | "(SELECT discard_time,type,value,path,key FROM gn011dc" |
113 | "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", | 113 | " WHERE key >= $1" |
114 | 3), | 114 | " AND discard_time >= $2" |
115 | " AND ( (type = $3) OR ( 0 = $3) )" | ||
116 | " ORDER BY key ASC" | ||
117 | " LIMIT $4)" | ||
118 | " UNION " | ||
119 | "(SELECT discard_time,type,value,path,key FROM gn011dc" | ||
120 | " WHERE key <= $1" | ||
121 | " AND discard_time >= $2" | ||
122 | " AND ( (type = $3) OR ( 0 = $3) )" | ||
123 | " ORDER BY key DESC" | ||
124 | " LIMIT $4)", | ||
125 | 4), | ||
115 | GNUNET_PQ_make_prepare ("delrow", | 126 | GNUNET_PQ_make_prepare ("delrow", |
116 | "DELETE FROM gn011dc WHERE oid=$1", | 127 | "DELETE FROM gn011dc WHERE oid=$1", |
117 | 1), | 128 | 1), |
@@ -511,6 +522,7 @@ extract_result_cb (void *cls, | |||
511 | * | 522 | * |
512 | * @param cls closure (internal context for the plugin) | 523 | * @param cls closure (internal context for the plugin) |
513 | * @param key area of the keyspace to look into | 524 | * @param key area of the keyspace to look into |
525 | * @param type desired block type for the replies | ||
514 | * @param num_results number of results that should be returned to @a iter | 526 | * @param num_results number of results that should be returned to @a iter |
515 | * @param iter maybe NULL (to just count) | 527 | * @param iter maybe NULL (to just count) |
516 | * @param iter_cls closure for @a iter | 528 | * @param iter_cls closure for @a iter |
@@ -519,16 +531,19 @@ extract_result_cb (void *cls, | |||
519 | static unsigned int | 531 | static unsigned int |
520 | postgres_plugin_get_closest (void *cls, | 532 | postgres_plugin_get_closest (void *cls, |
521 | const struct GNUNET_HashCode *key, | 533 | const struct GNUNET_HashCode *key, |
534 | enum GNUNET_BLOCK_Type type, | ||
522 | unsigned int num_results, | 535 | unsigned int num_results, |
523 | GNUNET_DATACACHE_Iterator iter, | 536 | GNUNET_DATACACHE_Iterator iter, |
524 | void *iter_cls) | 537 | void *iter_cls) |
525 | { | 538 | { |
526 | struct Plugin *plugin = cls; | 539 | struct Plugin *plugin = cls; |
527 | uint32_t num_results32 = (uint32_t) num_results; | 540 | uint32_t num_results32 = (uint32_t) num_results; |
541 | uint32_t type32 = (uint32_t) type; | ||
528 | struct GNUNET_TIME_Absolute now; | 542 | struct GNUNET_TIME_Absolute now; |
529 | struct GNUNET_PQ_QueryParam params[] = { | 543 | struct GNUNET_PQ_QueryParam params[] = { |
530 | GNUNET_PQ_query_param_auto_from_type (key), | 544 | GNUNET_PQ_query_param_auto_from_type (key), |
531 | GNUNET_PQ_query_param_absolute_time (&now), | 545 | GNUNET_PQ_query_param_absolute_time (&now), |
546 | GNUNET_PQ_query_param_uint32 (&type32), | ||
532 | GNUNET_PQ_query_param_uint32 (&num_results32), | 547 | GNUNET_PQ_query_param_uint32 (&num_results32), |
533 | GNUNET_PQ_query_param_end | 548 | GNUNET_PQ_query_param_end |
534 | }; | 549 | }; |
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c index d08b32caf..6f2165433 100644 --- a/src/datacache/plugin_datacache_sqlite.c +++ b/src/datacache/plugin_datacache_sqlite.c | |||
@@ -454,6 +454,7 @@ sqlite_plugin_del (void *cls) | |||
454 | * | 454 | * |
455 | * @param cls closure (internal context for the plugin) | 455 | * @param cls closure (internal context for the plugin) |
456 | * @param key area of the keyspace to look into | 456 | * @param key area of the keyspace to look into |
457 | * @param type desired block type for the replies | ||
457 | * @param num_results number of results that should be returned to @a iter | 458 | * @param num_results number of results that should be returned to @a iter |
458 | * @param iter maybe NULL (to just count) | 459 | * @param iter maybe NULL (to just count) |
459 | * @param iter_cls closure for @a iter | 460 | * @param iter_cls closure for @a iter |
@@ -462,11 +463,13 @@ sqlite_plugin_del (void *cls) | |||
462 | static unsigned int | 463 | static unsigned int |
463 | sqlite_plugin_get_closest (void *cls, | 464 | sqlite_plugin_get_closest (void *cls, |
464 | const struct GNUNET_HashCode *key, | 465 | const struct GNUNET_HashCode *key, |
466 | enum GNUNET_BLOCK_Type type, | ||
465 | unsigned int num_results, | 467 | unsigned int num_results, |
466 | GNUNET_DATACACHE_Iterator iter, | 468 | GNUNET_DATACACHE_Iterator iter, |
467 | void *iter_cls) | 469 | void *iter_cls) |
468 | { | 470 | { |
469 | struct Plugin *plugin = cls; | 471 | struct Plugin *plugin = cls; |
472 | uint32_t type32 = type; | ||
470 | uint32_t num_results32 = num_results; | 473 | uint32_t num_results32 = num_results; |
471 | struct GNUNET_TIME_Absolute now; | 474 | struct GNUNET_TIME_Absolute now; |
472 | struct GNUNET_TIME_Absolute exp; | 475 | struct GNUNET_TIME_Absolute exp; |
@@ -474,38 +477,46 @@ sqlite_plugin_get_closest (void *cls, | |||
474 | void *dat; | 477 | void *dat; |
475 | unsigned int cnt; | 478 | unsigned int cnt; |
476 | size_t psize; | 479 | size_t psize; |
477 | uint32_t type; | 480 | uint32_t rtype; |
478 | struct GNUNET_HashCode hc; | 481 | struct GNUNET_HashCode hc; |
479 | struct GNUNET_DHT_PathElement *path; | 482 | struct GNUNET_DHT_PathElement *path; |
480 | struct GNUNET_SQ_QueryParam params[] = | 483 | struct GNUNET_SQ_QueryParam params[] = { |
481 | { GNUNET_SQ_query_param_auto_from_type (key), | 484 | GNUNET_SQ_query_param_auto_from_type (key), |
482 | GNUNET_SQ_query_param_absolute_time (&now), | 485 | GNUNET_SQ_query_param_absolute_time (&now), |
486 | GNUNET_SQ_query_param_uint32 (&type32), | ||
483 | GNUNET_SQ_query_param_uint32 (&num_results32), | 487 | GNUNET_SQ_query_param_uint32 (&num_results32), |
484 | GNUNET_SQ_query_param_end }; | 488 | GNUNET_SQ_query_param_end |
485 | struct GNUNET_SQ_ResultSpec rs[] = | 489 | }; |
486 | { GNUNET_SQ_result_spec_variable_size (&dat, &size), | 490 | struct GNUNET_SQ_ResultSpec rs[] = { |
491 | GNUNET_SQ_result_spec_variable_size (&dat, &size), | ||
487 | GNUNET_SQ_result_spec_absolute_time (&exp), | 492 | GNUNET_SQ_result_spec_absolute_time (&exp), |
488 | GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), | 493 | GNUNET_SQ_result_spec_variable_size ((void **) &path, &psize), |
489 | GNUNET_SQ_result_spec_uint32 (&type), | 494 | GNUNET_SQ_result_spec_uint32 (&rtype), |
490 | GNUNET_SQ_result_spec_auto_from_type (&hc), | 495 | GNUNET_SQ_result_spec_auto_from_type (&hc), |
491 | GNUNET_SQ_result_spec_end }; | 496 | GNUNET_SQ_result_spec_end |
497 | }; | ||
492 | 498 | ||
493 | now = GNUNET_TIME_absolute_get (); | 499 | now = GNUNET_TIME_absolute_get (); |
494 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 500 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
495 | "Processing GET_CLOSEST for key `%s'\n", | 501 | "Processing GET_CLOSEST for key `%s'\n", |
496 | GNUNET_h2s (key)); | 502 | GNUNET_h2s (key)); |
497 | if (GNUNET_OK != GNUNET_SQ_bind (plugin->get_closest_stmt, params)) | 503 | if (GNUNET_OK != |
504 | GNUNET_SQ_bind (plugin->get_closest_stmt, | ||
505 | params)) | ||
498 | { | 506 | { |
499 | LOG_SQLITE (plugin->dbh, | 507 | LOG_SQLITE (plugin->dbh, |
500 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 508 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
501 | "sqlite3_bind_xxx"); | 509 | "sqlite3_bind_xxx"); |
502 | GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt); | 510 | GNUNET_SQ_reset (plugin->dbh, |
511 | plugin->get_closest_stmt); | ||
503 | return 0; | 512 | return 0; |
504 | } | 513 | } |
505 | cnt = 0; | 514 | cnt = 0; |
506 | while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt)) | 515 | while (SQLITE_ROW == sqlite3_step (plugin->get_closest_stmt)) |
507 | { | 516 | { |
508 | if (GNUNET_OK != GNUNET_SQ_extract_result (plugin->get_closest_stmt, rs)) | 517 | if (GNUNET_OK != |
518 | GNUNET_SQ_extract_result (plugin->get_closest_stmt, | ||
519 | rs)) | ||
509 | { | 520 | { |
510 | GNUNET_break (0); | 521 | GNUNET_break (0); |
511 | break; | 522 | break; |
@@ -522,14 +533,22 @@ sqlite_plugin_get_closest (void *cls, | |||
522 | "Found %u-byte result at %s when processing GET_CLOSE\n", | 533 | "Found %u-byte result at %s when processing GET_CLOSE\n", |
523 | (unsigned int) size, | 534 | (unsigned int) size, |
524 | GNUNET_h2s (&hc)); | 535 | GNUNET_h2s (&hc)); |
525 | if (GNUNET_OK != iter (iter_cls, &hc, size, dat, type, exp, psize, path)) | 536 | if (GNUNET_OK != iter (iter_cls, |
537 | &hc, | ||
538 | size, | ||
539 | dat, | ||
540 | rtype, | ||
541 | exp, | ||
542 | psize, | ||
543 | path)) | ||
526 | { | 544 | { |
527 | GNUNET_SQ_cleanup_result (rs); | 545 | GNUNET_SQ_cleanup_result (rs); |
528 | break; | 546 | break; |
529 | } | 547 | } |
530 | GNUNET_SQ_cleanup_result (rs); | 548 | GNUNET_SQ_cleanup_result (rs); |
531 | } | 549 | } |
532 | GNUNET_SQ_reset (plugin->dbh, plugin->get_closest_stmt); | 550 | GNUNET_SQ_reset (plugin->dbh, |
551 | plugin->get_closest_stmt); | ||
533 | return cnt; | 552 | return cnt; |
534 | } | 553 | } |
535 | 554 | ||
@@ -620,7 +639,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls) | |||
620 | &plugin->get_stmt)) || | 639 | &plugin->get_stmt)) || |
621 | (SQLITE_OK != sq_prepare (plugin->dbh, | 640 | (SQLITE_OK != sq_prepare (plugin->dbh, |
622 | "SELECT _ROWID_,key,value FROM ds091" | 641 | "SELECT _ROWID_,key,value FROM ds091" |
623 | " WHERE expire < ?" | 642 | " WHERE expire < ?1" |
624 | " ORDER BY expire ASC LIMIT 1", | 643 | " ORDER BY expire ASC LIMIT 1", |
625 | &plugin->del_expired_stmt)) || | 644 | &plugin->del_expired_stmt)) || |
626 | (SQLITE_OK != sq_prepare (plugin->dbh, | 645 | (SQLITE_OK != sq_prepare (plugin->dbh, |
@@ -632,8 +651,19 @@ libgnunet_plugin_datacache_sqlite_init (void *cls) | |||
632 | &plugin->del_stmt)) || | 651 | &plugin->del_stmt)) || |
633 | (SQLITE_OK != | 652 | (SQLITE_OK != |
634 | sq_prepare (plugin->dbh, | 653 | sq_prepare (plugin->dbh, |
635 | "SELECT value,expire,path,type,key FROM ds091 " | 654 | "SELECT * FROM (" |
636 | "WHERE key>=? AND expire >= ? ORDER BY KEY ASC LIMIT ?", | 655 | " SELECT value,expire,path,type,key FROM ds091 " |
656 | " WHERE key>=?1 " | ||
657 | " AND expire >= ?2" | ||
658 | " AND ( (type=?3) or (0 == ?3) )" | ||
659 | " ORDER BY KEY ASC LIMIT ?4)" | ||
660 | "UNION " | ||
661 | "SELECT * FROM (" | ||
662 | " SELECT value,expire,path,type,key FROM ds091 " | ||
663 | " WHERE key<=?1 " | ||
664 | " AND expire >= ?2" | ||
665 | " AND ( (type=?3) or (0 == ?3) )" | ||
666 | " ORDER BY KEY DESC LIMIT ?4)", | ||
637 | &plugin->get_closest_stmt))) | 667 | &plugin->get_closest_stmt))) |
638 | { | 668 | { |
639 | LOG_SQLITE (plugin->dbh, | 669 | LOG_SQLITE (plugin->dbh, |
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c index 231413ce9..2f7b41dbe 100644 --- a/src/datacache/plugin_datacache_template.c +++ b/src/datacache/plugin_datacache_template.c | |||
@@ -116,6 +116,7 @@ template_plugin_del (void *cls) | |||
116 | * | 116 | * |
117 | * @param cls closure (internal context for the plugin) | 117 | * @param cls closure (internal context for the plugin) |
118 | * @param key area of the keyspace to look into | 118 | * @param key area of the keyspace to look into |
119 | * @param type desired block type for the replies | ||
119 | * @param num_results number of results that should be returned to @a iter | 120 | * @param num_results number of results that should be returned to @a iter |
120 | * @param iter maybe NULL (to just count) | 121 | * @param iter maybe NULL (to just count) |
121 | * @param iter_cls closure for @a iter | 122 | * @param iter_cls closure for @a iter |
@@ -124,6 +125,7 @@ template_plugin_del (void *cls) | |||
124 | static unsigned int | 125 | static unsigned int |
125 | template_plugin_get_closest (void *cls, | 126 | template_plugin_get_closest (void *cls, |
126 | const struct GNUNET_HashCode *key, | 127 | const struct GNUNET_HashCode *key, |
128 | enum GNUNET_BLOCK_Type type, | ||
127 | unsigned int num_results, | 129 | unsigned int num_results, |
128 | GNUNET_DATACACHE_Iterator iter, | 130 | GNUNET_DATACACHE_Iterator iter, |
129 | void *iter_cls) | 131 | void *iter_cls) |
diff --git a/src/dht/.gitignore b/src/dht/.gitignore index 25b1daf28..bd8af1217 100644 --- a/src/dht/.gitignore +++ b/src/dht/.gitignore | |||
@@ -10,3 +10,4 @@ test_dht_monitor | |||
10 | test_dht_multipeer | 10 | test_dht_multipeer |
11 | test_dht_tools.py | 11 | test_dht_tools.py |
12 | test_dht_twopeer | 12 | test_dht_twopeer |
13 | gnunet-dht-hello | ||
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index be48fab02..68a17723d 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -50,7 +50,8 @@ libexec_PROGRAMS = \ | |||
50 | bin_PROGRAMS = \ | 50 | bin_PROGRAMS = \ |
51 | gnunet-dht-monitor \ | 51 | gnunet-dht-monitor \ |
52 | gnunet-dht-get \ | 52 | gnunet-dht-get \ |
53 | gnunet-dht-put | 53 | gnunet-dht-put \ |
54 | gnunet-dht-hello | ||
54 | 55 | ||
55 | noinst_PROGRAMS = \ | 56 | noinst_PROGRAMS = \ |
56 | gnunet-dht-profiler | 57 | gnunet-dht-profiler |
@@ -58,8 +59,6 @@ noinst_PROGRAMS = \ | |||
58 | gnunet_service_dht_SOURCES = \ | 59 | gnunet_service_dht_SOURCES = \ |
59 | gnunet-service-dht.c gnunet-service-dht.h \ | 60 | gnunet-service-dht.c gnunet-service-dht.h \ |
60 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ | 61 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ |
61 | gnunet-service-dht_hello.c gnunet-service-dht_hello.h \ | ||
62 | gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ | ||
63 | gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \ | 62 | gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \ |
64 | gnunet-service-dht_routing.c gnunet-service-dht_routing.h | 63 | gnunet-service-dht_routing.c gnunet-service-dht_routing.h |
65 | gnunet_service_dht_LDADD = \ | 64 | gnunet_service_dht_LDADD = \ |
@@ -72,6 +71,7 @@ gnunet_service_dht_LDADD = \ | |||
72 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 71 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
73 | $(top_builddir)/src/hello/libgnunethello.la \ | 72 | $(top_builddir)/src/hello/libgnunethello.la \ |
74 | $(top_builddir)/src/block/libgnunetblock.la \ | 73 | $(top_builddir)/src/block/libgnunetblock.la \ |
74 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
75 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | 75 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ |
76 | $(top_builddir)/src/util/libgnunetutil.la \ | 76 | $(top_builddir)/src/util/libgnunetutil.la \ |
77 | -lm | 77 | -lm |
@@ -82,16 +82,22 @@ gnunet_dht_get_SOURCES = \ | |||
82 | gnunet-dht-get.c | 82 | gnunet-dht-get.c |
83 | gnunet_dht_get_LDADD = \ | 83 | gnunet_dht_get_LDADD = \ |
84 | libgnunetdht.la \ | 84 | libgnunetdht.la \ |
85 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
86 | $(top_builddir)/src/util/libgnunetutil.la | 85 | $(top_builddir)/src/util/libgnunetutil.la |
87 | gnunet_dht_get_LDFLAGS = \ | 86 | gnunet_dht_get_LDFLAGS = \ |
88 | $(GN_LIBINTL) | 87 | $(GN_LIBINTL) |
89 | 88 | ||
89 | gnunet_dht_hello_SOURCES = \ | ||
90 | gnunet-dht-hello.c | ||
91 | gnunet_dht_hello_LDADD = \ | ||
92 | libgnunetdht.la \ | ||
93 | $(top_builddir)/src/util/libgnunetutil.la | ||
94 | gnunet_dht_hello_LDFLAGS = \ | ||
95 | $(GN_LIBINTL) | ||
96 | |||
90 | gnunet_dht_put_SOURCES = \ | 97 | gnunet_dht_put_SOURCES = \ |
91 | gnunet-dht-put.c | 98 | gnunet-dht-put.c |
92 | gnunet_dht_put_LDADD = \ | 99 | gnunet_dht_put_LDADD = \ |
93 | libgnunetdht.la \ | 100 | libgnunetdht.la \ |
94 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
95 | $(top_builddir)/src/util/libgnunetutil.la | 101 | $(top_builddir)/src/util/libgnunetutil.la |
96 | gnunet_dht_put_LDFLAGS = \ | 102 | gnunet_dht_put_LDFLAGS = \ |
97 | $(GN_LIBINTL) | 103 | $(GN_LIBINTL) |
@@ -100,7 +106,6 @@ gnunet_dht_monitor_SOURCES = \ | |||
100 | gnunet-dht-monitor.c | 106 | gnunet-dht-monitor.c |
101 | gnunet_dht_monitor_LDADD = \ | 107 | gnunet_dht_monitor_LDADD = \ |
102 | libgnunetdht.la \ | 108 | libgnunetdht.la \ |
103 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
104 | $(top_builddir)/src/util/libgnunetutil.la | 109 | $(top_builddir)/src/util/libgnunetutil.la |
105 | gnunet_dht_monitor_LDFLAGS = \ | 110 | gnunet_dht_monitor_LDFLAGS = \ |
106 | $(GN_LIBINTL) | 111 | $(GN_LIBINTL) |
@@ -199,7 +204,6 @@ test_dht_monitor_LDADD = \ | |||
199 | libgnunetdht.la | 204 | libgnunetdht.la |
200 | 205 | ||
201 | EXTRA_DIST = \ | 206 | EXTRA_DIST = \ |
202 | $(check_SCRIPTS) \ | ||
203 | gnunet-service-dht_clients.c \ | 207 | gnunet-service-dht_clients.c \ |
204 | test_dht_api_data.conf \ | 208 | test_dht_api_data.conf \ |
205 | test_dht_api_peer1.conf \ | 209 | test_dht_api_peer1.conf \ |
@@ -209,7 +213,10 @@ EXTRA_DIST = \ | |||
209 | test_dht_line.conf \ | 213 | test_dht_line.conf \ |
210 | test_dht_tools.conf \ | 214 | test_dht_tools.conf \ |
211 | test_dht_tools.py.in \ | 215 | test_dht_tools.py.in \ |
212 | test_dht_multipeer_topology.dat | 216 | test_dht_multipeer_topology.dat \ |
217 | dhtu_testbed_connect.sh \ | ||
218 | dhtu_testbed_deploy.conf \ | ||
219 | dhtu_testbed_deploy.sh | ||
213 | 220 | ||
214 | if HAVE_PYTHON | 221 | if HAVE_PYTHON |
215 | check_SCRIPTS = \ | 222 | check_SCRIPTS = \ |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 8389bbb95..474198004 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.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, 2012, 2016, 2018 GNUnet e.V. | 3 | Copyright (C) 2009-2012, 2016, 2018, 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 |
@@ -197,6 +197,40 @@ struct GNUNET_DHT_MonitorHandle | |||
197 | 197 | ||
198 | 198 | ||
199 | /** | 199 | /** |
200 | * Handle to get a HELLO URL from the DHT for manual bootstrapping. | ||
201 | */ | ||
202 | struct GNUNET_DHT_HelloGetHandle | ||
203 | { | ||
204 | |||
205 | /** | ||
206 | * DLL. | ||
207 | */ | ||
208 | struct GNUNET_DHT_HelloGetHandle *next; | ||
209 | |||
210 | /** | ||
211 | * DLL. | ||
212 | */ | ||
213 | struct GNUNET_DHT_HelloGetHandle *prev; | ||
214 | |||
215 | /** | ||
216 | * Function to call with the result. | ||
217 | */ | ||
218 | GNUNET_DHT_HelloGetCallback cb; | ||
219 | |||
220 | /** | ||
221 | * Closure for @a cb. | ||
222 | */ | ||
223 | void *cb_cls; | ||
224 | |||
225 | /** | ||
226 | * Connection to the DHT service. | ||
227 | */ | ||
228 | struct GNUNET_DHT_Handle *dht_handle; | ||
229 | |||
230 | }; | ||
231 | |||
232 | |||
233 | /** | ||
200 | * Connection to the DHT service. | 234 | * Connection to the DHT service. |
201 | */ | 235 | */ |
202 | struct GNUNET_DHT_Handle | 236 | struct GNUNET_DHT_Handle |
@@ -232,6 +266,16 @@ struct GNUNET_DHT_Handle | |||
232 | struct GNUNET_DHT_PutHandle *put_tail; | 266 | struct GNUNET_DHT_PutHandle *put_tail; |
233 | 267 | ||
234 | /** | 268 | /** |
269 | * DLL. | ||
270 | */ | ||
271 | struct GNUNET_DHT_HelloGetHandle *hgh_head; | ||
272 | |||
273 | /** | ||
274 | * DLL. | ||
275 | */ | ||
276 | struct GNUNET_DHT_HelloGetHandle *hgh_tail; | ||
277 | |||
278 | /** | ||
235 | * Hash map containing the current outstanding unique GET requests | 279 | * Hash map containing the current outstanding unique GET requests |
236 | * (values are of type `struct GNUNET_DHT_GetHandle`). | 280 | * (values are of type `struct GNUNET_DHT_GetHandle`). |
237 | */ | 281 | */ |
@@ -517,9 +561,10 @@ handle_monitor_get (void *cls, | |||
517 | const struct GNUNET_DHT_MonitorGetMessage *msg) | 561 | const struct GNUNET_DHT_MonitorGetMessage *msg) |
518 | { | 562 | { |
519 | struct GNUNET_DHT_Handle *handle = cls; | 563 | struct GNUNET_DHT_Handle *handle = cls; |
520 | struct GNUNET_DHT_MonitorHandle *mh; | ||
521 | 564 | ||
522 | for (mh = handle->monitor_head; NULL != mh; mh = mh->next) | 565 | for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head; |
566 | NULL != mh; | ||
567 | mh = mh->next) | ||
523 | { | 568 | { |
524 | if (NULL == mh->get_cb) | 569 | if (NULL == mh->get_cb) |
525 | continue; | 570 | continue; |
@@ -582,10 +627,12 @@ handle_monitor_get_resp (void *cls, | |||
582 | const struct GNUNET_DHT_PathElement *path; | 627 | const struct GNUNET_DHT_PathElement *path; |
583 | uint32_t getl = ntohl (msg->get_path_length); | 628 | uint32_t getl = ntohl (msg->get_path_length); |
584 | uint32_t putl = ntohl (msg->put_path_length); | 629 | uint32_t putl = ntohl (msg->put_path_length); |
585 | struct GNUNET_DHT_MonitorHandle *mh; | 630 | |
586 | 631 | ||
587 | path = (const struct GNUNET_DHT_PathElement *) &msg[1]; | 632 | path = (const struct GNUNET_DHT_PathElement *) &msg[1]; |
588 | for (mh = handle->monitor_head; NULL != mh; mh = mh->next) | 633 | for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head; |
634 | NULL != mh; | ||
635 | mh = mh->next) | ||
589 | { | 636 | { |
590 | if (NULL == mh->get_resp_cb) | 637 | if (NULL == mh->get_resp_cb) |
591 | continue; | 638 | continue; |
@@ -597,9 +644,9 @@ handle_monitor_get_resp (void *cls, | |||
597 | sizeof(struct GNUNET_HashCode))))) | 644 | sizeof(struct GNUNET_HashCode))))) |
598 | mh->get_resp_cb (mh->cb_cls, | 645 | mh->get_resp_cb (mh->cb_cls, |
599 | (enum GNUNET_BLOCK_Type) ntohl (msg->type), | 646 | (enum GNUNET_BLOCK_Type) ntohl (msg->type), |
600 | path, | 647 | &path[putl], |
601 | getl, | 648 | getl, |
602 | &path[getl], | 649 | path, |
603 | putl, | 650 | putl, |
604 | GNUNET_TIME_absolute_ntoh (msg->expiration_time), | 651 | GNUNET_TIME_absolute_ntoh (msg->expiration_time), |
605 | &msg->key, | 652 | &msg->key, |
@@ -726,14 +773,21 @@ process_client_result (void *cls, | |||
726 | const struct GNUNET_DHT_ClientResultMessage *crm = cls; | 773 | const struct GNUNET_DHT_ClientResultMessage *crm = cls; |
727 | struct GNUNET_DHT_GetHandle *get_handle = value; | 774 | struct GNUNET_DHT_GetHandle *get_handle = value; |
728 | size_t msize = ntohs (crm->header.size) - sizeof(*crm); | 775 | size_t msize = ntohs (crm->header.size) - sizeof(*crm); |
776 | uint16_t type = ntohl (crm->type); | ||
729 | uint32_t put_path_length = ntohl (crm->put_path_length); | 777 | uint32_t put_path_length = ntohl (crm->put_path_length); |
730 | uint32_t get_path_length = ntohl (crm->get_path_length); | 778 | uint32_t get_path_length = ntohl (crm->get_path_length); |
731 | const struct GNUNET_DHT_PathElement *put_path; | 779 | const struct GNUNET_DHT_PathElement *put_path |
732 | const struct GNUNET_DHT_PathElement *get_path; | 780 | = (const struct GNUNET_DHT_PathElement *) &crm[1]; |
781 | const struct GNUNET_DHT_PathElement *get_path | ||
782 | = &put_path[put_path_length]; | ||
783 | const void *data | ||
784 | = &get_path[get_path_length]; | ||
785 | size_t meta_length | ||
786 | = sizeof(struct GNUNET_DHT_PathElement) * (get_path_length | ||
787 | + put_path_length); | ||
788 | size_t data_length | ||
789 | = msize - meta_length; | ||
733 | struct GNUNET_HashCode hc; | 790 | struct GNUNET_HashCode hc; |
734 | size_t data_length; | ||
735 | size_t meta_length; | ||
736 | const void *data; | ||
737 | 791 | ||
738 | if (crm->unique_id != get_handle->unique_id) | 792 | if (crm->unique_id != get_handle->unique_id) |
739 | { | 793 | { |
@@ -745,12 +799,14 @@ process_client_result (void *cls, | |||
745 | (unsigned long long) get_handle->unique_id); | 799 | (unsigned long long) get_handle->unique_id); |
746 | return GNUNET_YES; | 800 | return GNUNET_YES; |
747 | } | 801 | } |
748 | /* FIXME: might want to check that type matches */ | 802 | if ( (get_handle->type != GNUNET_BLOCK_TYPE_ANY) && |
749 | meta_length = | 803 | (get_handle->type != type) ) |
750 | sizeof(struct GNUNET_DHT_PathElement) * (get_path_length + put_path_length); | 804 | { |
751 | data_length = msize - meta_length; | 805 | /* type mismatch */ |
752 | put_path = (const struct GNUNET_DHT_PathElement *) &crm[1]; | 806 | GNUNET_break (0); |
753 | get_path = &put_path[put_path_length]; | 807 | return GNUNET_YES; |
808 | } | ||
809 | |||
754 | { | 810 | { |
755 | char *pp; | 811 | char *pp; |
756 | char *gp; | 812 | char *gp; |
@@ -768,7 +824,6 @@ process_client_result (void *cls, | |||
768 | GNUNET_free (gp); | 824 | GNUNET_free (gp); |
769 | GNUNET_free (pp); | 825 | GNUNET_free (pp); |
770 | } | 826 | } |
771 | data = &get_path[get_path_length]; | ||
772 | /* remember that we've seen this result */ | 827 | /* remember that we've seen this result */ |
773 | GNUNET_CRYPTO_hash (data, | 828 | GNUNET_CRYPTO_hash (data, |
774 | data_length, | 829 | data_length, |
@@ -786,7 +841,7 @@ process_client_result (void *cls, | |||
786 | get_path_length, | 841 | get_path_length, |
787 | put_path, | 842 | put_path, |
788 | put_path_length, | 843 | put_path_length, |
789 | ntohl (crm->type), | 844 | type, |
790 | data_length, | 845 | data_length, |
791 | data); | 846 | data); |
792 | return GNUNET_YES; | 847 | return GNUNET_YES; |
@@ -813,6 +868,53 @@ handle_client_result (void *cls, | |||
813 | 868 | ||
814 | 869 | ||
815 | /** | 870 | /** |
871 | * Process a client HELLO message received from the service. | ||
872 | * | ||
873 | * @param cls The DHT handle. | ||
874 | * @param hdr HELLO URL message from the service. | ||
875 | * @return #GNUNET_OK if @a hdr is well-formed | ||
876 | */ | ||
877 | static enum GNUNET_GenericReturnValue | ||
878 | check_client_hello (void *cls, | ||
879 | const struct GNUNET_MessageHeader *hdr) | ||
880 | { | ||
881 | uint16_t len = ntohs (hdr->size); | ||
882 | const char *buf = (const char *) &hdr[1]; | ||
883 | |||
884 | (void) cls; | ||
885 | if ('\0' != buf[len - sizeof (*hdr) - 1]) | ||
886 | { | ||
887 | GNUNET_break (0); | ||
888 | return GNUNET_SYSERR; | ||
889 | } | ||
890 | return GNUNET_OK; | ||
891 | } | ||
892 | |||
893 | |||
894 | /** | ||
895 | * Process a client HELLO message received from the service. | ||
896 | * | ||
897 | * @param cls The DHT handle. | ||
898 | * @param hdr HELLO URL message from the service. | ||
899 | */ | ||
900 | static void | ||
901 | handle_client_hello (void *cls, | ||
902 | const struct GNUNET_MessageHeader *hdr) | ||
903 | { | ||
904 | struct GNUNET_DHT_Handle *handle = cls; | ||
905 | const char *url = (const char *) &hdr[1]; | ||
906 | struct GNUNET_DHT_HelloGetHandle *hgh; | ||
907 | |||
908 | while (NULL != (hgh = handle->hgh_head)) | ||
909 | { | ||
910 | hgh->cb (hgh->cb_cls, | ||
911 | url); | ||
912 | GNUNET_DHT_hello_get_cancel (hgh); | ||
913 | } | ||
914 | } | ||
915 | |||
916 | |||
917 | /** | ||
816 | * Process a MQ PUT transmission notification. | 918 | * Process a MQ PUT transmission notification. |
817 | * | 919 | * |
818 | * @param cls The DHT handle. | 920 | * @param cls The DHT handle. |
@@ -859,6 +961,10 @@ try_connect (struct GNUNET_DHT_Handle *h) | |||
859 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT, | 961 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT, |
860 | struct GNUNET_DHT_ClientResultMessage, | 962 | struct GNUNET_DHT_ClientResultMessage, |
861 | h), | 963 | h), |
964 | GNUNET_MQ_hd_var_size (client_hello, | ||
965 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL, | ||
966 | struct GNUNET_MessageHeader, | ||
967 | h), | ||
862 | GNUNET_MQ_handler_end () | 968 | GNUNET_MQ_handler_end () |
863 | }; | 969 | }; |
864 | 970 | ||
@@ -1194,8 +1300,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, | |||
1194 | 1300 | ||
1195 | 1301 | ||
1196 | unsigned int | 1302 | unsigned int |
1197 | GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, | 1303 | GNUNET_DHT_verify_path (const void *data, |
1198 | const void *data, | ||
1199 | size_t data_size, | 1304 | size_t data_size, |
1200 | struct GNUNET_TIME_Absolute exp_time, | 1305 | struct GNUNET_TIME_Absolute exp_time, |
1201 | const struct GNUNET_DHT_PathElement *put_path, | 1306 | const struct GNUNET_DHT_PathElement *put_path, |
@@ -1207,47 +1312,125 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, | |||
1207 | struct GNUNET_DHT_HopSignature hs = { | 1312 | struct GNUNET_DHT_HopSignature hs = { |
1208 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), | 1313 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), |
1209 | .purpose.size = htonl (sizeof (hs)), | 1314 | .purpose.size = htonl (sizeof (hs)), |
1210 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), | 1315 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time) |
1211 | .key = *key, | ||
1212 | }; | 1316 | }; |
1317 | const struct GNUNET_PeerIdentity *pred; | ||
1318 | const struct GNUNET_PeerIdentity *succ; | ||
1213 | unsigned int i; | 1319 | unsigned int i; |
1214 | 1320 | ||
1215 | if (0 == get_path_len + put_path_len) | 1321 | if (0 == get_path_len + put_path_len) |
1216 | return 0; | 1322 | return 0; |
1217 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1323 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1218 | "Verifying signatures with GPL: %u PPL: %u!\n", | 1324 | "%s is verifying signatures with GPL: %u PPL: %u!\n", |
1325 | GNUNET_i2s (me), | ||
1219 | get_path_len, | 1326 | get_path_len, |
1220 | put_path_len); | 1327 | put_path_len); |
1328 | for (unsigned int j = 0; j<put_path_len; j++) | ||
1329 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1330 | "PP%u=%s\n", | ||
1331 | j, | ||
1332 | GNUNET_i2s (&put_path[j].pred)); | ||
1333 | for (unsigned int j = 0; j<get_path_len; j++) | ||
1334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1335 | "GP%u=%s\n", | ||
1336 | j, | ||
1337 | GNUNET_i2s (&get_path[j].pred)); | ||
1338 | |||
1221 | i = put_path_len + get_path_len - 1; | 1339 | i = put_path_len + get_path_len - 1; |
1222 | GNUNET_CRYPTO_hash (data, | 1340 | GNUNET_CRYPTO_hash (data, |
1223 | data_size, | 1341 | data_size, |
1224 | &hs.h_data); | 1342 | &hs.h_data); |
1225 | while (i > 0) | 1343 | while (i > 0) |
1226 | { | 1344 | { |
1227 | hs.pred = (i - 1 >= put_path_len) | 1345 | pred = (i - 1 >= put_path_len) |
1228 | ? get_path[i - put_path_len - 1].pred | 1346 | ? &get_path[i - put_path_len - 1].pred |
1229 | : put_path[i - 1].pred; | 1347 | : &put_path[i - 1].pred; |
1230 | if (i + 1 == get_path_len + put_path_len) | 1348 | if (i + 1 == get_path_len + put_path_len) |
1231 | hs.succ = *me; | 1349 | succ = me; |
1232 | else | 1350 | else |
1233 | hs.succ = (i + 1 >= put_path_len) | 1351 | succ = (i + 1 >= put_path_len) |
1234 | ? get_path[i + 1 - put_path_len].pred | 1352 | ? &get_path[i + 1 - put_path_len].pred |
1235 | : put_path[i + 1].pred; | 1353 | : &put_path[i + 1].pred; |
1354 | hs.pred = *pred; | ||
1355 | hs.succ = *succ; | ||
1236 | if (GNUNET_OK != | 1356 | if (GNUNET_OK != |
1237 | GNUNET_CRYPTO_eddsa_verify ( | 1357 | GNUNET_CRYPTO_eddsa_verify ( |
1238 | GNUNET_SIGNATURE_PURPOSE_DHT_HOP, | 1358 | GNUNET_SIGNATURE_PURPOSE_DHT_HOP, |
1239 | &hs, | 1359 | &hs, |
1240 | (i - 1 >= put_path_len) | 1360 | (i - 1 >= put_path_len) |
1241 | ? &get_path[i - put_path_len - 1].sig | 1361 | ? &get_path[i - put_path_len - 1].sig |
1242 | : &put_path[i - 1].sig, | 1362 | : &put_path[i - 1].sig, |
1243 | (i >= put_path_len) | 1363 | (i >= put_path_len) |
1244 | ? &get_path[i - put_path_len].pred.public_key | 1364 | ? &get_path[i - put_path_len].pred.public_key |
1245 | : &put_path[i].pred.public_key)) | 1365 | : &put_path[i].pred.public_key)) |
1366 | { | ||
1367 | GNUNET_break_op (0); | ||
1246 | return i; | 1368 | return i; |
1369 | } | ||
1247 | i--; | 1370 | i--; |
1248 | } | 1371 | } |
1249 | return i; | 1372 | return i; |
1250 | } | 1373 | } |
1251 | 1374 | ||
1252 | 1375 | ||
1376 | struct GNUNET_DHT_HelloGetHandle * | ||
1377 | GNUNET_DHT_hello_get (struct GNUNET_DHT_Handle *dht_handle, | ||
1378 | GNUNET_DHT_HelloGetCallback cb, | ||
1379 | void *cb_cls) | ||
1380 | { | ||
1381 | struct GNUNET_DHT_HelloGetHandle *hgh; | ||
1382 | struct GNUNET_MessageHeader *hdr; | ||
1383 | struct GNUNET_MQ_Envelope *env; | ||
1384 | |||
1385 | hgh = GNUNET_new (struct GNUNET_DHT_HelloGetHandle); | ||
1386 | hgh->cb = cb; | ||
1387 | hgh->cb_cls = cb_cls; | ||
1388 | hgh->dht_handle = dht_handle; | ||
1389 | GNUNET_CONTAINER_DLL_insert (dht_handle->hgh_head, | ||
1390 | dht_handle->hgh_tail, | ||
1391 | hgh); | ||
1392 | env = GNUNET_MQ_msg (hdr, | ||
1393 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET); | ||
1394 | GNUNET_MQ_send (dht_handle->mq, | ||
1395 | env); | ||
1396 | return hgh; | ||
1397 | } | ||
1398 | |||
1399 | |||
1400 | void | ||
1401 | GNUNET_DHT_hello_get_cancel (struct GNUNET_DHT_HelloGetHandle *hgh) | ||
1402 | { | ||
1403 | struct GNUNET_DHT_Handle *dht_handle = hgh->dht_handle; | ||
1404 | |||
1405 | GNUNET_CONTAINER_DLL_remove (dht_handle->hgh_head, | ||
1406 | dht_handle->hgh_tail, | ||
1407 | hgh); | ||
1408 | GNUNET_free (hgh); | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | void | ||
1413 | GNUNET_DHT_hello_offer (struct GNUNET_DHT_Handle *dht_handle, | ||
1414 | const char *url, | ||
1415 | GNUNET_SCHEDULER_TaskCallback cb, | ||
1416 | void *cb_cls) | ||
1417 | { | ||
1418 | struct GNUNET_MessageHeader *hdr; | ||
1419 | size_t slen = strlen (url) + 1; | ||
1420 | struct GNUNET_MQ_Envelope *env; | ||
1421 | |||
1422 | env = GNUNET_MQ_msg_extra (hdr, | ||
1423 | slen, | ||
1424 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL); | ||
1425 | memcpy (&hdr[1], | ||
1426 | url, | ||
1427 | slen); | ||
1428 | GNUNET_MQ_notify_sent (env, | ||
1429 | cb, | ||
1430 | cb_cls); | ||
1431 | GNUNET_MQ_send (dht_handle->mq, | ||
1432 | env); | ||
1433 | } | ||
1434 | |||
1435 | |||
1253 | /* end of dht_api.c */ | 1436 | /* end of dht_api.c */ |
diff --git a/src/dht/dhtu_testbed_connect.sh b/src/dht/dhtu_testbed_connect.sh new file mode 100755 index 000000000..871e9eb1b --- /dev/null +++ b/src/dht/dhtu_testbed_connect.sh | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/bin/bash | ||
2 | # This file is in the public domain. | ||
3 | |||
4 | # Helper script for dhtu_testbed_deploy.sh. | ||
5 | # Do not invoke directly. | ||
6 | |||
7 | n=$1 | ||
8 | CFG="/tmp/deployment/${n}.conf" | ||
9 | HELLO=`gnunet-dht-hello -c $CFG` | ||
10 | |||
11 | # Create dense topology: | ||
12 | #for OFF in `seq 1 $MAX` | ||
13 | #do | ||
14 | # TCFG="/tmp/deployment/${OFF}.conf" | ||
15 | # gnunet-dht-hello -c $TCFG $HELLO | ||
16 | #done | ||
17 | #exit 0 | ||
18 | |||
19 | # Create sparse topology: | ||
20 | R=1 | ||
21 | while test `expr $R \* $R \* $R` -lt $MAX | ||
22 | do | ||
23 | END=`expr $R \* $R` | ||
24 | for M in `seq $R $R $END` | ||
25 | do | ||
26 | OFF=`expr \( $n + $M \) % $MAX` | ||
27 | TCFG="/tmp/deployment/${OFF}.conf" | ||
28 | gnunet-dht-hello -c $TCFG $HELLO | ||
29 | done | ||
30 | R=`expr $R + 1` | ||
31 | done | ||
diff --git a/src/dht/dhtu_testbed_deploy.conf b/src/dht/dhtu_testbed_deploy.conf new file mode 100644 index 000000000..59d69894a --- /dev/null +++ b/src/dht/dhtu_testbed_deploy.conf | |||
@@ -0,0 +1,26 @@ | |||
1 | # This file is in the public domain. | ||
2 | |||
3 | # Simple configuration template to deploy a DHT testbed | ||
4 | # with peers using the IP underlay. | ||
5 | |||
6 | [paths] | ||
7 | GNUNET_DATA_HOME=/tmp/%N% | ||
8 | |||
9 | [dht] | ||
10 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-dht-%N%.sock | ||
11 | |||
12 | [dhtu-ip] | ||
13 | ENABLED = YES | ||
14 | NSE = 10 | ||
15 | UDP_PORT = %N% | ||
16 | |||
17 | [dhtu-gnunet] | ||
18 | ENABLED = NO | ||
19 | |||
20 | [statistics] | ||
21 | DISABLE = YES | ||
22 | |||
23 | [dhtcache] | ||
24 | DATABASE = heap | ||
25 | QUOTA = 50 MB | ||
26 | DISABLE_BF_RC = YES | ||
diff --git a/src/dht/dhtu_testbed_deploy.sh b/src/dht/dhtu_testbed_deploy.sh new file mode 100755 index 000000000..908bbf685 --- /dev/null +++ b/src/dht/dhtu_testbed_deploy.sh | |||
@@ -0,0 +1,84 @@ | |||
1 | #!/bin/bash | ||
2 | # This file is in the public domain. | ||
3 | |||
4 | # We will use UDP ports above this number. | ||
5 | MINPORT=10000 | ||
6 | |||
7 | # Cleanup to run whenever we exit | ||
8 | function cleanup() | ||
9 | { | ||
10 | for n in `jobs -p` | ||
11 | do | ||
12 | kill $n 2> /dev/null || true | ||
13 | done | ||
14 | wait | ||
15 | } | ||
16 | |||
17 | # Install cleanup handler (except for kill -9) | ||
18 | trap cleanup EXIT | ||
19 | |||
20 | if test -z "$1" | ||
21 | then | ||
22 | echo "Call with the number of peers to launch." | ||
23 | exit 1 | ||
24 | fi | ||
25 | |||
26 | if test ! -x `which parallel` | ||
27 | then | ||
28 | echo "This script requires GNU parallel" | ||
29 | exit 1 | ||
30 | fi | ||
31 | |||
32 | if test ! -x `which gnunet-service-dht` | ||
33 | then | ||
34 | echo "This script requires gnunet-service-dht in \$PATH" | ||
35 | exit 1 | ||
36 | fi | ||
37 | |||
38 | if test ! -x `which gnunet-dht-hello` | ||
39 | then | ||
40 | echo "This script requires gnunet-dht-hello in \$PATH" | ||
41 | exit 1 | ||
42 | fi | ||
43 | |||
44 | MAX=`expr $1 - 1` | ||
45 | |||
46 | # export GNUNET_FORCE_LOG="dht*;;;;DEBUG" | ||
47 | |||
48 | echo -n "Starting $1 peers " | ||
49 | mkdir -p /tmp/deployment | ||
50 | for n in `seq 0 $MAX` | ||
51 | do | ||
52 | PORT=`expr $MINPORT + $n` | ||
53 | CFG="/tmp/deployment/${n}.conf" | ||
54 | cat dhtu_testbed_deploy.conf | sed -e "s/%N%/$PORT/" > $CFG | ||
55 | gnunet-service-dht -c $CFG &> /tmp/deployment/$n.log & | ||
56 | echo -n "." | ||
57 | done | ||
58 | |||
59 | echo "" | ||
60 | echo "$1 peers ready". | ||
61 | |||
62 | unset GNUNET_FORCE_LOG | ||
63 | |||
64 | function connect() | ||
65 | { | ||
66 | n=$1 | ||
67 | } | ||
68 | |||
69 | echo -n "Connecting peers ..." | ||
70 | |||
71 | export MAX | ||
72 | if test 0 != $MAX | ||
73 | then | ||
74 | seq 0 $MAX | parallel ./dhtu_testbed_connect.sh ::: | ||
75 | fi | ||
76 | |||
77 | |||
78 | echo "" | ||
79 | echo "Network ready. Press ENTER to terminate the testbed!" | ||
80 | echo "Interact with peers using '-c /tmp/deployment/\$N.conf'" | ||
81 | |||
82 | read | ||
83 | |||
84 | exit 0 | ||
diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c index f1076490b..42ffe75ba 100644 --- a/src/dht/gnunet-dht-get.c +++ b/src/dht/gnunet-dht-get.c | |||
@@ -58,6 +58,11 @@ static unsigned int verbose; | |||
58 | static int demultixplex_everywhere; | 58 | static int demultixplex_everywhere; |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Use #GNUNET_DHT_RO_RECORD_ROUTE. | ||
62 | */ | ||
63 | static int record_route; | ||
64 | |||
65 | /** | ||
61 | * Handle to the DHT | 66 | * Handle to the DHT |
62 | */ | 67 | */ |
63 | static struct GNUNET_DHT_Handle *dht_handle; | 68 | static struct GNUNET_DHT_Handle *dht_handle; |
@@ -160,9 +165,9 @@ get_result_iterator (void *cls, | |||
160 | : _ ("Result %d, type %d:\n"), | 165 | : _ ("Result %d, type %d:\n"), |
161 | result_count, | 166 | result_count, |
162 | type, | 167 | type, |
163 | (unsigned int) size, | 168 | (int) size, |
164 | (char *) data); | 169 | (char *) data); |
165 | if (verbose) | 170 | if (record_route && verbose) |
166 | { | 171 | { |
167 | fprintf (stdout, | 172 | fprintf (stdout, |
168 | " GET path: "); | 173 | " GET path: "); |
@@ -200,6 +205,7 @@ run (void *cls, | |||
200 | const struct GNUNET_CONFIGURATION_Handle *c) | 205 | const struct GNUNET_CONFIGURATION_Handle *c) |
201 | { | 206 | { |
202 | struct GNUNET_HashCode key; | 207 | struct GNUNET_HashCode key; |
208 | enum GNUNET_DHT_RouteOption ro; | ||
203 | 209 | ||
204 | cfg = c; | 210 | cfg = c; |
205 | if (NULL == query_key) | 211 | if (NULL == query_key) |
@@ -228,13 +234,16 @@ run (void *cls, | |||
228 | GNUNET_h2s_full (&key)); | 234 | GNUNET_h2s_full (&key)); |
229 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL); | 235 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL); |
230 | tt = GNUNET_SCHEDULER_add_delayed (timeout_request, &timeout_task, NULL); | 236 | tt = GNUNET_SCHEDULER_add_delayed (timeout_request, &timeout_task, NULL); |
237 | ro = GNUNET_DHT_RO_NONE; | ||
238 | if (demultixplex_everywhere) | ||
239 | ro |= GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE; | ||
240 | if (record_route) | ||
241 | ro |= GNUNET_DHT_RO_RECORD_ROUTE; | ||
231 | get_handle = GNUNET_DHT_get_start (dht_handle, | 242 | get_handle = GNUNET_DHT_get_start (dht_handle, |
232 | query_type, | 243 | query_type, |
233 | &key, | 244 | &key, |
234 | replication, | 245 | replication, |
235 | (demultixplex_everywhere) | 246 | ro, |
236 | ? GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE | ||
237 | : GNUNET_DHT_RO_NONE, | ||
238 | NULL, | 247 | NULL, |
239 | 0, | 248 | 0, |
240 | &get_result_iterator, | 249 | &get_result_iterator, |
@@ -265,6 +274,11 @@ main (int argc, char *const *argv) | |||
265 | "LEVEL", | 274 | "LEVEL", |
266 | gettext_noop ("how many parallel requests (replicas) to create"), | 275 | gettext_noop ("how many parallel requests (replicas) to create"), |
267 | &replication), | 276 | &replication), |
277 | GNUNET_GETOPT_option_flag ( | ||
278 | 'R', | ||
279 | "record", | ||
280 | gettext_noop ("use DHT's record route option"), | ||
281 | &record_route), | ||
268 | GNUNET_GETOPT_option_uint ( | 282 | GNUNET_GETOPT_option_uint ( |
269 | 't', | 283 | 't', |
270 | "type", | 284 | "type", |
diff --git a/src/dht/gnunet-dht-hello.c b/src/dht/gnunet-dht-hello.c new file mode 100644 index 000000000..369ed5643 --- /dev/null +++ b/src/dht/gnunet-dht-hello.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 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 | * @file dht/gnunet-dht-hello.c | ||
22 | * @brief Obtain HELLO from DHT for bootstrapping | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_dht_service.h" | ||
27 | |||
28 | #define LOG(kind, ...) GNUNET_log_from (kind, "dht-clients", __VA_ARGS__) | ||
29 | |||
30 | /** | ||
31 | * Handle to the DHT | ||
32 | */ | ||
33 | static struct GNUNET_DHT_Handle *dht_handle; | ||
34 | |||
35 | /** | ||
36 | * Handle to the DHT hello get operation. | ||
37 | */ | ||
38 | static struct GNUNET_DHT_HelloGetHandle *get_hello_handle; | ||
39 | |||
40 | /** | ||
41 | * Global status value | ||
42 | */ | ||
43 | static int global_ret; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Task run to clean up on shutdown. | ||
48 | * | ||
49 | * @param cls unused | ||
50 | */ | ||
51 | static void | ||
52 | cleanup_task (void *cls) | ||
53 | { | ||
54 | if (NULL != get_hello_handle) | ||
55 | { | ||
56 | GNUNET_DHT_hello_get_cancel (get_hello_handle); | ||
57 | get_hello_handle = NULL; | ||
58 | } | ||
59 | if (NULL != dht_handle) | ||
60 | { | ||
61 | GNUNET_DHT_disconnect (dht_handle); | ||
62 | dht_handle = NULL; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | |||
67 | /** | ||
68 | * Task run when we are finished. Triggers shutdown. | ||
69 | * | ||
70 | * @param cls unused | ||
71 | */ | ||
72 | static void | ||
73 | hello_done_cb (void *cls) | ||
74 | { | ||
75 | GNUNET_SCHEDULER_shutdown (); | ||
76 | } | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Function called on our HELLO. | ||
81 | * | ||
82 | * @param cls closure | ||
83 | * @param url the HELLO URL | ||
84 | */ | ||
85 | static void | ||
86 | hello_result_cb (void *cls, | ||
87 | const char *url) | ||
88 | { | ||
89 | get_hello_handle = NULL; | ||
90 | fprintf (stdout, | ||
91 | "%s\n", | ||
92 | url); | ||
93 | GNUNET_SCHEDULER_shutdown (); | ||
94 | } | ||
95 | |||
96 | |||
97 | /** | ||
98 | * Main function that will be run by the scheduler. | ||
99 | * | ||
100 | * @param cls closure, NULL | ||
101 | * @param args remaining command-line arguments | ||
102 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
103 | * @param cfg configuration | ||
104 | */ | ||
105 | static void | ||
106 | run (void *cls, | ||
107 | char *const *args, | ||
108 | const char *cfgfile, | ||
109 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
110 | { | ||
111 | (void) cls; | ||
112 | (void) cfgfile; | ||
113 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, | ||
114 | NULL); | ||
115 | if (NULL == (dht_handle = GNUNET_DHT_connect (cfg, | ||
116 | 1))) | ||
117 | { | ||
118 | fprintf (stderr, | ||
119 | _ ("Failed to connect to DHT service!\n")); | ||
120 | global_ret = EXIT_NOTCONFIGURED; | ||
121 | GNUNET_SCHEDULER_shutdown (); | ||
122 | return; | ||
123 | } | ||
124 | if (NULL == args[0]) | ||
125 | { | ||
126 | get_hello_handle = GNUNET_DHT_hello_get (dht_handle, | ||
127 | &hello_result_cb, | ||
128 | NULL); | ||
129 | GNUNET_break (NULL != get_hello_handle); | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | GNUNET_DHT_hello_offer (dht_handle, | ||
134 | args[0], | ||
135 | &hello_done_cb, | ||
136 | NULL); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Entry point for gnunet-dht-hello | ||
143 | * | ||
144 | * @param argc number of arguments from the command line | ||
145 | * @param argv command line arguments | ||
146 | * @return 0 ok, 1 on error | ||
147 | */ | ||
148 | int | ||
149 | main (int argc, | ||
150 | char *const *argv) | ||
151 | { | ||
152 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
153 | GNUNET_GETOPT_OPTION_END | ||
154 | }; | ||
155 | enum GNUNET_GenericReturnValue iret; | ||
156 | |||
157 | if (GNUNET_OK != | ||
158 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
159 | &argc, &argv)) | ||
160 | return 2; | ||
161 | iret = GNUNET_PROGRAM_run ( | ||
162 | argc, | ||
163 | argv, | ||
164 | "gnunet-dht-hello [URL]", | ||
165 | gettext_noop ( | ||
166 | "Obtain HELLO from DHT or provide HELLO to DHT for bootstrapping"), | ||
167 | options, | ||
168 | &run, | ||
169 | NULL); | ||
170 | if (GNUNET_SYSERR == iret) | ||
171 | return EXIT_FAILURE; | ||
172 | if (GNUNET_NO == iret) | ||
173 | return EXIT_SUCCESS; | ||
174 | return global_ret; | ||
175 | } | ||
176 | |||
177 | |||
178 | /* end of gnunet-dht-hello.c */ | ||
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index da46dcfee..39433791d 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c | |||
@@ -27,53 +27,335 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_block_lib.h" | 28 | #include "gnunet_block_lib.h" |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_transport_service.h" | ||
31 | #include "gnunet_transport_hello_service.h" | ||
32 | #include "gnunet_hello_lib.h" | 30 | #include "gnunet_hello_lib.h" |
31 | #include "gnunet_hello_uri_lib.h" | ||
33 | #include "gnunet_dht_service.h" | 32 | #include "gnunet_dht_service.h" |
34 | #include "gnunet_statistics_service.h" | 33 | #include "gnunet_statistics_service.h" |
35 | #include "gnunet-service-dht.h" | 34 | #include "gnunet-service-dht.h" |
36 | #include "gnunet-service-dht_datacache.h" | 35 | #include "gnunet-service-dht_datacache.h" |
37 | #include "gnunet-service-dht_hello.h" | ||
38 | #include "gnunet-service-dht_neighbours.h" | 36 | #include "gnunet-service-dht_neighbours.h" |
39 | #include "gnunet-service-dht_nse.h" | ||
40 | #include "gnunet-service-dht_routing.h" | 37 | #include "gnunet-service-dht_routing.h" |
41 | 38 | ||
42 | /** | 39 | /** |
40 | * How often do we broadcast our HELLO to neighbours if | ||
41 | * nothing special happens? | ||
42 | */ | ||
43 | #define HELLO_FREQUENCY GNUNET_TIME_UNIT_HOURS | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Information we keep per underlay. | ||
48 | */ | ||
49 | struct GDS_Underlay | ||
50 | { | ||
51 | |||
52 | /** | ||
53 | * Kept in a DLL. | ||
54 | */ | ||
55 | struct GDS_Underlay *next; | ||
56 | |||
57 | /** | ||
58 | * Kept in a DLL. | ||
59 | */ | ||
60 | struct GDS_Underlay *prev; | ||
61 | |||
62 | /** | ||
63 | * Environment for this underlay. | ||
64 | */ | ||
65 | struct GNUNET_DHTU_PluginEnvironment env; | ||
66 | |||
67 | /** | ||
68 | * Underlay API handle. | ||
69 | */ | ||
70 | struct GNUNET_DHTU_PluginFunctions *dhtu; | ||
71 | |||
72 | /** | ||
73 | * current network size estimate for this underlay. | ||
74 | */ | ||
75 | double network_size_estimate; | ||
76 | |||
77 | /** | ||
78 | * Name of the underlay (i.e. "gnunet" or "ip"). | ||
79 | */ | ||
80 | char *name; | ||
81 | |||
82 | /** | ||
83 | * Name of the library providing the underlay. | ||
84 | */ | ||
85 | char *libname; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * An address of this peer. | ||
91 | */ | ||
92 | struct MyAddress | ||
93 | { | ||
94 | /** | ||
95 | * Kept in a DLL. | ||
96 | */ | ||
97 | struct MyAddress *next; | ||
98 | |||
99 | /** | ||
100 | * Kept in a DLL. | ||
101 | */ | ||
102 | struct MyAddress *prev; | ||
103 | |||
104 | /** | ||
105 | * Underlay handle for the address. | ||
106 | */ | ||
107 | struct GNUNET_DHTU_Source *source; | ||
108 | |||
109 | /** | ||
110 | * Textual representation of the address. | ||
111 | */ | ||
112 | char *url; | ||
113 | |||
114 | /** | ||
115 | * Underlay of this address. | ||
116 | */ | ||
117 | struct GDS_Underlay *u; | ||
118 | }; | ||
119 | |||
120 | |||
121 | /** | ||
43 | * Our HELLO | 122 | * Our HELLO |
44 | */ | 123 | */ |
45 | struct GNUNET_MessageHeader *GDS_my_hello; | 124 | struct GNUNET_HELLO_Builder *GDS_my_hello; |
46 | 125 | ||
47 | /** | 126 | /** |
48 | * Handle to get our current HELLO. | 127 | * Identity of this peer. |
49 | */ | 128 | */ |
50 | static struct GNUNET_TRANSPORT_HelloGetHandle *ghh; | 129 | struct GNUNET_PeerIdentity GDS_my_identity; |
51 | 130 | ||
52 | /** | 131 | /** |
53 | * Hello address expiration | 132 | * Hash of the identity of this peer. |
54 | */ | 133 | */ |
55 | struct GNUNET_TIME_Relative hello_expiration; | 134 | struct GNUNET_HashCode GDS_my_identity_hash; |
135 | |||
136 | /** | ||
137 | * Our private key. | ||
138 | */ | ||
139 | struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key; | ||
140 | |||
141 | /** | ||
142 | * Task broadcasting our HELLO. | ||
143 | */ | ||
144 | static struct GNUNET_SCHEDULER_Task *hello_task; | ||
145 | |||
146 | /** | ||
147 | * Handles for the DHT underlays. | ||
148 | */ | ||
149 | static struct GDS_Underlay *u_head; | ||
150 | |||
151 | /** | ||
152 | * Handles for the DHT underlays. | ||
153 | */ | ||
154 | static struct GDS_Underlay *u_tail; | ||
155 | |||
156 | /** | ||
157 | * Head of addresses of this peer. | ||
158 | */ | ||
159 | static struct MyAddress *a_head; | ||
160 | |||
161 | /** | ||
162 | * Tail of addresses of this peer. | ||
163 | */ | ||
164 | static struct MyAddress *a_tail; | ||
165 | |||
166 | /** | ||
167 | * log of the current network size estimate, used as the point where | ||
168 | * we switch between random and deterministic routing. | ||
169 | */ | ||
170 | static double log_of_network_size_estimate; | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Callback that is called when network size estimate is updated. | ||
175 | * | ||
176 | * @param cls a `struct GDS_Underlay` | ||
177 | * @param timestamp time when the estimate was received from the server (or created by the server) | ||
178 | * @param logestimate the log(Base 2) value of the current network size estimate | ||
179 | * @param std_dev standard deviation for the estimate | ||
180 | * | ||
181 | */ | ||
182 | static void | ||
183 | update_network_size_estimate (void *cls, | ||
184 | struct GNUNET_TIME_Absolute timestamp, | ||
185 | double logestimate, | ||
186 | double std_dev) | ||
187 | { | ||
188 | struct GDS_Underlay *u = cls; | ||
189 | double sum = 0.0; | ||
190 | |||
191 | GNUNET_STATISTICS_update (GDS_stats, | ||
192 | "# Network size estimates received", | ||
193 | 1, | ||
194 | GNUNET_NO); | ||
195 | /* do not allow estimates < 0.5 */ | ||
196 | u->network_size_estimate = pow (2.0, | ||
197 | GNUNET_MAX (0.5, | ||
198 | logestimate)); | ||
199 | for (struct GDS_Underlay *p = u_head; NULL != p; p = p->next) | ||
200 | sum += p->network_size_estimate; | ||
201 | if (sum <= 2.0) | ||
202 | log_of_network_size_estimate = 0.5; | ||
203 | else | ||
204 | log_of_network_size_estimate = log2 (sum); | ||
205 | } | ||
206 | |||
207 | |||
208 | /** | ||
209 | * Return the current NSE | ||
210 | * | ||
211 | * @return the current NSE as a logarithm | ||
212 | */ | ||
213 | double | ||
214 | GDS_NSE_get (void) | ||
215 | { | ||
216 | return log_of_network_size_estimate; | ||
217 | } | ||
56 | 218 | ||
57 | 219 | ||
58 | #include "gnunet-service-dht_clients.c" | 220 | #include "gnunet-service-dht_clients.c" |
59 | 221 | ||
60 | 222 | ||
61 | /** | 223 | /** |
62 | * Receive the HELLO from transport service, free current and replace | 224 | * Task run periodically to broadcast our HELLO. |
63 | * if necessary. | ||
64 | * | 225 | * |
65 | * @param cls NULL | 226 | * @param cls NULL |
66 | * @param message HELLO message of peer | ||
67 | */ | 227 | */ |
68 | static void | 228 | static void |
69 | process_hello (void *cls, | 229 | broadcast_hello (void *cls) |
70 | const struct GNUNET_MessageHeader *message) | ||
71 | { | 230 | { |
72 | GNUNET_free (GDS_my_hello); | 231 | struct GNUNET_MessageHeader *hello; |
73 | GDS_my_hello = GNUNET_malloc (ntohs (message->size)); | 232 | |
74 | GNUNET_memcpy (GDS_my_hello, | 233 | (void) cls; |
75 | message, | 234 | /* TODO: randomize! */ |
76 | ntohs (message->size)); | 235 | hello_task = GNUNET_SCHEDULER_add_delayed (HELLO_FREQUENCY, |
236 | &broadcast_hello, | ||
237 | NULL); | ||
238 | hello = GNUNET_HELLO_builder_to_dht_hello_msg (GDS_my_hello, | ||
239 | &GDS_my_private_key); | ||
240 | if (NULL == hello) | ||
241 | { | ||
242 | GNUNET_break (0); | ||
243 | return; | ||
244 | } | ||
245 | GDS_NEIGHBOURS_broadcast (hello); | ||
246 | GNUNET_free (hello); | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
251 | * Function to call with new addresses of this peer. | ||
252 | * | ||
253 | * @param cls the closure | ||
254 | * @param address address under which we are likely reachable, | ||
255 | * pointer will remain valid until @e address_del_cb is called; to be used for HELLOs. Example: "ip+udp://$PID/1.1.1.1:2086/" | ||
256 | * @param source handle for sending from this address, NULL if we can only receive | ||
257 | * @param[out] ctx storage space for DHT to use in association with this address | ||
258 | */ | ||
259 | static void | ||
260 | u_address_add (void *cls, | ||
261 | const char *address, | ||
262 | struct GNUNET_DHTU_Source *source, | ||
263 | void **ctx) | ||
264 | { | ||
265 | struct GDS_Underlay *u = cls; | ||
266 | struct MyAddress *a; | ||
267 | |||
268 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
269 | "Underlay adds address %s for this peer\n", | ||
270 | address); | ||
271 | a = GNUNET_new (struct MyAddress); | ||
272 | a->source = source; | ||
273 | a->url = GNUNET_strdup (address); | ||
274 | a->u = u; | ||
275 | GNUNET_CONTAINER_DLL_insert (a_head, | ||
276 | a_tail, | ||
277 | a); | ||
278 | *ctx = a; | ||
279 | GNUNET_HELLO_builder_add_address (GDS_my_hello, | ||
280 | address); | ||
281 | if (NULL != hello_task) | ||
282 | GNUNET_SCHEDULER_cancel (hello_task); | ||
283 | hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello, | ||
284 | NULL); | ||
285 | } | ||
286 | |||
287 | |||
288 | /** | ||
289 | * Function to call with expired addresses of this peer. | ||
290 | * | ||
291 | * @param[in] ctx storage space used by the DHT in association with this address | ||
292 | */ | ||
293 | static void | ||
294 | u_address_del (void *ctx) | ||
295 | { | ||
296 | struct MyAddress *a = ctx; | ||
297 | |||
298 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
299 | "Underlay deletes address %s for this peer\n", | ||
300 | a->url); | ||
301 | GNUNET_HELLO_builder_del_address (GDS_my_hello, | ||
302 | a->url); | ||
303 | GNUNET_CONTAINER_DLL_remove (a_head, | ||
304 | a_tail, | ||
305 | a); | ||
306 | GNUNET_free (a->url); | ||
307 | GNUNET_free (a); | ||
308 | if (NULL != hello_task) | ||
309 | GNUNET_SCHEDULER_cancel (hello_task); | ||
310 | hello_task = GNUNET_SCHEDULER_add_now (&broadcast_hello, | ||
311 | NULL); | ||
312 | } | ||
313 | |||
314 | |||
315 | void | ||
316 | GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, | ||
317 | const char *address) | ||
318 | { | ||
319 | for (struct GDS_Underlay *u = u_head; | ||
320 | NULL != u; | ||
321 | u = u->next) | ||
322 | u->dhtu->try_connect (u->dhtu->cls, | ||
323 | pid, | ||
324 | address); | ||
325 | } | ||
326 | |||
327 | |||
328 | void | ||
329 | GDS_u_send (struct GDS_Underlay *u, | ||
330 | struct GNUNET_DHTU_Target *target, | ||
331 | const void *msg, | ||
332 | size_t msg_size, | ||
333 | GNUNET_SCHEDULER_TaskCallback finished_cb, | ||
334 | void *finished_cb_cls) | ||
335 | { | ||
336 | u->dhtu->send (u->dhtu->cls, | ||
337 | target, | ||
338 | msg, | ||
339 | msg_size, | ||
340 | finished_cb, | ||
341 | finished_cb_cls); | ||
342 | } | ||
343 | |||
344 | |||
345 | void | ||
346 | GDS_u_drop (struct GDS_Underlay *u, | ||
347 | struct GNUNET_DHTU_PreferenceHandle *ph) | ||
348 | { | ||
349 | u->dhtu->drop (ph); | ||
350 | } | ||
351 | |||
352 | |||
353 | struct GNUNET_DHTU_PreferenceHandle * | ||
354 | GDS_u_hold (struct GDS_Underlay *u, | ||
355 | struct GNUNET_DHTU_Target *target) | ||
356 | { | ||
357 | return u->dhtu->hold (u->dhtu->cls, | ||
358 | target); | ||
77 | } | 359 | } |
78 | 360 | ||
79 | 361 | ||
@@ -85,30 +367,97 @@ process_hello (void *cls, | |||
85 | static void | 367 | static void |
86 | shutdown_task (void *cls) | 368 | shutdown_task (void *cls) |
87 | { | 369 | { |
88 | if (NULL != ghh) | 370 | struct GDS_Underlay *u; |
371 | |||
372 | while (NULL != (u = u_head)) | ||
89 | { | 373 | { |
90 | GNUNET_TRANSPORT_hello_get_cancel (ghh); | 374 | GNUNET_PLUGIN_unload (u->libname, |
91 | ghh = NULL; | 375 | u->dhtu); |
376 | GNUNET_CONTAINER_DLL_remove (u_head, | ||
377 | u_tail, | ||
378 | u); | ||
379 | GNUNET_free (u->name); | ||
380 | GNUNET_free (u->libname); | ||
381 | GNUNET_free (u); | ||
92 | } | 382 | } |
93 | GDS_NEIGHBOURS_done (); | 383 | GDS_NEIGHBOURS_done (); |
94 | GDS_DATACACHE_done (); | 384 | GDS_DATACACHE_done (); |
95 | GDS_ROUTING_done (); | 385 | GDS_ROUTING_done (); |
96 | GDS_HELLO_done (); | ||
97 | GDS_NSE_done (); | ||
98 | if (NULL != GDS_block_context) | 386 | if (NULL != GDS_block_context) |
99 | { | 387 | { |
100 | GNUNET_BLOCK_context_destroy (GDS_block_context); | 388 | GNUNET_BLOCK_context_destroy (GDS_block_context); |
101 | GDS_block_context = NULL; | 389 | GDS_block_context = NULL; |
102 | } | 390 | } |
391 | GDS_CLIENTS_stop (); | ||
103 | if (NULL != GDS_stats) | 392 | if (NULL != GDS_stats) |
104 | { | 393 | { |
105 | GNUNET_STATISTICS_destroy (GDS_stats, | 394 | GNUNET_STATISTICS_destroy (GDS_stats, |
106 | GNUNET_YES); | 395 | GNUNET_YES); |
107 | GDS_stats = NULL; | 396 | GDS_stats = NULL; |
108 | } | 397 | } |
109 | GNUNET_free (GDS_my_hello); | 398 | if (NULL != GDS_my_hello) |
110 | GDS_my_hello = NULL; | 399 | { |
111 | GDS_CLIENTS_stop (); | 400 | GNUNET_HELLO_builder_free (GDS_my_hello); |
401 | GDS_my_hello = NULL; | ||
402 | } | ||
403 | if (NULL != hello_task) | ||
404 | { | ||
405 | GNUNET_SCHEDULER_cancel (hello_task); | ||
406 | hello_task = NULL; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | |||
411 | /** | ||
412 | * Function iterating over all configuration sections. | ||
413 | * Loads plugins for enabled DHT underlays. | ||
414 | * | ||
415 | * @param cls NULL | ||
416 | * @param section configuration section to inspect | ||
417 | */ | ||
418 | static void | ||
419 | load_underlay (void *cls, | ||
420 | const char *section) | ||
421 | { | ||
422 | struct GDS_Underlay *u; | ||
423 | char *libname; | ||
424 | |||
425 | (void) cls; | ||
426 | if (0 != strncasecmp (section, | ||
427 | "dhtu-", | ||
428 | strlen ("dhtu-"))) | ||
429 | return; | ||
430 | if (GNUNET_YES != | ||
431 | GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, | ||
432 | section, | ||
433 | "ENABLED")) | ||
434 | return; | ||
435 | section += strlen ("dhtu-"); | ||
436 | u = GNUNET_new (struct GDS_Underlay); | ||
437 | u->env.cls = u; | ||
438 | u->env.cfg = GDS_cfg; | ||
439 | u->env.address_add_cb = &u_address_add; | ||
440 | u->env.address_del_cb = &u_address_del; | ||
441 | u->env.network_size_cb = &update_network_size_estimate; | ||
442 | u->env.connect_cb = &GDS_u_connect; | ||
443 | u->env.disconnect_cb = &GDS_u_disconnect; | ||
444 | u->env.receive_cb = &GDS_u_receive; | ||
445 | GNUNET_asprintf (&libname, | ||
446 | "libgnunet_plugin_dhtu_%s", | ||
447 | section); | ||
448 | u->dhtu = GNUNET_PLUGIN_load (libname, | ||
449 | &u->env); | ||
450 | if (NULL == u->dhtu) | ||
451 | { | ||
452 | GNUNET_free (libname); | ||
453 | GNUNET_free (u); | ||
454 | return; | ||
455 | } | ||
456 | u->libname = libname; | ||
457 | u->name = GNUNET_strdup (section); | ||
458 | GNUNET_CONTAINER_DLL_insert (u_head, | ||
459 | u_tail, | ||
460 | u); | ||
112 | } | 461 | } |
113 | 462 | ||
114 | 463 | ||
@@ -126,34 +475,64 @@ run (void *cls, | |||
126 | { | 475 | { |
127 | GDS_cfg = c; | 476 | GDS_cfg = c; |
128 | GDS_service = service; | 477 | GDS_service = service; |
129 | if (GNUNET_OK != | ||
130 | GNUNET_CONFIGURATION_get_value_time (c, | ||
131 | "transport", | ||
132 | "HELLO_EXPIRATION", | ||
133 | &hello_expiration)) | ||
134 | { | 478 | { |
135 | hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION; | 479 | char *keyfile; |
480 | |||
481 | if (GNUNET_OK != | ||
482 | GNUNET_CONFIGURATION_get_value_filename (GDS_cfg, | ||
483 | "PEER", | ||
484 | "PRIVATE_KEY", | ||
485 | &keyfile)) | ||
486 | { | ||
487 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
488 | "PEER", | ||
489 | "PRIVATE_KEY"); | ||
490 | GNUNET_SCHEDULER_shutdown (); | ||
491 | return; | ||
492 | } | ||
493 | if (GNUNET_SYSERR == | ||
494 | GNUNET_CRYPTO_eddsa_key_from_file (keyfile, | ||
495 | GNUNET_YES, | ||
496 | &GDS_my_private_key)) | ||
497 | { | ||
498 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
499 | "Failed to setup peer's private key\n"); | ||
500 | GNUNET_free (keyfile); | ||
501 | GNUNET_SCHEDULER_shutdown (); | ||
502 | return; | ||
503 | } | ||
504 | GNUNET_free (keyfile); | ||
136 | } | 505 | } |
506 | GNUNET_CRYPTO_eddsa_key_get_public (&GDS_my_private_key, | ||
507 | &GDS_my_identity.public_key); | ||
508 | GDS_my_hello = GNUNET_HELLO_builder_new (&GDS_my_identity); | ||
509 | GNUNET_CRYPTO_hash (&GDS_my_identity, | ||
510 | sizeof(struct GNUNET_PeerIdentity), | ||
511 | &GDS_my_identity_hash); | ||
137 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); | 512 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); |
138 | GDS_stats = GNUNET_STATISTICS_create ("dht", | 513 | GDS_stats = GNUNET_STATISTICS_create ("dht", |
139 | GDS_cfg); | 514 | GDS_cfg); |
140 | GNUNET_SERVICE_suspend (GDS_service); | ||
141 | GDS_CLIENTS_init (); | 515 | GDS_CLIENTS_init (); |
142 | GDS_ROUTING_init (); | 516 | GDS_ROUTING_init (); |
143 | GDS_NSE_init (); | ||
144 | GDS_DATACACHE_init (); | 517 | GDS_DATACACHE_init (); |
145 | GDS_HELLO_init (); | 518 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
146 | if (GNUNET_OK != GDS_NEIGHBOURS_init ()) | 519 | NULL); |
520 | if (GNUNET_OK != | ||
521 | GDS_NEIGHBOURS_init ()) | ||
147 | { | 522 | { |
148 | shutdown_task (NULL); | 523 | GNUNET_SCHEDULER_shutdown (); |
524 | return; | ||
525 | } | ||
526 | GNUNET_CONFIGURATION_iterate_sections (GDS_cfg, | ||
527 | &load_underlay, | ||
528 | NULL); | ||
529 | if (NULL == u_head) | ||
530 | { | ||
531 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
532 | "No DHT underlays configured!\n"); | ||
533 | GNUNET_SCHEDULER_shutdown (); | ||
149 | return; | 534 | return; |
150 | } | 535 | } |
151 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | ||
152 | NULL); | ||
153 | ghh = GNUNET_TRANSPORT_hello_get (GDS_cfg, | ||
154 | GNUNET_TRANSPORT_AC_GLOBAL, | ||
155 | &process_hello, | ||
156 | NULL); | ||
157 | } | 536 | } |
158 | 537 | ||
159 | 538 | ||
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index 367ff426e..a1513fcce 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define GNUNET_SERVICE_DHT_H | 27 | #define GNUNET_SERVICE_DHT_H |
28 | 28 | ||
29 | #include "gnunet-service-dht_datacache.h" | 29 | #include "gnunet-service-dht_datacache.h" |
30 | #include "gnunet-service-dht_neighbours.h" | ||
30 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_service.h" | 32 | #include "gnunet_transport_service.h" |
32 | 33 | ||
@@ -34,6 +35,11 @@ | |||
34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | 35 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING |
35 | 36 | ||
36 | /** | 37 | /** |
38 | * Information we keep per underlay. | ||
39 | */ | ||
40 | struct GDS_Underlay; | ||
41 | |||
42 | /** | ||
37 | * Configuration we use. | 43 | * Configuration we use. |
38 | */ | 44 | */ |
39 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | 45 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; |
@@ -54,9 +60,81 @@ extern struct GNUNET_BLOCK_Context *GDS_block_context; | |||
54 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; | 60 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; |
55 | 61 | ||
56 | /** | 62 | /** |
57 | * Our HELLO | 63 | * Our HELLO builder. |
64 | */ | ||
65 | extern struct GNUNET_HELLO_Builder *GDS_my_hello; | ||
66 | |||
67 | /** | ||
68 | * Identity of this peer. | ||
69 | */ | ||
70 | extern struct GNUNET_PeerIdentity GDS_my_identity; | ||
71 | |||
72 | /** | ||
73 | * Hash of the identity of this peer. | ||
74 | */ | ||
75 | extern struct GNUNET_HashCode GDS_my_identity_hash; | ||
76 | |||
77 | /** | ||
78 | * Our private key. | ||
79 | */ | ||
80 | extern struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key; | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Ask all underlays to connect to peer @a pid at @a address. | ||
85 | * | ||
86 | * @param pid identity of the peer we would connect to | ||
87 | * @param address an address of @a pid | ||
88 | */ | ||
89 | void | ||
90 | GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, | ||
91 | const char *address); | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Send message to some other participant over the network. Note that | ||
96 | * sending is not guaranteeing that the other peer actually received the | ||
97 | * message. For any given @a target, the DHT must wait for the @a | ||
98 | * finished_cb to be called before calling send() again. | ||
99 | * | ||
100 | * @param u underlay to use for transmission | ||
101 | * @param target receiver identification | ||
102 | * @param msg message | ||
103 | * @param msg_size number of bytes in @a msg | ||
104 | * @param finished_cb function called once transmission is done | ||
105 | * (not called if @a target disconnects, then only the | ||
106 | * disconnect_cb is called). | ||
107 | * @param finished_cb_cls closure for @a finished_cb | ||
108 | */ | ||
109 | void | ||
110 | GDS_u_send (struct GDS_Underlay *u, | ||
111 | struct GNUNET_DHTU_Target *target, | ||
112 | const void *msg, | ||
113 | size_t msg_size, | ||
114 | GNUNET_SCHEDULER_TaskCallback finished_cb, | ||
115 | void *finished_cb_cls); | ||
116 | |||
117 | |||
118 | /** | ||
119 | * Drop a hold @a ph from underlay @a u. | ||
120 | * | ||
121 | * @param u the underlay controlling the hold | ||
122 | * @param ph the preference handle | ||
123 | */ | ||
124 | void | ||
125 | GDS_u_drop (struct GDS_Underlay *u, | ||
126 | struct GNUNET_DHTU_PreferenceHandle *ph); | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Create a hold on @a target at underlay @a u. | ||
131 | * | ||
132 | * @param u the underlay controlling the target | ||
133 | * @param target the peer to hold the connection to | ||
58 | */ | 134 | */ |
59 | extern struct GNUNET_MessageHeader *GDS_my_hello; | 135 | struct GNUNET_DHTU_PreferenceHandle * |
136 | GDS_u_hold (struct GDS_Underlay *u, | ||
137 | struct GNUNET_DHTU_Target *target); | ||
60 | 138 | ||
61 | 139 | ||
62 | /** | 140 | /** |
@@ -68,8 +146,9 @@ extern struct GNUNET_MessageHeader *GDS_my_hello; | |||
68 | * @param query_hash hash of the original query, might not match key in @a bd | 146 | * @param query_hash hash of the original query, might not match key in @a bd |
69 | * @param get_path_length number of entries in @a get_path | 147 | * @param get_path_length number of entries in @a get_path |
70 | * @param get_path path the reply has taken | 148 | * @param get_path path the reply has taken |
149 | * @return true on success, false on failures | ||
71 | */ | 150 | */ |
72 | void | 151 | bool |
73 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, | 152 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
74 | const struct GNUNET_HashCode *query_hash, | 153 | const struct GNUNET_HashCode *query_hash, |
75 | unsigned int get_path_length, | 154 | unsigned int get_path_length, |
@@ -128,4 +207,12 @@ GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, | |||
128 | uint32_t hop_count, | 207 | uint32_t hop_count, |
129 | uint32_t desired_replication_level); | 208 | uint32_t desired_replication_level); |
130 | 209 | ||
210 | /** | ||
211 | * Return the current NSE | ||
212 | * | ||
213 | * @return the current NSE as a logarithm | ||
214 | */ | ||
215 | double | ||
216 | GDS_NSE_get (void); | ||
217 | |||
131 | #endif | 218 | #endif |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index a1c3024de..6a4f58d1f 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -24,7 +24,6 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
26 | */ | 26 | */ |
27 | |||
28 | #include "platform.h" | 27 | #include "platform.h" |
29 | #include "gnunet_constants.h" | 28 | #include "gnunet_constants.h" |
30 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
@@ -36,6 +35,14 @@ | |||
36 | 35 | ||
37 | 36 | ||
38 | /** | 37 | /** |
38 | * Enable slow sanity checks to debug issues. | ||
39 | * 0: do not check | ||
40 | * 1: check all external inputs | ||
41 | * 2: check internal computations as well | ||
42 | */ | ||
43 | #define SANITY_CHECKS 2 | ||
44 | |||
45 | /** | ||
39 | * Should routing details be logged to stderr (for debugging)? | 46 | * Should routing details be logged to stderr (for debugging)? |
40 | */ | 47 | */ |
41 | #define LOG_TRAFFIC(kind, ...) GNUNET_log_from (kind, "dht-traffic", \ | 48 | #define LOG_TRAFFIC(kind, ...) GNUNET_log_from (kind, "dht-traffic", \ |
@@ -503,6 +510,15 @@ handle_dht_local_put (void *cls, | |||
503 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), | 510 | (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), |
504 | GNUNET_h2s (&dht_msg->key), | 511 | GNUNET_h2s (&dht_msg->key), |
505 | (unsigned int) bd.type); | 512 | (unsigned int) bd.type); |
513 | if (GNUNET_OK != | ||
514 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
515 | bd.type, | ||
516 | bd.data, | ||
517 | bd.data_size)) | ||
518 | { | ||
519 | GNUNET_break (0); | ||
520 | return; | ||
521 | } | ||
506 | GNUNET_STATISTICS_update (GDS_stats, | 522 | GNUNET_STATISTICS_update (GDS_stats, |
507 | "# PUT requests received from clients", | 523 | "# PUT requests received from clients", |
508 | 1, | 524 | 1, |
@@ -511,9 +527,9 @@ handle_dht_local_put (void *cls, | |||
511 | "CLIENT-PUT %s\n", | 527 | "CLIENT-PUT %s\n", |
512 | GNUNET_h2s_full (&dht_msg->key)); | 528 | GNUNET_h2s_full (&dht_msg->key)); |
513 | /* give to local clients */ | 529 | /* give to local clients */ |
514 | GDS_CLIENTS_handle_reply (&bd, | 530 | GNUNET_break (GDS_CLIENTS_handle_reply (&bd, |
515 | &bd.key, | 531 | &bd.key, |
516 | 0, NULL /* get path */); | 532 | 0, NULL /* get path */)); |
517 | 533 | ||
518 | { | 534 | { |
519 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 535 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; |
@@ -561,10 +577,12 @@ static void | |||
561 | handle_local_result (void *cls, | 577 | handle_local_result (void *cls, |
562 | const struct GDS_DATACACHE_BlockData *bd) | 578 | const struct GDS_DATACACHE_BlockData *bd) |
563 | { | 579 | { |
564 | /* FIXME: use 'cls' instead of looking up the client? */ | 580 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
565 | GDS_CLIENTS_handle_reply (bd, | 581 | "Datacache provided result for query key %s\n", |
566 | &bd->key, | 582 | GNUNET_h2s (&bd->key)); |
567 | 0, NULL /* get_path */); | 583 | GNUNET_break (GDS_CLIENTS_handle_reply (bd, |
584 | &bd->key, | ||
585 | 0, NULL /* get_path */)); | ||
568 | } | 586 | } |
569 | 587 | ||
570 | 588 | ||
@@ -917,7 +935,7 @@ forward_reply (void *cls, | |||
917 | GNUNET_NO); | 935 | GNUNET_NO); |
918 | return GNUNET_YES; /* type mismatch */ | 936 | return GNUNET_YES; /* type mismatch */ |
919 | } | 937 | } |
920 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_PEER)) && | 938 | if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) && |
921 | (0 != GNUNET_memcmp (&frc->bd->key, | 939 | (0 != GNUNET_memcmp (&frc->bd->key, |
922 | query_hash)) ) | 940 | query_hash)) ) |
923 | { | 941 | { |
@@ -973,9 +991,6 @@ forward_reply (void *cls, | |||
973 | /* should be impossible to encounter here */ | 991 | /* should be impossible to encounter here */ |
974 | GNUNET_break (0); | 992 | GNUNET_break (0); |
975 | return GNUNET_YES; | 993 | return GNUNET_YES; |
976 | case GNUNET_BLOCK_REPLY_INVALID: | ||
977 | GNUNET_break_op (0); | ||
978 | return GNUNET_NO; | ||
979 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | 994 | case GNUNET_BLOCK_REPLY_IRRELEVANT: |
980 | return GNUNET_YES; | 995 | return GNUNET_YES; |
981 | default: | 996 | default: |
@@ -996,7 +1011,7 @@ forward_reply (void *cls, | |||
996 | reply->put_path_length = htonl (frc->bd->put_path_length); | 1011 | reply->put_path_length = htonl (frc->bd->put_path_length); |
997 | reply->unique_id = record->unique_id; | 1012 | reply->unique_id = record->unique_id; |
998 | reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); | 1013 | reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); |
999 | reply->key = frc->bd->key; | 1014 | reply->key = *query_hash; |
1000 | paths = (struct GNUNET_DHT_PathElement *) &reply[1]; | 1015 | paths = (struct GNUNET_DHT_PathElement *) &reply[1]; |
1001 | GNUNET_memcpy (paths, | 1016 | GNUNET_memcpy (paths, |
1002 | frc->bd->put_path, | 1017 | frc->bd->put_path, |
@@ -1004,7 +1019,8 @@ forward_reply (void *cls, | |||
1004 | * frc->bd->put_path_length); | 1019 | * frc->bd->put_path_length); |
1005 | GNUNET_memcpy (&paths[frc->bd->put_path_length], | 1020 | GNUNET_memcpy (&paths[frc->bd->put_path_length], |
1006 | frc->get_path, | 1021 | frc->get_path, |
1007 | sizeof(struct GNUNET_DHT_PathElement) * frc->get_path_length); | 1022 | sizeof(struct GNUNET_DHT_PathElement) |
1023 | * frc->get_path_length); | ||
1008 | GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length], | 1024 | GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length], |
1009 | frc->bd->data, | 1025 | frc->bd->data, |
1010 | frc->bd->data_size); | 1026 | frc->bd->data_size); |
@@ -1020,7 +1036,7 @@ forward_reply (void *cls, | |||
1020 | } | 1036 | } |
1021 | 1037 | ||
1022 | 1038 | ||
1023 | void | 1039 | bool |
1024 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, | 1040 | GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, |
1025 | const struct GNUNET_HashCode *query_hash, | 1041 | const struct GNUNET_HashCode *query_hash, |
1026 | unsigned int get_path_length, | 1042 | unsigned int get_path_length, |
@@ -1035,14 +1051,31 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, | |||
1035 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) | 1051 | if (msize >= GNUNET_MAX_MESSAGE_SIZE) |
1036 | { | 1052 | { |
1037 | GNUNET_break (0); | 1053 | GNUNET_break (0); |
1038 | return; | 1054 | return false; |
1039 | } | 1055 | } |
1056 | #if SANITY_CHECKS > 1 | ||
1057 | if (0 != | ||
1058 | GNUNET_DHT_verify_path (bd->data, | ||
1059 | bd->data_size, | ||
1060 | bd->expiration_time, | ||
1061 | bd->put_path, | ||
1062 | bd->put_path_length, | ||
1063 | get_path, | ||
1064 | get_path_length, | ||
1065 | &GDS_my_identity)) | ||
1066 | { | ||
1067 | GNUNET_break (0); | ||
1068 | return false; | ||
1069 | } | ||
1070 | #endif | ||
1040 | frc.bd = bd; | 1071 | frc.bd = bd; |
1041 | frc.get_path = get_path; | 1072 | frc.get_path = get_path; |
1042 | frc.get_path_length = get_path_length; | 1073 | frc.get_path_length = get_path_length; |
1043 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1074 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1044 | "Forwarding reply for query hash %s to client\n", | 1075 | "Forwarding reply for query hash %s with GPL %u and PPL %u to client\n", |
1045 | GNUNET_h2s (query_hash)); | 1076 | GNUNET_h2s (query_hash), |
1077 | get_path_length, | ||
1078 | bd->put_path_length); | ||
1046 | if (0 == | 1079 | if (0 == |
1047 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | 1080 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, |
1048 | query_hash, | 1081 | query_hash, |
@@ -1057,6 +1090,102 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, | |||
1057 | 1, | 1090 | 1, |
1058 | GNUNET_NO); | 1091 | GNUNET_NO); |
1059 | } | 1092 | } |
1093 | return true; | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | /* **************** HELLO logic ***************** */ | ||
1098 | |||
1099 | /** | ||
1100 | * Handler for HELLO GET message. Reply to client | ||
1101 | * with a URL of our HELLO. | ||
1102 | * | ||
1103 | * @param cls the client we received this message from | ||
1104 | * @param msg the actual message received | ||
1105 | * | ||
1106 | */ | ||
1107 | static void | ||
1108 | handle_dht_local_hello_get (void *cls, | ||
1109 | const struct GNUNET_MessageHeader *msg) | ||
1110 | { | ||
1111 | struct ClientHandle *ch = cls; | ||
1112 | char *url = GNUNET_HELLO_builder_to_url (GDS_my_hello, | ||
1113 | &GDS_my_private_key); | ||
1114 | size_t slen = strlen (url) + 1; | ||
1115 | struct GNUNET_MessageHeader *hdr; | ||
1116 | struct GNUNET_MQ_Envelope *env; | ||
1117 | |||
1118 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1119 | "Handling request from local client for my HELLO\n"); | ||
1120 | env = GNUNET_MQ_msg_extra (hdr, | ||
1121 | slen, | ||
1122 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL); | ||
1123 | memcpy (&hdr[1], | ||
1124 | url, | ||
1125 | slen); | ||
1126 | GNUNET_free (url); | ||
1127 | GNUNET_MQ_send (ch->mq, | ||
1128 | env); | ||
1129 | GNUNET_SERVICE_client_continue (ch->client); | ||
1130 | } | ||
1131 | |||
1132 | |||
1133 | /** | ||
1134 | * Process a client HELLO message received from the service. | ||
1135 | * | ||
1136 | * @param cls the client we received this message from | ||
1137 | * @param hdr HELLO URL message from the service. | ||
1138 | * @return #GNUNET_OK if @a hdr is well-formed | ||
1139 | */ | ||
1140 | static enum GNUNET_GenericReturnValue | ||
1141 | check_dht_local_hello_offer (void *cls, | ||
1142 | const struct GNUNET_MessageHeader *hdr) | ||
1143 | { | ||
1144 | uint16_t len = ntohs (hdr->size); | ||
1145 | const char *buf = (const char *) &hdr[1]; | ||
1146 | |||
1147 | (void) cls; | ||
1148 | if ('\0' != buf[len - sizeof (*hdr) - 1]) | ||
1149 | { | ||
1150 | GNUNET_break (0); | ||
1151 | return GNUNET_SYSERR; | ||
1152 | } | ||
1153 | return GNUNET_OK; | ||
1154 | } | ||
1155 | |||
1156 | |||
1157 | /** | ||
1158 | * Handler for HELLO OFFER message. Try to use the | ||
1159 | * HELLO to connect to another peer. | ||
1160 | * | ||
1161 | * @param cls the client we received this message from | ||
1162 | * @param msg the actual message received | ||
1163 | */ | ||
1164 | static void | ||
1165 | handle_dht_local_hello_offer (void *cls, | ||
1166 | const struct GNUNET_MessageHeader *msg) | ||
1167 | { | ||
1168 | struct ClientHandle *ch = cls; | ||
1169 | const char *url = (const char *) &msg[1]; | ||
1170 | struct GNUNET_HELLO_Builder *b; | ||
1171 | struct GNUNET_PeerIdentity pid; | ||
1172 | |||
1173 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1174 | "Local client provided HELLO URL %s\n", | ||
1175 | url); | ||
1176 | b = GNUNET_HELLO_builder_from_url (url); | ||
1177 | if (NULL == b) | ||
1178 | { | ||
1179 | GNUNET_break (0); | ||
1180 | GNUNET_SERVICE_client_drop (ch->client); | ||
1181 | return; | ||
1182 | } | ||
1183 | GNUNET_SERVICE_client_continue (ch->client); | ||
1184 | GNUNET_HELLO_builder_iterate (b, | ||
1185 | &pid, | ||
1186 | &GDS_try_connect, | ||
1187 | &pid); | ||
1188 | GNUNET_HELLO_builder_free (b); | ||
1060 | } | 1189 | } |
1061 | 1190 | ||
1062 | 1191 | ||
@@ -1330,8 +1459,8 @@ response_action (void *cls, | |||
1330 | bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)); | 1459 | bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)); |
1331 | GNUNET_memcpy (path, | 1460 | GNUNET_memcpy (path, |
1332 | resp_ctx->get_path, | 1461 | resp_ctx->get_path, |
1333 | resp_ctx->get_path_length * sizeof(struct | 1462 | resp_ctx->get_path_length |
1334 | GNUNET_DHT_PathElement)); | 1463 | * sizeof(struct GNUNET_DHT_PathElement)); |
1335 | GNUNET_memcpy (&path[resp_ctx->get_path_length], | 1464 | GNUNET_memcpy (&path[resp_ctx->get_path_length], |
1336 | bd->data, | 1465 | bd->data, |
1337 | bd->data_size); | 1466 | bd->data_size); |
@@ -1504,6 +1633,14 @@ GDS_CLIENTS_stop (void) | |||
1504 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \ | 1633 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, \ |
1505 | struct GNUNET_DHT_ClientGetResultSeenMessage, \ | 1634 | struct GNUNET_DHT_ClientGetResultSeenMessage, \ |
1506 | NULL), \ | 1635 | NULL), \ |
1636 | GNUNET_MQ_hd_fixed_size (dht_local_hello_get, \ | ||
1637 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET, \ | ||
1638 | struct GNUNET_MessageHeader, \ | ||
1639 | NULL), \ | ||
1640 | GNUNET_MQ_hd_var_size (dht_local_hello_offer, \ | ||
1641 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL, \ | ||
1642 | struct GNUNET_MessageHeader, \ | ||
1643 | NULL), \ | ||
1507 | GNUNET_MQ_handler_end ()) | 1644 | GNUNET_MQ_handler_end ()) |
1508 | 1645 | ||
1509 | 1646 | ||
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index cb778717b..be0a6db81 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * How many "closest" results to we return for migration when | 36 | * How many "closest" results to we return for migration when |
37 | * asked (at most)? | 37 | * asked (at most)? |
38 | */ | 38 | */ |
39 | #define NUM_CLOSEST 42 | 39 | #define NUM_CLOSEST 4 |
40 | 40 | ||
41 | 41 | ||
42 | /** | 42 | /** |
@@ -68,7 +68,7 @@ GDS_DATACACHE_handle_put (const struct GDS_DATACACHE_BlockData *bd) | |||
68 | 1, | 68 | 1, |
69 | GNUNET_NO); | 69 | GNUNET_NO); |
70 | GNUNET_CRYPTO_hash_xor (&bd->key, | 70 | GNUNET_CRYPTO_hash_xor (&bd->key, |
71 | &my_identity_hash, | 71 | &GDS_my_identity_hash, |
72 | &xor); | 72 | &xor); |
73 | r = GNUNET_DATACACHE_put (datacache, | 73 | r = GNUNET_DATACACHE_put (datacache, |
74 | &bd->key, | 74 | &bd->key, |
@@ -126,7 +126,7 @@ struct GetRequestContext | |||
126 | /** | 126 | /** |
127 | * Return value to give back. | 127 | * Return value to give back. |
128 | */ | 128 | */ |
129 | enum GNUNET_BLOCK_EvaluationResult eval; | 129 | enum GNUNET_BLOCK_ReplyEvaluationResult eval; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | 132 | ||
@@ -204,13 +204,6 @@ datacache_get_iterator (void *cls, | |||
204 | 1, | 204 | 1, |
205 | GNUNET_NO); | 205 | GNUNET_NO); |
206 | break; | 206 | break; |
207 | case GNUNET_BLOCK_REPLY_INVALID: | ||
208 | /* maybe it expired? */ | ||
209 | GNUNET_STATISTICS_update (GDS_stats, | ||
210 | "# Invalid RESULTS found in datacache", | ||
211 | 1, | ||
212 | GNUNET_NO); | ||
213 | break; | ||
214 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | 207 | case GNUNET_BLOCK_REPLY_IRRELEVANT: |
215 | GNUNET_STATISTICS_update (GDS_stats, | 208 | GNUNET_STATISTICS_update (GDS_stats, |
216 | "# Irrelevant RESULTS found in datacache", | 209 | "# Irrelevant RESULTS found in datacache", |
@@ -222,7 +215,7 @@ datacache_get_iterator (void *cls, | |||
222 | } | 215 | } |
223 | 216 | ||
224 | 217 | ||
225 | enum GNUNET_BLOCK_EvaluationResult | 218 | enum GNUNET_BLOCK_ReplyEvaluationResult |
226 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | 219 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, |
227 | enum GNUNET_BLOCK_Type type, | 220 | enum GNUNET_BLOCK_Type type, |
228 | const void *xquery, | 221 | const void *xquery, |
@@ -231,22 +224,23 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
231 | GDS_DATACACHE_GetCallback gc, | 224 | GDS_DATACACHE_GetCallback gc, |
232 | void *gc_cls) | 225 | void *gc_cls) |
233 | { | 226 | { |
234 | struct GetRequestContext ctx; | 227 | struct GetRequestContext ctx = { |
228 | .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, | ||
229 | .key = *key, | ||
230 | .xquery = xquery, | ||
231 | .xquery_size = xquery_size, | ||
232 | .bg = bg, | ||
233 | .gc = gc, | ||
234 | .gc_cls = gc_cls | ||
235 | }; | ||
235 | unsigned int r; | 236 | unsigned int r; |
236 | 237 | ||
237 | if (NULL == datacache) | 238 | if (NULL == datacache) |
238 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | 239 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
239 | GNUNET_STATISTICS_update (GDS_stats, | 240 | GNUNET_STATISTICS_update (GDS_stats, |
240 | "# GET requests given to datacache", | 241 | "# GET requests given to datacache", |
241 | 1, | 242 | 1, |
242 | GNUNET_NO); | 243 | GNUNET_NO); |
243 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
244 | ctx.key = *key; | ||
245 | ctx.xquery = xquery; | ||
246 | ctx.xquery_size = xquery_size; | ||
247 | ctx.bg = bg; | ||
248 | ctx.gc = gc; | ||
249 | ctx.gc_cls = gc_cls; | ||
250 | r = GNUNET_DATACACHE_get (datacache, | 244 | r = GNUNET_DATACACHE_get (datacache, |
251 | key, | 245 | key, |
252 | type, | 246 | type, |
@@ -261,85 +255,44 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
261 | } | 255 | } |
262 | 256 | ||
263 | 257 | ||
264 | /** | 258 | enum GNUNET_BLOCK_ReplyEvaluationResult |
265 | * Closure for #datacache_get_successors_iterator(). | ||
266 | */ | ||
267 | struct SuccContext | ||
268 | { | ||
269 | /** | ||
270 | * Function to call on the result | ||
271 | */ | ||
272 | GDS_DATACACHE_GetCallback cb; | ||
273 | |||
274 | /** | ||
275 | * Closure for @e cb. | ||
276 | */ | ||
277 | void *cb_cls; | ||
278 | |||
279 | }; | ||
280 | |||
281 | |||
282 | /** | ||
283 | * Iterator for local get request results, | ||
284 | * | ||
285 | * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID | ||
286 | * @param key the key this data is stored under | ||
287 | * @param size the size of the data identified by key | ||
288 | * @param data the actual data | ||
289 | * @param type the type of the data | ||
290 | * @param exp when does this value expire? | ||
291 | * @param put_path_length number of peers in @a put_path | ||
292 | * @param put_path path the reply took on put | ||
293 | * @return #GNUNET_OK to continue iteration, anything else | ||
294 | * to stop iteration. | ||
295 | */ | ||
296 | static enum GNUNET_GenericReturnValue | ||
297 | datacache_get_successors_iterator (void *cls, | ||
298 | const struct GNUNET_HashCode *key, | ||
299 | size_t size, | ||
300 | const char *data, | ||
301 | enum GNUNET_BLOCK_Type type, | ||
302 | struct GNUNET_TIME_Absolute exp, | ||
303 | unsigned int put_path_length, | ||
304 | const struct | ||
305 | GNUNET_DHT_PathElement *put_path) | ||
306 | { | ||
307 | const struct SuccContext *sc = cls; | ||
308 | struct GDS_DATACACHE_BlockData bd = { | ||
309 | .key = *key, | ||
310 | .expiration_time = exp, | ||
311 | .put_path = put_path, | ||
312 | .data = data, | ||
313 | .data_size = size, | ||
314 | .put_path_length = put_path_length, | ||
315 | .type = type | ||
316 | }; | ||
317 | |||
318 | /* NOTE: The datacache currently does not store the RO from | ||
319 | the original 'put', so we don't know the 'correct' option | ||
320 | at this point anymore. Thus, we conservatively assume | ||
321 | that recording is desired (for now). */ | ||
322 | sc->cb (sc->cb_cls, | ||
323 | &bd); | ||
324 | return GNUNET_OK; | ||
325 | } | ||
326 | |||
327 | |||
328 | void | ||
329 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, | 259 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
260 | enum GNUNET_BLOCK_Type type, | ||
261 | const void *xquery, | ||
262 | size_t xquery_size, | ||
263 | struct GNUNET_BLOCK_Group *bg, | ||
330 | GDS_DATACACHE_GetCallback cb, | 264 | GDS_DATACACHE_GetCallback cb, |
331 | void *cb_cls) | 265 | void *cb_cls) |
332 | { | 266 | { |
333 | struct SuccContext sc = { | 267 | struct GetRequestContext ctx = { |
334 | .cb = cb, | 268 | .eval = GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, |
335 | .cb_cls = cb_cls | 269 | .key = *key, |
270 | .xquery = xquery, | ||
271 | .xquery_size = xquery_size, | ||
272 | .bg = bg, | ||
273 | .gc = cb, | ||
274 | .gc_cls = cb_cls | ||
336 | }; | 275 | }; |
276 | unsigned int r; | ||
337 | 277 | ||
338 | (void) GNUNET_DATACACHE_get_closest (datacache, | 278 | if (NULL == datacache) |
339 | key, | 279 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
340 | NUM_CLOSEST, | 280 | GNUNET_STATISTICS_update (GDS_stats, |
341 | &datacache_get_successors_iterator, | 281 | "# GET closest requests given to datacache", |
342 | &sc); | 282 | 1, |
283 | GNUNET_NO); | ||
284 | r = GNUNET_DATACACHE_get_closest (datacache, | ||
285 | key, | ||
286 | type, | ||
287 | NUM_CLOSEST, | ||
288 | &datacache_get_iterator, | ||
289 | &ctx); | ||
290 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
291 | "DATACACHE approximate GET for key %s completed (%d). %u results found.\n", | ||
292 | GNUNET_h2s (key), | ||
293 | ctx.eval, | ||
294 | r); | ||
295 | return ctx.eval; | ||
343 | } | 296 | } |
344 | 297 | ||
345 | 298 | ||
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 691a51e0e..d860139f5 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h | |||
@@ -107,7 +107,7 @@ typedef void | |||
107 | * @param gc_cls closure for @a gc | 107 | * @param gc_cls closure for @a gc |
108 | * @return evaluation result for the local replies | 108 | * @return evaluation result for the local replies |
109 | */ | 109 | */ |
110 | enum GNUNET_BLOCK_EvaluationResult | 110 | enum GNUNET_BLOCK_ReplyEvaluationResult |
111 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | 111 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, |
112 | enum GNUNET_BLOCK_Type type, | 112 | enum GNUNET_BLOCK_Type type, |
113 | const void *xquery, | 113 | const void *xquery, |
@@ -122,11 +122,20 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
122 | * another peer. | 122 | * another peer. |
123 | * | 123 | * |
124 | * @param key the location at which the peer is looking for data that is close | 124 | * @param key the location at which the peer is looking for data that is close |
125 | * @param type requested data type | ||
126 | * @param xquery extended query | ||
127 | * @param xquery_size number of bytes in xquery | ||
128 | * @param bg block group to use for evaluation of replies | ||
125 | * @param cb function to call with the result | 129 | * @param cb function to call with the result |
126 | * @param cb_cls closure for @a cb | 130 | * @param cb_cls closure for @a cb |
131 | * @return evaluation result for the local replies | ||
127 | */ | 132 | */ |
128 | void | 133 | enum GNUNET_BLOCK_ReplyEvaluationResult |
129 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, | 134 | GDS_DATACACHE_get_closest (const struct GNUNET_HashCode *key, |
135 | enum GNUNET_BLOCK_Type type, | ||
136 | const void *xquery, | ||
137 | size_t xquery_size, | ||
138 | struct GNUNET_BLOCK_Group *bg, | ||
130 | GDS_DATACACHE_GetCallback cb, | 139 | GDS_DATACACHE_GetCallback cb, |
131 | void *cb_cls); | 140 | void *cb_cls); |
132 | 141 | ||
diff --git a/src/dht/gnunet-service-dht_hello.c b/src/dht/gnunet-service-dht_hello.c deleted file mode 100644 index 949456575..000000000 --- a/src/dht/gnunet-service-dht_hello.c +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 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 | * @file dht/gnunet-service-dht_hello.c | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * TODO: | ||
27 | * - consider adding mechanism to remove expired HELLOs | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet-service-dht.h" | ||
31 | #include "gnunet-service-dht_hello.h" | ||
32 | #include "gnunet_peerinfo_service.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Handle for peerinfo notifications. | ||
37 | */ | ||
38 | static struct GNUNET_PEERINFO_NotifyContext *pnc; | ||
39 | |||
40 | /** | ||
41 | * Hash map of peers to HELLOs. | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_MultiPeerMap *peer_to_hello; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Obtain a peer's HELLO if available | ||
48 | * | ||
49 | * @param peer peer to look for a HELLO from | ||
50 | * @return HELLO for the given peer | ||
51 | */ | ||
52 | const struct GNUNET_HELLO_Message * | ||
53 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer) | ||
54 | { | ||
55 | if (NULL == peer_to_hello) | ||
56 | return NULL; | ||
57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, | ||
58 | peer); | ||
59 | } | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Function called for each HELLO known to PEERINFO. | ||
64 | * | ||
65 | * @param cls closure | ||
66 | * @param peer id of the peer, NULL for last call | ||
67 | * @param hello hello message for the peer (can be NULL) | ||
68 | * @param err_msg error message (not used) | ||
69 | * | ||
70 | * FIXME this is called once per address. Merge instead of replacing? | ||
71 | */ | ||
72 | static void | ||
73 | process_hello (void *cls, | ||
74 | const struct GNUNET_PeerIdentity *peer, | ||
75 | const struct GNUNET_HELLO_Message *hello, | ||
76 | const char *err_msg) | ||
77 | { | ||
78 | struct GNUNET_TIME_Absolute ex; | ||
79 | struct GNUNET_HELLO_Message *hm; | ||
80 | |||
81 | if (NULL == hello) | ||
82 | return; | ||
83 | ex = GNUNET_HELLO_get_last_expiration (hello); | ||
84 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) | ||
85 | return; | ||
86 | GNUNET_STATISTICS_update (GDS_stats, | ||
87 | "# HELLOs obtained from peerinfo", | ||
88 | 1, | ||
89 | GNUNET_NO); | ||
90 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, | ||
91 | peer); | ||
92 | GNUNET_free (hm); | ||
93 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); | ||
94 | GNUNET_memcpy (hm, | ||
95 | hello, | ||
96 | GNUNET_HELLO_size (hello)); | ||
97 | GNUNET_assert (GNUNET_SYSERR != | ||
98 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, | ||
99 | peer, | ||
100 | hm, | ||
101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); | ||
102 | } | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Initialize HELLO subsystem. | ||
107 | */ | ||
108 | void | ||
109 | GDS_HELLO_init () | ||
110 | { | ||
111 | pnc = GNUNET_PEERINFO_notify (GDS_cfg, | ||
112 | GNUNET_NO, | ||
113 | &process_hello, | ||
114 | NULL); | ||
115 | peer_to_hello = GNUNET_CONTAINER_multipeermap_create (256, | ||
116 | GNUNET_NO); | ||
117 | } | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Free memory occopied by the HELLO. | ||
122 | */ | ||
123 | static enum GNUNET_GenericReturnValue | ||
124 | free_hello (void *cls, | ||
125 | const struct GNUNET_PeerIdentity *key, | ||
126 | void *hello) | ||
127 | { | ||
128 | GNUNET_free (hello); | ||
129 | return GNUNET_OK; | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Shutdown HELLO subsystem. | ||
135 | */ | ||
136 | void | ||
137 | GDS_HELLO_done () | ||
138 | { | ||
139 | if (NULL != pnc) | ||
140 | { | ||
141 | GNUNET_PEERINFO_notify_cancel (pnc); | ||
142 | pnc = NULL; | ||
143 | } | ||
144 | if (NULL != peer_to_hello) | ||
145 | { | ||
146 | GNUNET_CONTAINER_multipeermap_iterate (peer_to_hello, | ||
147 | &free_hello, | ||
148 | NULL); | ||
149 | GNUNET_CONTAINER_multipeermap_destroy (peer_to_hello); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | |||
154 | /* end of gnunet-service-dht_hello.c */ | ||
diff --git a/src/dht/gnunet-service-dht_hello.h b/src/dht/gnunet-service-dht_hello.h deleted file mode 100644 index f8b90862d..000000000 --- a/src/dht/gnunet-service-dht_hello.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 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 | * @file dht/gnunet-service-dht_hello.h | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_DHT_HELLO_H | ||
27 | #define GNUNET_SERVICE_DHT_HELLO_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | |||
32 | /** | ||
33 | * Obtain a peer's HELLO if available | ||
34 | * | ||
35 | * @param peer peer to look for a HELLO from | ||
36 | * @return HELLO for the given peer | ||
37 | */ | ||
38 | const struct GNUNET_HELLO_Message * | ||
39 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer); | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Initialize HELLO subsystem. | ||
44 | */ | ||
45 | void | ||
46 | GDS_HELLO_init (void); | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Shutdown HELLO subsystem. | ||
51 | */ | ||
52 | void | ||
53 | GDS_HELLO_done (void); | ||
54 | |||
55 | #endif | ||
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index cf150ea0c..2f9cbab84 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -28,13 +28,10 @@ | |||
28 | #include "gnunet_constants.h" | 28 | #include "gnunet_constants.h" |
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "gnunet_signatures.h" | 30 | #include "gnunet_signatures.h" |
31 | #include "gnunet_ats_service.h" | ||
32 | #include "gnunet_core_service.h" | ||
33 | #include "gnunet_hello_lib.h" | 31 | #include "gnunet_hello_lib.h" |
32 | #include "gnunet_hello_uri_lib.h" | ||
34 | #include "gnunet-service-dht.h" | 33 | #include "gnunet-service-dht.h" |
35 | #include "gnunet-service-dht_hello.h" | ||
36 | #include "gnunet-service-dht_neighbours.h" | 34 | #include "gnunet-service-dht_neighbours.h" |
37 | #include "gnunet-service-dht_nse.h" | ||
38 | #include "gnunet-service-dht_routing.h" | 35 | #include "gnunet-service-dht_routing.h" |
39 | #include "dht.h" | 36 | #include "dht.h" |
40 | 37 | ||
@@ -42,9 +39,17 @@ | |||
42 | __VA_ARGS__) | 39 | __VA_ARGS__) |
43 | 40 | ||
44 | /** | 41 | /** |
45 | * Enable slow sanity checks to debug issues. | 42 | * Enable slow sanity checks to debug issues. |
43 | * | ||
44 | * TODO: might want to eventually implement probabilistic | ||
45 | * load-based path verification, but for now it is all or nothing | ||
46 | * based on this define. | ||
47 | * | ||
48 | * 0: do not check -- if signatures become performance critical | ||
49 | * 1: check all external inputs -- normal production for now | ||
50 | * 2: check internal computations as well -- for debugging | ||
46 | */ | 51 | */ |
47 | #define SANITY_CHECKS 1 | 52 | #define SANITY_CHECKS 2 |
48 | 53 | ||
49 | /** | 54 | /** |
50 | * How many buckets will we allow in total. | 55 | * How many buckets will we allow in total. |
@@ -74,6 +79,7 @@ | |||
74 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 79 | #define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
75 | GNUNET_TIME_UNIT_MINUTES, 2) | 80 | GNUNET_TIME_UNIT_MINUTES, 2) |
76 | 81 | ||
82 | |||
77 | /** | 83 | /** |
78 | * How long to additionally wait on average per #bucket_size to send out the | 84 | * How long to additionally wait on average per #bucket_size to send out the |
79 | * FIND PEER requests if we did successfully connect (!) to a a new peer and | 85 | * FIND PEER requests if we did successfully connect (!) to a a new peer and |
@@ -83,7 +89,7 @@ | |||
83 | * top). Also the range in which we randomize, so the effective value | 89 | * top). Also the range in which we randomize, so the effective value |
84 | * is half of the number given here. | 90 | * is half of the number given here. |
85 | */ | 91 | */ |
86 | #define DHT_AVG_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ | 92 | #define DHT_AVG_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply ( \ |
87 | GNUNET_TIME_UNIT_SECONDS, 6) | 93 | GNUNET_TIME_UNIT_SECONDS, 6) |
88 | 94 | ||
89 | /** | 95 | /** |
@@ -91,11 +97,6 @@ | |||
91 | */ | 97 | */ |
92 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) | 98 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) |
93 | 99 | ||
94 | /** | ||
95 | * Hello address expiration | ||
96 | */ | ||
97 | extern struct GNUNET_TIME_Relative hello_expiration; | ||
98 | |||
99 | 100 | ||
100 | GNUNET_NETWORK_STRUCT_BEGIN | 101 | GNUNET_NETWORK_STRUCT_BEGIN |
101 | 102 | ||
@@ -263,81 +264,134 @@ GNUNET_NETWORK_STRUCT_END | |||
263 | /** | 264 | /** |
264 | * Entry for a peer in a bucket. | 265 | * Entry for a peer in a bucket. |
265 | */ | 266 | */ |
266 | struct PeerInfo | 267 | struct PeerInfo; |
268 | |||
269 | |||
270 | /** | ||
271 | * List of targets that we can use to reach this peer. | ||
272 | */ | ||
273 | struct Target | ||
267 | { | 274 | { |
268 | /** | 275 | /** |
269 | * Next peer entry (DLL) | 276 | * Kept in a DLL. |
270 | */ | 277 | */ |
271 | struct PeerInfo *next; | 278 | struct Target *next; |
272 | 279 | ||
273 | /** | 280 | /** |
274 | * Prev peer entry (DLL) | 281 | * Kept in a DLL. |
275 | */ | 282 | */ |
276 | struct PeerInfo *prev; | 283 | struct Target *prev; |
277 | 284 | ||
278 | /** | 285 | /** |
279 | * Handle for sending messages to this peer. | 286 | * Handle for sending messages to this peer. |
280 | */ | 287 | */ |
281 | struct GNUNET_MQ_Handle *mq; | 288 | struct GNUNET_DHTU_Target *utarget; |
282 | 289 | ||
283 | /** | 290 | /** |
284 | * What is the identity of the peer? | 291 | * Underlay providing this target. |
285 | */ | 292 | */ |
286 | const struct GNUNET_PeerIdentity *id; | 293 | struct GDS_Underlay *u; |
287 | 294 | ||
288 | /** | 295 | /** |
289 | * Hash of @e id. | 296 | * Peer this is a target for. |
290 | */ | 297 | */ |
291 | struct GNUNET_HashCode phash; | 298 | struct PeerInfo *pi; |
292 | 299 | ||
293 | /** | 300 | /** |
294 | * Which bucket is this peer in? | 301 | * Handle used to 'hold' the connection to this peer. |
295 | */ | 302 | */ |
296 | int peer_bucket; | 303 | struct GNUNET_DHTU_PreferenceHandle *ph; |
304 | |||
305 | /** | ||
306 | * Set to number of messages are waiting for the transmission to finish. | ||
307 | */ | ||
308 | unsigned int load; | ||
309 | |||
310 | /** | ||
311 | * Set to @a true if the target was dropped, but we could not clean | ||
312 | * up yet because @e busy was also true. | ||
313 | */ | ||
314 | bool dropped; | ||
315 | |||
297 | }; | 316 | }; |
298 | 317 | ||
299 | 318 | ||
300 | /** | 319 | /** |
301 | * Peers are grouped into buckets. | 320 | * Entry for a peer in a bucket. |
302 | */ | 321 | */ |
303 | struct PeerBucket | 322 | struct PeerInfo |
304 | { | 323 | { |
305 | /** | 324 | /** |
306 | * Head of DLL | 325 | * What is the identity of the peer? |
307 | */ | 326 | */ |
308 | struct PeerInfo *head; | 327 | struct GNUNET_PeerIdentity id; |
309 | 328 | ||
310 | /** | 329 | /** |
311 | * Tail of DLL | 330 | * Hash of @e id. |
312 | */ | 331 | */ |
313 | struct PeerInfo *tail; | 332 | struct GNUNET_HashCode phash; |
314 | 333 | ||
315 | /** | 334 | /** |
316 | * Number of peers in the bucket. | 335 | * When does our HELLO from this peer expire? |
317 | */ | 336 | */ |
318 | unsigned int peers_size; | 337 | struct GNUNET_TIME_Absolute hello_expiration; |
338 | |||
339 | /** | ||
340 | * Next peer entry (DLL) | ||
341 | */ | ||
342 | struct PeerInfo *next; | ||
343 | |||
344 | /** | ||
345 | * Prev peer entry (DLL) | ||
346 | */ | ||
347 | struct PeerInfo *prev; | ||
348 | |||
349 | /** | ||
350 | * Head of DLL of targets for this peer. | ||
351 | */ | ||
352 | struct Target *t_head; | ||
353 | |||
354 | /** | ||
355 | * Tail of DLL of targets for this peer. | ||
356 | */ | ||
357 | struct Target *t_tail; | ||
358 | |||
359 | /** | ||
360 | * Block with a HELLO of this peer. | ||
361 | */ | ||
362 | void *hello; | ||
363 | |||
364 | /** | ||
365 | * Number of bytes in @e hello. | ||
366 | */ | ||
367 | size_t hello_size; | ||
368 | |||
369 | /** | ||
370 | * Which bucket is this peer in? | ||
371 | */ | ||
372 | int peer_bucket; | ||
319 | }; | 373 | }; |
320 | 374 | ||
321 | 375 | ||
322 | /** | 376 | /** |
323 | * Information about a peer that we would like to connect to. | 377 | * Peers are grouped into buckets. |
324 | */ | 378 | */ |
325 | struct ConnectInfo | 379 | struct PeerBucket |
326 | { | 380 | { |
327 | /** | 381 | /** |
328 | * Handle to active HELLO offer operation, or NULL. | 382 | * Head of DLL |
329 | */ | 383 | */ |
330 | struct GNUNET_TRANSPORT_OfferHelloHandle *oh; | 384 | struct PeerInfo *head; |
331 | 385 | ||
332 | /** | 386 | /** |
333 | * Handle to active connectivity suggestion operation, or NULL. | 387 | * Tail of DLL |
334 | */ | 388 | */ |
335 | struct GNUNET_ATS_ConnectivitySuggestHandle *sh; | 389 | struct PeerInfo *tail; |
336 | 390 | ||
337 | /** | 391 | /** |
338 | * How much would we like to connect to this peer? | 392 | * Number of peers in the bucket. |
339 | */ | 393 | */ |
340 | uint32_t strength; | 394 | unsigned int peers_size; |
341 | }; | 395 | }; |
342 | 396 | ||
343 | 397 | ||
@@ -374,12 +428,6 @@ static struct PeerBucket k_buckets[MAX_BUCKETS]; | |||
374 | static struct GNUNET_CONTAINER_MultiPeerMap *all_connected_peers; | 428 | static struct GNUNET_CONTAINER_MultiPeerMap *all_connected_peers; |
375 | 429 | ||
376 | /** | 430 | /** |
377 | * Hash map of all peers we would like to be connected to. | ||
378 | * Values are of type `struct ConnectInfo`. | ||
379 | */ | ||
380 | static struct GNUNET_CONTAINER_MultiPeerMap *all_desired_peers; | ||
381 | |||
382 | /** | ||
383 | * Maximum size for each bucket. | 431 | * Maximum size for each bucket. |
384 | */ | 432 | */ |
385 | static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; | 433 | static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; |
@@ -389,30 +437,83 @@ static unsigned int bucket_size = DEFAULT_BUCKET_SIZE; | |||
389 | */ | 437 | */ |
390 | static struct GNUNET_SCHEDULER_Task *find_peer_task; | 438 | static struct GNUNET_SCHEDULER_Task *find_peer_task; |
391 | 439 | ||
392 | /** | ||
393 | * Identity of this peer. | ||
394 | */ | ||
395 | static struct GNUNET_PeerIdentity my_identity; | ||
396 | 440 | ||
397 | /** | 441 | /** |
398 | * Hash of the identity of this peer. | 442 | * Function called whenever we finished sending to a target. |
443 | * Marks the transmission as finished (and the target as ready | ||
444 | * for the next message). | ||
445 | * | ||
446 | * @param cls a `struct Target *` | ||
399 | */ | 447 | */ |
400 | struct GNUNET_HashCode my_identity_hash; | 448 | static void |
449 | send_done_cb (void *cls) | ||
450 | { | ||
451 | struct Target *t = cls; | ||
452 | struct PeerInfo *pi = t->pi; /* NULL if t->dropped! */ | ||
401 | 453 | ||
402 | /** | 454 | GNUNET_assert (t->load > 0); |
403 | * Handle to CORE. | 455 | t->load--; |
404 | */ | 456 | if (0 < t->load) |
405 | static struct GNUNET_CORE_Handle *core_api; | 457 | return; |
458 | if (t->dropped) | ||
459 | { | ||
460 | GNUNET_free (t); | ||
461 | return; | ||
462 | } | ||
463 | /* move target back to the front */ | ||
464 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
465 | pi->t_tail, | ||
466 | t); | ||
467 | GNUNET_CONTAINER_DLL_insert (pi->t_head, | ||
468 | pi->t_tail, | ||
469 | t); | ||
470 | } | ||
406 | 471 | ||
407 | /** | ||
408 | * Handle to ATS connectivity. | ||
409 | */ | ||
410 | static struct GNUNET_ATS_ConnectivityHandle *ats_ch; | ||
411 | 472 | ||
412 | /** | 473 | /** |
413 | * Our private key. | 474 | * Send @a msg to @a pi. |
475 | * | ||
476 | * @param pi where to send the message | ||
477 | * @param msg message to send | ||
414 | */ | 478 | */ |
415 | static struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key; | 479 | static void |
480 | do_send (struct PeerInfo *pi, | ||
481 | const struct GNUNET_MessageHeader *msg) | ||
482 | { | ||
483 | struct Target *t; | ||
484 | |||
485 | for (t = pi->t_head; | ||
486 | NULL != t; | ||
487 | t = t->next) | ||
488 | if (t->load < MAXIMUM_PENDING_PER_PEER) | ||
489 | break; | ||
490 | if (NULL == t) | ||
491 | { | ||
492 | /* all targets busy, drop message */ | ||
493 | GNUNET_STATISTICS_update (GDS_stats, | ||
494 | "# messages dropped (underlays busy)", | ||
495 | 1, | ||
496 | GNUNET_NO); | ||
497 | return; | ||
498 | } | ||
499 | t->load++; | ||
500 | /* rotate busy targets to the end */ | ||
501 | if (MAXIMUM_PENDING_PER_PEER == t->load) | ||
502 | { | ||
503 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
504 | pi->t_tail, | ||
505 | t); | ||
506 | GNUNET_CONTAINER_DLL_insert_tail (pi->t_head, | ||
507 | pi->t_tail, | ||
508 | t); | ||
509 | } | ||
510 | GDS_u_send (t->u, | ||
511 | t->utarget, | ||
512 | msg, | ||
513 | ntohs (msg->size), | ||
514 | &send_done_cb, | ||
515 | t); | ||
516 | } | ||
416 | 517 | ||
417 | 518 | ||
418 | /** | 519 | /** |
@@ -426,11 +527,10 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key; | |||
426 | * @param pred predecessor peer ID | 527 | * @param pred predecessor peer ID |
427 | * @param succ successor peer ID | 528 | * @param succ successor peer ID |
428 | * @param[out] sig where to write the signature | 529 | * @param[out] sig where to write the signature |
429 | * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP) | 530 | * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP) |
430 | */ | 531 | */ |
431 | static void | 532 | static void |
432 | sign_path (const struct GNUNET_HashCode *key, | 533 | sign_path (const void *data, |
433 | const void *data, | ||
434 | size_t data_size, | 534 | size_t data_size, |
435 | struct GNUNET_TIME_Absolute exp_time, | 535 | struct GNUNET_TIME_Absolute exp_time, |
436 | const struct GNUNET_PeerIdentity *pred, | 536 | const struct GNUNET_PeerIdentity *pred, |
@@ -441,7 +541,6 @@ sign_path (const struct GNUNET_HashCode *key, | |||
441 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), | 541 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), |
442 | .purpose.size = htonl (sizeof (hs)), | 542 | .purpose.size = htonl (sizeof (hs)), |
443 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), | 543 | .expiration_time = GNUNET_TIME_absolute_hton (exp_time), |
444 | .key = *key, | ||
445 | .pred = *pred, | 544 | .pred = *pred, |
446 | .succ = *succ | 545 | .succ = *succ |
447 | }; | 546 | }; |
@@ -449,7 +548,7 @@ sign_path (const struct GNUNET_HashCode *key, | |||
449 | GNUNET_CRYPTO_hash (data, | 548 | GNUNET_CRYPTO_hash (data, |
450 | data_size, | 549 | data_size, |
451 | &hs.h_data); | 550 | &hs.h_data); |
452 | GNUNET_CRYPTO_eddsa_sign (&my_private_key, | 551 | GNUNET_CRYPTO_eddsa_sign (&GDS_my_private_key, |
453 | &hs, | 552 | &hs, |
454 | sig); | 553 | sig); |
455 | } | 554 | } |
@@ -469,7 +568,7 @@ find_bucket (const struct GNUNET_HashCode *hc) | |||
469 | unsigned int bits; | 568 | unsigned int bits; |
470 | 569 | ||
471 | GNUNET_CRYPTO_hash_xor (hc, | 570 | GNUNET_CRYPTO_hash_xor (hc, |
472 | &my_identity_hash, | 571 | &GDS_my_identity_hash, |
473 | &xor); | 572 | &xor); |
474 | bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | 573 | bits = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); |
475 | if (bits == MAX_BUCKETS) | 574 | if (bits == MAX_BUCKETS) |
@@ -483,171 +582,6 @@ find_bucket (const struct GNUNET_HashCode *hc) | |||
483 | 582 | ||
484 | 583 | ||
485 | /** | 584 | /** |
486 | * Function called when #GNUNET_TRANSPORT_offer_hello() is done. | ||
487 | * Clean up the "oh" field in the @a cls | ||
488 | * | ||
489 | * @param cls a `struct ConnectInfo` | ||
490 | */ | ||
491 | static void | ||
492 | offer_hello_done (void *cls) | ||
493 | { | ||
494 | struct ConnectInfo *ci = cls; | ||
495 | |||
496 | ci->oh = NULL; | ||
497 | } | ||
498 | |||
499 | |||
500 | /** | ||
501 | * Function called for all entries in #all_desired_peers to clean up. | ||
502 | * | ||
503 | * @param cls NULL | ||
504 | * @param peer peer the entry is for | ||
505 | * @param value the value to remove | ||
506 | * @return #GNUNET_YES | ||
507 | */ | ||
508 | static enum GNUNET_GenericReturnValue | ||
509 | free_connect_info (void *cls, | ||
510 | const struct GNUNET_PeerIdentity *peer, | ||
511 | void *value) | ||
512 | { | ||
513 | struct ConnectInfo *ci = value; | ||
514 | |||
515 | (void) cls; | ||
516 | GNUNET_assert (GNUNET_YES == | ||
517 | GNUNET_CONTAINER_multipeermap_remove (all_desired_peers, | ||
518 | peer, | ||
519 | ci)); | ||
520 | if (NULL != ci->sh) | ||
521 | { | ||
522 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); | ||
523 | ci->sh = NULL; | ||
524 | } | ||
525 | if (NULL != ci->oh) | ||
526 | { | ||
527 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | ||
528 | ci->oh = NULL; | ||
529 | } | ||
530 | GNUNET_free (ci); | ||
531 | return GNUNET_YES; | ||
532 | } | ||
533 | |||
534 | |||
535 | /** | ||
536 | * Consider if we want to connect to a given peer, and if so | ||
537 | * let ATS know. If applicable, the HELLO is offered to the | ||
538 | * TRANSPORT service. | ||
539 | * | ||
540 | * @param pid peer to consider connectivity requirements for | ||
541 | * @param h a HELLO message, or NULL | ||
542 | */ | ||
543 | static void | ||
544 | try_connect (const struct GNUNET_PeerIdentity *pid, | ||
545 | const struct GNUNET_MessageHeader *h) | ||
546 | { | ||
547 | int bucket_idx; | ||
548 | struct GNUNET_HashCode pid_hash; | ||
549 | struct ConnectInfo *ci; | ||
550 | uint32_t strength; | ||
551 | struct PeerBucket *bucket; | ||
552 | |||
553 | GNUNET_CRYPTO_hash (pid, | ||
554 | sizeof(struct GNUNET_PeerIdentity), | ||
555 | &pid_hash); | ||
556 | bucket_idx = find_bucket (&pid_hash); | ||
557 | if (bucket_idx < 0) | ||
558 | { | ||
559 | GNUNET_break (0); | ||
560 | return; /* self!? */ | ||
561 | } | ||
562 | bucket = &k_buckets[bucket_idx]; | ||
563 | ci = GNUNET_CONTAINER_multipeermap_get (all_desired_peers, | ||
564 | pid); | ||
565 | if (bucket->peers_size < bucket_size) | ||
566 | strength = (bucket_size - bucket->peers_size) * bucket_idx; | ||
567 | else | ||
568 | strength = 0; | ||
569 | if (GNUNET_YES == | ||
570 | GNUNET_CONTAINER_multipeermap_contains (all_connected_peers, | ||
571 | pid)) | ||
572 | strength *= 2; /* double for connected peers */ | ||
573 | if ( (0 == strength) && | ||
574 | (NULL != ci) ) | ||
575 | { | ||
576 | /* release request */ | ||
577 | GNUNET_assert (GNUNET_YES == | ||
578 | free_connect_info (NULL, | ||
579 | pid, | ||
580 | ci)); | ||
581 | return; | ||
582 | } | ||
583 | if (NULL == ci) | ||
584 | { | ||
585 | ci = GNUNET_new (struct ConnectInfo); | ||
586 | GNUNET_assert (GNUNET_OK == | ||
587 | GNUNET_CONTAINER_multipeermap_put (all_desired_peers, | ||
588 | pid, | ||
589 | ci, | ||
590 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
591 | } | ||
592 | if ( (NULL != ci->oh) && | ||
593 | (NULL != h) ) | ||
594 | GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); | ||
595 | if (NULL != h) | ||
596 | ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg, | ||
597 | h, | ||
598 | &offer_hello_done, | ||
599 | ci); | ||
600 | if ( (NULL != ci->sh) && | ||
601 | (ci->strength != strength) ) | ||
602 | GNUNET_ATS_connectivity_suggest_cancel (ci->sh); | ||
603 | if (ci->strength != strength) | ||
604 | { | ||
605 | ci->sh = GNUNET_ATS_connectivity_suggest (ats_ch, | ||
606 | pid, | ||
607 | strength); | ||
608 | ci->strength = strength; | ||
609 | } | ||
610 | } | ||
611 | |||
612 | |||
613 | /** | ||
614 | * Function called for each peer in #all_desired_peers during | ||
615 | * #update_connect_preferences() if we have reason to adjust | ||
616 | * the strength of our desire to keep connections to certain | ||
617 | * peers. Calls #try_connect() to update the calculations for | ||
618 | * the given @a pid. | ||
619 | * | ||
620 | * @param cls NULL | ||
621 | * @param pid peer to update | ||
622 | * @param value unused | ||
623 | * @return #GNUNET_YES (continue to iterate) | ||
624 | */ | ||
625 | static enum GNUNET_GenericReturnValue | ||
626 | update_desire_strength (void *cls, | ||
627 | const struct GNUNET_PeerIdentity *pid, | ||
628 | void *value) | ||
629 | { | ||
630 | (void) cls; | ||
631 | (void) value; | ||
632 | try_connect (pid, | ||
633 | NULL); | ||
634 | return GNUNET_YES; | ||
635 | } | ||
636 | |||
637 | |||
638 | /** | ||
639 | * Update our preferences for connectivity as given to ATS. | ||
640 | */ | ||
641 | static void | ||
642 | update_connect_preferences (void) | ||
643 | { | ||
644 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, | ||
645 | &update_desire_strength, | ||
646 | NULL); | ||
647 | } | ||
648 | |||
649 | |||
650 | /** | ||
651 | * Add each of the peers we already know to the Bloom filter of | 585 | * Add each of the peers we already know to the Bloom filter of |
652 | * the request so that we don't get duplicate HELLOs. | 586 | * the request so that we don't get duplicate HELLOs. |
653 | * | 587 | * |
@@ -702,7 +636,7 @@ send_find_peer_message (void *cls) | |||
702 | GNUNET_CRYPTO_QUALITY_WEAK, | 636 | GNUNET_CRYPTO_QUALITY_WEAK, |
703 | GNUNET_TIME_relative_multiply ( | 637 | GNUNET_TIME_relative_multiply ( |
704 | DHT_AVG_FIND_PEER_INTERVAL, | 638 | DHT_AVG_FIND_PEER_INTERVAL, |
705 | 100 * (1 + newly_found_peers) / bucket_size).rel_value_us); | 639 | 1 + 100 * (1 + newly_found_peers) / bucket_size).rel_value_us); |
706 | newly_found_peers = 0; | 640 | newly_found_peers = 0; |
707 | GNUNET_assert (NULL == find_peer_task); | 641 | GNUNET_assert (NULL == find_peer_task); |
708 | find_peer_task = | 642 | find_peer_task = |
@@ -719,7 +653,7 @@ send_find_peer_message (void *cls) | |||
719 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; | 653 | struct GNUNET_CONTAINER_BloomFilter *peer_bf; |
720 | 654 | ||
721 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | 655 | bg = GNUNET_BLOCK_group_create (GDS_block_context, |
722 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 656 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
723 | GNUNET_CRYPTO_random_u32 ( | 657 | GNUNET_CRYPTO_random_u32 ( |
724 | GNUNET_CRYPTO_QUALITY_WEAK, | 658 | GNUNET_CRYPTO_QUALITY_WEAK, |
725 | UINT32_MAX), | 659 | UINT32_MAX), |
@@ -736,12 +670,12 @@ send_find_peer_message (void *cls) | |||
736 | DHT_BLOOM_SIZE, | 670 | DHT_BLOOM_SIZE, |
737 | GNUNET_CONSTANTS_BLOOMFILTER_K); | 671 | GNUNET_CONSTANTS_BLOOMFILTER_K); |
738 | if (GNUNET_OK != | 672 | if (GNUNET_OK != |
739 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | 673 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
740 | GNUNET_DHT_RO_FIND_PEER | 674 | GNUNET_DHT_RO_FIND_APPROXIMATE |
741 | | GNUNET_DHT_RO_RECORD_ROUTE, | 675 | | GNUNET_DHT_RO_RECORD_ROUTE, |
742 | FIND_PEER_REPLICATION_LEVEL, | 676 | FIND_PEER_REPLICATION_LEVEL, |
743 | 0, /* hop count */ | 677 | 0, /* hop count */ |
744 | &my_identity_hash, | 678 | &GDS_my_identity_hash, |
745 | NULL, 0, /* xquery */ | 679 | NULL, 0, /* xquery */ |
746 | bg, | 680 | bg, |
747 | peer_bf)) | 681 | peer_bf)) |
@@ -765,123 +699,180 @@ send_find_peer_message (void *cls) | |||
765 | 699 | ||
766 | 700 | ||
767 | /** | 701 | /** |
768 | * Method called whenever a peer connects. | 702 | * The list of the first #bucket_size peers of @a bucket |
703 | * changed. We should thus make sure we have called 'hold' | ||
704 | * all of the first bucket_size peers! | ||
769 | * | 705 | * |
770 | * @param cls closure | 706 | * @param[in,out] bucket the bucket where the peer set changed |
771 | * @param peer peer identity this notification is about | ||
772 | * @param mq message queue for sending messages to @a peer | ||
773 | * @return our `struct PeerInfo` for @a peer | ||
774 | */ | 707 | */ |
775 | static void * | 708 | static void |
776 | handle_core_connect (void *cls, | 709 | update_hold (struct PeerBucket *bucket) |
777 | const struct GNUNET_PeerIdentity *peer, | ||
778 | struct GNUNET_MQ_Handle *mq) | ||
779 | { | 710 | { |
711 | unsigned int off = 0; | ||
712 | |||
713 | /* find the peer -- we just go over all of them, should | ||
714 | be hardly any more expensive than just finding the 'right' | ||
715 | one. */ | ||
716 | for (struct PeerInfo *pos = bucket->head; | ||
717 | NULL != pos; | ||
718 | pos = pos->next) | ||
719 | { | ||
720 | if (off > bucket_size) | ||
721 | break; /* We only hold up to #bucket_size peers per bucket */ | ||
722 | off++; | ||
723 | for (struct Target *tp = pos->t_head; | ||
724 | NULL != tp; | ||
725 | tp = tp->next) | ||
726 | if (NULL == tp->ph) | ||
727 | tp->ph = GDS_u_hold (tp->u, | ||
728 | tp->utarget); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | |||
733 | void | ||
734 | GDS_u_connect (void *cls, | ||
735 | struct GNUNET_DHTU_Target *target, | ||
736 | const struct GNUNET_PeerIdentity *pid, | ||
737 | void **ctx) | ||
738 | { | ||
739 | struct GDS_Underlay *u = cls; | ||
780 | struct PeerInfo *pi; | 740 | struct PeerInfo *pi; |
781 | struct PeerBucket *bucket; | 741 | struct PeerBucket *bucket; |
742 | bool do_hold = false; | ||
782 | 743 | ||
783 | (void) cls; | ||
784 | /* Check for connect to self message */ | 744 | /* Check for connect to self message */ |
785 | if (0 == GNUNET_memcmp (&my_identity, | 745 | if (0 == GNUNET_memcmp (&GDS_my_identity, |
786 | peer)) | 746 | pid)) |
787 | return NULL; | 747 | return; |
788 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 748 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
789 | "Connected to peer %s\n", | 749 | "Connected to peer %s\n", |
790 | GNUNET_i2s (peer)); | 750 | GNUNET_i2s (pid)); |
791 | GNUNET_assert (NULL == | 751 | pi = GNUNET_CONTAINER_multipeermap_get (all_connected_peers, |
792 | GNUNET_CONTAINER_multipeermap_get (all_connected_peers, | 752 | pid); |
793 | peer)); | 753 | if (NULL == pi) |
794 | GNUNET_STATISTICS_update (GDS_stats, | ||
795 | "# peers connected", | ||
796 | 1, | ||
797 | GNUNET_NO); | ||
798 | pi = GNUNET_new (struct PeerInfo); | ||
799 | pi->id = peer; | ||
800 | pi->mq = mq; | ||
801 | GNUNET_CRYPTO_hash (peer, | ||
802 | sizeof(struct GNUNET_PeerIdentity), | ||
803 | &pi->phash); | ||
804 | pi->peer_bucket = find_bucket (&pi->phash); | ||
805 | GNUNET_assert ( (pi->peer_bucket >= 0) && | ||
806 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | ||
807 | bucket = &k_buckets[pi->peer_bucket]; | ||
808 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, | ||
809 | bucket->tail, | ||
810 | pi); | ||
811 | bucket->peers_size++; | ||
812 | closest_bucket = GNUNET_MAX (closest_bucket, | ||
813 | (unsigned int) pi->peer_bucket + 1); | ||
814 | GNUNET_assert (GNUNET_OK == | ||
815 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | ||
816 | pi->id, | ||
817 | pi, | ||
818 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
819 | if (bucket->peers_size <= bucket_size) | ||
820 | { | 754 | { |
821 | update_connect_preferences (); | 755 | GNUNET_STATISTICS_update (GDS_stats, |
822 | newly_found_peers++; | 756 | "# peers connected", |
757 | 1, | ||
758 | GNUNET_NO); | ||
759 | pi = GNUNET_new (struct PeerInfo); | ||
760 | pi->id = *pid; | ||
761 | GNUNET_CRYPTO_hash (pid, | ||
762 | sizeof(*pid), | ||
763 | &pi->phash); | ||
764 | pi->peer_bucket = find_bucket (&pi->phash); | ||
765 | GNUNET_assert ( (pi->peer_bucket >= 0) && | ||
766 | ((unsigned int) pi->peer_bucket < MAX_BUCKETS)); | ||
767 | bucket = &k_buckets[pi->peer_bucket]; | ||
768 | GNUNET_CONTAINER_DLL_insert_tail (bucket->head, | ||
769 | bucket->tail, | ||
770 | pi); | ||
771 | bucket->peers_size++; | ||
772 | closest_bucket = GNUNET_MAX (closest_bucket, | ||
773 | (unsigned int) pi->peer_bucket + 1); | ||
774 | GNUNET_assert (GNUNET_OK == | ||
775 | GNUNET_CONTAINER_multipeermap_put (all_connected_peers, | ||
776 | &pi->id, | ||
777 | pi, | ||
778 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
779 | if (bucket->peers_size <= bucket_size) | ||
780 | { | ||
781 | newly_found_peers++; | ||
782 | do_hold = true; | ||
783 | } | ||
784 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | ||
785 | (GNUNET_YES != disable_try_connect) ) | ||
786 | { | ||
787 | /* got a first connection, good time to start with FIND PEER requests... */ | ||
788 | GNUNET_assert (NULL == find_peer_task); | ||
789 | find_peer_task = GNUNET_SCHEDULER_add_now (&send_find_peer_message, | ||
790 | NULL); | ||
791 | } | ||
823 | } | 792 | } |
824 | if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | ||
825 | (GNUNET_YES != disable_try_connect) ) | ||
826 | { | 793 | { |
827 | /* got a first connection, good time to start with FIND PEER requests... */ | 794 | struct Target *t; |
828 | GNUNET_assert (NULL == find_peer_task); | 795 | |
829 | find_peer_task = GNUNET_SCHEDULER_add_now (&send_find_peer_message, | 796 | t = GNUNET_new (struct Target); |
830 | NULL); | 797 | t->u = u; |
798 | t->utarget = target; | ||
799 | t->pi = pi; | ||
800 | GNUNET_CONTAINER_DLL_insert (pi->t_head, | ||
801 | pi->t_tail, | ||
802 | t); | ||
803 | *ctx = t; | ||
804 | |||
831 | } | 805 | } |
832 | return pi; | 806 | if (do_hold) |
807 | update_hold (bucket); | ||
833 | } | 808 | } |
834 | 809 | ||
835 | 810 | ||
836 | /** | 811 | void |
837 | * Method called whenever a peer disconnects. | 812 | GDS_u_disconnect (void *ctx) |
838 | * | ||
839 | * @param cls closure | ||
840 | * @param peer peer identity this notification is about | ||
841 | * @param internal_cls our `struct PeerInfo` for @a peer | ||
842 | */ | ||
843 | static void | ||
844 | handle_core_disconnect (void *cls, | ||
845 | const struct GNUNET_PeerIdentity *peer, | ||
846 | void *internal_cls) | ||
847 | { | 813 | { |
848 | struct PeerInfo *to_remove = internal_cls; | 814 | struct Target *t = ctx; |
815 | struct PeerInfo *pi; | ||
849 | struct PeerBucket *bucket; | 816 | struct PeerBucket *bucket; |
817 | bool was_held = false; | ||
850 | 818 | ||
851 | (void) cls; | ||
852 | /* Check for disconnect from self message (on shutdown) */ | 819 | /* Check for disconnect from self message (on shutdown) */ |
853 | if (NULL == to_remove) | 820 | if (NULL == t) |
854 | return; | 821 | return; |
822 | pi = t->pi; | ||
823 | GNUNET_CONTAINER_DLL_remove (pi->t_head, | ||
824 | pi->t_tail, | ||
825 | t); | ||
826 | if (NULL != t->ph) | ||
827 | { | ||
828 | GDS_u_drop (t->u, | ||
829 | t->ph); | ||
830 | t->ph = NULL; | ||
831 | was_held = true; | ||
832 | } | ||
833 | if (t->load > 0) | ||
834 | { | ||
835 | t->dropped = true; | ||
836 | t->pi = NULL; | ||
837 | } | ||
838 | else | ||
839 | { | ||
840 | GNUNET_free (t); | ||
841 | } | ||
842 | if (NULL != pi->t_head) | ||
843 | return; /* got other connections still */ | ||
855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 844 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
856 | "Disconnected from peer %s\n", | 845 | "Disconnected from peer %s\n", |
857 | GNUNET_i2s (peer)); | 846 | GNUNET_i2s (&pi->id)); |
858 | GNUNET_STATISTICS_update (GDS_stats, | 847 | GNUNET_STATISTICS_update (GDS_stats, |
859 | "# peers connected", | 848 | "# peers connected", |
860 | -1, | 849 | -1, |
861 | GNUNET_NO); | 850 | GNUNET_NO); |
862 | GNUNET_assert (GNUNET_YES == | 851 | GNUNET_assert (GNUNET_YES == |
863 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, | 852 | GNUNET_CONTAINER_multipeermap_remove (all_connected_peers, |
864 | peer, | 853 | &pi->id, |
865 | to_remove)); | 854 | pi)); |
866 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && | 855 | if ( (0 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && |
867 | (GNUNET_YES != disable_try_connect)) | 856 | (GNUNET_YES != disable_try_connect)) |
868 | { | 857 | { |
869 | GNUNET_SCHEDULER_cancel (find_peer_task); | 858 | GNUNET_SCHEDULER_cancel (find_peer_task); |
870 | find_peer_task = NULL; | 859 | find_peer_task = NULL; |
871 | } | 860 | } |
872 | GNUNET_assert (to_remove->peer_bucket >= 0); | 861 | GNUNET_assert (pi->peer_bucket >= 0); |
873 | bucket = &k_buckets[to_remove->peer_bucket]; | 862 | bucket = &k_buckets[pi->peer_bucket]; |
874 | GNUNET_CONTAINER_DLL_remove (bucket->head, | 863 | GNUNET_CONTAINER_DLL_remove (bucket->head, |
875 | bucket->tail, | 864 | bucket->tail, |
876 | to_remove); | 865 | pi); |
877 | GNUNET_assert (bucket->peers_size > 0); | 866 | GNUNET_assert (bucket->peers_size > 0); |
878 | bucket->peers_size--; | 867 | bucket->peers_size--; |
868 | if ( (was_held) && | ||
869 | (bucket->peers_size >= bucket_size - 1) ) | ||
870 | update_hold (bucket); | ||
879 | while ( (closest_bucket > 0) && | 871 | while ( (closest_bucket > 0) && |
880 | (0 == k_buckets[closest_bucket - 1].peers_size)) | 872 | (0 == k_buckets[closest_bucket - 1].peers_size)) |
881 | closest_bucket--; | 873 | closest_bucket--; |
882 | if (bucket->peers_size < bucket_size) | 874 | GNUNET_free (pi->hello); |
883 | update_connect_preferences (); | 875 | GNUNET_free (pi); |
884 | GNUNET_free (to_remove); | ||
885 | } | 876 | } |
886 | 877 | ||
887 | 878 | ||
@@ -894,17 +885,14 @@ handle_core_disconnect (void *cls, | |||
894 | * @return Some number of peers to forward the message to | 885 | * @return Some number of peers to forward the message to |
895 | */ | 886 | */ |
896 | static unsigned int | 887 | static unsigned int |
897 | get_forward_count (uint32_t hop_count, | 888 | get_forward_count (uint16_t hop_count, |
898 | uint32_t target_replication) | 889 | uint16_t target_replication) |
899 | { | 890 | { |
900 | uint32_t random_value; | 891 | uint32_t random_value; |
901 | uint32_t forward_count; | 892 | uint32_t forward_count; |
902 | float target_value; | 893 | float target_value; |
894 | float rm1; | ||
903 | 895 | ||
904 | if (0 == target_replication) | ||
905 | target_replication = 1; /* 0 is verboten */ | ||
906 | if (target_replication > GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL) | ||
907 | target_replication = GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL; | ||
908 | if (hop_count > GDS_NSE_get () * 4.0) | 896 | if (hop_count > GDS_NSE_get () * 4.0) |
909 | { | 897 | { |
910 | /* forcefully terminate */ | 898 | /* forcefully terminate */ |
@@ -919,15 +907,15 @@ get_forward_count (uint32_t hop_count, | |||
919 | /* Once we have reached our ideal number of hops, only forward to 1 peer */ | 907 | /* Once we have reached our ideal number of hops, only forward to 1 peer */ |
920 | return 1; | 908 | return 1; |
921 | } | 909 | } |
922 | /* bound by system-wide maximum */ | 910 | /* bound by system-wide maximum and minimum */ |
911 | if (0 == target_replication) | ||
912 | target_replication = 1; /* 0 is verboten */ | ||
923 | target_replication = | 913 | target_replication = |
924 | GNUNET_MIN (GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL, | 914 | GNUNET_MIN (GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL, |
925 | target_replication); | 915 | target_replication); |
916 | rm1 = target_replication - 1.0; | ||
926 | target_value = | 917 | target_value = |
927 | 1 + (target_replication - 1.0) / (GDS_NSE_get () | 918 | 1 + (rm1) / (GDS_NSE_get () + (rm1 * hop_count)); |
928 | + ((float) (target_replication - 1.0) | ||
929 | * hop_count)); | ||
930 | |||
931 | 919 | ||
932 | /* Set forward count to floor of target_value */ | 920 | /* Set forward count to floor of target_value */ |
933 | forward_count = (uint32_t) target_value; | 921 | forward_count = (uint32_t) target_value; |
@@ -956,7 +944,7 @@ enum GNUNET_GenericReturnValue | |||
956 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, | 944 | GDS_am_closest_peer (const struct GNUNET_HashCode *key, |
957 | const struct GNUNET_CONTAINER_BloomFilter *bloom) | 945 | const struct GNUNET_CONTAINER_BloomFilter *bloom) |
958 | { | 946 | { |
959 | if (0 == GNUNET_memcmp (&my_identity_hash, | 947 | if (0 == GNUNET_memcmp (&GDS_my_identity_hash, |
960 | key)) | 948 | key)) |
961 | return GNUNET_YES; | 949 | return GNUNET_YES; |
962 | for (int bucket_num = find_bucket (key); | 950 | for (int bucket_num = find_bucket (key); |
@@ -983,7 +971,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
983 | because an unfiltered peer exists, we are not the | 971 | because an unfiltered peer exists, we are not the |
984 | closest. */ | 972 | closest. */ |
985 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, | 973 | int delta = GNUNET_CRYPTO_hash_xorcmp (&pos->phash, |
986 | &my_identity_hash, | 974 | &GDS_my_identity_hash, |
987 | key); | 975 | key); |
988 | switch (delta) | 976 | switch (delta) |
989 | { | 977 | { |
@@ -1047,7 +1035,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1047 | struct GNUNET_HashCode xor; | 1035 | struct GNUNET_HashCode xor; |
1048 | 1036 | ||
1049 | GNUNET_CRYPTO_hash_xor (key, | 1037 | GNUNET_CRYPTO_hash_xor (key, |
1050 | &my_identity_hash, | 1038 | &GDS_my_identity_hash, |
1051 | &xor); | 1039 | &xor); |
1052 | best_bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); | 1040 | best_bucket = GNUNET_CRYPTO_hash_count_leading_zeros (&xor); |
1053 | } | 1041 | } |
@@ -1067,13 +1055,14 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1067 | if (count >= bucket_size) | 1055 | if (count >= bucket_size) |
1068 | break; /* we only consider first #bucket_size entries per bucket */ | 1056 | break; /* we only consider first #bucket_size entries per bucket */ |
1069 | count++; | 1057 | count++; |
1070 | if (GNUNET_YES == | 1058 | if ( (NULL != bloom) && |
1071 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1059 | (GNUNET_YES == |
1072 | &pos->phash)) | 1060 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1061 | &pos->phash)) ) | ||
1073 | { | 1062 | { |
1074 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1063 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1075 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", | 1064 | "Excluded peer `%s' due to BF match in greedy routing for %s\n", |
1076 | GNUNET_i2s (pos->id), | 1065 | GNUNET_i2s (&pos->id), |
1077 | GNUNET_h2s (key)); | 1066 | GNUNET_h2s (key)); |
1078 | continue; | 1067 | continue; |
1079 | } | 1068 | } |
@@ -1140,7 +1129,7 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1140 | } | 1129 | } |
1141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1130 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1142 | "Selected peer `%s' in greedy routing for %s\n", | 1131 | "Selected peer `%s' in greedy routing for %s\n", |
1143 | GNUNET_i2s (chosen->id), | 1132 | GNUNET_i2s (&chosen->id), |
1144 | GNUNET_h2s (key)); | 1133 | GNUNET_h2s (key)); |
1145 | return chosen; | 1134 | return chosen; |
1146 | } /* end of 'greedy' peer selection */ | 1135 | } /* end of 'greedy' peer selection */ |
@@ -1155,22 +1144,24 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1155 | 1144 | ||
1156 | for (unsigned int bc = 0; bc < closest_bucket; bc++) | 1145 | for (unsigned int bc = 0; bc < closest_bucket; bc++) |
1157 | { | 1146 | { |
1147 | struct PeerBucket *bucket = &k_buckets[bc]; | ||
1158 | unsigned int count = 0; | 1148 | unsigned int count = 0; |
1159 | 1149 | ||
1160 | for (struct PeerInfo *pos = k_buckets[bc].head; | 1150 | for (struct PeerInfo *pos = bucket->head; |
1161 | NULL != pos; | 1151 | NULL != pos; |
1162 | pos = pos->next) | 1152 | pos = pos->next) |
1163 | { | 1153 | { |
1164 | count++; | 1154 | count++; |
1165 | if (count > bucket_size) | 1155 | if (count > bucket_size) |
1166 | break; /* limits search to #bucket_size peers per bucket */ | 1156 | break; /* limits search to #bucket_size peers per bucket */ |
1167 | if (GNUNET_YES == | 1157 | if ( (NULL != bloom) && |
1168 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1158 | (GNUNET_YES == |
1169 | &pos->phash)) | 1159 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1160 | &pos->phash)) ) | ||
1170 | { | 1161 | { |
1171 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1162 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1172 | "Excluded peer `%s' due to BF match in random routing for %s\n", | 1163 | "Excluded peer `%s' due to BF match in random routing for %s\n", |
1173 | GNUNET_i2s (pos->id), | 1164 | GNUNET_i2s (&pos->id), |
1174 | GNUNET_h2s (key)); | 1165 | GNUNET_h2s (key)); |
1175 | continue; /* Ignore filtered peers */ | 1166 | continue; /* Ignore filtered peers */ |
1176 | } | 1167 | } |
@@ -1201,15 +1192,16 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1201 | if (count > bucket_size) | 1192 | if (count > bucket_size) |
1202 | break; /* limits search to #bucket_size peers per bucket */ | 1193 | break; /* limits search to #bucket_size peers per bucket */ |
1203 | 1194 | ||
1204 | if (GNUNET_YES == | 1195 | if ( (NULL != bloom) && |
1205 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1196 | (GNUNET_YES == |
1206 | &pos->phash)) | 1197 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1198 | &pos->phash)) ) | ||
1207 | continue; /* Ignore bloomfiltered peers */ | 1199 | continue; /* Ignore bloomfiltered peers */ |
1208 | if (0 == selected--) | 1200 | if (0 == selected--) |
1209 | { | 1201 | { |
1210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1211 | "Selected peer `%s' in random routing for %s\n", | 1203 | "Selected peer `%s' in random routing for %s\n", |
1212 | GNUNET_i2s (pos->id), | 1204 | GNUNET_i2s (&pos->id), |
1213 | GNUNET_h2s (key)); | 1205 | GNUNET_h2s (key)); |
1214 | return pos; | 1206 | return pos; |
1215 | } | 1207 | } |
@@ -1237,8 +1229,8 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1237 | static unsigned int | 1229 | static unsigned int |
1238 | get_target_peers (const struct GNUNET_HashCode *key, | 1230 | get_target_peers (const struct GNUNET_HashCode *key, |
1239 | struct GNUNET_CONTAINER_BloomFilter *bloom, | 1231 | struct GNUNET_CONTAINER_BloomFilter *bloom, |
1240 | uint32_t hop_count, | 1232 | uint16_t hop_count, |
1241 | uint32_t target_replication, | 1233 | uint16_t target_replication, |
1242 | struct PeerInfo ***targets) | 1234 | struct PeerInfo ***targets) |
1243 | { | 1235 | { |
1244 | unsigned int target; | 1236 | unsigned int target; |
@@ -1294,11 +1286,36 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1294 | } | 1286 | } |
1295 | 1287 | ||
1296 | 1288 | ||
1289 | /** | ||
1290 | * If we got a HELLO, consider it for our own routing table | ||
1291 | * | ||
1292 | * @param bd block data we got | ||
1293 | */ | ||
1294 | static void | ||
1295 | hello_check (const struct GDS_DATACACHE_BlockData *bd) | ||
1296 | { | ||
1297 | struct GNUNET_PeerIdentity pid; | ||
1298 | struct GNUNET_HELLO_Builder *b; | ||
1299 | |||
1300 | if (GNUNET_BLOCK_TYPE_DHT_URL_HELLO != bd->type) | ||
1301 | return; | ||
1302 | |||
1303 | b = GNUNET_HELLO_builder_from_block (bd->data, | ||
1304 | bd->data_size); | ||
1305 | if (GNUNET_YES != disable_try_connect) | ||
1306 | GNUNET_HELLO_builder_iterate (b, | ||
1307 | &pid, | ||
1308 | &GDS_try_connect, | ||
1309 | &pid); | ||
1310 | GNUNET_HELLO_builder_free (b); | ||
1311 | } | ||
1312 | |||
1313 | |||
1297 | enum GNUNET_GenericReturnValue | 1314 | enum GNUNET_GenericReturnValue |
1298 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | 1315 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
1299 | enum GNUNET_DHT_RouteOption options, | 1316 | enum GNUNET_DHT_RouteOption options, |
1300 | uint32_t desired_replication_level, | 1317 | uint16_t desired_replication_level, |
1301 | uint32_t hop_count, | 1318 | uint16_t hop_count, |
1302 | struct GNUNET_CONTAINER_BloomFilter *bf) | 1319 | struct GNUNET_CONTAINER_BloomFilter *bf) |
1303 | { | 1320 | { |
1304 | unsigned int target_count; | 1321 | unsigned int target_count; |
@@ -1308,27 +1325,31 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1308 | unsigned int put_path_length = bd->put_path_length; | 1325 | unsigned int put_path_length = bd->put_path_length; |
1309 | 1326 | ||
1310 | GNUNET_assert (NULL != bf); | 1327 | GNUNET_assert (NULL != bf); |
1311 | #if SANITY_CHECKS | 1328 | #if SANITY_CHECKS > 1 |
1312 | if (0 != | 1329 | if (0 != |
1313 | GNUNET_DHT_verify_path (&bd->key, | 1330 | GNUNET_DHT_verify_path (bd->data, |
1314 | bd->data, | ||
1315 | bd->data_size, | 1331 | bd->data_size, |
1316 | bd->expiration_time, | 1332 | bd->expiration_time, |
1317 | bd->put_path, | 1333 | bd->put_path, |
1318 | bd->put_path_length, | 1334 | bd->put_path_length, |
1319 | NULL, 0, /* get_path */ | 1335 | NULL, 0, /* get_path */ |
1320 | &my_identity)) | 1336 | &GDS_my_identity)) |
1321 | { | 1337 | { |
1322 | GNUNET_break_op (0); | 1338 | GNUNET_break_op (0); |
1323 | put_path_length = 0; | 1339 | put_path_length = 0; |
1324 | } | 1340 | } |
1325 | #endif | 1341 | #endif |
1326 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1327 | "Adding myself (%s) to PUT bloomfilter for %s\n", | 1343 | "Adding myself (%s) to PUT bloomfilter for %s with RO(%s/%s)\n", |
1328 | GNUNET_i2s (&my_identity), | 1344 | GNUNET_i2s (&GDS_my_identity), |
1329 | GNUNET_h2s (&bd->key)); | 1345 | GNUNET_h2s (&bd->key), |
1346 | (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", | ||
1347 | (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); | ||
1348 | |||
1349 | /* if we got a HELLO, consider it for our own routing table */ | ||
1350 | hello_check (bd); | ||
1330 | GNUNET_CONTAINER_bloomfilter_add (bf, | 1351 | GNUNET_CONTAINER_bloomfilter_add (bf, |
1331 | &my_identity_hash); | 1352 | &GDS_my_identity_hash); |
1332 | GNUNET_STATISTICS_update (GDS_stats, | 1353 | GNUNET_STATISTICS_update (GDS_stats, |
1333 | "# PUT requests routed", | 1354 | "# PUT requests routed", |
1334 | 1, | 1355 | 1, |
@@ -1345,7 +1366,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1345 | "Routing PUT for %s terminates after %u hops at %s\n", | 1366 | "Routing PUT for %s terminates after %u hops at %s\n", |
1346 | GNUNET_h2s (&bd->key), | 1367 | GNUNET_h2s (&bd->key), |
1347 | (unsigned int) hop_count, | 1368 | (unsigned int) hop_count, |
1348 | GNUNET_i2s (&my_identity)); | 1369 | GNUNET_i2s (&GDS_my_identity)); |
1349 | return GNUNET_NO; | 1370 | return GNUNET_NO; |
1350 | } | 1371 | } |
1351 | msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement) | 1372 | msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement) |
@@ -1367,33 +1388,23 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1367 | for (unsigned int i = 0; i < target_count; i++) | 1388 | for (unsigned int i = 0; i < target_count; i++) |
1368 | { | 1389 | { |
1369 | struct PeerInfo *target = targets[i]; | 1390 | struct PeerInfo *target = targets[i]; |
1370 | struct GNUNET_MQ_Envelope *env; | ||
1371 | struct PeerPutMessage *ppm; | 1391 | struct PeerPutMessage *ppm; |
1392 | char buf[sizeof (*ppm) + msize] GNUNET_ALIGN; | ||
1372 | struct GNUNET_DHT_PathElement *pp; | 1393 | struct GNUNET_DHT_PathElement *pp; |
1373 | 1394 | ||
1374 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1375 | { | ||
1376 | /* skip */ | ||
1377 | GNUNET_STATISTICS_update (GDS_stats, | ||
1378 | "# P2P messages dropped due to full queue", | ||
1379 | 1, | ||
1380 | GNUNET_NO); | ||
1381 | skip_count++; | ||
1382 | continue; | ||
1383 | } | ||
1384 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1395 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1385 | "Routing PUT for %s after %u hops to %s\n", | 1396 | "Routing PUT for %s after %u hops to %s\n", |
1386 | GNUNET_h2s (&bd->key), | 1397 | GNUNET_h2s (&bd->key), |
1387 | (unsigned int) hop_count, | 1398 | (unsigned int) hop_count, |
1388 | GNUNET_i2s (target->id)); | 1399 | GNUNET_i2s (&target->id)); |
1389 | env = GNUNET_MQ_msg_extra (ppm, | 1400 | ppm = (struct PeerPutMessage *) buf; |
1390 | msize, | 1401 | ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); |
1391 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); | 1402 | ppm->header.size = htons (sizeof (buf)); |
1392 | ppm->options = htonl (options); | ||
1393 | ppm->type = htonl (bd->type); | 1403 | ppm->type = htonl (bd->type); |
1394 | ppm->hop_count = htonl (hop_count + 1); | 1404 | ppm->options = htons (options); |
1395 | ppm->desired_replication_level = htonl (desired_replication_level); | 1405 | ppm->hop_count = htons (hop_count + 1); |
1396 | ppm->put_path_length = htonl (put_path_length); | 1406 | ppm->desired_replication_level = htons (desired_replication_level); |
1407 | ppm->put_path_length = htons (put_path_length); | ||
1397 | ppm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); | 1408 | ppm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1398 | GNUNET_break (GNUNET_YES == | 1409 | GNUNET_break (GNUNET_YES == |
1399 | GNUNET_CONTAINER_bloomfilter_test (bf, | 1410 | GNUNET_CONTAINER_bloomfilter_test (bf, |
@@ -1412,20 +1423,23 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1412 | { | 1423 | { |
1413 | /* Note that the signature in 'put_path' was not initialized before, | 1424 | /* Note that the signature in 'put_path' was not initialized before, |
1414 | so this is crucial to avoid sending garbage. */ | 1425 | so this is crucial to avoid sending garbage. */ |
1415 | sign_path (&bd->key, | 1426 | sign_path (bd->data, |
1416 | bd->data, | ||
1417 | bd->data_size, | 1427 | bd->data_size, |
1418 | bd->expiration_time, | 1428 | bd->expiration_time, |
1419 | &pp[put_path_length - 1].pred, | 1429 | &pp[put_path_length - 1].pred, |
1420 | target->id, | 1430 | &target->id, |
1421 | &pp[put_path_length - 1].sig); | 1431 | &pp[put_path_length - 1].sig); |
1432 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1433 | "Signing PUT PATH %u => %s\n", | ||
1434 | put_path_length, | ||
1435 | GNUNET_B2S (&pp[put_path_length - 1].sig)); | ||
1422 | } | 1436 | } |
1423 | 1437 | ||
1424 | GNUNET_memcpy (&pp[put_path_length], | 1438 | GNUNET_memcpy (&pp[put_path_length], |
1425 | bd->data, | 1439 | bd->data, |
1426 | bd->data_size); | 1440 | bd->data_size); |
1427 | GNUNET_MQ_send (target->mq, | 1441 | do_send (target, |
1428 | env); | 1442 | &ppm->header); |
1429 | } | 1443 | } |
1430 | GNUNET_free (targets); | 1444 | GNUNET_free (targets); |
1431 | GNUNET_STATISTICS_update (GDS_stats, | 1445 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -1439,8 +1453,8 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
1439 | enum GNUNET_GenericReturnValue | 1453 | enum GNUNET_GenericReturnValue |
1440 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 1454 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
1441 | enum GNUNET_DHT_RouteOption options, | 1455 | enum GNUNET_DHT_RouteOption options, |
1442 | uint32_t desired_replication_level, | 1456 | uint16_t desired_replication_level, |
1443 | uint32_t hop_count, | 1457 | uint16_t hop_count, |
1444 | const struct GNUNET_HashCode *key, | 1458 | const struct GNUNET_HashCode *key, |
1445 | const void *xquery, | 1459 | const void *xquery, |
1446 | size_t xquery_size, | 1460 | size_t xquery_size, |
@@ -1466,18 +1480,21 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1466 | desired_replication_level, | 1480 | desired_replication_level, |
1467 | &targets); | 1481 | &targets); |
1468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1482 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1469 | "Adding myself (%s) to GET bloomfilter for %s\n", | 1483 | "Adding myself (%s) to GET bloomfilter for %s with RO(%s/%s)\n", |
1470 | GNUNET_i2s (&my_identity), | 1484 | GNUNET_i2s (&GDS_my_identity), |
1471 | GNUNET_h2s (key)); | 1485 | GNUNET_h2s (key), |
1486 | (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", | ||
1487 | (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); | ||
1488 | |||
1472 | GNUNET_CONTAINER_bloomfilter_add (peer_bf, | 1489 | GNUNET_CONTAINER_bloomfilter_add (peer_bf, |
1473 | &my_identity_hash); | 1490 | &GDS_my_identity_hash); |
1474 | if (0 == target_count) | 1491 | if (0 == target_count) |
1475 | { | 1492 | { |
1476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1493 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1477 | "Routing GET for %s terminates after %u hops at %s\n", | 1494 | "Routing GET for %s terminates after %u hops at %s\n", |
1478 | GNUNET_h2s (key), | 1495 | GNUNET_h2s (key), |
1479 | (unsigned int) hop_count, | 1496 | (unsigned int) hop_count, |
1480 | GNUNET_i2s (&my_identity)); | 1497 | GNUNET_i2s (&GDS_my_identity)); |
1481 | return GNUNET_NO; | 1498 | return GNUNET_NO; |
1482 | } | 1499 | } |
1483 | if (GNUNET_OK != | 1500 | if (GNUNET_OK != |
@@ -1504,32 +1521,22 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1504 | for (unsigned int i = 0; i < target_count; i++) | 1521 | for (unsigned int i = 0; i < target_count; i++) |
1505 | { | 1522 | { |
1506 | struct PeerInfo *target = targets[i]; | 1523 | struct PeerInfo *target = targets[i]; |
1507 | struct GNUNET_MQ_Envelope *env; | ||
1508 | struct PeerGetMessage *pgm; | 1524 | struct PeerGetMessage *pgm; |
1525 | char buf[sizeof (*pgm) + msize] GNUNET_ALIGN; | ||
1509 | char *xq; | 1526 | char *xq; |
1510 | 1527 | ||
1511 | if (GNUNET_MQ_get_length (target->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1512 | { | ||
1513 | /* skip */ | ||
1514 | GNUNET_STATISTICS_update (GDS_stats, | ||
1515 | "# P2P messages dropped due to full queue", | ||
1516 | 1, | ||
1517 | GNUNET_NO); | ||
1518 | skip_count++; | ||
1519 | continue; | ||
1520 | } | ||
1521 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1528 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1522 | "Routing GET for %s after %u hops to %s\n", | 1529 | "Routing GET for %s after %u hops to %s\n", |
1523 | GNUNET_h2s (key), | 1530 | GNUNET_h2s (key), |
1524 | (unsigned int) hop_count, | 1531 | (unsigned int) hop_count, |
1525 | GNUNET_i2s (target->id)); | 1532 | GNUNET_i2s (&target->id)); |
1526 | env = GNUNET_MQ_msg_extra (pgm, | 1533 | pgm = (struct PeerGetMessage *) buf; |
1527 | msize, | 1534 | pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET); |
1528 | GNUNET_MESSAGE_TYPE_DHT_P2P_GET); | 1535 | pgm->header.size = htons (sizeof (buf)); |
1529 | pgm->options = htonl (options); | ||
1530 | pgm->type = htonl (type); | 1536 | pgm->type = htonl (type); |
1531 | pgm->hop_count = htonl (hop_count + 1); | 1537 | pgm->options = htons (options); |
1532 | pgm->desired_replication_level = htonl (desired_replication_level); | 1538 | pgm->hop_count = htons (hop_count + 1); |
1539 | pgm->desired_replication_level = htons (desired_replication_level); | ||
1533 | pgm->xquery_size = htonl (xquery_size); | 1540 | pgm->xquery_size = htonl (xquery_size); |
1534 | pgm->bf_mutator = bf_nonce; | 1541 | pgm->bf_mutator = bf_nonce; |
1535 | GNUNET_break (GNUNET_YES == | 1542 | GNUNET_break (GNUNET_YES == |
@@ -1547,8 +1554,8 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
1547 | GNUNET_memcpy (&xq[xquery_size], | 1554 | GNUNET_memcpy (&xq[xquery_size], |
1548 | reply_bf, | 1555 | reply_bf, |
1549 | reply_bf_size); | 1556 | reply_bf_size); |
1550 | GNUNET_MQ_send (target->mq, | 1557 | do_send (target, |
1551 | env); | 1558 | &pgm->header); |
1552 | } | 1559 | } |
1553 | GNUNET_STATISTICS_update (GDS_stats, | 1560 | GNUNET_STATISTICS_update (GDS_stats, |
1554 | "# GET messages queued for transmission", | 1561 | "# GET messages queued for transmission", |
@@ -1568,34 +1575,30 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target) | |||
1568 | } | 1575 | } |
1569 | 1576 | ||
1570 | 1577 | ||
1571 | void | 1578 | bool |
1572 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | 1579 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, |
1573 | const struct GDS_DATACACHE_BlockData *bd, | 1580 | const struct GDS_DATACACHE_BlockData *bd, |
1574 | const struct GNUNET_HashCode *query_hash, | 1581 | const struct GNUNET_HashCode *query_hash, |
1575 | unsigned int get_path_length, | 1582 | unsigned int get_path_length, |
1576 | const struct GNUNET_DHT_PathElement *get_path) | 1583 | const struct GNUNET_DHT_PathElement *get_path) |
1577 | { | 1584 | { |
1578 | struct GNUNET_MQ_Envelope *env; | ||
1579 | struct PeerResultMessage *prm; | ||
1580 | struct GNUNET_DHT_PathElement *paths; | 1585 | struct GNUNET_DHT_PathElement *paths; |
1581 | size_t msize; | 1586 | size_t msize; |
1582 | unsigned int ppl = bd->put_path_length; | 1587 | unsigned int ppl = bd->put_path_length; |
1583 | 1588 | ||
1584 | #if SANITY_CHECKS | 1589 | #if SANITY_CHECKS > 1 |
1585 | if (0 != | 1590 | if (0 != |
1586 | GNUNET_DHT_verify_path (&bd->key, | 1591 | GNUNET_DHT_verify_path (bd->data, |
1587 | bd->data, | ||
1588 | bd->data_size, | 1592 | bd->data_size, |
1589 | bd->expiration_time, | 1593 | bd->expiration_time, |
1590 | bd->put_path, | 1594 | bd->put_path, |
1591 | bd->put_path_length, | 1595 | bd->put_path_length, |
1592 | get_path, | 1596 | get_path, |
1593 | get_path_length, | 1597 | get_path_length, |
1594 | &my_identity)) | 1598 | &GDS_my_identity)) |
1595 | { | 1599 | { |
1596 | GNUNET_break_op (0); | 1600 | GNUNET_break_op (0); |
1597 | get_path_length = 0; | 1601 | return false; |
1598 | ppl = 0; | ||
1599 | } | 1602 | } |
1600 | #endif | 1603 | #endif |
1601 | msize = bd->data_size + (get_path_length + ppl) | 1604 | msize = bd->data_size + (get_path_length + ppl) |
@@ -1620,84 +1623,99 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | |||
1620 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) | 1623 | (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) |
1621 | { | 1624 | { |
1622 | GNUNET_break (0); | 1625 | GNUNET_break (0); |
1623 | return; | 1626 | return false; |
1624 | } | ||
1625 | if (GNUNET_MQ_get_length (pi->mq) >= MAXIMUM_PENDING_PER_PEER) | ||
1626 | { | ||
1627 | /* skip */ | ||
1628 | GNUNET_STATISTICS_update (GDS_stats, | ||
1629 | "# P2P messages dropped due to full queue", | ||
1630 | 1, | ||
1631 | GNUNET_NO); | ||
1632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1633 | "Peer queue full, ignoring reply for key %s\n", | ||
1634 | GNUNET_h2s (&bd->key)); | ||
1635 | return; | ||
1636 | } | 1627 | } |
1637 | |||
1638 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1639 | "Forwarding reply for key %s to peer %s\n", | 1629 | "Forwarding reply for key %s to peer %s\n", |
1640 | GNUNET_h2s (query_hash), | 1630 | GNUNET_h2s (query_hash), |
1641 | GNUNET_i2s (pi->id)); | 1631 | GNUNET_i2s (&pi->id)); |
1642 | GNUNET_STATISTICS_update (GDS_stats, | 1632 | GNUNET_STATISTICS_update (GDS_stats, |
1643 | "# RESULT messages queued for transmission", | 1633 | "# RESULT messages queued for transmission", |
1644 | 1, | 1634 | 1, |
1645 | GNUNET_NO); | 1635 | GNUNET_NO); |
1646 | env = GNUNET_MQ_msg_extra (prm, | ||
1647 | msize, | ||
1648 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); | ||
1649 | prm->type = htonl (bd->type); | ||
1650 | prm->put_path_length = htonl (ppl); | ||
1651 | prm->get_path_length = htonl (get_path_length); | ||
1652 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); | ||
1653 | prm->key = *query_hash; | ||
1654 | paths = (struct GNUNET_DHT_PathElement *) &prm[1]; | ||
1655 | GNUNET_memcpy (paths, | ||
1656 | bd->put_path, | ||
1657 | ppl * sizeof(struct GNUNET_DHT_PathElement)); | ||
1658 | GNUNET_memcpy (&paths[ppl], | ||
1659 | get_path, | ||
1660 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); | ||
1661 | /* 0 == get_path_length means path is not being tracked */ | ||
1662 | if (0 != get_path_length) | ||
1663 | { | 1636 | { |
1664 | /* Note that the signature in 'get_path' was not initialized before, | 1637 | struct PeerResultMessage *prm; |
1665 | so this is crucial to avoid sending garbage. */ | 1638 | char buf[sizeof (*prm) + msize] GNUNET_ALIGN; |
1666 | sign_path (&bd->key, | 1639 | |
1667 | bd->data, | 1640 | prm = (struct PeerResultMessage *) buf; |
1668 | bd->data_size, | 1641 | prm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); |
1669 | bd->expiration_time, | 1642 | prm->header.size = htons (sizeof (buf)); |
1670 | &paths[ppl + get_path_length - 1].pred, | 1643 | prm->type = htonl (bd->type); |
1671 | pi->id, | 1644 | prm->reserved = htonl (0); |
1672 | &paths[ppl + get_path_length - 1].sig); | 1645 | prm->put_path_length = htons (ppl); |
1673 | } | 1646 | prm->get_path_length = htons (get_path_length); |
1674 | GNUNET_memcpy (&paths[ppl + get_path_length], | 1647 | prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); |
1675 | bd->data, | 1648 | prm->key = *query_hash; |
1676 | bd->data_size); | 1649 | paths = (struct GNUNET_DHT_PathElement *) &prm[1]; |
1677 | GNUNET_MQ_send (pi->mq, | 1650 | if (NULL != bd->put_path) |
1678 | env); | 1651 | { |
1679 | } | 1652 | GNUNET_memcpy (paths, |
1653 | bd->put_path, | ||
1654 | ppl * sizeof(struct GNUNET_DHT_PathElement)); | ||
1655 | } | ||
1656 | else | ||
1657 | { | ||
1658 | GNUNET_assert (0 == ppl); | ||
1659 | } | ||
1660 | if (NULL != get_path) | ||
1661 | { | ||
1662 | GNUNET_memcpy (&paths[ppl], | ||
1663 | get_path, | ||
1664 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); | ||
1665 | } | ||
1666 | else | ||
1667 | { | ||
1668 | GNUNET_assert (0 == get_path_length); | ||
1669 | } | ||
1670 | /* 0 == get_path_length+ppl means path is not being tracked */ | ||
1671 | if (0 != (get_path_length + ppl)) | ||
1672 | { | ||
1673 | /* Note that the last signature in 'paths' was not initialized before, | ||
1674 | so this is crucial to avoid sending garbage. */ | ||
1675 | sign_path (bd->data, | ||
1676 | bd->data_size, | ||
1677 | bd->expiration_time, | ||
1678 | &paths[ppl + get_path_length - 1].pred, | ||
1679 | &pi->id, | ||
1680 | &paths[ppl + get_path_length - 1].sig); | ||
1681 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1682 | "Signing GET PATH %u/%u of %s => %s\n", | ||
1683 | ppl, | ||
1684 | get_path_length, | ||
1685 | GNUNET_h2s (query_hash), | ||
1686 | GNUNET_B2S (&paths[ppl + get_path_length - 1].sig)); | ||
1687 | } | ||
1688 | GNUNET_memcpy (&paths[ppl + get_path_length], | ||
1689 | bd->data, | ||
1690 | bd->data_size); | ||
1680 | 1691 | ||
1692 | #if SANITY_CHECKS > 1 | ||
1693 | { | ||
1694 | struct GNUNET_DHT_PathElement xpaths[get_path_length + 1]; | ||
1681 | 1695 | ||
1682 | /** | 1696 | memcpy (xpaths, |
1683 | * To be called on core init. | 1697 | &paths[ppl], |
1684 | * | 1698 | get_path_length * sizeof (struct GNUNET_DHT_PathElement)); |
1685 | * @param cls service closure | 1699 | xpaths[get_path_length].pred = GDS_my_identity; |
1686 | * @param identity the public identity of this peer | 1700 | if (0 != |
1687 | */ | 1701 | GNUNET_DHT_verify_path (bd->data, |
1688 | static void | 1702 | bd->data_size, |
1689 | core_init (void *cls, | 1703 | bd->expiration_time, |
1690 | const struct GNUNET_PeerIdentity *identity) | 1704 | paths, |
1691 | { | 1705 | ppl, |
1692 | (void) cls; | 1706 | xpaths, |
1693 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1707 | get_path_length + 1, |
1694 | "CORE called, I am %s\n", | 1708 | &pi->id)) |
1695 | GNUNET_i2s (identity)); | 1709 | { |
1696 | my_identity = *identity; | 1710 | GNUNET_break (0); |
1697 | GNUNET_CRYPTO_hash (identity, | 1711 | return false; |
1698 | sizeof(struct GNUNET_PeerIdentity), | 1712 | } |
1699 | &my_identity_hash); | 1713 | } |
1700 | GNUNET_SERVICE_resume (GDS_service); | 1714 | #endif |
1715 | do_send (pi, | ||
1716 | &prm->header); | ||
1717 | } | ||
1718 | return true; | ||
1701 | } | 1719 | } |
1702 | 1720 | ||
1703 | 1721 | ||
@@ -1713,7 +1731,7 @@ check_dht_p2p_put (void *cls, | |||
1713 | const struct PeerPutMessage *put) | 1731 | const struct PeerPutMessage *put) |
1714 | { | 1732 | { |
1715 | uint16_t msize = ntohs (put->header.size); | 1733 | uint16_t msize = ntohs (put->header.size); |
1716 | uint32_t putlen = ntohl (put->put_path_length); | 1734 | uint16_t putlen = ntohs (put->put_path_length); |
1717 | 1735 | ||
1718 | (void) cls; | 1736 | (void) cls; |
1719 | if ( (msize < | 1737 | if ( (msize < |
@@ -1732,34 +1750,37 @@ check_dht_p2p_put (void *cls, | |||
1732 | /** | 1750 | /** |
1733 | * Core handler for p2p put requests. | 1751 | * Core handler for p2p put requests. |
1734 | * | 1752 | * |
1735 | * @param cls closure with the `struct PeerInfo` of the sender | 1753 | * @param cls closure with the `struct Target` of the sender |
1736 | * @param message message | 1754 | * @param message message |
1737 | */ | 1755 | */ |
1738 | static void | 1756 | static void |
1739 | handle_dht_p2p_put (void *cls, | 1757 | handle_dht_p2p_put (void *cls, |
1740 | const struct PeerPutMessage *put) | 1758 | const struct PeerPutMessage *put) |
1741 | { | 1759 | { |
1742 | struct PeerInfo *peer = cls; | 1760 | struct Target *t = cls; |
1761 | struct PeerInfo *peer = t->pi; | ||
1743 | uint16_t msize = ntohs (put->header.size); | 1762 | uint16_t msize = ntohs (put->header.size); |
1744 | enum GNUNET_DHT_RouteOption options | 1763 | enum GNUNET_DHT_RouteOption options |
1745 | = (enum GNUNET_DHT_RouteOption) ntohl (put->options); | 1764 | = (enum GNUNET_DHT_RouteOption) ntohs (put->options); |
1765 | const struct GNUNET_DHT_PathElement *put_path | ||
1766 | = (const struct GNUNET_DHT_PathElement *) &put[1]; | ||
1767 | uint16_t putlen | ||
1768 | = ntohs (put->put_path_length); | ||
1746 | struct GDS_DATACACHE_BlockData bd = { | 1769 | struct GDS_DATACACHE_BlockData bd = { |
1747 | .key = put->key, | 1770 | .key = put->key, |
1748 | .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), | 1771 | .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), |
1749 | .type = ntohl (put->type) | 1772 | .type = ntohl (put->type), |
1773 | .data_size = msize - (sizeof(*put) | ||
1774 | + putlen * sizeof(struct GNUNET_DHT_PathElement)), | ||
1775 | .data = &put_path[putlen] | ||
1750 | }; | 1776 | }; |
1751 | const struct GNUNET_DHT_PathElement *put_path | ||
1752 | = (const struct GNUNET_DHT_PathElement *) &put[1]; | ||
1753 | uint32_t putlen | ||
1754 | = ntohl (put->put_path_length); | ||
1755 | 1777 | ||
1756 | bd.data_size = msize - (sizeof(*put) | ||
1757 | + putlen * sizeof(struct GNUNET_DHT_PathElement)); | ||
1758 | bd.data = &put_path[putlen]; | ||
1759 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1778 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1760 | "PUT for `%s' from %s\n", | 1779 | "PUT for `%s' from %s with RO (%s/%s)\n", |
1761 | GNUNET_h2s (&put->key), | 1780 | GNUNET_h2s (&put->key), |
1762 | GNUNET_i2s (peer->id)); | 1781 | GNUNET_i2s (&peer->id), |
1782 | (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", | ||
1783 | (options & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); | ||
1763 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) | 1784 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) |
1764 | { | 1785 | { |
1765 | GNUNET_STATISTICS_update (GDS_stats, | 1786 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -1768,6 +1789,17 @@ handle_dht_p2p_put (void *cls, | |||
1768 | GNUNET_NO); | 1789 | GNUNET_NO); |
1769 | return; | 1790 | return; |
1770 | } | 1791 | } |
1792 | if (GNUNET_NO == | ||
1793 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
1794 | bd.type, | ||
1795 | bd.data, | ||
1796 | bd.data_size)) | ||
1797 | { | ||
1798 | GNUNET_break_op (0); | ||
1799 | return; | ||
1800 | } | ||
1801 | if (0 == (options & GNUNET_DHT_RO_RECORD_ROUTE)) | ||
1802 | putlen = 0; | ||
1771 | GNUNET_STATISTICS_update (GDS_stats, | 1803 | GNUNET_STATISTICS_update (GDS_stats, |
1772 | "# P2P PUT requests received", | 1804 | "# P2P PUT requests received", |
1773 | 1, | 1805 | 1, |
@@ -1796,25 +1828,14 @@ handle_dht_p2p_put (void *cls, | |||
1796 | } | 1828 | } |
1797 | break; | 1829 | break; |
1798 | case GNUNET_NO: | 1830 | case GNUNET_NO: |
1799 | GNUNET_break_op (0); | ||
1800 | return; | ||
1801 | case GNUNET_SYSERR: | ||
1802 | /* cannot verify, good luck */ | 1831 | /* cannot verify, good luck */ |
1803 | break; | 1832 | break; |
1833 | case GNUNET_SYSERR: | ||
1834 | /* block type not supported, good luck */ | ||
1835 | break; | ||
1804 | } | 1836 | } |
1805 | } | 1837 | } |
1806 | 1838 | ||
1807 | if (GNUNET_NO == | ||
1808 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
1809 | bd.type, | ||
1810 | &bd.key, | ||
1811 | bd.data, | ||
1812 | bd.data_size)) | ||
1813 | { | ||
1814 | GNUNET_break_op (0); | ||
1815 | return; | ||
1816 | } | ||
1817 | |||
1818 | { | 1839 | { |
1819 | struct GNUNET_CONTAINER_BloomFilter *bf; | 1840 | struct GNUNET_CONTAINER_BloomFilter *bf; |
1820 | struct GNUNET_DHT_PathElement pp[putlen + 1]; | 1841 | struct GNUNET_DHT_PathElement pp[putlen + 1]; |
@@ -1830,42 +1851,39 @@ handle_dht_p2p_put (void *cls, | |||
1830 | bd.put_path_length = putlen + 1; | 1851 | bd.put_path_length = putlen + 1; |
1831 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) | 1852 | if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) |
1832 | { | 1853 | { |
1833 | #if SANITY_CHECKS | 1854 | unsigned int failure_offset; |
1834 | for (unsigned int i = 0; i <= putlen; i++) | 1855 | |
1835 | { | ||
1836 | for (unsigned int j = 0; j < i; j++) | ||
1837 | { | ||
1838 | GNUNET_break (0 != | ||
1839 | GNUNET_memcmp (&pp[i].pred, | ||
1840 | &pp[j].pred)); | ||
1841 | } | ||
1842 | GNUNET_break (0 != | ||
1843 | GNUNET_memcmp (&pp[i].pred, | ||
1844 | peer->id)); | ||
1845 | } | ||
1846 | if (0 != | ||
1847 | GNUNET_DHT_verify_path (&bd.key, | ||
1848 | bd.data, | ||
1849 | bd.data_size, | ||
1850 | bd.expiration_time, | ||
1851 | bd.put_path, | ||
1852 | putlen, | ||
1853 | NULL, 0, /* get_path */ | ||
1854 | &my_identity)) | ||
1855 | { | ||
1856 | GNUNET_break_op (0); | ||
1857 | putlen = 0; | ||
1858 | } | ||
1859 | #endif | ||
1860 | GNUNET_memcpy (pp, | 1856 | GNUNET_memcpy (pp, |
1861 | put_path, | 1857 | put_path, |
1862 | putlen * sizeof(struct GNUNET_DHT_PathElement)); | 1858 | putlen * sizeof(struct GNUNET_DHT_PathElement)); |
1863 | pp[putlen].pred = *peer->id; | 1859 | pp[putlen].pred = peer->id; |
1864 | /* zero-out signature, not valid until we actually do forward! */ | 1860 | /* zero-out signature, not valid until we actually do forward! */ |
1865 | memset (&pp[putlen].sig, | 1861 | memset (&pp[putlen].sig, |
1866 | 0, | 1862 | 0, |
1867 | sizeof (pp[putlen].sig)); | 1863 | sizeof (pp[putlen].sig)); |
1868 | putlen++; | 1864 | #if SANITY_CHECKS |
1865 | /* TODO: might want to eventually implement probabilistic | ||
1866 | load-based path verification, but for now it is all or nothing */ | ||
1867 | failure_offset | ||
1868 | = GNUNET_DHT_verify_path (bd.data, | ||
1869 | bd.data_size, | ||
1870 | bd.expiration_time, | ||
1871 | pp, | ||
1872 | putlen + 1, | ||
1873 | NULL, 0, /* get_path */ | ||
1874 | &GDS_my_identity); | ||
1875 | #else | ||
1876 | failure_offset = 0; | ||
1877 | #endif | ||
1878 | if (0 != failure_offset) | ||
1879 | { | ||
1880 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1881 | "Recorded put path invalid at offset %u, truncating\n", | ||
1882 | failure_offset); | ||
1883 | GNUNET_assert (failure_offset <= putlen); | ||
1884 | bd.put_path = &pp[failure_offset]; | ||
1885 | bd.put_path_length = putlen - failure_offset; | ||
1886 | } | ||
1869 | } | 1887 | } |
1870 | else | 1888 | else |
1871 | { | 1889 | { |
@@ -1873,9 +1891,9 @@ handle_dht_p2p_put (void *cls, | |||
1873 | } | 1891 | } |
1874 | 1892 | ||
1875 | /* give to local clients */ | 1893 | /* give to local clients */ |
1876 | GDS_CLIENTS_handle_reply (&bd, | 1894 | GNUNET_break (GDS_CLIENTS_handle_reply (&bd, |
1877 | &bd.key, | 1895 | &bd.key, |
1878 | 0, NULL /* get path */); | 1896 | 0, NULL /* get path */)); |
1879 | 1897 | ||
1880 | /* store locally */ | 1898 | /* store locally */ |
1881 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 1899 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
@@ -1889,8 +1907,8 @@ handle_dht_p2p_put (void *cls, | |||
1889 | forwarded | 1907 | forwarded |
1890 | = GDS_NEIGHBOURS_handle_put (&bd, | 1908 | = GDS_NEIGHBOURS_handle_put (&bd, |
1891 | options, | 1909 | options, |
1892 | ntohl (put->desired_replication_level), | 1910 | ntohs (put->desired_replication_level), |
1893 | ntohl (put->hop_count), | 1911 | ntohs (put->hop_count), |
1894 | bf); | 1912 | bf); |
1895 | /* notify monitoring clients */ | 1913 | /* notify monitoring clients */ |
1896 | GDS_CLIENTS_process_put (options | 1914 | GDS_CLIENTS_process_put (options |
@@ -1898,8 +1916,8 @@ handle_dht_p2p_put (void *cls, | |||
1898 | ? GNUNET_DHT_RO_LAST_HOP | 1916 | ? GNUNET_DHT_RO_LAST_HOP |
1899 | : 0), | 1917 | : 0), |
1900 | &bd, | 1918 | &bd, |
1901 | ntohl (put->hop_count), | 1919 | ntohs (put->hop_count), |
1902 | ntohl (put->desired_replication_level)); | 1920 | ntohs (put->desired_replication_level)); |
1903 | } | 1921 | } |
1904 | GNUNET_CONTAINER_bloomfilter_free (bf); | 1922 | GNUNET_CONTAINER_bloomfilter_free (bf); |
1905 | } | 1923 | } |
@@ -1907,49 +1925,64 @@ handle_dht_p2p_put (void *cls, | |||
1907 | 1925 | ||
1908 | 1926 | ||
1909 | /** | 1927 | /** |
1910 | * We have received a FIND PEER request. Send matching | 1928 | * We have received a request for a HELLO. Sends our |
1911 | * HELLOs back. | 1929 | * HELLO back. |
1912 | * | 1930 | * |
1913 | * @param pi sender of the FIND PEER request | 1931 | * @param pi sender of the request |
1914 | * @param key peers close to this key are desired | 1932 | * @param key peers close to this key are desired |
1915 | * @param bg group for filtering peers | 1933 | * @param bg group for filtering peers |
1916 | */ | 1934 | */ |
1917 | static void | 1935 | static void |
1918 | handle_find_peer (struct PeerInfo *pi, | 1936 | handle_find_my_hello (struct PeerInfo *pi, |
1919 | const struct GNUNET_HashCode *query_hash, | 1937 | const struct GNUNET_HashCode *query_hash, |
1920 | struct GNUNET_BLOCK_Group *bg) | 1938 | struct GNUNET_BLOCK_Group *bg) |
1921 | { | 1939 | { |
1922 | int bucket_idx; | 1940 | size_t block_size = 0; |
1923 | struct PeerBucket *bucket; | 1941 | |
1924 | struct PeerInfo *peer; | 1942 | /* TODO: consider caching our HELLO block for a bit, to |
1925 | unsigned int choice; | 1943 | avoid signing too often here... */ |
1926 | struct GDS_DATACACHE_BlockData bd = { | 1944 | GNUNET_break (GNUNET_NO == |
1927 | .type = GNUNET_BLOCK_TYPE_DHT_HELLO | 1945 | GNUNET_HELLO_builder_to_block (GDS_my_hello, |
1928 | }; | 1946 | &GDS_my_private_key, |
1929 | 1947 | NULL, | |
1930 | /* first, check about our own HELLO */ | 1948 | &block_size)); |
1931 | if (NULL != GDS_my_hello) | ||
1932 | { | 1949 | { |
1933 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | 1950 | char block[block_size]; |
1934 | hello_expiration), | 1951 | |
1935 | bd.key = my_identity_hash, | 1952 | if (GNUNET_OK != |
1936 | bd.data = GDS_my_hello; | 1953 | GNUNET_HELLO_builder_to_block (GDS_my_hello, |
1937 | bd.data_size = GNUNET_HELLO_size ( | 1954 | &GDS_my_private_key, |
1938 | (const struct GNUNET_HELLO_Message *) GDS_my_hello); | 1955 | block, |
1939 | GNUNET_break (bd.data_size >= sizeof(struct GNUNET_MessageHeader)); | 1956 | &block_size)) |
1940 | if (GNUNET_BLOCK_REPLY_OK_MORE == | ||
1941 | GNUNET_BLOCK_check_reply (GDS_block_context, | ||
1942 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1943 | bg, | ||
1944 | &my_identity_hash, | ||
1945 | NULL, 0, | ||
1946 | bd.data, | ||
1947 | bd.data_size)) | ||
1948 | { | 1957 | { |
1949 | GDS_NEIGHBOURS_handle_reply (pi, | 1958 | GNUNET_STATISTICS_update (GDS_stats, |
1950 | &bd, | 1959 | "# FIND PEER requests ignored due to lack of HELLO", |
1951 | query_hash, | 1960 | 1, |
1952 | 0, NULL /* get path */); | 1961 | GNUNET_NO); |
1962 | } | ||
1963 | else if (GNUNET_BLOCK_REPLY_OK_MORE == | ||
1964 | GNUNET_BLOCK_check_reply (GDS_block_context, | ||
1965 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1966 | bg, | ||
1967 | &GDS_my_identity_hash, | ||
1968 | NULL, 0, | ||
1969 | block, | ||
1970 | block_size)) | ||
1971 | { | ||
1972 | struct GDS_DATACACHE_BlockData bd = { | ||
1973 | .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
1974 | .expiration_time | ||
1975 | = GNUNET_TIME_relative_to_absolute ( | ||
1976 | GNUNET_HELLO_ADDRESS_EXPIRATION), | ||
1977 | .key = GDS_my_identity_hash, | ||
1978 | .data = block, | ||
1979 | .data_size = block_size | ||
1980 | }; | ||
1981 | |||
1982 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi, | ||
1983 | &bd, | ||
1984 | query_hash, | ||
1985 | 0, NULL /* get path */)); | ||
1953 | } | 1986 | } |
1954 | else | 1987 | else |
1955 | { | 1988 | { |
@@ -1959,70 +1992,52 @@ handle_find_peer (struct PeerInfo *pi, | |||
1959 | GNUNET_NO); | 1992 | GNUNET_NO); |
1960 | } | 1993 | } |
1961 | } | 1994 | } |
1962 | else | 1995 | } |
1963 | { | ||
1964 | GNUNET_STATISTICS_update (GDS_stats, | ||
1965 | "# FIND PEER requests ignored due to lack of HELLO", | ||
1966 | 1, | ||
1967 | GNUNET_NO); | ||
1968 | } | ||
1969 | 1996 | ||
1970 | /* then, also consider sending a random HELLO from the closest bucket */ | ||
1971 | /* FIXME: How can this be true? Shouldnt we just do find_bucket() ? */ | ||
1972 | if (0 == | ||
1973 | GNUNET_memcmp (&my_identity_hash, | ||
1974 | query_hash)) | ||
1975 | bucket_idx = closest_bucket - 1; | ||
1976 | else | ||
1977 | bucket_idx = GNUNET_MIN ((int) closest_bucket - 1, | ||
1978 | find_bucket (query_hash)); | ||
1979 | if (bucket_idx < 0) | ||
1980 | return; | ||
1981 | bucket = &k_buckets[bucket_idx]; | ||
1982 | if (bucket->peers_size == 0) | ||
1983 | return; | ||
1984 | choice = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1985 | bucket->peers_size); | ||
1986 | peer = bucket->head; | ||
1987 | while (choice > 0) | ||
1988 | { | ||
1989 | GNUNET_assert (NULL != peer); | ||
1990 | peer = peer->next; | ||
1991 | choice--; | ||
1992 | } | ||
1993 | choice = bucket->peers_size; | ||
1994 | 1997 | ||
1995 | { | 1998 | /** |
1996 | const struct GNUNET_HELLO_Message *hello; | 1999 | * We have received a request for nearby HELLOs. Sends matching |
1997 | size_t hello_size; | 2000 | * HELLOs back. |
2001 | * | ||
2002 | * @param pi sender of the request | ||
2003 | * @param key peers close to this key are desired | ||
2004 | * @param bg group for filtering peers | ||
2005 | */ | ||
2006 | static void | ||
2007 | handle_find_local_hello (struct PeerInfo *pi, | ||
2008 | const struct GNUNET_HashCode *query_hash, | ||
2009 | struct GNUNET_BLOCK_Group *bg) | ||
2010 | { | ||
2011 | /* Force non-random selection by hop count */ | ||
2012 | struct PeerInfo *peer; | ||
1998 | 2013 | ||
1999 | do | 2014 | peer = select_peer (query_hash, |
2000 | { | 2015 | NULL, |
2001 | peer = peer->next; | 2016 | GDS_NSE_get () + 1); |
2002 | if (0 == choice--) | 2017 | if ( (NULL != peer->hello) && |
2003 | return; /* no non-masked peer available */ | 2018 | (! GNUNET_TIME_absolute_is_past (peer->hello_expiration)) && |
2004 | if (NULL == peer) | 2019 | (GNUNET_BLOCK_REPLY_OK_MORE == |
2005 | peer = bucket->head; | 2020 | GNUNET_BLOCK_check_reply ( |
2006 | hello = GDS_HELLO_get (peer->id); | 2021 | GDS_block_context, |
2007 | } while ( (NULL == hello) || | 2022 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
2008 | (GNUNET_BLOCK_REPLY_OK_MORE != | 2023 | bg, |
2009 | GNUNET_BLOCK_check_reply ( | 2024 | &peer->phash, |
2010 | GDS_block_context, | 2025 | NULL, 0, /* xquery */ |
2011 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 2026 | peer->hello, |
2012 | bg, | 2027 | peer->hello_size)) ) |
2013 | &peer->phash, | 2028 | { |
2014 | NULL, 0, /* xquery */ | 2029 | struct GDS_DATACACHE_BlockData bd = { |
2015 | hello, | 2030 | .type = GNUNET_BLOCK_TYPE_DHT_URL_HELLO, |
2016 | (hello_size = GNUNET_HELLO_size (hello))))); | 2031 | .expiration_time = peer->hello_expiration, |
2017 | bd.expiration_time = GNUNET_TIME_relative_to_absolute ( | 2032 | .key = peer->phash, |
2018 | GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION); | 2033 | .data = peer->hello, |
2019 | bd.key = peer->phash; | 2034 | .data_size = peer->hello_size |
2020 | bd.data = hello; | 2035 | }; |
2021 | bd.data_size = hello_size; | 2036 | |
2022 | GDS_NEIGHBOURS_handle_reply (pi, | 2037 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi, |
2023 | &bd, | 2038 | &bd, |
2024 | query_hash, | 2039 | query_hash, |
2025 | 0, NULL /* get path */); | 2040 | 0, NULL /* get path */)); |
2026 | } | 2041 | } |
2027 | } | 2042 | } |
2028 | 2043 | ||
@@ -2039,17 +2054,17 @@ handle_local_result (void *cls, | |||
2039 | { | 2054 | { |
2040 | struct PeerInfo *peer = cls; | 2055 | struct PeerInfo *peer = cls; |
2041 | 2056 | ||
2042 | GDS_NEIGHBOURS_handle_reply (peer, | 2057 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (peer, |
2043 | bd, | 2058 | bd, |
2044 | &bd->key, | 2059 | &bd->key, |
2045 | 0, NULL /* get path */); | 2060 | 0, NULL /* get path */)); |
2046 | } | 2061 | } |
2047 | 2062 | ||
2048 | 2063 | ||
2049 | /** | 2064 | /** |
2050 | * Check validity of p2p get request. | 2065 | * Check validity of p2p get request. |
2051 | * | 2066 | * |
2052 | * @param cls closure with the `struct PeerInfo` of the sender | 2067 | * @param cls closure with the `struct Target` of the sender |
2053 | * @param get the message | 2068 | * @param get the message |
2054 | * @return #GNUNET_OK if the message is well-formed | 2069 | * @return #GNUNET_OK if the message is well-formed |
2055 | */ | 2070 | */ |
@@ -2073,20 +2088,21 @@ check_dht_p2p_get (void *cls, | |||
2073 | /** | 2088 | /** |
2074 | * Core handler for p2p get requests. | 2089 | * Core handler for p2p get requests. |
2075 | * | 2090 | * |
2076 | * @param cls closure with the `struct PeerInfo` of the sender | 2091 | * @param cls closure with the `struct Target` of the sender |
2077 | * @param get the message | 2092 | * @param get the message |
2078 | */ | 2093 | */ |
2079 | static void | 2094 | static void |
2080 | handle_dht_p2p_get (void *cls, | 2095 | handle_dht_p2p_get (void *cls, |
2081 | const struct PeerGetMessage *get) | 2096 | const struct PeerGetMessage *get) |
2082 | { | 2097 | { |
2083 | struct PeerInfo *peer = cls; | 2098 | struct Target *t = cls; |
2099 | struct PeerInfo *peer = t->pi; | ||
2084 | uint16_t msize = ntohs (get->header.size); | 2100 | uint16_t msize = ntohs (get->header.size); |
2085 | uint32_t xquery_size = ntohl (get->xquery_size); | 2101 | uint32_t xquery_size = ntohl (get->xquery_size); |
2086 | uint32_t hop_count = ntohl (get->hop_count); | 2102 | uint32_t hop_count = ntohs (get->hop_count); |
2087 | size_t reply_bf_size = msize - (sizeof(*get) + xquery_size); | 2103 | size_t reply_bf_size = msize - (sizeof(*get) + xquery_size); |
2088 | enum GNUNET_BLOCK_Type type = (enum GNUNET_BLOCK_Type) ntohl (get->type); | 2104 | enum GNUNET_BLOCK_Type type = (enum GNUNET_BLOCK_Type) ntohl (get->type); |
2089 | enum GNUNET_DHT_RouteOption options = (enum GNUNET_DHT_RouteOption) ntohl ( | 2105 | enum GNUNET_DHT_RouteOption options = (enum GNUNET_DHT_RouteOption) ntohs ( |
2090 | get->options); | 2106 | get->options); |
2091 | enum GNUNET_BLOCK_ReplyEvaluationResult eval = GNUNET_BLOCK_REPLY_OK_MORE; | 2107 | enum GNUNET_BLOCK_ReplyEvaluationResult eval = GNUNET_BLOCK_REPLY_OK_MORE; |
2092 | const void *xquery = (const void *) &get[1]; | 2108 | const void *xquery = (const void *) &get[1]; |
@@ -2133,32 +2149,45 @@ handle_dht_p2p_get (void *cls, | |||
2133 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2149 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2134 | "GET for %s at %s after %u hops\n", | 2150 | "GET for %s at %s after %u hops\n", |
2135 | GNUNET_h2s (&get->key), | 2151 | GNUNET_h2s (&get->key), |
2136 | GNUNET_i2s (&my_identity), | 2152 | GNUNET_i2s (&GDS_my_identity), |
2137 | (unsigned int) hop_count); | 2153 | (unsigned int) hop_count); |
2138 | /* local lookup (this may update the reply_bf) */ | 2154 | /* local lookup (this may update the bg) */ |
2139 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 2155 | if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
2140 | (GDS_am_closest_peer (&get->key, | 2156 | (GDS_am_closest_peer (&get->key, |
2141 | peer_bf)) ) | 2157 | peer_bf)) ) |
2142 | { | 2158 | { |
2143 | if ((0 != (options & GNUNET_DHT_RO_FIND_PEER))) | 2159 | if (GNUNET_BLOCK_TYPE_DHT_URL_HELLO == type) |
2144 | { | 2160 | { |
2145 | GNUNET_STATISTICS_update (GDS_stats, | 2161 | GNUNET_STATISTICS_update (GDS_stats, |
2146 | "# P2P FIND PEER requests processed", | 2162 | "# P2P HELLO lookup requests processed", |
2147 | 1, | 2163 | 1, |
2148 | GNUNET_NO); | 2164 | GNUNET_NO); |
2149 | handle_find_peer (peer, | 2165 | handle_find_my_hello (peer, |
2150 | &get->key, | 2166 | &get->key, |
2151 | bg); | 2167 | bg); |
2168 | if (0 != (options & GNUNET_DHT_RO_FIND_APPROXIMATE)) | ||
2169 | handle_find_local_hello (peer, | ||
2170 | &get->key, | ||
2171 | bg); | ||
2152 | } | 2172 | } |
2153 | else | 2173 | else |
2154 | { | 2174 | { |
2155 | eval = GDS_DATACACHE_handle_get (&get->key, | 2175 | if (0 != (options & GNUNET_DHT_RO_FIND_APPROXIMATE)) |
2156 | type, | 2176 | eval = GDS_DATACACHE_get_closest (&get->key, |
2157 | xquery, | 2177 | type, |
2158 | xquery_size, | 2178 | xquery, |
2159 | bg, | 2179 | xquery_size, |
2160 | &handle_local_result, | 2180 | bg, |
2161 | peer); | 2181 | &handle_local_result, |
2182 | peer); | ||
2183 | else | ||
2184 | eval = GDS_DATACACHE_handle_get (&get->key, | ||
2185 | type, | ||
2186 | xquery, | ||
2187 | xquery_size, | ||
2188 | bg, | ||
2189 | &handle_local_result, | ||
2190 | peer); | ||
2162 | } | 2191 | } |
2163 | } | 2192 | } |
2164 | else | 2193 | else |
@@ -2169,8 +2198,10 @@ handle_dht_p2p_get (void *cls, | |||
2169 | GNUNET_NO); | 2198 | GNUNET_NO); |
2170 | } | 2199 | } |
2171 | 2200 | ||
2172 | /* remember request for routing replies */ | 2201 | /* remember request for routing replies |
2173 | GDS_ROUTING_add (peer->id, | 2202 | TODO: why should we do this if GNUNET_BLOCK_REPLY_OK_LAST == eval? |
2203 | */ | ||
2204 | GDS_ROUTING_add (&peer->id, | ||
2174 | type, | 2205 | type, |
2175 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | 2206 | bg, /* bg now owned by routing, but valid at least until end of this function! */ |
2176 | options, | 2207 | options, |
@@ -2181,7 +2212,7 @@ handle_dht_p2p_get (void *cls, | |||
2181 | /* P2P forwarding */ | 2212 | /* P2P forwarding */ |
2182 | { | 2213 | { |
2183 | bool forwarded = false; | 2214 | bool forwarded = false; |
2184 | uint32_t desired_replication_level = ntohl ( | 2215 | uint16_t desired_replication_level = ntohs ( |
2185 | get->desired_replication_level); | 2216 | get->desired_replication_level); |
2186 | 2217 | ||
2187 | if (eval != GNUNET_BLOCK_REPLY_OK_LAST) | 2218 | if (eval != GNUNET_BLOCK_REPLY_OK_LAST) |
@@ -2220,18 +2251,25 @@ handle_dht_p2p_get (void *cls, | |||
2220 | * @param query_hash hash of the original query, might not match key in @a bd | 2251 | * @param query_hash hash of the original query, might not match key in @a bd |
2221 | * @param get_path_length number of entries in @a get_path | 2252 | * @param get_path_length number of entries in @a get_path |
2222 | * @param get_path path the reply has taken | 2253 | * @param get_path path the reply has taken |
2254 | * @return true on success | ||
2223 | */ | 2255 | */ |
2224 | static void | 2256 | static bool |
2225 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, | 2257 | process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, |
2226 | const struct GNUNET_HashCode *query_hash, | 2258 | const struct GNUNET_HashCode *query_hash, |
2227 | unsigned int get_path_length, | 2259 | unsigned int get_path_length, |
2228 | const struct GNUNET_DHT_PathElement *get_path) | 2260 | const struct GNUNET_DHT_PathElement *get_path) |
2229 | { | 2261 | { |
2230 | /* forward to local clients */ | 2262 | /* forward to local clients */ |
2231 | GDS_CLIENTS_handle_reply (bd, | 2263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2232 | query_hash, | 2264 | "Forwarding reply to local clients\n"); |
2233 | get_path_length, | 2265 | if (! GDS_CLIENTS_handle_reply (bd, |
2234 | get_path); | 2266 | query_hash, |
2267 | get_path_length, | ||
2268 | get_path)) | ||
2269 | { | ||
2270 | GNUNET_break (0); | ||
2271 | return false; | ||
2272 | } | ||
2235 | GDS_CLIENTS_process_get_resp (bd, | 2273 | GDS_CLIENTS_process_get_resp (bd, |
2236 | get_path, | 2274 | get_path, |
2237 | get_path_length); | 2275 | get_path_length); |
@@ -2256,6 +2294,7 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, | |||
2256 | query_hash, | 2294 | query_hash, |
2257 | get_path_length, | 2295 | get_path_length, |
2258 | get_path); | 2296 | get_path); |
2297 | return true; | ||
2259 | } | 2298 | } |
2260 | 2299 | ||
2261 | 2300 | ||
@@ -2270,8 +2309,8 @@ static enum GNUNET_GenericReturnValue | |||
2270 | check_dht_p2p_result (void *cls, | 2309 | check_dht_p2p_result (void *cls, |
2271 | const struct PeerResultMessage *prm) | 2310 | const struct PeerResultMessage *prm) |
2272 | { | 2311 | { |
2273 | uint32_t get_path_length = ntohl (prm->get_path_length); | 2312 | uint16_t get_path_length = ntohs (prm->get_path_length); |
2274 | uint32_t put_path_length = ntohl (prm->put_path_length); | 2313 | uint16_t put_path_length = ntohs (prm->put_path_length); |
2275 | uint16_t msize = ntohs (prm->header.size); | 2314 | uint16_t msize = ntohs (prm->header.size); |
2276 | 2315 | ||
2277 | (void) cls; | 2316 | (void) cls; |
@@ -2301,18 +2340,20 @@ static void | |||
2301 | handle_dht_p2p_result (void *cls, | 2340 | handle_dht_p2p_result (void *cls, |
2302 | const struct PeerResultMessage *prm) | 2341 | const struct PeerResultMessage *prm) |
2303 | { | 2342 | { |
2304 | struct PeerInfo *peer = cls; | 2343 | struct Target *t = cls; |
2344 | struct PeerInfo *peer = t->pi; | ||
2305 | uint16_t msize = ntohs (prm->header.size); | 2345 | uint16_t msize = ntohs (prm->header.size); |
2306 | uint32_t get_path_length = ntohl (prm->get_path_length); | 2346 | uint16_t get_path_length = ntohs (prm->get_path_length); |
2307 | struct GDS_DATACACHE_BlockData bd = { | 2347 | struct GDS_DATACACHE_BlockData bd = { |
2308 | .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), | 2348 | .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2309 | .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1], | 2349 | .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1], |
2310 | .put_path_length = ntohl (prm->put_path_length), | 2350 | .put_path_length = ntohs (prm->put_path_length), |
2351 | .key = prm->key, | ||
2311 | .type = ntohl (prm->type) | 2352 | .type = ntohl (prm->type) |
2312 | }; | 2353 | }; |
2313 | const struct GNUNET_DHT_PathElement *get_path | 2354 | const struct GNUNET_DHT_PathElement *get_path |
2314 | = &bd.put_path[bd.put_path_length]; | 2355 | = &bd.put_path[bd.put_path_length]; |
2315 | 2356 | ||
2316 | /* parse and validate message */ | 2357 | /* parse and validate message */ |
2317 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) | 2358 | if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) |
2318 | { | 2359 | { |
@@ -2327,6 +2368,15 @@ handle_dht_p2p_result (void *cls, | |||
2327 | bd.data_size = msize - (sizeof(struct PeerResultMessage) | 2368 | bd.data_size = msize - (sizeof(struct PeerResultMessage) |
2328 | + (get_path_length + bd.put_path_length) | 2369 | + (get_path_length + bd.put_path_length) |
2329 | * sizeof(struct GNUNET_DHT_PathElement)); | 2370 | * sizeof(struct GNUNET_DHT_PathElement)); |
2371 | if (GNUNET_OK != | ||
2372 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
2373 | bd.type, | ||
2374 | bd.data, | ||
2375 | bd.data_size)) | ||
2376 | { | ||
2377 | GNUNET_break_op (0); | ||
2378 | return; | ||
2379 | } | ||
2330 | GNUNET_STATISTICS_update (GDS_stats, | 2380 | GNUNET_STATISTICS_update (GDS_stats, |
2331 | "# P2P RESULTS received", | 2381 | "# P2P RESULTS received", |
2332 | 1, | 2382 | 1, |
@@ -2337,7 +2387,6 @@ handle_dht_p2p_result (void *cls, | |||
2337 | GNUNET_NO); | 2387 | GNUNET_NO); |
2338 | { | 2388 | { |
2339 | enum GNUNET_GenericReturnValue ret; | 2389 | enum GNUNET_GenericReturnValue ret; |
2340 | const struct GNUNET_HashCode *pquery; | ||
2341 | 2390 | ||
2342 | ret = GNUNET_BLOCK_get_key (GDS_block_context, | 2391 | ret = GNUNET_BLOCK_get_key (GDS_block_context, |
2343 | bd.type, | 2392 | bd.type, |
@@ -2345,102 +2394,274 @@ handle_dht_p2p_result (void *cls, | |||
2345 | bd.data_size, | 2394 | bd.data_size, |
2346 | &bd.key); | 2395 | &bd.key); |
2347 | if (GNUNET_NO == ret) | 2396 | if (GNUNET_NO == ret) |
2348 | { | 2397 | bd.key = prm->key; |
2349 | GNUNET_break_op (0); | ||
2350 | return; | ||
2351 | } | ||
2352 | pquery = (GNUNET_OK == ret) ? &bd.key : &prm->key; | ||
2353 | if (GNUNET_OK != | ||
2354 | GNUNET_BLOCK_check_block (GDS_block_context, | ||
2355 | bd.type, | ||
2356 | pquery, | ||
2357 | bd.data, | ||
2358 | bd.data_size)) | ||
2359 | { | ||
2360 | GNUNET_break_op (0); | ||
2361 | return; | ||
2362 | } | ||
2363 | } | 2398 | } |
2364 | 2399 | ||
2365 | /* if we got a HELLO, consider it for our own routing table */ | 2400 | /* if we got a HELLO, consider it for our own routing table */ |
2366 | if (GNUNET_BLOCK_TYPE_DHT_HELLO == bd.type) | 2401 | hello_check (&bd); |
2367 | { | ||
2368 | const struct GNUNET_MessageHeader *h = bd.data; | ||
2369 | struct GNUNET_PeerIdentity pid; | ||
2370 | |||
2371 | /* Should be a HELLO, validate and consider using it! */ | ||
2372 | if (bd.data_size < sizeof(struct GNUNET_HELLO_Message)) | ||
2373 | { | ||
2374 | GNUNET_break (0); | ||
2375 | return; | ||
2376 | } | ||
2377 | if (bd.data_size != ntohs (h->size)) | ||
2378 | { | ||
2379 | GNUNET_break (0); | ||
2380 | return; | ||
2381 | } | ||
2382 | if (GNUNET_OK != | ||
2383 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) h, | ||
2384 | &pid)) | ||
2385 | { | ||
2386 | GNUNET_break_op (0); | ||
2387 | return; | ||
2388 | } | ||
2389 | if ( (GNUNET_YES != disable_try_connect) && | ||
2390 | (0 != GNUNET_memcmp (&my_identity, | ||
2391 | &pid)) ) | ||
2392 | try_connect (&pid, | ||
2393 | h); | ||
2394 | } | ||
2395 | 2402 | ||
2396 | /* First, check if 'peer' is already on the path, and if | 2403 | /* Need to append 'peer' to 'get_path' */ |
2397 | so, truncate it instead of expanding. */ | ||
2398 | for (unsigned int i = 0; i <= get_path_length; i++) | ||
2399 | if (0 == GNUNET_memcmp (&get_path[i].pred, | ||
2400 | peer->id)) | ||
2401 | { | ||
2402 | process_reply_with_path (&bd, | ||
2403 | &prm->key, | ||
2404 | i, get_path); | ||
2405 | return; | ||
2406 | } | ||
2407 | |||
2408 | /* Need to append 'peer' to 'get_path' (normal case) */ | ||
2409 | { | 2404 | { |
2410 | struct GNUNET_DHT_PathElement xget_path[get_path_length + 1]; | 2405 | struct GNUNET_DHT_PathElement xget_path[get_path_length + 1]; |
2406 | struct GNUNET_DHT_PathElement *gp = xget_path; | ||
2407 | unsigned int failure_offset; | ||
2411 | 2408 | ||
2412 | GNUNET_memcpy (xget_path, | 2409 | GNUNET_memcpy (xget_path, |
2413 | get_path, | 2410 | get_path, |
2414 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); | 2411 | get_path_length * sizeof(struct GNUNET_DHT_PathElement)); |
2415 | xget_path[get_path_length].pred = *peer->id; | 2412 | xget_path[get_path_length].pred = peer->id; |
2416 | memset (&xget_path[get_path_length].sig, | 2413 | memset (&xget_path[get_path_length].sig, |
2417 | 0, | 2414 | 0, |
2418 | sizeof (xget_path[get_path_length].sig)); | 2415 | sizeof (xget_path[get_path_length].sig)); |
2419 | process_reply_with_path (&bd, | 2416 | #if SANITY_CHECKS |
2420 | &prm->key, | 2417 | /* TODO: might want to eventually implement probabilistic |
2421 | get_path_length + 1, xget_path); | 2418 | load-based path verification, but for now it is all or nothing */ |
2419 | failure_offset | ||
2420 | = GNUNET_DHT_verify_path (bd.data, | ||
2421 | bd.data_size, | ||
2422 | bd.expiration_time, | ||
2423 | bd.put_path, | ||
2424 | bd.put_path_length, | ||
2425 | xget_path, | ||
2426 | get_path_length + 1, | ||
2427 | &GDS_my_identity); | ||
2428 | #else | ||
2429 | failure_offset = 0; | ||
2430 | #endif | ||
2431 | if (0 != failure_offset) | ||
2432 | { | ||
2433 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2434 | "Recorded path invalid at offset %u, truncating\n", | ||
2435 | failure_offset); | ||
2436 | GNUNET_assert (failure_offset <= bd.put_path_length + get_path_length); | ||
2437 | if (failure_offset >= bd.put_path_length) | ||
2438 | { | ||
2439 | /* failure on get path */ | ||
2440 | get_path_length -= (failure_offset - bd.put_path_length); | ||
2441 | gp = &xget_path[failure_offset - bd.put_path_length]; | ||
2442 | bd.put_path_length = 0; | ||
2443 | } | ||
2444 | else | ||
2445 | { | ||
2446 | /* failure on put path */ | ||
2447 | bd.put_path = &bd.put_path[failure_offset]; | ||
2448 | bd.put_path_length -= failure_offset; | ||
2449 | } | ||
2450 | } | ||
2451 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2452 | "Extending GET path of length %u with %s\n", | ||
2453 | get_path_length, | ||
2454 | GNUNET_i2s (&peer->id)); | ||
2455 | GNUNET_break (process_reply_with_path (&bd, | ||
2456 | &prm->key, | ||
2457 | get_path_length + 1, | ||
2458 | gp)); | ||
2422 | } | 2459 | } |
2423 | } | 2460 | } |
2424 | 2461 | ||
2425 | 2462 | ||
2426 | enum GNUNET_GenericReturnValue | 2463 | /** |
2427 | GDS_NEIGHBOURS_init () | 2464 | * Check validity of a p2p hello message. |
2465 | * | ||
2466 | * @param cls closure | ||
2467 | * @param hello message | ||
2468 | * @return #GNUNET_YES if the message is well-formed | ||
2469 | */ | ||
2470 | static enum GNUNET_GenericReturnValue | ||
2471 | check_dht_p2p_hello (void *cls, | ||
2472 | const struct GNUNET_MessageHeader *hello) | ||
2428 | { | 2473 | { |
2474 | struct Target *t = cls; | ||
2475 | struct PeerInfo *peer = t->pi; | ||
2476 | enum GNUNET_GenericReturnValue ret; | ||
2477 | size_t hellob_size; | ||
2478 | void *hellob; | ||
2479 | struct GNUNET_TIME_Absolute expiration; | ||
2480 | |||
2481 | ret = GNUNET_HELLO_dht_msg_to_block (hello, | ||
2482 | &peer->id, | ||
2483 | &hellob, | ||
2484 | &hellob_size, | ||
2485 | &expiration); | ||
2486 | GNUNET_free (hellob); | ||
2487 | return ret; | ||
2488 | } | ||
2489 | |||
2490 | |||
2491 | /** | ||
2492 | * Core handler for p2p HELLO messages. | ||
2493 | * | ||
2494 | * @param cls closure | ||
2495 | * @param message message | ||
2496 | */ | ||
2497 | static void | ||
2498 | handle_dht_p2p_hello (void *cls, | ||
2499 | const struct GNUNET_MessageHeader *hello) | ||
2500 | { | ||
2501 | struct Target *t = cls; | ||
2502 | struct PeerInfo *peer = t->pi; | ||
2503 | |||
2504 | GNUNET_free (peer->hello); | ||
2505 | peer->hello_size = 0; | ||
2506 | GNUNET_break (GNUNET_OK == | ||
2507 | GNUNET_HELLO_dht_msg_to_block (hello, | ||
2508 | &peer->id, | ||
2509 | &peer->hello, | ||
2510 | &peer->hello_size, | ||
2511 | &peer->hello_expiration)); | ||
2512 | } | ||
2513 | |||
2514 | |||
2515 | void | ||
2516 | GDS_u_receive (void *cls, | ||
2517 | void **tctx, | ||
2518 | void **sctx, | ||
2519 | const void *message, | ||
2520 | size_t message_size) | ||
2521 | { | ||
2522 | struct Target *t = *tctx; | ||
2429 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | 2523 | struct GNUNET_MQ_MessageHandler core_handlers[] = { |
2430 | GNUNET_MQ_hd_var_size (dht_p2p_get, | 2524 | GNUNET_MQ_hd_var_size (dht_p2p_get, |
2431 | GNUNET_MESSAGE_TYPE_DHT_P2P_GET, | 2525 | GNUNET_MESSAGE_TYPE_DHT_P2P_GET, |
2432 | struct PeerGetMessage, | 2526 | struct PeerGetMessage, |
2433 | NULL), | 2527 | t), |
2434 | GNUNET_MQ_hd_var_size (dht_p2p_put, | 2528 | GNUNET_MQ_hd_var_size (dht_p2p_put, |
2435 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, | 2529 | GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, |
2436 | struct PeerPutMessage, | 2530 | struct PeerPutMessage, |
2437 | NULL), | 2531 | t), |
2438 | GNUNET_MQ_hd_var_size (dht_p2p_result, | 2532 | GNUNET_MQ_hd_var_size (dht_p2p_result, |
2439 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, | 2533 | GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT, |
2440 | struct PeerResultMessage, | 2534 | struct PeerResultMessage, |
2441 | NULL), | 2535 | t), |
2536 | GNUNET_MQ_hd_var_size (dht_p2p_hello, | ||
2537 | GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO, | ||
2538 | struct GNUNET_MessageHeader, | ||
2539 | t), | ||
2442 | GNUNET_MQ_handler_end () | 2540 | GNUNET_MQ_handler_end () |
2443 | }; | 2541 | }; |
2542 | const struct GNUNET_MessageHeader *mh = message; | ||
2543 | |||
2544 | (void) cls; /* the 'struct GDS_Underlay' */ | ||
2545 | (void) sctx; /* our receiver address */ | ||
2546 | if (NULL == t) | ||
2547 | { | ||
2548 | /* Received message claiming to originate from myself? | ||
2549 | Ignore! */ | ||
2550 | GNUNET_break_op (0); | ||
2551 | return; | ||
2552 | } | ||
2553 | if (message_size < sizeof (*mh)) | ||
2554 | { | ||
2555 | GNUNET_break_op (0); | ||
2556 | return; | ||
2557 | } | ||
2558 | if (message_size != ntohs (mh->size)) | ||
2559 | { | ||
2560 | GNUNET_break_op (0); | ||
2561 | return; | ||
2562 | } | ||
2563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2564 | "Handling message of type %u from peer %s\n", | ||
2565 | ntohs (mh->type), | ||
2566 | GNUNET_i2s (&t->pi->id)); | ||
2567 | if (GNUNET_OK != | ||
2568 | GNUNET_MQ_handle_message (core_handlers, | ||
2569 | mh)) | ||
2570 | { | ||
2571 | GNUNET_break_op (0); | ||
2572 | return; | ||
2573 | } | ||
2574 | } | ||
2575 | |||
2576 | |||
2577 | /** | ||
2578 | * Callback function used to extract URIs from a builder. | ||
2579 | * Called when we should consider connecting to a peer. | ||
2580 | * | ||
2581 | * @param cls closure pointing to a `struct GNUNET_PeerIdentity *` | ||
2582 | * @param uri one of the URIs | ||
2583 | */ | ||
2584 | void | ||
2585 | GDS_try_connect (void *cls, | ||
2586 | const char *uri) | ||
2587 | { | ||
2588 | const struct GNUNET_PeerIdentity *pid = cls; | ||
2589 | struct GNUNET_HashCode phash; | ||
2590 | int peer_bucket; | ||
2591 | struct PeerBucket *bucket; | ||
2592 | |||
2593 | if (0 == GNUNET_memcmp (&GDS_my_identity, | ||
2594 | pid)) | ||
2595 | { | ||
2596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2597 | "Got a HELLO for my own PID, ignoring it\n"); | ||
2598 | return; /* that's us! */ | ||
2599 | } | ||
2600 | GNUNET_CRYPTO_hash (pid, | ||
2601 | sizeof(*pid), | ||
2602 | &phash); | ||
2603 | peer_bucket = find_bucket (&phash); | ||
2604 | GNUNET_assert ( (peer_bucket >= 0) && | ||
2605 | ((unsigned int) peer_bucket < MAX_BUCKETS)); | ||
2606 | bucket = &k_buckets[peer_bucket]; | ||
2607 | if (bucket->peers_size >= bucket_size) | ||
2608 | return; /* do not care */ | ||
2609 | for (struct PeerInfo *pi = bucket->head; | ||
2610 | NULL != pi; | ||
2611 | pi = pi->next) | ||
2612 | if (0 == | ||
2613 | GNUNET_memcmp (&pi->id, | ||
2614 | pid)) | ||
2615 | { | ||
2616 | /* already connected */ | ||
2617 | /* TODO: maybe consider 'uri' anyway as an additional | ||
2618 | alternative address??? */ | ||
2619 | return; | ||
2620 | } | ||
2621 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2622 | "Discovered peer %s at %s suitable for bucket %d (%u/%u), trying to connect\n", | ||
2623 | GNUNET_i2s (pid), | ||
2624 | uri, | ||
2625 | peer_bucket, | ||
2626 | bucket->peers_size, | ||
2627 | bucket_size); | ||
2628 | /* new peer that we like! */ | ||
2629 | GDS_u_try_connect (pid, | ||
2630 | uri); | ||
2631 | } | ||
2632 | |||
2633 | |||
2634 | /** | ||
2635 | * Send @a msg to all peers in our buckets. | ||
2636 | * | ||
2637 | * @param msg message to broadcast | ||
2638 | */ | ||
2639 | void | ||
2640 | GDS_NEIGHBOURS_broadcast (const struct GNUNET_MessageHeader *msg) | ||
2641 | { | ||
2642 | for (unsigned int bc = 0; bc<closest_bucket; bc++) | ||
2643 | { | ||
2644 | struct PeerBucket *bucket = &k_buckets[bc]; | ||
2645 | unsigned int count = 0; | ||
2646 | |||
2647 | for (struct PeerInfo *pos = bucket->head; | ||
2648 | NULL != pos; | ||
2649 | pos = pos->next) | ||
2650 | { | ||
2651 | if (count >= bucket_size) | ||
2652 | break; /* we only consider first #bucket_size entries per bucket */ | ||
2653 | count++; | ||
2654 | do_send (pos, | ||
2655 | msg); | ||
2656 | } | ||
2657 | } | ||
2658 | } | ||
2659 | |||
2660 | |||
2661 | enum GNUNET_GenericReturnValue | ||
2662 | GDS_NEIGHBOURS_init () | ||
2663 | { | ||
2664 | |||
2444 | unsigned long long temp_config_num; | 2665 | unsigned long long temp_config_num; |
2445 | 2666 | ||
2446 | disable_try_connect | 2667 | disable_try_connect |
@@ -2457,45 +2678,8 @@ GDS_NEIGHBOURS_init () | |||
2457 | = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, | 2678 | = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, |
2458 | "DHT", | 2679 | "DHT", |
2459 | "CACHE_RESULTS"); | 2680 | "CACHE_RESULTS"); |
2460 | { | ||
2461 | char *keyfile; | ||
2462 | |||
2463 | if (GNUNET_OK != | ||
2464 | GNUNET_CONFIGURATION_get_value_filename (GDS_cfg, | ||
2465 | "PEER", | ||
2466 | "PRIVATE_KEY", | ||
2467 | &keyfile)) | ||
2468 | { | ||
2469 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2470 | "Core service is lacking HOSTKEY configuration setting. Exiting.\n"); | ||
2471 | return GNUNET_SYSERR; | ||
2472 | } | ||
2473 | if (GNUNET_SYSERR == | ||
2474 | GNUNET_CRYPTO_eddsa_key_from_file (keyfile, | ||
2475 | GNUNET_YES, | ||
2476 | &my_private_key)) | ||
2477 | { | ||
2478 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2479 | "Failed to setup peer's private key\n"); | ||
2480 | GNUNET_free (keyfile); | ||
2481 | return GNUNET_SYSERR; | ||
2482 | } | ||
2483 | GNUNET_free (keyfile); | ||
2484 | } | ||
2485 | |||
2486 | ats_ch = GNUNET_ATS_connectivity_init (GDS_cfg); | ||
2487 | core_api = GNUNET_CORE_connect (GDS_cfg, | ||
2488 | NULL, | ||
2489 | &core_init, | ||
2490 | &handle_core_connect, | ||
2491 | &handle_core_disconnect, | ||
2492 | core_handlers); | ||
2493 | if (NULL == core_api) | ||
2494 | return GNUNET_SYSERR; | ||
2495 | all_connected_peers = GNUNET_CONTAINER_multipeermap_create (256, | 2681 | all_connected_peers = GNUNET_CONTAINER_multipeermap_create (256, |
2496 | GNUNET_YES); | 2682 | GNUNET_YES); |
2497 | all_desired_peers = GNUNET_CONTAINER_multipeermap_create (256, | ||
2498 | GNUNET_NO); | ||
2499 | return GNUNET_OK; | 2683 | return GNUNET_OK; |
2500 | } | 2684 | } |
2501 | 2685 | ||
@@ -2503,21 +2687,12 @@ GDS_NEIGHBOURS_init () | |||
2503 | void | 2687 | void |
2504 | GDS_NEIGHBOURS_done () | 2688 | GDS_NEIGHBOURS_done () |
2505 | { | 2689 | { |
2506 | if (NULL == core_api) | 2690 | if (NULL == all_connected_peers) |
2507 | return; | 2691 | return; |
2508 | GNUNET_CORE_disconnect (core_api); | ||
2509 | core_api = NULL; | ||
2510 | GNUNET_assert (0 == | 2692 | GNUNET_assert (0 == |
2511 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers)); | 2693 | GNUNET_CONTAINER_multipeermap_size (all_connected_peers)); |
2512 | GNUNET_CONTAINER_multipeermap_destroy (all_connected_peers); | 2694 | GNUNET_CONTAINER_multipeermap_destroy (all_connected_peers); |
2513 | all_connected_peers = NULL; | 2695 | all_connected_peers = NULL; |
2514 | GNUNET_CONTAINER_multipeermap_iterate (all_desired_peers, | ||
2515 | &free_connect_info, | ||
2516 | NULL); | ||
2517 | GNUNET_CONTAINER_multipeermap_destroy (all_desired_peers); | ||
2518 | all_desired_peers = NULL; | ||
2519 | GNUNET_ATS_connectivity_done (ats_ch); | ||
2520 | ats_ch = NULL; | ||
2521 | GNUNET_assert (NULL == find_peer_task); | 2696 | GNUNET_assert (NULL == find_peer_task); |
2522 | } | 2697 | } |
2523 | 2698 | ||
@@ -2525,7 +2700,7 @@ GDS_NEIGHBOURS_done () | |||
2525 | struct GNUNET_PeerIdentity * | 2700 | struct GNUNET_PeerIdentity * |
2526 | GDS_NEIGHBOURS_get_id () | 2701 | GDS_NEIGHBOURS_get_id () |
2527 | { | 2702 | { |
2528 | return &my_identity; | 2703 | return &GDS_my_identity; |
2529 | } | 2704 | } |
2530 | 2705 | ||
2531 | 2706 | ||
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 35bbb125d..4f4172f71 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h | |||
@@ -30,13 +30,9 @@ | |||
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_dhtu_plugin.h" | ||
33 | #include "gnunet-service-dht_datacache.h" | 34 | #include "gnunet-service-dht_datacache.h" |
34 | 35 | ||
35 | /** | ||
36 | * Hash of the identity of this peer. | ||
37 | */ | ||
38 | extern struct GNUNET_HashCode my_identity_hash; | ||
39 | |||
40 | 36 | ||
41 | struct PeerInfo; | 37 | struct PeerInfo; |
42 | 38 | ||
@@ -67,8 +63,8 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target); | |||
67 | enum GNUNET_GenericReturnValue | 63 | enum GNUNET_GenericReturnValue |
68 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | 64 | GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, |
69 | enum GNUNET_DHT_RouteOption options, | 65 | enum GNUNET_DHT_RouteOption options, |
70 | uint32_t desired_replication_level, | 66 | uint16_t desired_replication_level, |
71 | uint32_t hop_count, | 67 | uint16_t hop_count, |
72 | struct GNUNET_CONTAINER_BloomFilter *bf); | 68 | struct GNUNET_CONTAINER_BloomFilter *bf); |
73 | 69 | ||
74 | 70 | ||
@@ -92,8 +88,8 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd, | |||
92 | enum GNUNET_GenericReturnValue | 88 | enum GNUNET_GenericReturnValue |
93 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | 89 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, |
94 | enum GNUNET_DHT_RouteOption options, | 90 | enum GNUNET_DHT_RouteOption options, |
95 | uint32_t desired_replication_level, | 91 | uint16_t desired_replication_level, |
96 | uint32_t hop_count, | 92 | uint16_t hop_count, |
97 | const struct GNUNET_HashCode *key, | 93 | const struct GNUNET_HashCode *key, |
98 | const void *xquery, | 94 | const void *xquery, |
99 | size_t xquery_size, | 95 | size_t xquery_size, |
@@ -112,8 +108,9 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | |||
112 | * @param query_hash query that was used for the request | 108 | * @param query_hash query that was used for the request |
113 | * @param get_path_length number of entries in put_path | 109 | * @param get_path_length number of entries in put_path |
114 | * @param get_path peers this reply has traversed so far (if tracked) | 110 | * @param get_path peers this reply has traversed so far (if tracked) |
111 | * @return true on success | ||
115 | */ | 112 | */ |
116 | void | 113 | bool |
117 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, | 114 | GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, |
118 | const struct GDS_DATACACHE_BlockData *bd, | 115 | const struct GDS_DATACACHE_BlockData *bd, |
119 | const struct GNUNET_HashCode *query_hash, | 116 | const struct GNUNET_HashCode *query_hash, |
@@ -137,6 +134,73 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, | |||
137 | 134 | ||
138 | 135 | ||
139 | /** | 136 | /** |
137 | * Callback function used to extract URIs from a builder. | ||
138 | * Called when we should consider connecting to a peer. | ||
139 | * | ||
140 | * @param cls closure pointing to a `struct GNUNET_PeerIdentity *` | ||
141 | * @param uri one of the URIs | ||
142 | */ | ||
143 | void | ||
144 | GDS_try_connect (void *cls, | ||
145 | const char *uri); | ||
146 | |||
147 | |||
148 | /** | ||
149 | * Function to call when we connect to a peer and can henceforth transmit to | ||
150 | * that peer. | ||
151 | * | ||
152 | * @param cls the closure, must be a `struct GDS_Underlay` | ||
153 | * @param target handle to the target, | ||
154 | * pointer will remain valid until @e disconnect_cb is called | ||
155 | * @para pid peer identity, | ||
156 | * pointer will remain valid until @e disconnect_cb is called | ||
157 | * @param[out] ctx storage space for DHT to use in association with this target | ||
158 | */ | ||
159 | void | ||
160 | GDS_u_connect (void *cls, | ||
161 | struct GNUNET_DHTU_Target *target, | ||
162 | const struct GNUNET_PeerIdentity *pid, | ||
163 | void **ctx); | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Function to call when we disconnected from a peer and can henceforth | ||
168 | * cannot transmit to that peer anymore. | ||
169 | * | ||
170 | * @param[in] ctx storage space used by the DHT in association with this target | ||
171 | */ | ||
172 | void | ||
173 | GDS_u_disconnect (void *ctx); | ||
174 | |||
175 | |||
176 | /** | ||
177 | * Function to call when we receive a message. | ||
178 | * | ||
179 | * @param cls the closure | ||
180 | * @param origin where the message originated from | ||
181 | * @param[in,out] tctx ctx of target address where we received the message from | ||
182 | * @param[in,out] sctx ctx of our own source address at which we received the message | ||
183 | * @param message the message we received @param message_size number of | ||
184 | * bytes in @a message | ||
185 | */ | ||
186 | void | ||
187 | GDS_u_receive (void *cls, | ||
188 | void **tctx, | ||
189 | void **sctx, | ||
190 | const void *message, | ||
191 | size_t message_size); | ||
192 | |||
193 | |||
194 | /** | ||
195 | * Send @a msg to all peers in our buckets. | ||
196 | * | ||
197 | * @param msg message to broadcast | ||
198 | */ | ||
199 | void | ||
200 | GDS_NEIGHBOURS_broadcast (const struct GNUNET_MessageHeader *msg); | ||
201 | |||
202 | |||
203 | /** | ||
140 | * Initialize neighbours subsystem. | 204 | * Initialize neighbours subsystem. |
141 | * | 205 | * |
142 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 206 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c deleted file mode 100644 index 58f18816a..000000000 --- a/src/dht/gnunet-service-dht_nse.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011 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 | * @file dht/gnunet-service-dht_nse.c | ||
23 | * @brief GNUnet DHT integration with NSE | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_nse_service.h" | ||
28 | #include "gnunet-service-dht.h" | ||
29 | #include "gnunet-service-dht_nse.h" | ||
30 | |||
31 | /** | ||
32 | * log of the current network size estimate, used as the point where | ||
33 | * we switch between random and deterministic routing. Default | ||
34 | * value of 4.0 is used if NSE module is not available (i.e. not | ||
35 | * configured). | ||
36 | */ | ||
37 | static double log_of_network_size_estimate = 4.0; | ||
38 | |||
39 | /** | ||
40 | * Network size estimation handle. | ||
41 | */ | ||
42 | static struct GNUNET_NSE_Handle *nse; | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Callback that is called when network size estimate is updated. | ||
47 | * | ||
48 | * @param cls closure | ||
49 | * @param timestamp time when the estimate was received from the server (or created by the server) | ||
50 | * @param logestimate the log(Base 2) value of the current network size estimate | ||
51 | * @param std_dev standard deviation for the estimate | ||
52 | * | ||
53 | */ | ||
54 | static void | ||
55 | update_network_size_estimate (void *cls, | ||
56 | struct GNUNET_TIME_Absolute timestamp, | ||
57 | double logestimate, | ||
58 | double std_dev) | ||
59 | { | ||
60 | GNUNET_STATISTICS_update (GDS_stats, | ||
61 | "# Network size estimates received", | ||
62 | 1, GNUNET_NO); | ||
63 | /* do not allow estimates < 0.5 */ | ||
64 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Return the log of the current network size estimate. | ||
70 | * | ||
71 | * @return log of NSE | ||
72 | */ | ||
73 | double | ||
74 | GDS_NSE_get () | ||
75 | { | ||
76 | return log_of_network_size_estimate; | ||
77 | } | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Initialize NSE subsystem. | ||
82 | */ | ||
83 | void | ||
84 | GDS_NSE_init () | ||
85 | { | ||
86 | unsigned long long hops; | ||
87 | |||
88 | if ( (GNUNET_YES == | ||
89 | GNUNET_CONFIGURATION_have_value (GDS_cfg, | ||
90 | "dht", | ||
91 | "FORCE_NSE")) && | ||
92 | (GNUNET_OK == | ||
93 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, | ||
94 | "dht", | ||
95 | "FORCE_NSE", | ||
96 | &hops)) ) | ||
97 | { | ||
98 | log_of_network_size_estimate = (double) hops; | ||
99 | return; | ||
100 | } | ||
101 | nse = GNUNET_NSE_connect (GDS_cfg, | ||
102 | &update_network_size_estimate, | ||
103 | NULL); | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Shutdown NSE subsystem. | ||
109 | */ | ||
110 | void | ||
111 | GDS_NSE_done () | ||
112 | { | ||
113 | if (NULL != nse) | ||
114 | { | ||
115 | GNUNET_NSE_disconnect (nse); | ||
116 | nse = NULL; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | |||
121 | /* end of gnunet-service-dht_nse.c */ | ||
diff --git a/src/dht/gnunet-service-dht_nse.h b/src/dht/gnunet-service-dht_nse.h deleted file mode 100644 index e99389e74..000000000 --- a/src/dht/gnunet-service-dht_nse.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 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 | * @file dht/gnunet-service-dht_nse.h | ||
23 | * @brief GNUnet DHT integration with NSE | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_DHT_NSE_H | ||
27 | #define GNUNET_SERVICE_DHT_NSE_H | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Return the log of the current network size estimate. | ||
32 | * | ||
33 | * @return log of NSE | ||
34 | */ | ||
35 | double | ||
36 | GDS_NSE_get (void); | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Initialize NSE subsystem. | ||
41 | */ | ||
42 | void | ||
43 | GDS_NSE_init (void); | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Shutdown NSE subsystem. | ||
48 | */ | ||
49 | void | ||
50 | GDS_NSE_done (void); | ||
51 | |||
52 | #endif | ||
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index e7b5c3571..6deb5fa16 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet-service-dht_neighbours.h" | 27 | #include "gnunet-service-dht_neighbours.h" |
28 | #include "gnunet-service-dht_routing.h" | 28 | #include "gnunet-service-dht_routing.h" |
29 | #include "gnunet-service-dht.h" | 29 | #include "gnunet-service-dht.h" |
30 | #include "gnunet_block_group_lib.h" | ||
30 | 31 | ||
31 | 32 | ||
32 | /** | 33 | /** |
@@ -151,7 +152,7 @@ process (void *cls, | |||
151 | bdx.put_path_length = 0; | 152 | bdx.put_path_length = 0; |
152 | bdx.put_path = NULL; | 153 | bdx.put_path = NULL; |
153 | } | 154 | } |
154 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) && | 155 | if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_APPROXIMATE)) && |
155 | (0 != GNUNET_memcmp (query_hash, | 156 | (0 != GNUNET_memcmp (query_hash, |
156 | &bdx.key)) ) | 157 | &bdx.key)) ) |
157 | { | 158 | { |
@@ -174,6 +175,22 @@ process (void *cls, | |||
174 | GNUNET_h2s (&bdx.key), | 175 | GNUNET_h2s (&bdx.key), |
175 | bdx.type, | 176 | bdx.type, |
176 | eval); | 177 | eval); |
178 | if (GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED == eval) | ||
179 | { | ||
180 | /* If we do not know the block type, we still filter | ||
181 | exact duplicates by the block content */ | ||
182 | struct GNUNET_HashCode chash; | ||
183 | |||
184 | GNUNET_CRYPTO_hash (bdx.data, | ||
185 | bdx.data_size, | ||
186 | &chash); | ||
187 | if (GNUNET_YES == | ||
188 | GNUNET_BLOCK_GROUP_bf_test_and_set (rr->bg, | ||
189 | &chash)) | ||
190 | eval = GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
191 | else | ||
192 | eval = GNUNET_BLOCK_REPLY_OK_MORE; | ||
193 | } | ||
177 | switch (eval) | 194 | switch (eval) |
178 | { | 195 | { |
179 | case GNUNET_BLOCK_REPLY_OK_MORE: | 196 | case GNUNET_BLOCK_REPLY_OK_MORE: |
@@ -195,10 +212,11 @@ process (void *cls, | |||
195 | GNUNET_h2s (query_hash)); | 212 | GNUNET_h2s (query_hash)); |
196 | return GNUNET_OK; | 213 | return GNUNET_OK; |
197 | } | 214 | } |
198 | GDS_NEIGHBOURS_handle_reply (pi, | 215 | GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi, |
199 | &bdx, | 216 | &bdx, |
200 | query_hash, | 217 | query_hash, |
201 | get_path_length, pc->get_path); | 218 | get_path_length, |
219 | pc->get_path)); | ||
202 | } | 220 | } |
203 | break; | 221 | break; |
204 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: | 222 | case GNUNET_BLOCK_REPLY_OK_DUPLICATE: |
@@ -207,13 +225,6 @@ process (void *cls, | |||
207 | 1, | 225 | 1, |
208 | GNUNET_NO); | 226 | GNUNET_NO); |
209 | return GNUNET_OK; | 227 | return GNUNET_OK; |
210 | case GNUNET_BLOCK_REPLY_INVALID: | ||
211 | GNUNET_break (0); | ||
212 | GNUNET_STATISTICS_update (GDS_stats, | ||
213 | "# Invalid REPLIES matched against routing table", | ||
214 | 1, | ||
215 | GNUNET_NO); | ||
216 | return GNUNET_OK; | ||
217 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | 228 | case GNUNET_BLOCK_REPLY_IRRELEVANT: |
218 | GNUNET_STATISTICS_update (GDS_stats, | 229 | GNUNET_STATISTICS_update (GDS_stats, |
219 | "# Irrelevant REPLIES matched against routing table", | 230 | "# Irrelevant REPLIES matched against routing table", |
@@ -325,6 +336,7 @@ try_combine_recent (void *cls, | |||
325 | * | 336 | * |
326 | * @param sender peer that originated the request | 337 | * @param sender peer that originated the request |
327 | * @param type type of the block | 338 | * @param type type of the block |
339 | * @param[in] bg block group for filtering duplicate replies | ||
328 | * @param options options for processing | 340 | * @param options options for processing |
329 | * @param key key for the content | 341 | * @param key key for the content |
330 | * @param xquery extended query | 342 | * @param xquery extended query |
diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index 7c6fb9ed6..3dd3dd792 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.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, 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 |
@@ -28,6 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_constants.h" | 29 | #include "gnunet_constants.h" |
30 | #include "gnunet_hello_lib.h" | 30 | #include "gnunet_hello_lib.h" |
31 | #include "gnunet_hello_uri_lib.h" | ||
31 | #include "gnunet_block_plugin.h" | 32 | #include "gnunet_block_plugin.h" |
32 | #include "gnunet_block_group_lib.h" | 33 | #include "gnunet_block_group_lib.h" |
33 | 34 | ||
@@ -89,80 +90,9 @@ block_plugin_dht_create_group (void *cls, | |||
89 | 90 | ||
90 | 91 | ||
91 | /** | 92 | /** |
92 | * Function called to validate a reply or a request. For | ||
93 | * request evaluation, simply pass "NULL" for the @a reply_block. | ||
94 | * | ||
95 | * @param cls closure | ||
96 | * @param ctx context | ||
97 | * @param type block type | ||
98 | * @param group block group to check against | ||
99 | * @param eo control flags | ||
100 | * @param query original query (hash) | ||
101 | * @param xquery extended query data (can be NULL, depending on type) | ||
102 | * @param xquery_size number of bytes in @a xquery | ||
103 | * @param reply_block response to validate | ||
104 | * @param reply_block_size number of bytes in @a reply_block | ||
105 | * @return characterization of result | ||
106 | */ | ||
107 | static enum GNUNET_BLOCK_EvaluationResult | ||
108 | block_plugin_dht_evaluate (void *cls, | ||
109 | struct GNUNET_BLOCK_Context *ctx, | ||
110 | enum GNUNET_BLOCK_Type type, | ||
111 | struct GNUNET_BLOCK_Group *group, | ||
112 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
113 | const struct GNUNET_HashCode *query, | ||
114 | const void *xquery, | ||
115 | size_t xquery_size, | ||
116 | const void *reply_block, | ||
117 | size_t reply_block_size) | ||
118 | { | ||
119 | const struct GNUNET_HELLO_Message *hello; | ||
120 | struct GNUNET_PeerIdentity pid; | ||
121 | const struct GNUNET_MessageHeader *msg; | ||
122 | struct GNUNET_HashCode phash; | ||
123 | |||
124 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | ||
125 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
126 | if (0 != xquery_size) | ||
127 | { | ||
128 | GNUNET_break_op (0); | ||
129 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
130 | } | ||
131 | if (NULL == reply_block) | ||
132 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
133 | if (reply_block_size < sizeof(struct GNUNET_MessageHeader)) | ||
134 | { | ||
135 | GNUNET_break_op (0); | ||
136 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
137 | } | ||
138 | msg = reply_block; | ||
139 | if (reply_block_size != ntohs (msg->size)) | ||
140 | { | ||
141 | GNUNET_break_op (0); | ||
142 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
143 | } | ||
144 | hello = reply_block; | ||
145 | if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) | ||
146 | { | ||
147 | GNUNET_break_op (0); | ||
148 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
149 | } | ||
150 | GNUNET_CRYPTO_hash (&pid, | ||
151 | sizeof(pid), | ||
152 | &phash); | ||
153 | if (GNUNET_YES == | ||
154 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
155 | &phash)) | ||
156 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
157 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Function called to validate a query. | 93 | * Function called to validate a query. |
163 | * | 94 | * |
164 | * @param cls closure | 95 | * @param cls closure |
165 | * @param ctx block context | ||
166 | * @param type block type | 96 | * @param type block type |
167 | * @param query original query (hash) | 97 | * @param query original query (hash) |
168 | * @param xquery extrended query data (can be NULL, depending on type) | 98 | * @param xquery extrended query data (can be NULL, depending on type) |
@@ -171,19 +101,31 @@ block_plugin_dht_evaluate (void *cls, | |||
171 | */ | 101 | */ |
172 | static enum GNUNET_GenericReturnValue | 102 | static enum GNUNET_GenericReturnValue |
173 | block_plugin_dht_check_query (void *cls, | 103 | block_plugin_dht_check_query (void *cls, |
174 | enum GNUNET_BLOCK_Type type, | 104 | enum GNUNET_BLOCK_Type type, |
175 | const struct GNUNET_HashCode *query, | 105 | const struct GNUNET_HashCode *query, |
176 | const void *xquery, | 106 | const void *xquery, |
177 | size_t xquery_size) | 107 | size_t xquery_size) |
178 | { | 108 | { |
179 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | 109 | switch (type) |
180 | return GNUNET_SYSERR; | ||
181 | if (0 != xquery_size) | ||
182 | { | 110 | { |
183 | GNUNET_break_op (0); | 111 | case GNUNET_BLOCK_TYPE_DHT_HELLO: |
184 | return GNUNET_NO; | 112 | if (0 != xquery_size) |
113 | { | ||
114 | GNUNET_break_op (0); | ||
115 | return GNUNET_NO; | ||
116 | } | ||
117 | return GNUNET_OK; | ||
118 | case GNUNET_BLOCK_TYPE_DHT_URL_HELLO: | ||
119 | if (0 != xquery_size) | ||
120 | { | ||
121 | GNUNET_break_op (0); | ||
122 | return GNUNET_NO; | ||
123 | } | ||
124 | return GNUNET_OK; | ||
125 | default: | ||
126 | GNUNET_break (0); | ||
127 | return GNUNET_SYSERR; | ||
185 | } | 128 | } |
186 | return GNUNET_OK; | ||
187 | } | 129 | } |
188 | 130 | ||
189 | 131 | ||
@@ -192,44 +134,71 @@ block_plugin_dht_check_query (void *cls, | |||
192 | * | 134 | * |
193 | * @param cls closure | 135 | * @param cls closure |
194 | * @param type block type | 136 | * @param type block type |
195 | * @param query key for the block (hash), must match exactly | ||
196 | * @param block block data to validate | 137 | * @param block block data to validate |
197 | * @param block_size number of bytes in @a block | 138 | * @param block_size number of bytes in @a block |
198 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 139 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
199 | */ | 140 | */ |
200 | static enum GNUNET_GenericReturnValue | 141 | static enum GNUNET_GenericReturnValue |
201 | block_plugin_dht_check_block (void *cls, | 142 | block_plugin_dht_check_block (void *cls, |
202 | enum GNUNET_BLOCK_Type type, | 143 | enum GNUNET_BLOCK_Type type, |
203 | const struct GNUNET_HashCode *query, | 144 | const void *block, |
204 | const void *block, | 145 | size_t block_size) |
205 | size_t block_size) | ||
206 | { | 146 | { |
207 | const struct GNUNET_HELLO_Message *hello; | 147 | switch (type) |
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 | { | 148 | { |
229 | GNUNET_break_op (0); | 149 | case GNUNET_BLOCK_TYPE_DHT_HELLO: |
230 | return GNUNET_NO; | 150 | { |
151 | const struct GNUNET_HELLO_Message *hello; | ||
152 | struct GNUNET_PeerIdentity pid; | ||
153 | const struct GNUNET_MessageHeader *msg; | ||
154 | |||
155 | if (block_size < sizeof(struct GNUNET_MessageHeader)) | ||
156 | { | ||
157 | GNUNET_break_op (0); | ||
158 | return GNUNET_NO; | ||
159 | } | ||
160 | msg = block; | ||
161 | if (block_size != ntohs (msg->size)) | ||
162 | { | ||
163 | GNUNET_break_op (0); | ||
164 | return GNUNET_NO; | ||
165 | } | ||
166 | hello = block; | ||
167 | if (GNUNET_OK != | ||
168 | GNUNET_HELLO_get_id (hello, | ||
169 | &pid)) | ||
170 | { | ||
171 | GNUNET_break_op (0); | ||
172 | return GNUNET_NO; | ||
173 | } | ||
174 | return GNUNET_OK; | ||
175 | } | ||
176 | case GNUNET_BLOCK_TYPE_DHT_URL_HELLO: | ||
177 | { | ||
178 | struct GNUNET_HELLO_Builder *b; | ||
179 | struct GNUNET_PeerIdentity pid; | ||
180 | struct GNUNET_HashCode h_pid; | ||
181 | |||
182 | b = GNUNET_HELLO_builder_from_block (block, | ||
183 | block_size); | ||
184 | if (NULL == b) | ||
185 | { | ||
186 | GNUNET_break (0); | ||
187 | return GNUNET_NO; | ||
188 | } | ||
189 | GNUNET_HELLO_builder_iterate (b, | ||
190 | &pid, | ||
191 | NULL, NULL); | ||
192 | GNUNET_CRYPTO_hash (&pid, | ||
193 | sizeof (pid), | ||
194 | &h_pid); | ||
195 | GNUNET_HELLO_builder_free (b); | ||
196 | return GNUNET_OK; | ||
197 | } | ||
198 | default: | ||
199 | GNUNET_break (0); | ||
200 | return GNUNET_SYSERR; | ||
231 | } | 201 | } |
232 | return GNUNET_OK; | ||
233 | } | 202 | } |
234 | 203 | ||
235 | 204 | ||
@@ -251,49 +220,63 @@ block_plugin_dht_check_block (void *cls, | |||
251 | */ | 220 | */ |
252 | static enum GNUNET_BLOCK_ReplyEvaluationResult | 221 | static enum GNUNET_BLOCK_ReplyEvaluationResult |
253 | block_plugin_dht_check_reply ( | 222 | block_plugin_dht_check_reply ( |
254 | void *cls, | 223 | void *cls, |
255 | enum GNUNET_BLOCK_Type type, | 224 | enum GNUNET_BLOCK_Type type, |
256 | struct GNUNET_BLOCK_Group *group, | 225 | struct GNUNET_BLOCK_Group *group, |
257 | const struct GNUNET_HashCode *query, | 226 | const struct GNUNET_HashCode *query, |
258 | const void *xquery, | 227 | const void *xquery, |
259 | size_t xquery_size, | 228 | size_t xquery_size, |
260 | const void *reply_block, | 229 | const void *reply_block, |
261 | size_t reply_block_size) | 230 | size_t reply_block_size) |
262 | { | 231 | { |
263 | const struct GNUNET_HELLO_Message *hello; | 232 | switch (type) |
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 | { | 233 | { |
286 | GNUNET_break_op (0); | 234 | case GNUNET_BLOCK_TYPE_DHT_HELLO: |
287 | return GNUNET_BLOCK_REPLY_INVALID; | 235 | { |
236 | const struct GNUNET_MessageHeader *msg = reply_block; | ||
237 | const struct GNUNET_HELLO_Message *hello = reply_block; | ||
238 | struct GNUNET_PeerIdentity pid; | ||
239 | struct GNUNET_HashCode phash; | ||
240 | |||
241 | GNUNET_assert (reply_block_size >= sizeof(struct GNUNET_MessageHeader)); | ||
242 | GNUNET_assert (reply_block_size == ntohs (msg->size)); | ||
243 | GNUNET_assert (GNUNET_OK == | ||
244 | GNUNET_HELLO_get_id (hello, | ||
245 | &pid)); | ||
246 | GNUNET_CRYPTO_hash (&pid, | ||
247 | sizeof(pid), | ||
248 | &phash); | ||
249 | if (GNUNET_YES == | ||
250 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
251 | &phash)) | ||
252 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
253 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
254 | } | ||
255 | case GNUNET_BLOCK_TYPE_DHT_URL_HELLO: | ||
256 | { | ||
257 | struct GNUNET_HELLO_Builder *b; | ||
258 | struct GNUNET_PeerIdentity pid; | ||
259 | struct GNUNET_HashCode h_pid; | ||
260 | |||
261 | b = GNUNET_HELLO_builder_from_block (reply_block, | ||
262 | reply_block_size); | ||
263 | GNUNET_assert (NULL != b); | ||
264 | GNUNET_HELLO_builder_iterate (b, | ||
265 | &pid, | ||
266 | NULL, NULL); | ||
267 | GNUNET_CRYPTO_hash (&pid, | ||
268 | sizeof (pid), | ||
269 | &h_pid); | ||
270 | GNUNET_HELLO_builder_free (b); | ||
271 | if (GNUNET_YES == | ||
272 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
273 | &h_pid)) | ||
274 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
275 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
276 | } | ||
277 | default: | ||
278 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
288 | } | 279 | } |
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 | } | 280 | } |
298 | 281 | ||
299 | 282 | ||
@@ -315,41 +298,76 @@ block_plugin_dht_get_key (void *cls, | |||
315 | size_t block_size, | 298 | size_t block_size, |
316 | struct GNUNET_HashCode *key) | 299 | struct GNUNET_HashCode *key) |
317 | { | 300 | { |
318 | const struct GNUNET_MessageHeader *msg; | 301 | switch (type) |
319 | const struct GNUNET_HELLO_Message *hello; | ||
320 | struct GNUNET_PeerIdentity *pid; | ||
321 | |||
322 | if (type != GNUNET_BLOCK_TYPE_DHT_HELLO) | ||
323 | return GNUNET_SYSERR; | ||
324 | if (block_size < sizeof(struct GNUNET_MessageHeader)) | ||
325 | { | 302 | { |
326 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 303 | case GNUNET_BLOCK_TYPE_DHT_HELLO: |
327 | "block-dht", | 304 | { |
328 | _ ("Block not of type %u\n"), | 305 | const struct GNUNET_MessageHeader *msg; |
329 | GNUNET_BLOCK_TYPE_DHT_HELLO); | 306 | const struct GNUNET_HELLO_Message *hello; |
330 | return GNUNET_NO; | 307 | struct GNUNET_PeerIdentity *pid; |
331 | } | 308 | |
332 | msg = block; | 309 | if (block_size < sizeof(struct GNUNET_MessageHeader)) |
333 | if (block_size != ntohs (msg->size)) | 310 | { |
334 | { | 311 | GNUNET_break_op (0); |
335 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 312 | memset (key, |
336 | "block-dht", | 313 | 0, |
337 | _ ("Size mismatch for block with type %u\n"), | 314 | sizeof (*key)); |
338 | GNUNET_BLOCK_TYPE_DHT_HELLO); | 315 | return GNUNET_OK; |
339 | return GNUNET_NO; | 316 | } |
340 | } | 317 | msg = block; |
341 | hello = block; | 318 | if (block_size != ntohs (msg->size)) |
342 | memset (key, 0, sizeof(*key)); | 319 | { |
343 | pid = (struct GNUNET_PeerIdentity *) key; | 320 | GNUNET_break_op (0); |
344 | if (GNUNET_OK != GNUNET_HELLO_get_id (hello, pid)) | 321 | memset (key, |
345 | { | 322 | 0, |
346 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 323 | sizeof (*key)); |
347 | "block-dht", | 324 | return GNUNET_OK; |
348 | _ ("Block of type %u is malformed\n"), | 325 | } |
349 | GNUNET_BLOCK_TYPE_DHT_HELLO); | 326 | hello = block; |
350 | return GNUNET_NO; | 327 | memset (key, |
328 | 0, | ||
329 | sizeof(*key)); | ||
330 | pid = (struct GNUNET_PeerIdentity *) key; | ||
331 | if (GNUNET_OK != | ||
332 | GNUNET_HELLO_get_id (hello, | ||
333 | pid)) | ||
334 | { | ||
335 | GNUNET_break_op (0); | ||
336 | memset (key, | ||
337 | 0, | ||
338 | sizeof (*key)); | ||
339 | return GNUNET_OK; | ||
340 | } | ||
341 | return GNUNET_OK; | ||
342 | } | ||
343 | case GNUNET_BLOCK_TYPE_DHT_URL_HELLO: | ||
344 | { | ||
345 | struct GNUNET_HELLO_Builder *b; | ||
346 | struct GNUNET_PeerIdentity pid; | ||
347 | |||
348 | b = GNUNET_HELLO_builder_from_block (block, | ||
349 | block_size); | ||
350 | if (NULL == b) | ||
351 | { | ||
352 | GNUNET_break (0); | ||
353 | memset (key, | ||
354 | 0, | ||
355 | sizeof (*key)); | ||
356 | return GNUNET_OK; | ||
357 | } | ||
358 | GNUNET_HELLO_builder_iterate (b, | ||
359 | &pid, | ||
360 | NULL, NULL); | ||
361 | GNUNET_CRYPTO_hash (&pid, | ||
362 | sizeof (pid), | ||
363 | key); | ||
364 | GNUNET_HELLO_builder_free (b); | ||
365 | return GNUNET_OK; | ||
366 | } | ||
367 | default: | ||
368 | GNUNET_break (0); | ||
369 | return GNUNET_SYSERR; | ||
351 | } | 370 | } |
352 | return GNUNET_OK; | ||
353 | } | 371 | } |
354 | 372 | ||
355 | 373 | ||
@@ -361,12 +379,12 @@ libgnunet_plugin_block_dht_init (void *cls) | |||
361 | { | 379 | { |
362 | static enum GNUNET_BLOCK_Type types[] = { | 380 | static enum GNUNET_BLOCK_Type types[] = { |
363 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 381 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
382 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO, | ||
364 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 383 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
365 | }; | 384 | }; |
366 | struct GNUNET_BLOCK_PluginFunctions *api; | 385 | struct GNUNET_BLOCK_PluginFunctions *api; |
367 | 386 | ||
368 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 387 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
369 | api->evaluate = &block_plugin_dht_evaluate; | ||
370 | api->get_key = &block_plugin_dht_get_key; | 388 | api->get_key = &block_plugin_dht_get_key; |
371 | api->check_query = &block_plugin_dht_check_query; | 389 | api->check_query = &block_plugin_dht_check_query; |
372 | api->check_block = &block_plugin_dht_check_block; | 390 | api->check_block = &block_plugin_dht_check_block; |
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index eb7e80d3b..4830ba629 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c | |||
@@ -326,7 +326,7 @@ timeout_cb (void *cls) | |||
326 | * | 326 | * |
327 | * @param cls closure with our 'struct GetOperation' | 327 | * @param cls closure with our 'struct GetOperation' |
328 | * @param exp when will this value expire | 328 | * @param exp when will this value expire |
329 | * @param key key of the result | 329 | * @param query query hash |
330 | * @param get_path peers on reply path (or NULL if not recorded) | 330 | * @param get_path peers on reply path (or NULL if not recorded) |
331 | * @param get_path_length number of entries in @a get_path | 331 | * @param get_path_length number of entries in @a get_path |
332 | * @param put_path peers on the PUT path (or NULL if not recorded) | 332 | * @param put_path peers on the PUT path (or NULL if not recorded) |
@@ -338,7 +338,7 @@ timeout_cb (void *cls) | |||
338 | static void | 338 | static void |
339 | dht_get_handler (void *cls, | 339 | dht_get_handler (void *cls, |
340 | struct GNUNET_TIME_Absolute exp, | 340 | struct GNUNET_TIME_Absolute exp, |
341 | const struct GNUNET_HashCode *key, | 341 | const struct GNUNET_HashCode *query, |
342 | const struct GNUNET_DHT_PathElement *get_path, | 342 | const struct GNUNET_DHT_PathElement *get_path, |
343 | unsigned int get_path_length, | 343 | unsigned int get_path_length, |
344 | const struct GNUNET_DHT_PathElement *put_path, | 344 | const struct GNUNET_DHT_PathElement *put_path, |
@@ -359,8 +359,15 @@ dht_get_handler (void *cls, | |||
359 | GNUNET_break (0); | 359 | GNUNET_break (0); |
360 | return; | 360 | return; |
361 | } | 361 | } |
362 | GNUNET_CRYPTO_hash (key, | 362 | if (0 != GNUNET_memcmp (query, |
363 | sizeof(*key), | 363 | &get_op->key)) |
364 | { | ||
365 | /* exact search should only yield exact results */ | ||
366 | GNUNET_break (0); | ||
367 | return; | ||
368 | } | ||
369 | GNUNET_CRYPTO_hash (query, | ||
370 | sizeof(*query), | ||
364 | &want); | 371 | &want); |
365 | if (0 != memcmp (&want, | 372 | if (0 != memcmp (&want, |
366 | data, | 373 | data, |
@@ -370,18 +377,21 @@ dht_get_handler (void *cls, | |||
370 | return; | 377 | return; |
371 | } | 378 | } |
372 | if (0 != | 379 | if (0 != |
373 | GNUNET_DHT_verify_path (key, | 380 | GNUNET_DHT_verify_path (data, |
374 | data, | ||
375 | size, | 381 | size, |
376 | exp, | 382 | exp, |
377 | get_path, | ||
378 | get_path_length, | ||
379 | put_path, | 383 | put_path, |
380 | put_path_length, | 384 | put_path_length, |
385 | get_path, | ||
386 | get_path_length, | ||
381 | &get_op->me)) | 387 | &get_op->me)) |
382 | { | 388 | { |
389 | GNUNET_break (0); | ||
383 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 390 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
384 | "Path signature verification failed!\n"); | 391 | "Path signature (%u/%u) verification failed for peer %s!\n", |
392 | get_path_length, | ||
393 | put_path_length, | ||
394 | GNUNET_i2s (&get_op->me)); | ||
385 | } | 395 | } |
386 | else | 396 | else |
387 | { | 397 | { |
diff --git a/src/dhtu/Makefile.am b/src/dhtu/Makefile.am index 0e10721cd..ebffa9ecf 100644 --- a/src/dhtu/Makefile.am +++ b/src/dhtu/Makefile.am | |||
@@ -10,6 +10,10 @@ if USE_COVERAGE | |||
10 | XLIBS = -lgcov | 10 | XLIBS = -lgcov |
11 | endif | 11 | endif |
12 | 12 | ||
13 | pkgcfg_DATA = \ | ||
14 | dhtu.conf | ||
15 | |||
16 | |||
13 | plugin_LTLIBRARIES = \ | 17 | plugin_LTLIBRARIES = \ |
14 | libgnunet_plugin_dhtu_gnunet.la \ | 18 | libgnunet_plugin_dhtu_gnunet.la \ |
15 | libgnunet_plugin_dhtu_ip.la | 19 | libgnunet_plugin_dhtu_ip.la |
@@ -67,6 +71,9 @@ test_dhtu_ip_LDADD = \ | |||
67 | check_PROGRAMS = \ | 71 | check_PROGRAMS = \ |
68 | test_dhtu_ip | 72 | test_dhtu_ip |
69 | 73 | ||
74 | EXTRA_DIST = \ | ||
75 | dhtu.conf | ||
76 | |||
70 | if ENABLE_TEST_RUN | 77 | if ENABLE_TEST_RUN |
71 | 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; |
72 | TESTS = \ | 79 | TESTS = \ |
diff --git a/src/dhtu/dhtu.conf b/src/dhtu/dhtu.conf new file mode 100644 index 000000000..ea5ade752 --- /dev/null +++ b/src/dhtu/dhtu.conf | |||
@@ -0,0 +1,7 @@ | |||
1 | [dhtu-gnunet] | ||
2 | ENABLED = YES | ||
3 | |||
4 | [dhtu-ip] | ||
5 | ENABLED = NO | ||
6 | NSE = 4 | ||
7 | UDP_PORT = 6666 | ||
diff --git a/src/dhtu/plugin_dhtu_gnunet.c b/src/dhtu/plugin_dhtu_gnunet.c index 2163af941..b072be2be 100644 --- a/src/dhtu/plugin_dhtu_gnunet.c +++ b/src/dhtu/plugin_dhtu_gnunet.c | |||
@@ -70,11 +70,6 @@ struct GNUNET_DHTU_Source | |||
70 | { | 70 | { |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * Hash of @e pid, position of this peer in the DHT overlay. | ||
74 | */ | ||
75 | struct GNUNET_DHTU_HashKey id; | ||
76 | |||
77 | /** | ||
78 | * Application context for this source. | 73 | * Application context for this source. |
79 | */ | 74 | */ |
80 | void *app_ctx; | 75 | void *app_ctx; |
@@ -125,11 +120,6 @@ struct GNUNET_DHTU_Target | |||
125 | struct GNUNET_PeerIdentity pid; | 120 | struct GNUNET_PeerIdentity pid; |
126 | 121 | ||
127 | /** | 122 | /** |
128 | * Hash of @e pid, position of this peer in the DHT overlay. | ||
129 | */ | ||
130 | struct GNUNET_DHTU_HashKey id; | ||
131 | |||
132 | /** | ||
133 | * Preference counter, length of the @a ph_head DLL. | 123 | * Preference counter, length of the @a ph_head DLL. |
134 | */ | 124 | */ |
135 | unsigned int ph_count; | 125 | unsigned int ph_count; |
@@ -240,27 +230,26 @@ hello_offered_cb (void *cls) | |||
240 | * Request creation of a session with a peer at the given @a address. | 230 | * Request creation of a session with a peer at the given @a address. |
241 | * | 231 | * |
242 | * @param cls closure (internal context for the plugin) | 232 | * @param cls closure (internal context for the plugin) |
233 | * @param pid target identity of the peer to connect to | ||
243 | * @param address target address to connect to | 234 | * @param address target address to connect to |
244 | */ | 235 | */ |
245 | static void | 236 | static void |
246 | ip_try_connect (void *cls, | 237 | gnunet_try_connect (void *cls, |
247 | const char *address) | 238 | const struct GNUNET_PeerIdentity *pid, |
239 | const char *address) | ||
248 | { | 240 | { |
249 | struct Plugin *plugin = cls; | 241 | struct Plugin *plugin = cls; |
250 | struct GNUNET_HELLO_Message *hello = NULL; | 242 | struct GNUNET_HELLO_Message *hello = NULL; |
251 | struct HelloHandle *hh; | 243 | struct HelloHandle *hh; |
252 | struct GNUNET_CRYPTO_EddsaPublicKey pubkey; | 244 | struct GNUNET_CRYPTO_EddsaPublicKey pubkey; |
253 | 245 | ||
246 | (void) pid; /* will be needed with future address URIs */ | ||
254 | if (GNUNET_OK != | 247 | if (GNUNET_OK != |
255 | GNUNET_HELLO_parse_uri (address, | 248 | GNUNET_HELLO_parse_uri (address, |
256 | &pubkey, | 249 | &pubkey, |
257 | &hello, | 250 | &hello, |
258 | &GPI_plugins_find)) | 251 | &GPI_plugins_find)) |
259 | { | ||
260 | GNUNET_break (0); | ||
261 | return; | 252 | return; |
262 | } | ||
263 | |||
264 | hh = GNUNET_new (struct HelloHandle); | 253 | hh = GNUNET_new (struct HelloHandle); |
265 | hh->plugin = plugin; | 254 | hh->plugin = plugin; |
266 | GNUNET_CONTAINER_DLL_insert (plugin->hh_head, | 255 | GNUNET_CONTAINER_DLL_insert (plugin->hh_head, |
@@ -283,8 +272,8 @@ ip_try_connect (void *cls, | |||
283 | * @param target connection to keep alive | 272 | * @param target connection to keep alive |
284 | */ | 273 | */ |
285 | static struct GNUNET_DHTU_PreferenceHandle * | 274 | static struct GNUNET_DHTU_PreferenceHandle * |
286 | ip_hold (void *cls, | 275 | gnunet_hold (void *cls, |
287 | struct GNUNET_DHTU_Target *target) | 276 | struct GNUNET_DHTU_Target *target) |
288 | { | 277 | { |
289 | struct Plugin *plugin = cls; | 278 | struct Plugin *plugin = cls; |
290 | struct GNUNET_DHTU_PreferenceHandle *ph; | 279 | struct GNUNET_DHTU_PreferenceHandle *ph; |
@@ -312,7 +301,7 @@ ip_hold (void *cls, | |||
312 | * @param target connection to keep alive | 301 | * @param target connection to keep alive |
313 | */ | 302 | */ |
314 | static void | 303 | static void |
315 | ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) | 304 | gnunet_drop (struct GNUNET_DHTU_PreferenceHandle *ph) |
316 | { | 305 | { |
317 | struct GNUNET_DHTU_Target *target = ph->target; | 306 | struct GNUNET_DHTU_Target *target = ph->target; |
318 | struct Plugin *plugin = target->plugin; | 307 | struct Plugin *plugin = target->plugin; |
@@ -350,12 +339,12 @@ ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) | |||
350 | * @param finished_cb_cls closure for @a finished_cb | 339 | * @param finished_cb_cls closure for @a finished_cb |
351 | */ | 340 | */ |
352 | static void | 341 | static void |
353 | ip_send (void *cls, | 342 | gnunet_send (void *cls, |
354 | struct GNUNET_DHTU_Target *target, | 343 | struct GNUNET_DHTU_Target *target, |
355 | const void *msg, | 344 | const void *msg, |
356 | size_t msg_size, | 345 | size_t msg_size, |
357 | GNUNET_SCHEDULER_TaskCallback finished_cb, | 346 | GNUNET_SCHEDULER_TaskCallback finished_cb, |
358 | void *finished_cb_cls) | 347 | void *finished_cb_cls) |
359 | { | 348 | { |
360 | struct GNUNET_MQ_Envelope *env; | 349 | struct GNUNET_MQ_Envelope *env; |
361 | struct GNUNET_MessageHeader *cmsg; | 350 | struct GNUNET_MessageHeader *cmsg; |
@@ -394,12 +383,9 @@ core_connect_cb (void *cls, | |||
394 | target->plugin = plugin; | 383 | target->plugin = plugin; |
395 | target->mq = mq; | 384 | target->mq = mq; |
396 | target->pid = *peer; | 385 | target->pid = *peer; |
397 | GNUNET_CRYPTO_hash (peer, | ||
398 | sizeof (*peer), | ||
399 | &target->id.sha512); | ||
400 | plugin->env->connect_cb (plugin->env->cls, | 386 | plugin->env->connect_cb (plugin->env->cls, |
401 | target, | 387 | target, |
402 | &target->id, | 388 | &target->pid, |
403 | &target->app_ctx); | 389 | &target->app_ctx); |
404 | return target; | 390 | return target; |
405 | } | 391 | } |
@@ -461,11 +447,7 @@ peerinfo_cb (void *cls, | |||
461 | &GPI_plugins_find); | 447 | &GPI_plugins_find); |
462 | if (NULL == addr) | 448 | if (NULL == addr) |
463 | return; | 449 | return; |
464 | GNUNET_CRYPTO_hash (peer, | ||
465 | sizeof (*peer), | ||
466 | &plugin->src.id.sha512); | ||
467 | plugin->env->address_add_cb (plugin->env->cls, | 450 | plugin->env->address_add_cb (plugin->env->cls, |
468 | &plugin->src.id, | ||
469 | addr, | 451 | addr, |
470 | &plugin->src, | 452 | &plugin->src, |
471 | &plugin->src.app_ctx); | 453 | &plugin->src.app_ctx); |
@@ -584,6 +566,10 @@ libgnunet_plugin_dhtu_gnunet_done (void *cls) | |||
584 | } | 566 | } |
585 | if (NULL != plugin->nse) | 567 | if (NULL != plugin->nse) |
586 | GNUNET_NSE_disconnect (plugin->nse); | 568 | GNUNET_NSE_disconnect (plugin->nse); |
569 | plugin->env->network_size_cb (plugin->env->cls, | ||
570 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
571 | 0.0, | ||
572 | 0.0); | ||
587 | if (NULL != plugin->core) | 573 | if (NULL != plugin->core) |
588 | GNUNET_CORE_disconnect (plugin->core); | 574 | GNUNET_CORE_disconnect (plugin->core); |
589 | if (NULL != plugin->ats) | 575 | if (NULL != plugin->ats) |
@@ -604,7 +590,7 @@ libgnunet_plugin_dhtu_gnunet_done (void *cls) | |||
604 | * @return the plugin's API | 590 | * @return the plugin's API |
605 | */ | 591 | */ |
606 | void * | 592 | void * |
607 | libgnunet_plugin_dhtu_ip_init (void *cls) | 593 | libgnunet_plugin_dhtu_gnunet_init (void *cls) |
608 | { | 594 | { |
609 | struct GNUNET_DHTU_PluginEnvironment *env = cls; | 595 | struct GNUNET_DHTU_PluginEnvironment *env = cls; |
610 | struct GNUNET_DHTU_PluginFunctions *api; | 596 | struct GNUNET_DHTU_PluginFunctions *api; |
@@ -621,10 +607,10 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
621 | plugin->env = env; | 607 | plugin->env = env; |
622 | api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions); | 608 | api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions); |
623 | api->cls = plugin; | 609 | api->cls = plugin; |
624 | api->try_connect = &ip_try_connect; | 610 | api->try_connect = &gnunet_try_connect; |
625 | api->hold = &ip_hold; | 611 | api->hold = &gnunet_hold; |
626 | api->drop = &ip_drop; | 612 | api->drop = &gnunet_drop; |
627 | api->send = &ip_send; | 613 | api->send = &gnunet_send; |
628 | plugin->ats = GNUNET_ATS_connectivity_init (env->cfg); | 614 | plugin->ats = GNUNET_ATS_connectivity_init (env->cfg); |
629 | plugin->core = GNUNET_CORE_connect (env->cfg, | 615 | plugin->core = GNUNET_CORE_connect (env->cfg, |
630 | plugin, | 616 | plugin, |
@@ -640,6 +626,7 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
640 | (NULL == plugin->nse) ) | 626 | (NULL == plugin->nse) ) |
641 | { | 627 | { |
642 | GNUNET_break (0); | 628 | GNUNET_break (0); |
629 | GNUNET_free (api); | ||
643 | libgnunet_plugin_dhtu_gnunet_done (plugin); | 630 | libgnunet_plugin_dhtu_gnunet_done (plugin); |
644 | return NULL; | 631 | return NULL; |
645 | } | 632 | } |
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c index 8eec6294b..612d2c119 100644 --- a/src/dhtu/plugin_dhtu_ip.c +++ b/src/dhtu/plugin_dhtu_ip.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2021 GNUnet e.V. | 3 | Copyright (C) 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 |
@@ -56,17 +56,12 @@ struct GNUNET_DHTU_Source | |||
56 | struct GNUNET_DHTU_Source *prev; | 56 | struct GNUNET_DHTU_Source *prev; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Position of this peer in the DHT. | ||
60 | */ | ||
61 | struct GNUNET_DHTU_HashKey id; | ||
62 | |||
63 | /** | ||
64 | * Application context for this source. | 59 | * Application context for this source. |
65 | */ | 60 | */ |
66 | void *app_ctx; | 61 | void *app_ctx; |
67 | 62 | ||
68 | /** | 63 | /** |
69 | * Address in URL form ("ip+udp://$IP:$PORT") | 64 | * Address in URL form ("ip+udp://$PID/$IP:$PORT") |
70 | */ | 65 | */ |
71 | char *address; | 66 | char *address; |
72 | 67 | ||
@@ -121,9 +116,9 @@ struct GNUNET_DHTU_Target | |||
121 | struct GNUNET_DHTU_PreferenceHandle *ph_tail; | 116 | struct GNUNET_DHTU_PreferenceHandle *ph_tail; |
122 | 117 | ||
123 | /** | 118 | /** |
124 | * Position of this peer in the DHT. | 119 | * Peer's identity. |
125 | */ | 120 | */ |
126 | struct GNUNET_DHTU_HashKey id; | 121 | struct GNUNET_PeerIdentity pid; |
127 | 122 | ||
128 | /** | 123 | /** |
129 | * Target IP address. | 124 | * Target IP address. |
@@ -217,14 +212,24 @@ struct Plugin | |||
217 | char *port; | 212 | char *port; |
218 | 213 | ||
219 | /** | 214 | /** |
215 | * My UDP socket. | ||
216 | */ | ||
217 | struct GNUNET_NETWORK_Handle *sock; | ||
218 | |||
219 | /** | ||
220 | * My identity. | ||
221 | */ | ||
222 | struct GNUNET_PeerIdentity my_id; | ||
223 | |||
224 | /** | ||
220 | * How often have we scanned for IPs? | 225 | * How often have we scanned for IPs? |
221 | */ | 226 | */ |
222 | unsigned int scan_generation; | 227 | unsigned int scan_generation; |
223 | 228 | ||
224 | /** | 229 | /** |
225 | * My UDP socket. | 230 | * Port as a 16-bit value. |
226 | */ | 231 | */ |
227 | struct GNUNET_NETWORK_Handle *sock; | 232 | uint16_t port16; |
228 | }; | 233 | }; |
229 | 234 | ||
230 | 235 | ||
@@ -232,18 +237,20 @@ struct Plugin | |||
232 | * Create a target to which we may send traffic. | 237 | * Create a target to which we may send traffic. |
233 | * | 238 | * |
234 | * @param plugin our plugin | 239 | * @param plugin our plugin |
240 | * @param pid presumed identity of the target | ||
235 | * @param addr target address | 241 | * @param addr target address |
236 | * @param addrlen number of bytes in @a addr | 242 | * @param addrlen number of bytes in @a addr |
237 | * @return new target object | 243 | * @return new target object |
238 | */ | 244 | */ |
239 | static struct GNUNET_DHTU_Target * | 245 | static struct GNUNET_DHTU_Target * |
240 | create_target (struct Plugin *plugin, | 246 | create_target (struct Plugin *plugin, |
247 | const struct GNUNET_PeerIdentity *pid, | ||
241 | const struct sockaddr *addr, | 248 | const struct sockaddr *addr, |
242 | socklen_t addrlen) | 249 | socklen_t addrlen) |
243 | { | 250 | { |
244 | struct GNUNET_DHTU_Target *dst; | 251 | struct GNUNET_DHTU_Target *dst; |
245 | 252 | ||
246 | if (MAX_DESTS > | 253 | if (MAX_DESTS <= |
247 | GNUNET_CONTAINER_multihashmap_size (plugin->dsts)) | 254 | GNUNET_CONTAINER_multihashmap_size (plugin->dsts)) |
248 | { | 255 | { |
249 | struct GNUNET_HashCode key; | 256 | struct GNUNET_HashCode key; |
@@ -275,42 +282,16 @@ create_target (struct Plugin *plugin, | |||
275 | } | 282 | } |
276 | dst = GNUNET_new (struct GNUNET_DHTU_Target); | 283 | dst = GNUNET_new (struct GNUNET_DHTU_Target); |
277 | dst->addrlen = addrlen; | 284 | dst->addrlen = addrlen; |
285 | dst->pid = *pid; | ||
278 | memcpy (&dst->addr, | 286 | memcpy (&dst->addr, |
279 | addr, | 287 | addr, |
280 | addrlen); | 288 | addrlen); |
281 | switch (addr->sa_family) | ||
282 | { | ||
283 | case AF_INET: | ||
284 | { | ||
285 | const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr; | ||
286 | |||
287 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); | ||
288 | GNUNET_CRYPTO_hash (&s4->sin_addr, | ||
289 | sizeof (struct in_addr), | ||
290 | &dst->id.sha512); | ||
291 | } | ||
292 | break; | ||
293 | case AF_INET6: | ||
294 | { | ||
295 | const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr; | ||
296 | |||
297 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); | ||
298 | GNUNET_CRYPTO_hash (&s6->sin6_addr, | ||
299 | sizeof (struct in6_addr), | ||
300 | &dst->id.sha512); | ||
301 | } | ||
302 | break; | ||
303 | default: | ||
304 | GNUNET_break (0); | ||
305 | GNUNET_free (dst); | ||
306 | return NULL; | ||
307 | } | ||
308 | GNUNET_CONTAINER_DLL_insert (plugin->dst_head, | 289 | GNUNET_CONTAINER_DLL_insert (plugin->dst_head, |
309 | plugin->dst_tail, | 290 | plugin->dst_tail, |
310 | dst); | 291 | dst); |
311 | plugin->env->connect_cb (plugin->env->cls, | 292 | plugin->env->connect_cb (plugin->env->cls, |
312 | dst, | 293 | dst, |
313 | &dst->id, | 294 | &dst->pid, |
314 | &dst->app_ctx); | 295 | &dst->app_ctx); |
315 | return dst; | 296 | return dst; |
316 | } | 297 | } |
@@ -321,6 +302,7 @@ create_target (struct Plugin *plugin, | |||
321 | * create one! | 302 | * create one! |
322 | * | 303 | * |
323 | * @param plugin the plugin handle | 304 | * @param plugin the plugin handle |
305 | * @param pid presumed identity of the target | ||
324 | * @param src source target is from, or NULL if unknown | 306 | * @param src source target is from, or NULL if unknown |
325 | * @param addr socket address to find | 307 | * @param addr socket address to find |
326 | * @param addrlen number of bytes in @a addr | 308 | * @param addrlen number of bytes in @a addr |
@@ -328,6 +310,7 @@ create_target (struct Plugin *plugin, | |||
328 | */ | 310 | */ |
329 | static struct GNUNET_DHTU_Target * | 311 | static struct GNUNET_DHTU_Target * |
330 | find_target (struct Plugin *plugin, | 312 | find_target (struct Plugin *plugin, |
313 | const struct GNUNET_PeerIdentity *pid, | ||
331 | const void *addr, | 314 | const void *addr, |
332 | size_t addrlen) | 315 | size_t addrlen) |
333 | { | 316 | { |
@@ -342,6 +325,7 @@ find_target (struct Plugin *plugin, | |||
342 | if (NULL == dst) | 325 | if (NULL == dst) |
343 | { | 326 | { |
344 | dst = create_target (plugin, | 327 | dst = create_target (plugin, |
328 | pid, | ||
345 | (const struct sockaddr *) addr, | 329 | (const struct sockaddr *) addr, |
346 | addrlen); | 330 | addrlen); |
347 | GNUNET_assert (GNUNET_YES == | 331 | GNUNET_assert (GNUNET_YES == |
@@ -370,10 +354,12 @@ find_target (struct Plugin *plugin, | |||
370 | * Request creation of a session with a peer at the given @a address. | 354 | * Request creation of a session with a peer at the given @a address. |
371 | * | 355 | * |
372 | * @param cls closure (internal context for the plugin) | 356 | * @param cls closure (internal context for the plugin) |
357 | * @param pid identity of the target peer | ||
373 | * @param address target address to connect to | 358 | * @param address target address to connect to |
374 | */ | 359 | */ |
375 | static void | 360 | static void |
376 | ip_try_connect (void *cls, | 361 | ip_try_connect (void *cls, |
362 | const struct GNUNET_PeerIdentity *pid, | ||
377 | const char *address) | 363 | const char *address) |
378 | { | 364 | { |
379 | struct Plugin *plugin = cls; | 365 | struct Plugin *plugin = cls; |
@@ -389,19 +375,13 @@ ip_try_connect (void *cls, | |||
389 | strncmp (address, | 375 | strncmp (address, |
390 | "ip+", | 376 | "ip+", |
391 | strlen ("ip+"))) | 377 | strlen ("ip+"))) |
392 | { | ||
393 | GNUNET_break (0); | ||
394 | return; | 378 | return; |
395 | } | ||
396 | address += strlen ("ip+"); | 379 | address += strlen ("ip+"); |
397 | if (0 != | 380 | if (0 != |
398 | strncmp (address, | 381 | strncmp (address, |
399 | "udp://", | 382 | "udp://", |
400 | strlen ("udp://"))) | 383 | strlen ("udp://"))) |
401 | { | ||
402 | GNUNET_break (0); | ||
403 | return; | 384 | return; |
404 | } | ||
405 | address += strlen ("udp://"); | 385 | address += strlen ("udp://"); |
406 | addr = GNUNET_strdup (address); | 386 | addr = GNUNET_strdup (address); |
407 | colon = strchr (addr, ':'); | 387 | colon = strchr (addr, ':'); |
@@ -426,6 +406,7 @@ ip_try_connect (void *cls, | |||
426 | } | 406 | } |
427 | GNUNET_free (addr); | 407 | GNUNET_free (addr); |
428 | (void) find_target (plugin, | 408 | (void) find_target (plugin, |
409 | pid, | ||
429 | result->ai_addr, | 410 | result->ai_addr, |
430 | result->ai_addrlen); | 411 | result->ai_addrlen); |
431 | freeaddrinfo (result); | 412 | freeaddrinfo (result); |
@@ -499,10 +480,17 @@ ip_send (void *cls, | |||
499 | void *finished_cb_cls) | 480 | void *finished_cb_cls) |
500 | { | 481 | { |
501 | struct Plugin *plugin = cls; | 482 | struct Plugin *plugin = cls; |
502 | 483 | char buf[sizeof (plugin->my_id) + msg_size]; | |
484 | |||
485 | memcpy (buf, | ||
486 | &plugin->my_id, | ||
487 | sizeof (plugin->my_id)); | ||
488 | memcpy (&buf[sizeof (plugin->my_id)], | ||
489 | msg, | ||
490 | msg_size); | ||
503 | GNUNET_NETWORK_socket_sendto (plugin->sock, | 491 | GNUNET_NETWORK_socket_sendto (plugin->sock, |
504 | msg, | 492 | buf, |
505 | msg_size, | 493 | sizeof (buf), |
506 | (const struct sockaddr *) &target->addr, | 494 | (const struct sockaddr *) &target->addr, |
507 | target->addrlen); | 495 | target->addrlen); |
508 | finished_cb (finished_cb_cls); | 496 | finished_cb (finished_cb_cls); |
@@ -538,9 +526,6 @@ create_source (struct Plugin *plugin, | |||
538 | char buf[INET_ADDRSTRLEN]; | 526 | char buf[INET_ADDRSTRLEN]; |
539 | 527 | ||
540 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); | 528 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); |
541 | GNUNET_CRYPTO_hash (&s4->sin_addr, | ||
542 | sizeof (struct in_addr), | ||
543 | &src->id.sha512); | ||
544 | GNUNET_asprintf (&src->address, | 529 | GNUNET_asprintf (&src->address, |
545 | "ip+udp://%s:%u", | 530 | "ip+udp://%s:%u", |
546 | inet_ntop (AF_INET, | 531 | inet_ntop (AF_INET, |
@@ -556,9 +541,6 @@ create_source (struct Plugin *plugin, | |||
556 | char buf[INET6_ADDRSTRLEN]; | 541 | char buf[INET6_ADDRSTRLEN]; |
557 | 542 | ||
558 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); | 543 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); |
559 | GNUNET_CRYPTO_hash (&s6->sin6_addr, | ||
560 | sizeof (struct in6_addr), | ||
561 | &src->id.sha512); | ||
562 | GNUNET_asprintf (&src->address, | 544 | GNUNET_asprintf (&src->address, |
563 | "ip+udp://[%s]:%u", | 545 | "ip+udp://[%s]:%u", |
564 | inet_ntop (AF_INET6, | 546 | inet_ntop (AF_INET6, |
@@ -577,7 +559,6 @@ create_source (struct Plugin *plugin, | |||
577 | plugin->src_tail, | 559 | plugin->src_tail, |
578 | src); | 560 | src); |
579 | plugin->env->address_add_cb (plugin->env->cls, | 561 | plugin->env->address_add_cb (plugin->env->cls, |
580 | &src->id, | ||
581 | src->address, | 562 | src->address, |
582 | src, | 563 | src, |
583 | &src->app_ctx); | 564 | &src->app_ctx); |
@@ -586,6 +567,101 @@ create_source (struct Plugin *plugin, | |||
586 | 567 | ||
587 | 568 | ||
588 | /** | 569 | /** |
570 | * Compare two addresses excluding the ports for equality. Only compares IP | ||
571 | * address. Must only be called on AF_INET or AF_INET6 addresses. | ||
572 | * | ||
573 | * @param a1 address to compare | ||
574 | * @param a2 address to compare | ||
575 | * @param alen number of bytes in @a a1 and @a a2 | ||
576 | * @return 0 if @a a1 == @a a2. | ||
577 | */ | ||
578 | static int | ||
579 | addrcmp_np (const struct sockaddr *a1, | ||
580 | const struct sockaddr *a2, | ||
581 | size_t alen) | ||
582 | { | ||
583 | GNUNET_assert (a1->sa_family == a2->sa_family); | ||
584 | switch (a1->sa_family) | ||
585 | { | ||
586 | case AF_INET: | ||
587 | GNUNET_assert (sizeof (struct sockaddr_in) == alen); | ||
588 | { | ||
589 | const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1; | ||
590 | const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2; | ||
591 | |||
592 | if (s1->sin_addr.s_addr != s2->sin_addr.s_addr) | ||
593 | return 1; | ||
594 | break; | ||
595 | } | ||
596 | case AF_INET6: | ||
597 | GNUNET_assert (sizeof (struct sockaddr_in6) == alen); | ||
598 | { | ||
599 | const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1; | ||
600 | const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2; | ||
601 | |||
602 | if (0 != GNUNET_memcmp (&s1->sin6_addr, | ||
603 | &s2->sin6_addr)) | ||
604 | return 1; | ||
605 | break; | ||
606 | } | ||
607 | default: | ||
608 | GNUNET_assert (0); | ||
609 | } | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | |||
614 | /** | ||
615 | * Compare two addresses for equality. Only | ||
616 | * compares IP address and port. Must only be | ||
617 | * called on AF_INET or AF_INET6 addresses. | ||
618 | * | ||
619 | * @param a1 address to compare | ||
620 | * @param a2 address to compare | ||
621 | * @param alen number of bytes in @a a1 and @a a2 | ||
622 | * @return 0 if @a a1 == @a a2. | ||
623 | */ | ||
624 | static int | ||
625 | addrcmp (const struct sockaddr *a1, | ||
626 | const struct sockaddr *a2, | ||
627 | size_t alen) | ||
628 | { | ||
629 | GNUNET_assert (a1->sa_family == a2->sa_family); | ||
630 | switch (a1->sa_family) | ||
631 | { | ||
632 | case AF_INET: | ||
633 | GNUNET_assert (sizeof (struct sockaddr_in) == alen); | ||
634 | { | ||
635 | const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1; | ||
636 | const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2; | ||
637 | |||
638 | if (s1->sin_port != s2->sin_port) | ||
639 | return 1; | ||
640 | if (s1->sin_addr.s_addr != s2->sin_addr.s_addr) | ||
641 | return 1; | ||
642 | break; | ||
643 | } | ||
644 | case AF_INET6: | ||
645 | GNUNET_assert (sizeof (struct sockaddr_in6) == alen); | ||
646 | { | ||
647 | const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1; | ||
648 | const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2; | ||
649 | |||
650 | if (s1->sin6_port != s2->sin6_port) | ||
651 | return 1; | ||
652 | if (0 != GNUNET_memcmp (&s1->sin6_addr, | ||
653 | &s2->sin6_addr)) | ||
654 | return 1; | ||
655 | break; | ||
656 | } | ||
657 | default: | ||
658 | GNUNET_assert (0); | ||
659 | } | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | |||
664 | /** | ||
589 | * Callback function invoked for each interface found. | 665 | * Callback function invoked for each interface found. |
590 | * | 666 | * |
591 | * @param cls closure | 667 | * @param cls closure |
@@ -597,7 +673,7 @@ create_source (struct Plugin *plugin, | |||
597 | * @param addrlen length of the address | 673 | * @param addrlen length of the address |
598 | * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort | 674 | * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort |
599 | */ | 675 | */ |
600 | static int | 676 | static enum GNUNET_GenericReturnValue |
601 | process_ifcs (void *cls, | 677 | process_ifcs (void *cls, |
602 | const char *name, | 678 | const char *name, |
603 | int isDefault, | 679 | int isDefault, |
@@ -614,17 +690,45 @@ process_ifcs (void *cls, | |||
614 | src = src->next) | 690 | src = src->next) |
615 | { | 691 | { |
616 | if ( (addrlen == src->addrlen) && | 692 | if ( (addrlen == src->addrlen) && |
617 | (0 == memcmp (addr, | 693 | (0 == addrcmp_np (addr, |
618 | &src->addr, | 694 | (const struct sockaddr *) &src->addr, |
619 | addrlen)) ) | 695 | addrlen)) ) |
620 | { | 696 | { |
621 | src->scan_generation = plugin->scan_generation; | 697 | src->scan_generation = plugin->scan_generation; |
622 | return GNUNET_OK; | 698 | return GNUNET_OK; |
623 | } | 699 | } |
624 | } | 700 | } |
625 | (void) create_source (plugin, | 701 | switch (addr->sa_family) |
626 | addr, | 702 | { |
627 | addrlen); | 703 | case AF_INET: |
704 | { | ||
705 | struct sockaddr_in v4; | ||
706 | |||
707 | GNUNET_assert (sizeof(v4) == addrlen); | ||
708 | memcpy (&v4, | ||
709 | addr, | ||
710 | addrlen); | ||
711 | v4.sin_port = htons (plugin->port16); | ||
712 | (void) create_source (plugin, | ||
713 | (const struct sockaddr *) &v4, | ||
714 | sizeof (v4)); | ||
715 | break; | ||
716 | } | ||
717 | case AF_INET6: | ||
718 | { | ||
719 | struct sockaddr_in6 v6; | ||
720 | |||
721 | GNUNET_assert (sizeof(v6) == addrlen); | ||
722 | memcpy (&v6, | ||
723 | addr, | ||
724 | addrlen); | ||
725 | v6.sin6_port = htons (plugin->port16); | ||
726 | (void) create_source (plugin, | ||
727 | (const struct sockaddr *) &v6, | ||
728 | sizeof (v6)); | ||
729 | break; | ||
730 | } | ||
731 | } | ||
628 | return GNUNET_OK; | 732 | return GNUNET_OK; |
629 | } | 733 | } |
630 | 734 | ||
@@ -648,7 +752,7 @@ scan (void *cls) | |||
648 | src = next) | 752 | src = next) |
649 | { | 753 | { |
650 | next = src->next; | 754 | next = src->next; |
651 | if (src->scan_generation == plugin->scan_generation) | 755 | if (src->scan_generation >= plugin->scan_generation) |
652 | continue; | 756 | continue; |
653 | GNUNET_CONTAINER_DLL_remove (plugin->src_head, | 757 | GNUNET_CONTAINER_DLL_remove (plugin->src_head, |
654 | plugin->src_tail, | 758 | plugin->src_tail, |
@@ -682,9 +786,9 @@ find_source (struct Plugin *plugin, | |||
682 | src = src->next) | 786 | src = src->next) |
683 | { | 787 | { |
684 | if ( (addrlen == src->addrlen) && | 788 | if ( (addrlen == src->addrlen) && |
685 | (0 == memcmp (addr, | 789 | (0 == addrcmp (addr, |
686 | &src->addr, | 790 | (const struct sockaddr *) &src->addr, |
687 | addrlen)) ) | 791 | addrlen)) ) |
688 | return src; | 792 | return src; |
689 | } | 793 | } |
690 | 794 | ||
@@ -704,7 +808,8 @@ read_cb (void *cls) | |||
704 | { | 808 | { |
705 | struct Plugin *plugin = cls; | 809 | struct Plugin *plugin = cls; |
706 | ssize_t ret; | 810 | ssize_t ret; |
707 | char buf[65536]; | 811 | const struct GNUNET_PeerIdentity *pid; |
812 | char buf[65536] GNUNET_ALIGN; | ||
708 | struct sockaddr_storage sa; | 813 | struct sockaddr_storage sa; |
709 | struct iovec iov = { | 814 | struct iovec iov = { |
710 | .iov_base = buf, | 815 | .iov_base = buf, |
@@ -719,98 +824,120 @@ read_cb (void *cls) | |||
719 | .msg_control = ctl, | 824 | .msg_control = ctl, |
720 | .msg_controllen = sizeof (ctl) | 825 | .msg_controllen = sizeof (ctl) |
721 | }; | 826 | }; |
827 | struct GNUNET_DHTU_Target *dst = NULL; | ||
828 | struct GNUNET_DHTU_Source *src = NULL; | ||
722 | 829 | ||
723 | ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock), | 830 | ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock), |
724 | &mh, | 831 | &mh, |
725 | MSG_DONTWAIT); | 832 | MSG_DONTWAIT); |
726 | if (ret >= 0) | 833 | plugin->read_task = GNUNET_SCHEDULER_add_read_net ( |
834 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
835 | plugin->sock, | ||
836 | &read_cb, | ||
837 | plugin); | ||
838 | if (ret < 0) | ||
839 | return; /* read failure, hopefully EAGAIN */ | ||
840 | if (ret < sizeof (*pid)) | ||
841 | { | ||
842 | GNUNET_break_op (0); | ||
843 | return; | ||
844 | } | ||
845 | /* find IP where we received message */ | ||
846 | for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mh); | ||
847 | NULL != cmsg; | ||
848 | cmsg = CMSG_NXTHDR (&mh, | ||
849 | cmsg)) | ||
727 | { | 850 | { |
728 | struct GNUNET_DHTU_Target *dst = NULL; | 851 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
729 | struct GNUNET_DHTU_Source *src = NULL; | 852 | "Got CMSG level %u (%d/%d), type %u (%d/%d)\n", |
730 | struct cmsghdr *cmsg; | 853 | cmsg->cmsg_level, |
731 | 854 | (cmsg->cmsg_level == IPPROTO_IP), | |
732 | /* find IP where we received message */ | 855 | (cmsg->cmsg_level == IPPROTO_IPV6), |
733 | for (cmsg = CMSG_FIRSTHDR (&mh); | 856 | cmsg->cmsg_type, |
734 | NULL != cmsg; | 857 | (cmsg->cmsg_type == IP_PKTINFO), |
735 | cmsg = CMSG_NXTHDR (&mh, | 858 | (cmsg->cmsg_type == IPV6_PKTINFO)); |
736 | cmsg)) | 859 | if ( (cmsg->cmsg_level == IPPROTO_IP) && |
860 | (cmsg->cmsg_type == IP_PKTINFO) ) | ||
737 | { | 861 | { |
738 | if ( (cmsg->cmsg_level == IPPROTO_IP) && | 862 | if (CMSG_LEN (sizeof (struct in_pktinfo)) == |
739 | (cmsg->cmsg_type == IP_PKTINFO) ) | 863 | cmsg->cmsg_len) |
740 | { | 864 | { |
741 | if (CMSG_LEN (sizeof (struct in_pktinfo)) == | 865 | struct in_pktinfo pi; |
742 | cmsg->cmsg_len) | 866 | |
867 | memcpy (&pi, | ||
868 | CMSG_DATA (cmsg), | ||
869 | sizeof (pi)); | ||
743 | { | 870 | { |
744 | struct in_pktinfo pi; | 871 | struct sockaddr_in sa = { |
745 | 872 | .sin_family = AF_INET, | |
746 | memcpy (&pi, | 873 | .sin_addr = pi.ipi_addr, |
747 | CMSG_DATA (cmsg), | 874 | .sin_port = htons (plugin->port16) |
748 | sizeof (pi)); | 875 | }; |
749 | { | 876 | |
750 | struct sockaddr_in sa = { | 877 | src = find_source (plugin, |
751 | .sin_family = AF_INET, | 878 | &sa, |
752 | .sin_addr = pi.ipi_addr | 879 | sizeof (sa)); |
753 | }; | 880 | /* For sources we discovered by reading, |
754 | 881 | force the generation far into the future */ | |
755 | src = find_source (plugin, | 882 | src->scan_generation = plugin->scan_generation + 60; |
756 | &sa, | ||
757 | sizeof (sa)); | ||
758 | } | ||
759 | break; | ||
760 | } | 883 | } |
761 | else | 884 | break; |
762 | GNUNET_break (0); | ||
763 | } | 885 | } |
764 | if ( (cmsg->cmsg_level == IPPROTO_IPV6) && | 886 | else |
765 | (cmsg->cmsg_type == IPV6_RECVPKTINFO) ) | 887 | GNUNET_break (0); |
888 | } | ||
889 | if ( (cmsg->cmsg_level == IPPROTO_IPV6) && | ||
890 | (cmsg->cmsg_type == IPV6_PKTINFO) ) | ||
891 | { | ||
892 | if (CMSG_LEN (sizeof (struct in6_pktinfo)) == | ||
893 | cmsg->cmsg_len) | ||
766 | { | 894 | { |
767 | if (CMSG_LEN (sizeof (struct in6_pktinfo)) == | 895 | struct in6_pktinfo pi; |
768 | cmsg->cmsg_len) | 896 | |
897 | memcpy (&pi, | ||
898 | CMSG_DATA (cmsg), | ||
899 | sizeof (pi)); | ||
769 | { | 900 | { |
770 | struct in6_pktinfo pi; | 901 | struct sockaddr_in6 sa = { |
771 | 902 | .sin6_family = AF_INET6, | |
772 | memcpy (&pi, | 903 | .sin6_addr = pi.ipi6_addr, |
773 | CMSG_DATA (cmsg), | 904 | .sin6_port = htons (plugin->port16), |
774 | sizeof (pi)); | 905 | .sin6_scope_id = pi.ipi6_ifindex |
775 | { | 906 | }; |
776 | struct sockaddr_in6 sa = { | 907 | |
777 | .sin6_family = AF_INET6, | 908 | src = find_source (plugin, |
778 | .sin6_addr = pi.ipi6_addr, | 909 | &sa, |
779 | .sin6_scope_id = pi.ipi6_ifindex | 910 | sizeof (sa)); |
780 | }; | 911 | /* For sources we discovered by reading, |
781 | 912 | force the generation far into the future */ | |
782 | src = find_source (plugin, | 913 | src->scan_generation = plugin->scan_generation + 60; |
783 | &sa, | 914 | break; |
784 | sizeof (sa)); | ||
785 | break; | ||
786 | } | ||
787 | } | 915 | } |
788 | else | ||
789 | GNUNET_break (0); | ||
790 | } | 916 | } |
791 | } | 917 | else |
792 | dst = find_target (plugin, | 918 | GNUNET_break (0); |
793 | &sa, | ||
794 | mh.msg_namelen); | ||
795 | if ( (NULL == src) || | ||
796 | (NULL == dst) ) | ||
797 | { | ||
798 | GNUNET_break (0); | ||
799 | } | ||
800 | else | ||
801 | { | ||
802 | plugin->env->receive_cb (plugin->env->cls, | ||
803 | dst->app_ctx, | ||
804 | src->app_ctx, | ||
805 | buf, | ||
806 | ret); | ||
807 | } | 919 | } |
808 | } | 920 | } |
809 | plugin->read_task = GNUNET_SCHEDULER_add_read_net ( | 921 | if (NULL == src) |
810 | GNUNET_TIME_UNIT_FOREVER_REL, | 922 | { |
811 | plugin->sock, | 923 | GNUNET_break (0); |
812 | &read_cb, | 924 | return; |
813 | plugin); | 925 | } |
926 | pid = (const struct GNUNET_PeerIdentity *) buf; | ||
927 | dst = find_target (plugin, | ||
928 | pid, | ||
929 | &sa, | ||
930 | mh.msg_namelen); | ||
931 | if (NULL == dst) | ||
932 | { | ||
933 | GNUNET_break (0); | ||
934 | return; | ||
935 | } | ||
936 | plugin->env->receive_cb (plugin->env->cls, | ||
937 | &dst->app_ctx, | ||
938 | &src->app_ctx, | ||
939 | &buf[sizeof(*pid)], | ||
940 | ret - sizeof (*pid)); | ||
814 | } | 941 | } |
815 | 942 | ||
816 | 943 | ||
@@ -874,6 +1001,14 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
874 | plugin = GNUNET_new (struct Plugin); | 1001 | plugin = GNUNET_new (struct Plugin); |
875 | plugin->env = env; | 1002 | plugin->env = env; |
876 | plugin->port = port; | 1003 | plugin->port = port; |
1004 | plugin->port16 = (uint16_t) nport; | ||
1005 | if (GNUNET_OK != | ||
1006 | GNUNET_CRYPTO_get_peer_identity (env->cfg, | ||
1007 | &plugin->my_id)) | ||
1008 | { | ||
1009 | GNUNET_free (plugin); | ||
1010 | return NULL; | ||
1011 | } | ||
877 | af = AF_INET6; | 1012 | af = AF_INET6; |
878 | sock = socket (af, | 1013 | sock = socket (af, |
879 | SOCK_DGRAM, | 1014 | SOCK_DGRAM, |
@@ -1017,9 +1152,18 @@ libgnunet_plugin_dhtu_ip_done (void *cls) | |||
1017 | GNUNET_free (src->address); | 1152 | GNUNET_free (src->address); |
1018 | GNUNET_free (src); | 1153 | GNUNET_free (src); |
1019 | } | 1154 | } |
1155 | plugin->env->network_size_cb (plugin->env->cls, | ||
1156 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
1157 | 0.0, | ||
1158 | 0.0); | ||
1020 | GNUNET_CONTAINER_multihashmap_destroy (plugin->dsts); | 1159 | GNUNET_CONTAINER_multihashmap_destroy (plugin->dsts); |
1160 | if (NULL != plugin->read_task) | ||
1161 | { | ||
1162 | GNUNET_SCHEDULER_cancel (plugin->read_task); | ||
1163 | plugin->read_task = NULL; | ||
1164 | } | ||
1021 | GNUNET_SCHEDULER_cancel (plugin->scan_task); | 1165 | GNUNET_SCHEDULER_cancel (plugin->scan_task); |
1022 | GNUNET_break (0 == | 1166 | GNUNET_break (GNUNET_OK == |
1023 | GNUNET_NETWORK_socket_close (plugin->sock)); | 1167 | GNUNET_NETWORK_socket_close (plugin->sock)); |
1024 | GNUNET_free (plugin->port); | 1168 | GNUNET_free (plugin->port); |
1025 | GNUNET_free (plugin); | 1169 | GNUNET_free (plugin); |
diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c index d3eb7d2b9..a596beb28 100644 --- a/src/dns/plugin_block_dns.c +++ b/src/dns/plugin_block_dns.c | |||
@@ -90,93 +90,6 @@ block_plugin_dns_create_group (void *cls, | |||
90 | 90 | ||
91 | 91 | ||
92 | /** | 92 | /** |
93 | * Function called to validate a reply or a request. For | ||
94 | * request evaluation, simply pass "NULL" for the reply_block. | ||
95 | * | ||
96 | * @param cls closure | ||
97 | * @param ctx block context | ||
98 | * @param type block type | ||
99 | * @param bg group to evaluate against | ||
100 | * @param eo control flags | ||
101 | * @param query original query (hash) | ||
102 | * @param xquery extended query data (can be NULL, depending on type) | ||
103 | * @param xquery_size number of bytes in @a xquery | ||
104 | * @param reply_block response to validate | ||
105 | * @param reply_block_size number of bytes in @a reply_block | ||
106 | * @return characterization of result | ||
107 | */ | ||
108 | static enum GNUNET_BLOCK_EvaluationResult | ||
109 | block_plugin_dns_evaluate (void *cls, | ||
110 | struct GNUNET_BLOCK_Context *ctx, | ||
111 | enum GNUNET_BLOCK_Type type, | ||
112 | struct GNUNET_BLOCK_Group *bg, | ||
113 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
114 | const struct GNUNET_HashCode *query, | ||
115 | const void *xquery, | ||
116 | size_t xquery_size, | ||
117 | const void *reply_block, | ||
118 | size_t reply_block_size) | ||
119 | { | ||
120 | const struct GNUNET_DNS_Advertisement *ad; | ||
121 | struct GNUNET_HashCode phash; | ||
122 | |||
123 | switch (type) | ||
124 | { | ||
125 | case GNUNET_BLOCK_TYPE_DNS: | ||
126 | if (0 != xquery_size) | ||
127 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
128 | |||
129 | if (NULL == reply_block) | ||
130 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
131 | |||
132 | if (sizeof(struct GNUNET_DNS_Advertisement) != reply_block_size) | ||
133 | { | ||
134 | GNUNET_break_op (0); | ||
135 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
136 | } | ||
137 | ad = reply_block; | ||
138 | |||
139 | if (ntohl (ad->purpose.size) != | ||
140 | sizeof(struct GNUNET_DNS_Advertisement) | ||
141 | - sizeof(struct GNUNET_CRYPTO_EddsaSignature)) | ||
142 | { | ||
143 | GNUNET_break_op (0); | ||
144 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
145 | } | ||
146 | if (0 == | ||
147 | GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh | ||
148 | (ad->expiration_time)). | ||
149 | rel_value_us) | ||
150 | { | ||
151 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
152 | "DNS advertisement has expired\n"); | ||
153 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
154 | } | ||
155 | if (GNUNET_OK != | ||
156 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, | ||
157 | &ad->purpose, | ||
158 | &ad->signature, | ||
159 | &ad->peer.public_key)) | ||
160 | { | ||
161 | GNUNET_break_op (0); | ||
162 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
163 | } | ||
164 | GNUNET_CRYPTO_hash (reply_block, | ||
165 | reply_block_size, | ||
166 | &phash); | ||
167 | if (GNUNET_YES == | ||
168 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
169 | &phash)) | ||
170 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
171 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
172 | |||
173 | default: | ||
174 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | |||
179 | /** | ||
180 | * Function called to validate a query. | 93 | * Function called to validate a query. |
181 | * | 94 | * |
182 | * @param cls closure | 95 | * @param cls closure |
@@ -198,9 +111,13 @@ block_plugin_dns_check_query (void *cls, | |||
198 | { | 111 | { |
199 | case GNUNET_BLOCK_TYPE_DNS: | 112 | case GNUNET_BLOCK_TYPE_DNS: |
200 | if (0 != xquery_size) | 113 | if (0 != xquery_size) |
201 | return GNUNET_NO; | 114 | { |
115 | GNUNET_break_op (0); | ||
116 | return GNUNET_NO; | ||
117 | } | ||
202 | return GNUNET_OK; | 118 | return GNUNET_OK; |
203 | default: | 119 | default: |
120 | GNUNET_break (0); | ||
204 | return GNUNET_SYSERR; | 121 | return GNUNET_SYSERR; |
205 | } | 122 | } |
206 | } | 123 | } |
@@ -211,17 +128,15 @@ block_plugin_dns_check_query (void *cls, | |||
211 | * | 128 | * |
212 | * @param cls closure | 129 | * @param cls closure |
213 | * @param type block type | 130 | * @param type block type |
214 | * @param query key for the block (hash), must match exactly | ||
215 | * @param block block data to validate | 131 | * @param block block data to validate |
216 | * @param block_size number of bytes in @a block | 132 | * @param block_size number of bytes in @a block |
217 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 133 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
218 | */ | 134 | */ |
219 | static enum GNUNET_GenericReturnValue | 135 | static enum GNUNET_GenericReturnValue |
220 | block_plugin_dns_check_block (void *cls, | 136 | block_plugin_dns_check_block (void *cls, |
221 | enum GNUNET_BLOCK_Type type, | 137 | enum GNUNET_BLOCK_Type type, |
222 | const struct GNUNET_HashCode *query, | 138 | const void *block, |
223 | const void *block, | 139 | size_t block_size) |
224 | size_t block_size) | ||
225 | { | 140 | { |
226 | const struct GNUNET_DNS_Advertisement *ad; | 141 | const struct GNUNET_DNS_Advertisement *ad; |
227 | 142 | ||
@@ -260,6 +175,7 @@ block_plugin_dns_check_block (void *cls, | |||
260 | } | 175 | } |
261 | return GNUNET_OK; | 176 | return GNUNET_OK; |
262 | default: | 177 | default: |
178 | GNUNET_break (0); | ||
263 | return GNUNET_SYSERR; | 179 | return GNUNET_SYSERR; |
264 | } | 180 | } |
265 | } | 181 | } |
@@ -283,14 +199,14 @@ block_plugin_dns_check_block (void *cls, | |||
283 | */ | 199 | */ |
284 | static enum GNUNET_BLOCK_ReplyEvaluationResult | 200 | static enum GNUNET_BLOCK_ReplyEvaluationResult |
285 | block_plugin_dns_check_reply ( | 201 | block_plugin_dns_check_reply ( |
286 | void *cls, | 202 | void *cls, |
287 | enum GNUNET_BLOCK_Type type, | 203 | enum GNUNET_BLOCK_Type type, |
288 | struct GNUNET_BLOCK_Group *group, | 204 | struct GNUNET_BLOCK_Group *group, |
289 | const struct GNUNET_HashCode *query, | 205 | const struct GNUNET_HashCode *query, |
290 | const void *xquery, | 206 | const void *xquery, |
291 | size_t xquery_size, | 207 | size_t xquery_size, |
292 | const void *reply_block, | 208 | const void *reply_block, |
293 | size_t reply_block_size) | 209 | size_t reply_block_size) |
294 | { | 210 | { |
295 | struct GNUNET_HashCode phash; | 211 | struct GNUNET_HashCode phash; |
296 | 212 | ||
@@ -306,6 +222,7 @@ block_plugin_dns_check_reply ( | |||
306 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | 222 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; |
307 | return GNUNET_BLOCK_REPLY_OK_MORE; | 223 | return GNUNET_BLOCK_REPLY_OK_MORE; |
308 | default: | 224 | default: |
225 | GNUNET_break (0); | ||
309 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | 226 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
310 | } | 227 | } |
311 | } | 228 | } |
@@ -329,8 +246,12 @@ block_plugin_dns_get_key (void *cls, | |||
329 | size_t block_size, | 246 | size_t block_size, |
330 | struct GNUNET_HashCode *key) | 247 | struct GNUNET_HashCode *key) |
331 | { | 248 | { |
332 | /* we cannot extract a key from a block of this type */ | 249 | if (GNUNET_BLOCK_TYPE_DNS != type) |
333 | return GNUNET_SYSERR; | 250 | { |
251 | GNUNET_break (0); | ||
252 | return GNUNET_SYSERR; | ||
253 | } | ||
254 | return GNUNET_NO; | ||
334 | } | 255 | } |
335 | 256 | ||
336 | 257 | ||
@@ -347,7 +268,6 @@ libgnunet_plugin_block_dns_init (void *cls) | |||
347 | struct GNUNET_BLOCK_PluginFunctions *api; | 268 | struct GNUNET_BLOCK_PluginFunctions *api; |
348 | 269 | ||
349 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 270 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
350 | api->evaluate = &block_plugin_dns_evaluate; | ||
351 | api->get_key = &block_plugin_dns_get_key; | 271 | api->get_key = &block_plugin_dns_get_key; |
352 | api->check_query = &block_plugin_dns_check_query; | 272 | api->check_query = &block_plugin_dns_check_query; |
353 | api->check_block = &block_plugin_dns_check_block; | 273 | api->check_block = &block_plugin_dns_check_block; |
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 3324abd58..c5faa14d4 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c | |||
@@ -57,7 +57,7 @@ GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s) | |||
57 | * @return "filename" field of the structure (can be NULL) | 57 | * @return "filename" field of the structure (can be NULL) |
58 | */ | 58 | */ |
59 | const char * | 59 | const char * |
60 | GNUNET_FS_file_information_get_filename (struct GNUNET_FS_FileInformation *s) | 60 | GNUNET_FS_file_information_get_filename (const struct GNUNET_FS_FileInformation *s) |
61 | { | 61 | { |
62 | return s->filename; | 62 | return s->filename; |
63 | } | 63 | } |
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 73ea5d60d..2d5566b54 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c | |||
@@ -653,18 +653,24 @@ GNUNET_FS_uri_parse (const char *uri, char **emsg) | |||
653 | *emsg = GNUNET_strdup (_ ("invalid argument")); | 653 | *emsg = GNUNET_strdup (_ ("invalid argument")); |
654 | return NULL; | 654 | return NULL; |
655 | } | 655 | } |
656 | if (NULL == emsg) | 656 | /** |
657 | emsg = &msg; | 657 | * FIXME: Do we want to log this? |
658 | *emsg = NULL; | 658 | */ |
659 | if ((NULL != (ret = uri_chk_parse (uri, emsg))) || | 659 | msg = NULL; |
660 | (NULL != (ret = uri_ksk_parse (uri, emsg))) || | 660 | if (NULL != (ret = uri_chk_parse (uri, &msg))) |
661 | (NULL != (ret = uri_sks_parse (uri, emsg))) || | 661 | return ret; |
662 | (NULL != (ret = uri_loc_parse (uri, emsg)))) | 662 | GNUNET_free (msg); |
663 | if (NULL != (ret = uri_ksk_parse (uri, &msg))) | ||
664 | return ret; | ||
665 | GNUNET_free (msg); | ||
666 | if (NULL != (ret = uri_sks_parse (uri, &msg))) | ||
667 | return ret; | ||
668 | GNUNET_free (msg); | ||
669 | if (NULL != (ret = uri_loc_parse (uri, &msg))) | ||
663 | return ret; | 670 | return ret; |
664 | if (NULL == *emsg) | 671 | GNUNET_free (msg); |
672 | if (NULL != emsg) | ||
665 | *emsg = GNUNET_strdup (_ ("Unrecognized URI type")); | 673 | *emsg = GNUNET_strdup (_ ("Unrecognized URI type")); |
666 | if (emsg == &msg) | ||
667 | GNUNET_free (msg); | ||
668 | return NULL; | 674 | return NULL; |
669 | } | 675 | } |
670 | 676 | ||
diff --git a/src/fs/gnunet-search.c b/src/fs/gnunet-search.c index 3bf013650..7e2e4d2a6 100644 --- a/src/fs/gnunet-search.c +++ b/src/fs/gnunet-search.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 GNUnet e.V. | 3 | Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 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 |
@@ -24,10 +24,57 @@ | |||
24 | * @author Krista Bennett | 24 | * @author Krista Bennett |
25 | * @author James Blackwell | 25 | * @author James Blackwell |
26 | * @author Igor Wronsky | 26 | * @author Igor Wronsky |
27 | * @author madmurphy | ||
27 | */ | 28 | */ |
29 | #include <ctype.h> | ||
30 | #include <inttypes.h> | ||
31 | #include <limits.h> | ||
28 | #include "platform.h" | 32 | #include "platform.h" |
29 | #include "gnunet_fs_service.h" | 33 | #include "gnunet_fs_service.h" |
30 | 34 | ||
35 | |||
36 | #define GNUNET_SEARCH_log(kind, ...) \ | ||
37 | GNUNET_log_from(kind, "gnunet-search", __VA_ARGS__) | ||
38 | |||
39 | |||
40 | /* The default settings that we use for the printed output */ | ||
41 | |||
42 | #define DEFAULT_DIR_FORMAT "#%n:\ngnunet-download -o \"%f\" -R %u\n\n" | ||
43 | #define HELP_DEFAULT_DIR_FORMAT "#%n:\\ngnunet-download -o \"%f\" -R %u\\n\\n" | ||
44 | #define DEFAULT_FILE_FORMAT "#%n:\ngnunet-download -o \"%f\" %u\n\n" | ||
45 | #define HELP_DEFAULT_FILE_FORMAT "#%n:\\ngnunet-download -o \"%f\" %u\\n\\n" | ||
46 | #define VERB_DEFAULT_DIR_FORMAT DEFAULT_DIR_FORMAT "%a\n" | ||
47 | #define VERB_DEFAULT_FILE_FORMAT DEFAULT_FILE_FORMAT "%a\n" | ||
48 | |||
49 | #if HAVE_LIBEXTRACTOR | ||
50 | #define DEFAULT_META_FORMAT " %t: %p\n" | ||
51 | #define HELP_DEFAULT_META_FORMAT " %t: %p\\n" | ||
52 | #define HELP_EXTRACTOR_TEXTADD ", %t" | ||
53 | #else | ||
54 | #define DEFAULT_META_FORMAT " MetaType #%i: %p\n" | ||
55 | #define HELP_DEFAULT_META_FORMAT " MetaType #%i: %p\\n" | ||
56 | #define HELP_EXTRACTOR_TEXTADD "" | ||
57 | #endif | ||
58 | |||
59 | #define GENERIC_DIRECTORY_NAME "collection" | ||
60 | #define GENERIC_FILE_NAME "no-name" | ||
61 | #define GENERIC_FILE_MIMETYPE "application/octet-stream" | ||
62 | |||
63 | |||
64 | enum GNUNET_SEARCH_MetadataPrinterFlags { | ||
65 | METADATA_PRINTER_FLAG_NONE = 0, | ||
66 | METADATA_PRINTER_FLAG_ONE_RUN = 1, | ||
67 | METADATA_PRINTER_FLAG_HAVE_TYPE = 2 | ||
68 | }; | ||
69 | |||
70 | |||
71 | struct GNUNET_SEARCH_MetadataPrinterInfo { | ||
72 | unsigned int counter; | ||
73 | unsigned int flags; | ||
74 | int type; | ||
75 | }; | ||
76 | |||
77 | |||
31 | static int ret; | 78 | static int ret; |
32 | 79 | ||
33 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 80 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
@@ -38,6 +85,12 @@ static struct GNUNET_FS_SearchContext *sc; | |||
38 | 85 | ||
39 | static char *output_filename; | 86 | static char *output_filename; |
40 | 87 | ||
88 | static char *format_string; | ||
89 | |||
90 | static char *dir_format_string; | ||
91 | |||
92 | static char *meta_format_string; | ||
93 | |||
41 | static struct GNUNET_FS_DirectoryBuilder *db; | 94 | static struct GNUNET_FS_DirectoryBuilder *db; |
42 | 95 | ||
43 | static unsigned int anonymity = 1; | 96 | static unsigned int anonymity = 1; |
@@ -53,16 +106,79 @@ static unsigned int results; | |||
53 | 106 | ||
54 | static unsigned int verbose; | 107 | static unsigned int verbose; |
55 | 108 | ||
109 | static int bookmark_only; | ||
110 | |||
56 | static int local_only; | 111 | static int local_only; |
57 | 112 | ||
113 | static int silent_mode; | ||
114 | |||
58 | static struct GNUNET_SCHEDULER_Task *tt; | 115 | static struct GNUNET_SCHEDULER_Task *tt; |
59 | 116 | ||
60 | 117 | ||
61 | /** | 118 | /** |
119 | * Print the escape sequence at the beginning of a string. | ||
120 | * | ||
121 | * @param esc a string that **must** begin with a backslash (the function only | ||
122 | * assumes that it does, but does not check) | ||
123 | * @return the fragment that follows what has been printed | ||
124 | * @author madmurphy | ||
125 | * | ||
126 | * If `"\\nfoo"` is passed as argument, this function prints a new line and | ||
127 | * returns `"foo"` | ||
128 | */ | ||
129 | static const char * | ||
130 | print_escape_sequence (const char *const esc) | ||
131 | { | ||
132 | unsigned int probe; | ||
133 | const char * cursor = esc + 1; | ||
134 | char tmp; | ||
135 | switch (*cursor) | ||
136 | { | ||
137 | /* Trivia */ | ||
138 | case '\\': putchar ('\\'); return cursor + 1; | ||
139 | case 'a': putchar ('\a'); return cursor + 1; | ||
140 | case 'b': putchar ('\b'); return cursor + 1; | ||
141 | case 'e': putchar ('\x1B'); return cursor + 1; | ||
142 | case 'f': putchar ('\f'); return cursor + 1; | ||
143 | case 'n': putchar ('\n'); return cursor + 1; | ||
144 | case 'r': putchar ('\r'); return cursor + 1; | ||
145 | case 't': putchar ('\t'); return cursor + 1; | ||
146 | case 'v': putchar ('\v'); return cursor + 1; | ||
147 | |||
148 | /* Possibly hexadecimal code point */ | ||
149 | case 'x': | ||
150 | probe = 0; | ||
151 | while (probe < 256 && isxdigit((tmp = *++cursor))) | ||
152 | probe = (probe << 4) + tmp - (tmp > 96 ? 87 : tmp > 64 ? 55 : 48); | ||
153 | goto maybe_codepoint; | ||
154 | |||
155 | /* Possibly octal code point */ | ||
156 | case '0': case '1': case '2': case '3': | ||
157 | case '4': case '5': case '6': case '7': | ||
158 | probe = *cursor++ - 48; | ||
159 | do probe = (probe << 3) + *cursor++ - 48; | ||
160 | while (probe < 256 && cursor < esc + 4 && *cursor > 47 && *cursor < 56); | ||
161 | goto maybe_codepoint; | ||
162 | |||
163 | /* Boredom */ | ||
164 | case '\0': putchar ('\\'); return cursor; | ||
165 | default: printf ("\\%c", *cursor); return cursor + 1; | ||
166 | } | ||
167 | |||
168 | maybe_codepoint: | ||
169 | if (probe < 256) | ||
170 | putchar (probe); | ||
171 | else | ||
172 | fwrite (esc, 1, cursor - esc, stdout); | ||
173 | return cursor; | ||
174 | } | ||
175 | |||
176 | |||
177 | /** | ||
62 | * Type of a function that libextractor calls for each | 178 | * Type of a function that libextractor calls for each |
63 | * meta data item found. | 179 | * meta data item found. |
64 | * | 180 | * |
65 | * @param cls closure (user-defined, unused) | 181 | * @param cls closure (user-defined, used for the iteration info) |
66 | * @param plugin_name name of the plugin that produced this value; | 182 | * @param plugin_name name of the plugin that produced this value; |
67 | * special values can be used (e.g. '<zlib>' for zlib being | 183 | * special values can be used (e.g. '<zlib>' for zlib being |
68 | * used in the main libextractor library and yielding | 184 | * used in the main libextractor library and yielding |
@@ -76,33 +192,228 @@ static struct GNUNET_SCHEDULER_Task *tt; | |||
76 | * @return 0 to continue extracting, 1 to abort | 192 | * @return 0 to continue extracting, 1 to abort |
77 | */ | 193 | */ |
78 | static int | 194 | static int |
79 | item_printer (void *cls, | 195 | item_printer (void *const cls, |
80 | const char *plugin_name, | 196 | const char *const plugin_name, |
81 | enum EXTRACTOR_MetaType type, | 197 | const enum EXTRACTOR_MetaType type, |
82 | enum EXTRACTOR_MetaFormat format, | 198 | const enum EXTRACTOR_MetaFormat format, |
83 | const char *data_mime_type, | 199 | const char *const data_mime_type, |
84 | const char *data, | 200 | const char *const data, |
85 | size_t data_size) | 201 | const size_t data_size) |
86 | { | 202 | { |
87 | if ((format != EXTRACTOR_METAFORMAT_UTF8) && | 203 | #define info ((struct GNUNET_SEARCH_MetadataPrinterInfo *) cls) |
88 | (format != EXTRACTOR_METAFORMAT_C_STRING)) | 204 | if ((format != EXTRACTOR_METAFORMAT_UTF8 && |
205 | format != EXTRACTOR_METAFORMAT_C_STRING) || | ||
206 | type == EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME) | ||
89 | return 0; | 207 | return 0; |
90 | if (type == EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME) | 208 | info->counter++; |
209 | if ((info->flags & METADATA_PRINTER_FLAG_HAVE_TYPE) && type != info->type) | ||
91 | return 0; | 210 | return 0; |
211 | |||
212 | const char *cursor = meta_format_string; | ||
213 | const char *next_spec = strchr(cursor, '%'); | ||
214 | const char *next_esc = strchr(cursor, '\\'); | ||
215 | |||
216 | parse_format: | ||
217 | |||
218 | /* If an escape sequence exists before the next format specifier... */ | ||
219 | if (next_esc && (!next_spec || next_esc < next_spec)) | ||
220 | { | ||
221 | if (next_esc > cursor) | ||
222 | fwrite (cursor, 1, next_esc - cursor, stdout); | ||
223 | |||
224 | cursor = print_escape_sequence (next_esc); | ||
225 | next_esc = strchr(cursor, '\\'); | ||
226 | goto parse_format; | ||
227 | } | ||
228 | |||
229 | /* If a format specifier exists before the next escape sequence... */ | ||
230 | if (next_spec && (!next_esc || next_spec < next_esc)) | ||
231 | { | ||
232 | if (next_spec > cursor) | ||
233 | fwrite (cursor, 1, next_spec - cursor, stdout); | ||
234 | |||
235 | switch (*++next_spec) | ||
236 | { | ||
237 | case '%': putchar('%'); break; | ||
238 | case 'i': printf ("%d", type); break; | ||
239 | case 'l': printf ("%lu", (long unsigned int) data_size); break; | ||
240 | case 'n': printf ("%u", info->counter); break; | ||
241 | case 'p': printf ("%s", data); break; | ||
92 | #if HAVE_LIBEXTRACTOR | 242 | #if HAVE_LIBEXTRACTOR |
93 | printf ("\t%20s: %s\n", | 243 | case 't': |
94 | dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, | 244 | printf ("%s", |
95 | EXTRACTOR_metatype_to_string (type)), | 245 | dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, |
96 | data); | 246 | EXTRACTOR_metatype_to_string (type))); |
97 | #else | 247 | break; |
98 | printf ("\t%20d: %s\n", type, data); | ||
99 | #endif | 248 | #endif |
100 | return 0; | 249 | case 'w': printf ("%s", plugin_name); break; |
250 | case '\0': putchar('%'); return 0; | ||
251 | default: printf ("%%%c", *next_spec); break; | ||
252 | } | ||
253 | cursor = next_spec + 1; | ||
254 | next_spec = strchr(cursor, '%'); | ||
255 | goto parse_format; | ||
256 | } | ||
257 | |||
258 | if (*cursor) | ||
259 | printf ("%s", cursor); | ||
260 | |||
261 | return info->flags & METADATA_PRINTER_FLAG_ONE_RUN; | ||
262 | #undef info | ||
263 | } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * Print a search result according to the current formats | ||
268 | * | ||
269 | * @param filename the filename for this result | ||
270 | * @param uri the `struct GNUNET_FS_Uri` this result refers to | ||
271 | * @param metadata the `struct GNUNET_CONTAINER_MetaData` associated with this | ||
272 | result | ||
273 | * @param resultnum the result number | ||
274 | * @param is_directory GNUNET_YES if this is a directory, otherwise GNUNET_NO | ||
275 | * @author madmurphy | ||
276 | */ | ||
277 | static void | ||
278 | print_search_result (const char *const filename, | ||
279 | const struct GNUNET_FS_Uri *const uri, | ||
280 | const struct GNUNET_CONTAINER_MetaData *const metadata, | ||
281 | const unsigned int resultnum, | ||
282 | const int is_directory) | ||
283 | { | ||
284 | |||
285 | const char *cursor = GNUNET_YES == is_directory ? | ||
286 | dir_format_string | ||
287 | : format_string; | ||
288 | |||
289 | const char *next_spec = strchr(cursor, '%'); | ||
290 | const char *next_esc = strchr(cursor, '\\'); | ||
291 | char *placeholder; | ||
292 | struct GNUNET_SEARCH_MetadataPrinterInfo info; | ||
293 | |||
294 | parse_format: | ||
295 | /* If an escape sequence exists before the next format specifier... */ | ||
296 | if (next_esc && (!next_spec || next_esc < next_spec)) | ||
297 | { | ||
298 | if (next_esc > cursor) | ||
299 | fwrite (cursor, 1, next_esc - cursor, stdout); | ||
300 | |||
301 | cursor = print_escape_sequence (next_esc); | ||
302 | next_esc = strchr(cursor, '\\'); | ||
303 | goto parse_format; | ||
304 | } | ||
305 | |||
306 | /* If a format specifier exists before the next escape sequence... */ | ||
307 | if (next_spec && (!next_esc || next_spec < next_esc)) | ||
308 | { | ||
309 | if (next_spec > cursor) | ||
310 | fwrite (cursor, 1, next_spec - cursor, stdout); | ||
311 | |||
312 | switch (*++next_spec) | ||
313 | { | ||
314 | /* All metadata fields */ | ||
315 | case 'a': | ||
316 | info.flags = METADATA_PRINTER_FLAG_NONE; | ||
317 | |||
318 | iterate_meta: | ||
319 | info.counter = 0; | ||
320 | GNUNET_CONTAINER_meta_data_iterate (metadata, &item_printer, &info); | ||
321 | break; | ||
322 | /* File's name */ | ||
323 | case 'f': | ||
324 | if (GNUNET_YES == is_directory) | ||
325 | { | ||
326 | printf ("%s%s", filename, GNUNET_FS_DIRECTORY_EXT); | ||
327 | break; | ||
328 | } | ||
329 | printf ("%s", filename); | ||
330 | break; | ||
331 | /* Only the first metadata field */ | ||
332 | case 'j': | ||
333 | info.flags = METADATA_PRINTER_FLAG_ONE_RUN; | ||
334 | goto iterate_meta; | ||
335 | /* File name's length */ | ||
336 | case 'l': | ||
337 | printf ("%lu", | ||
338 | (long unsigned int) ( GNUNET_YES == is_directory ? | ||
339 | strlen(filename) + | ||
340 | (sizeof(GNUNET_FS_DIRECTORY_EXT) - 1) | ||
341 | : | ||
342 | strlen(filename))); | ||
343 | break; | ||
344 | /* File's mime type */ | ||
345 | case 'm': | ||
346 | if (GNUNET_YES == is_directory) | ||
347 | { | ||
348 | printf ("%s", GNUNET_FS_DIRECTORY_MIME); | ||
349 | break; | ||
350 | } | ||
351 | placeholder = GNUNET_CONTAINER_meta_data_get_by_type ( | ||
352 | metadata, | ||
353 | EXTRACTOR_METATYPE_MIMETYPE); | ||
354 | printf ("%s", placeholder ? placeholder : GENERIC_FILE_MIMETYPE); | ||
355 | GNUNET_free (placeholder); | ||
356 | break; | ||
357 | /* Result number */ | ||
358 | case 'n': printf ("%u", resultnum); break; | ||
359 | /* File's size */ | ||
360 | case 's': | ||
361 | printf ("%" PRIu64, GNUNET_FS_uri_chk_get_file_size (uri)); | ||
362 | break; | ||
363 | /* File's URI */ | ||
364 | case 'u': | ||
365 | placeholder = GNUNET_FS_uri_to_string (uri); | ||
366 | printf ("%s", placeholder); | ||
367 | GNUNET_free (placeholder); | ||
368 | break; | ||
369 | |||
370 | /* We can add as many cases as we want here... */ | ||
371 | |||
372 | /* Handle `%123#a` and `%123#j` (e.g. `%5#j` is a book title) */ | ||
373 | case '0': case '1': case '2': case '3': case '4': | ||
374 | case '5': case '6': case '7': case '8': case '9': | ||
375 | cursor = next_spec; | ||
376 | info.type = *cursor - 48; | ||
377 | while (isdigit(*++cursor) && info.type < (INT_MAX - *cursor + 48) / 10) | ||
378 | info.type = info.type * 10 + *cursor - 48; | ||
379 | if (info.type == 0 || *cursor != '#') | ||
380 | goto not_a_specifier; | ||
381 | switch (*++cursor) | ||
382 | { | ||
383 | /* All metadata fields of type `info.type` */ | ||
384 | case 'a': | ||
385 | next_spec = cursor; | ||
386 | info.flags = METADATA_PRINTER_FLAG_HAVE_TYPE; | ||
387 | goto iterate_meta; | ||
388 | |||
389 | /* Only the first metadata field of type `info.type` */ | ||
390 | case 'j': | ||
391 | next_spec = cursor; | ||
392 | info.flags = METADATA_PRINTER_FLAG_HAVE_TYPE | | ||
393 | METADATA_PRINTER_FLAG_ONE_RUN; | ||
394 | goto iterate_meta; | ||
395 | } | ||
396 | goto not_a_specifier; | ||
397 | |||
398 | /* All other cases */ | ||
399 | case '%': putchar('%'); break; | ||
400 | case '\0': putchar('%'); return; | ||
401 | |||
402 | not_a_specifier: | ||
403 | default: printf ("%%%c", *next_spec); break; | ||
404 | } | ||
405 | cursor = next_spec + 1; | ||
406 | next_spec = strchr(cursor, '%'); | ||
407 | goto parse_format; | ||
408 | } | ||
409 | |||
410 | if (*cursor) | ||
411 | printf ("%s", cursor); | ||
101 | } | 412 | } |
102 | 413 | ||
103 | 414 | ||
104 | static void | 415 | static void |
105 | clean_task (void *cls) | 416 | clean_task (void *const cls) |
106 | { | 417 | { |
107 | size_t dsize; | 418 | size_t dsize; |
108 | void *ddata; | 419 | void *ddata; |
@@ -126,9 +437,10 @@ clean_task (void *cls) | |||
126 | GNUNET_DISK_PERM_USER_READ | 437 | GNUNET_DISK_PERM_USER_READ |
127 | | GNUNET_DISK_PERM_USER_WRITE)) | 438 | | GNUNET_DISK_PERM_USER_WRITE)) |
128 | { | 439 | { |
129 | fprintf (stderr, | 440 | GNUNET_SEARCH_log(GNUNET_ERROR_TYPE_ERROR, |
130 | _ ("Failed to write directory with search results to `%s'\n"), | 441 | _ ("Failed to write directory with search results to " |
131 | output_filename); | 442 | "`%s'\n"), |
443 | output_filename); | ||
132 | } | 444 | } |
133 | GNUNET_free (ddata); | 445 | GNUNET_free (ddata); |
134 | GNUNET_free (output_filename); | 446 | GNUNET_free (output_filename); |
@@ -149,11 +461,11 @@ clean_task (void *cls) | |||
149 | * field in the GNUNET_FS_ProgressInfo struct. | 461 | * field in the GNUNET_FS_ProgressInfo struct. |
150 | */ | 462 | */ |
151 | static void * | 463 | static void * |
152 | progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | 464 | progress_cb (void *const cls, |
465 | const struct GNUNET_FS_ProgressInfo *const info) | ||
153 | { | 466 | { |
154 | static unsigned int cnt; | 467 | static unsigned int cnt; |
155 | int is_directory; | 468 | int is_directory; |
156 | char *uri; | ||
157 | char *filename; | 469 | char *filename; |
158 | 470 | ||
159 | switch (info->status) | 471 | switch (info->status) |
@@ -162,13 +474,17 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | |||
162 | break; | 474 | break; |
163 | 475 | ||
164 | case GNUNET_FS_STATUS_SEARCH_RESULT: | 476 | case GNUNET_FS_STATUS_SEARCH_RESULT: |
477 | if (silent_mode) | ||
478 | break; | ||
479 | |||
165 | if (db != NULL) | 480 | if (db != NULL) |
166 | GNUNET_FS_directory_builder_add (db, | 481 | GNUNET_FS_directory_builder_add ( |
167 | info->value.search.specifics.result.uri, | 482 | db, |
168 | info->value.search.specifics.result.meta, | 483 | info->value.search.specifics.result.uri, |
169 | NULL); | 484 | info->value.search.specifics.result.meta, |
170 | uri = GNUNET_FS_uri_to_string (info->value.search.specifics.result.uri); | 485 | NULL); |
171 | printf ("#%u:\n", ++cnt); | 486 | |
487 | cnt++; | ||
172 | filename = GNUNET_CONTAINER_meta_data_get_by_type ( | 488 | filename = GNUNET_CONTAINER_meta_data_get_by_type ( |
173 | info->value.search.specifics.result.meta, | 489 | info->value.search.specifics.result.meta, |
174 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); | 490 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); |
@@ -179,45 +495,37 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | |||
179 | while ((filename[0] != '\0') && ('/' == filename[strlen (filename) - 1])) | 495 | while ((filename[0] != '\0') && ('/' == filename[strlen (filename) - 1])) |
180 | filename[strlen (filename) - 1] = '\0'; | 496 | filename[strlen (filename) - 1] = '\0'; |
181 | GNUNET_DISK_filename_canonicalize (filename); | 497 | GNUNET_DISK_filename_canonicalize (filename); |
182 | if (GNUNET_YES == is_directory) | ||
183 | printf ("gnunet-download -o \"%s%s\" -R %s\n", | ||
184 | filename, | ||
185 | GNUNET_FS_DIRECTORY_EXT, | ||
186 | uri); | ||
187 | else | ||
188 | printf ("gnunet-download -o \"%s\" %s\n", filename, uri); | ||
189 | } | 498 | } |
190 | else if (GNUNET_YES == is_directory) | 499 | print_search_result ( filename ? |
191 | printf ("gnunet-download -o \"collection%s\" -R %s\n", | 500 | filename |
192 | GNUNET_FS_DIRECTORY_EXT, | 501 | : is_directory ? |
193 | uri); | 502 | GENERIC_DIRECTORY_NAME |
194 | else | 503 | : |
195 | printf ("gnunet-download %s\n", uri); | 504 | GENERIC_FILE_NAME, |
196 | if (verbose) | 505 | info->value.search.specifics.result.uri, |
197 | GNUNET_CONTAINER_meta_data_iterate (info->value.search.specifics.result | 506 | info->value.search.specifics.result.meta, |
198 | .meta, | 507 | cnt, |
199 | &item_printer, | 508 | is_directory); |
200 | NULL); | ||
201 | printf ("\n"); | ||
202 | fflush (stdout); | 509 | fflush (stdout); |
203 | GNUNET_free (filename); | 510 | GNUNET_free (filename); |
204 | GNUNET_free (uri); | ||
205 | results++; | 511 | results++; |
206 | if ((results_limit > 0) && (results >= results_limit)) | 512 | if ((results_limit > 0) && (results >= results_limit)) |
513 | { | ||
207 | GNUNET_SCHEDULER_shutdown (); | 514 | GNUNET_SCHEDULER_shutdown (); |
515 | /* otherwise the function might keep printing results for a while... */ | ||
516 | silent_mode = GNUNET_YES; | ||
517 | } | ||
208 | break; | 518 | break; |
209 | 519 | ||
210 | case GNUNET_FS_STATUS_SEARCH_UPDATE: | 520 | case GNUNET_FS_STATUS_SEARCH_UPDATE: |
211 | break; | ||
212 | |||
213 | case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: | 521 | case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: |
214 | /* ignore */ | 522 | /* ignore */ |
215 | break; | 523 | break; |
216 | 524 | ||
217 | case GNUNET_FS_STATUS_SEARCH_ERROR: | 525 | case GNUNET_FS_STATUS_SEARCH_ERROR: |
218 | fprintf (stderr, | 526 | GNUNET_SEARCH_log(GNUNET_ERROR_TYPE_ERROR, |
219 | _ ("Error searching: %s.\n"), | 527 | _ ("Error searching: %s.\n"), |
220 | info->value.search.specifics.error.message); | 528 | info->value.search.specifics.error.message); |
221 | GNUNET_SCHEDULER_shutdown (); | 529 | GNUNET_SCHEDULER_shutdown (); |
222 | break; | 530 | break; |
223 | 531 | ||
@@ -226,7 +534,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | |||
226 | break; | 534 | break; |
227 | 535 | ||
228 | default: | 536 | default: |
229 | fprintf (stderr, _ ("Unexpected status: %d\n"), info->status); | 537 | GNUNET_SEARCH_log(GNUNET_ERROR_TYPE_ERROR, |
538 | _ ("Unexpected status: %d\n"), | ||
539 | info->status); | ||
230 | break; | 540 | break; |
231 | } | 541 | } |
232 | return NULL; | 542 | return NULL; |
@@ -234,7 +544,7 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) | |||
234 | 544 | ||
235 | 545 | ||
236 | static void | 546 | static void |
237 | shutdown_task (void *cls) | 547 | shutdown_task (void *const cls) |
238 | { | 548 | { |
239 | if (sc != NULL) | 549 | if (sc != NULL) |
240 | { | 550 | { |
@@ -245,9 +555,10 @@ shutdown_task (void *cls) | |||
245 | 555 | ||
246 | 556 | ||
247 | static void | 557 | static void |
248 | timeout_task (void *cls) | 558 | timeout_task (void *const cls) |
249 | { | 559 | { |
250 | tt = NULL; | 560 | tt = NULL; |
561 | silent_mode = GNUNET_YES; | ||
251 | GNUNET_SCHEDULER_shutdown (); | 562 | GNUNET_SCHEDULER_shutdown (); |
252 | } | 563 | } |
253 | 564 | ||
@@ -258,18 +569,47 @@ timeout_task (void *cls) | |||
258 | * @param cls closure | 569 | * @param cls closure |
259 | * @param args remaining command-line arguments | 570 | * @param args remaining command-line arguments |
260 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | 571 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) |
261 | * @param c configuration | 572 | * @param cfgarg configuration |
262 | */ | 573 | */ |
263 | static void | 574 | static void |
264 | run (void *cls, | 575 | run (void *const cls, |
265 | char *const *args, | 576 | char *const *const args, |
266 | const char *cfgfile, | 577 | const char *const cfgfile, |
267 | const struct GNUNET_CONFIGURATION_Handle *c) | 578 | const struct GNUNET_CONFIGURATION_Handle *const cfgarg) |
268 | { | 579 | { |
269 | struct GNUNET_FS_Uri *uri; | 580 | struct GNUNET_FS_Uri *uri; |
270 | unsigned int argc; | 581 | unsigned int argc; |
271 | enum GNUNET_FS_SearchOptions options; | 582 | enum GNUNET_FS_SearchOptions options; |
272 | 583 | ||
584 | if (silent_mode && bookmark_only) | ||
585 | { | ||
586 | fprintf (stderr, | ||
587 | _ ("Conflicting options --bookmark-only and --silent.\n")); | ||
588 | ret = 1; | ||
589 | return; | ||
590 | } | ||
591 | if (bookmark_only && output_filename) | ||
592 | { | ||
593 | fprintf (stderr, | ||
594 | _ ("Conflicting options --bookmark-only and --output.\n")); | ||
595 | ret = 1; | ||
596 | return; | ||
597 | } | ||
598 | if (silent_mode && !output_filename) | ||
599 | { | ||
600 | fprintf (stderr, _ ("An output file is mandatory for silent mode.\n")); | ||
601 | ret = 1; | ||
602 | return; | ||
603 | } | ||
604 | if (NULL == dir_format_string) | ||
605 | dir_format_string = format_string ? format_string | ||
606 | : verbose ? VERB_DEFAULT_DIR_FORMAT | ||
607 | : DEFAULT_DIR_FORMAT; | ||
608 | if (NULL == format_string) | ||
609 | format_string = verbose ? VERB_DEFAULT_FILE_FORMAT | ||
610 | : DEFAULT_FILE_FORMAT; | ||
611 | if (NULL == meta_format_string) | ||
612 | meta_format_string = DEFAULT_META_FORMAT; | ||
273 | argc = 0; | 613 | argc = 0; |
274 | while (NULL != args[argc]) | 614 | while (NULL != args[argc]) |
275 | argc++; | 615 | argc++; |
@@ -282,7 +622,27 @@ run (void *cls, | |||
282 | ret = 1; | 622 | ret = 1; |
283 | return; | 623 | return; |
284 | } | 624 | } |
285 | cfg = c; | 625 | if (!GNUNET_FS_uri_test_ksk (uri) && !GNUNET_FS_uri_test_sks (uri)) |
626 | { | ||
627 | fprintf (stderr, | ||
628 | "%s", | ||
629 | _ ("Invalid URI. Valid URIs for searching are keyword query " | ||
630 | "URIs\n(\"gnunet://fs/ksk/...\") and namespace content URIs " | ||
631 | "(\"gnunet://fs/sks/...\").\n")); | ||
632 | GNUNET_FS_uri_destroy (uri); | ||
633 | ret = 1; | ||
634 | return; | ||
635 | } | ||
636 | if (bookmark_only) | ||
637 | { | ||
638 | char * bmstr = GNUNET_FS_uri_to_string (uri); | ||
639 | printf ("%s\n", bmstr); | ||
640 | GNUNET_free (bmstr); | ||
641 | GNUNET_FS_uri_destroy (uri); | ||
642 | ret = 0; | ||
643 | return; | ||
644 | } | ||
645 | cfg = cfgarg; | ||
286 | ctx = GNUNET_FS_start (cfg, | 646 | ctx = GNUNET_FS_start (cfg, |
287 | "gnunet-search", | 647 | "gnunet-search", |
288 | &progress_cb, | 648 | &progress_cb, |
@@ -291,7 +651,7 @@ run (void *cls, | |||
291 | GNUNET_FS_OPTIONS_END); | 651 | GNUNET_FS_OPTIONS_END); |
292 | if (NULL == ctx) | 652 | if (NULL == ctx) |
293 | { | 653 | { |
294 | fprintf (stderr, _ ("Could not initialize `%s' subsystem.\n"), "FS"); | 654 | fprintf (stderr, _ ("Could not initialize the `%s` subsystem.\n"), "FS"); |
295 | GNUNET_FS_uri_destroy (uri); | 655 | GNUNET_FS_uri_destroy (uri); |
296 | ret = 1; | 656 | ret = 1; |
297 | return; | 657 | return; |
@@ -321,18 +681,59 @@ run (void *cls, | |||
321 | * | 681 | * |
322 | * @param argc number of arguments from the command line | 682 | * @param argc number of arguments from the command line |
323 | * @param argv command line arguments | 683 | * @param argv command line arguments |
324 | * @return 0 ok, 1 on error | 684 | * @return 0 ok, an error number on error |
325 | */ | 685 | */ |
326 | int | 686 | int |
327 | main (int argc, char *const *argv) | 687 | main (int argc, char *const *argv) |
328 | { | 688 | { |
329 | struct GNUNET_GETOPT_CommandLineOption options[] = | 689 | struct GNUNET_GETOPT_CommandLineOption options[] = |
330 | { GNUNET_GETOPT_option_uint ('a', | 690 | { GNUNET_GETOPT_option_uint ( |
331 | "anonymity", | 691 | 'a', |
332 | "LEVEL", | 692 | "anonymity", |
333 | gettext_noop ( | 693 | "LEVEL", |
334 | "set the desired LEVEL of receiver-anonymity"), | 694 | gettext_noop ("set the desired LEVEL of receiver-anonymity (default: " |
335 | &anonymity), | 695 | "1)"), |
696 | &anonymity), | ||
697 | GNUNET_GETOPT_option_flag ( | ||
698 | 'b', | ||
699 | "bookmark-only", | ||
700 | gettext_noop ("do not search, print only the URI that points to this " | ||
701 | "search"), | ||
702 | &bookmark_only), | ||
703 | GNUNET_GETOPT_option_string ( | ||
704 | 'F', | ||
705 | "dir-printf", | ||
706 | "FORMAT", | ||
707 | gettext_noop ("write search results for directories according to " | ||
708 | "FORMAT; accepted placeholders are: %a, %f, %j, %l, %m, " | ||
709 | "%n, %s; defaults to the value of --printf when omitted " | ||
710 | "or to `" HELP_DEFAULT_DIR_FORMAT "` if --printf is " | ||
711 | "omitted too"), | ||
712 | &dir_format_string), | ||
713 | GNUNET_GETOPT_option_string ( | ||
714 | 'f', | ||
715 | "printf", | ||
716 | "FORMAT", | ||
717 | gettext_noop ("write search results according to FORMAT; accepted " | ||
718 | "placeholders are: %a, %f, %j, %l, %m, %n, %s; defaults " | ||
719 | "to `" HELP_DEFAULT_FILE_FORMAT "` when omitted"), | ||
720 | &format_string), | ||
721 | GNUNET_GETOPT_option_string ( | ||
722 | 'i', | ||
723 | "iter-printf", | ||
724 | "FORMAT", | ||
725 | gettext_noop ("when the %a or %j placeholders appear in --printf or " | ||
726 | "--dir-printf, list each metadata property according to " | ||
727 | "FORMAT; accepted placeholders are: %i, %l, %n, %p" | ||
728 | HELP_EXTRACTOR_TEXTADD ", %w; defaults to `" | ||
729 | HELP_DEFAULT_META_FORMAT "` when omitted"), | ||
730 | &meta_format_string), | ||
731 | GNUNET_GETOPT_option_uint ('N', | ||
732 | "results", | ||
733 | "VALUE", | ||
734 | gettext_noop ("automatically terminate search " | ||
735 | "after VALUE results are found"), | ||
736 | &results_limit), | ||
336 | GNUNET_GETOPT_option_flag ( | 737 | GNUNET_GETOPT_option_flag ( |
337 | 'n', | 738 | 'n', |
338 | "no-network", | 739 | "no-network", |
@@ -341,39 +742,49 @@ main (int argc, char *const *argv) | |||
341 | GNUNET_GETOPT_option_string ( | 742 | GNUNET_GETOPT_option_string ( |
342 | 'o', | 743 | 'o', |
343 | "output", | 744 | "output", |
344 | "PREFIX", | 745 | "FILENAME", |
345 | gettext_noop ("write search results to file starting with PREFIX"), | 746 | gettext_noop ("create a GNUnet directory with search results at " |
747 | "FILENAME (e.g. `gnunet-search --output=commons" | ||
748 | GNUNET_FS_DIRECTORY_EXT " commons`)"), | ||
346 | &output_filename), | 749 | &output_filename), |
750 | GNUNET_GETOPT_option_flag ( | ||
751 | 's', | ||
752 | "silent", | ||
753 | gettext_noop ("silent mode (requires the --output argument)"), | ||
754 | &silent_mode), | ||
347 | GNUNET_GETOPT_option_relative_time ( | 755 | GNUNET_GETOPT_option_relative_time ( |
348 | 't', | 756 | 't', |
349 | "timeout", | 757 | "timeout", |
350 | "DELAY", | 758 | "DELAY", |
351 | gettext_noop ("automatically terminate search after DELAY"), | 759 | gettext_noop ("automatically terminate search after DELAY; the value " |
760 | "given must be a number followed by a space and a time " | ||
761 | "unit, for example \"500 ms\"; without a unit it defaults " | ||
762 | "to microseconds - 1000000 = 1 second; if 0 or omitted " | ||
763 | "it means to wait for CTRL-C"), | ||
352 | &timeout), | 764 | &timeout), |
353 | GNUNET_GETOPT_option_verbose (&verbose), | 765 | GNUNET_GETOPT_option_increment_uint ( |
354 | GNUNET_GETOPT_option_uint ('N', | 766 | 'V', |
355 | "results", | 767 | "verbose", |
356 | "VALUE", | 768 | gettext_noop ("be verbose (append \"%a\\n\" to the default --printf and " |
357 | gettext_noop ("automatically terminate search " | 769 | "--dir-printf arguments - ignored when these are provided " |
358 | "after VALUE results are found"), | 770 | "by the user)"), |
359 | &results_limit), | 771 | &verbose), |
360 | GNUNET_GETOPT_OPTION_END }; | 772 | GNUNET_GETOPT_OPTION_END }; |
361 | 773 | ||
362 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 774 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
363 | return 2; | 775 | return 12; |
364 | 776 | ||
365 | ret = | 777 | if (GNUNET_SYSERR == |
366 | (GNUNET_OK == | 778 | GNUNET_PROGRAM_run (argc, |
367 | GNUNET_PROGRAM_run (argc, | 779 | argv, |
368 | argv, | 780 | "gnunet-search [OPTIONS] KEYWORD1 KEYWORD2 ...", |
369 | "gnunet-search [OPTIONS] KEYWORD", | 781 | gettext_noop ("Search for files that have been " |
370 | gettext_noop ( | 782 | "published on GNUnet\n"), |
371 | "Search GNUnet for files that were published on GNUnet"), | ||
372 | options, | 783 | options, |
373 | &run, | 784 | &run, |
374 | NULL)) | 785 | NULL)) |
375 | ? ret | 786 | ret = 1; |
376 | : 1; | 787 | |
377 | GNUNET_free_nz ((void *) argv); | 788 | GNUNET_free_nz ((void *) argv); |
378 | return ret; | 789 | return ret; |
379 | } | 790 | } |
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index beb29a506..154c454ca 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c | |||
@@ -247,7 +247,8 @@ static unsigned long long max_pending_requests = (32 * 1024); | |||
247 | * @param pr request for which the BF is to be recomputed | 247 | * @param pr request for which the BF is to be recomputed |
248 | */ | 248 | */ |
249 | static void | 249 | static void |
250 | refresh_bloomfilter (enum GNUNET_BLOCK_Type type, struct GSF_PendingRequest *pr) | 250 | refresh_bloomfilter (enum GNUNET_BLOCK_Type type, |
251 | struct GSF_PendingRequest *pr) | ||
251 | { | 252 | { |
252 | if (NULL != pr->bg) | 253 | if (NULL != pr->bg) |
253 | { | 254 | { |
@@ -406,7 +407,7 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, | |||
406 | break; /* let the request live briefly... */ | 407 | break; /* let the request live briefly... */ |
407 | if (NULL != dpr->rh) | 408 | if (NULL != dpr->rh) |
408 | dpr->rh (dpr->rh_cls, | 409 | dpr->rh (dpr->rh_cls, |
409 | GNUNET_BLOCK_EVALUATION_REQUEST_VALID, | 410 | GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, |
410 | dpr, | 411 | dpr, |
411 | UINT32_MAX, | 412 | UINT32_MAX, |
412 | GNUNET_TIME_UNIT_FOREVER_ABS, | 413 | GNUNET_TIME_UNIT_FOREVER_ABS, |
@@ -557,7 +558,10 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr) | |||
557 | k++; | 558 | k++; |
558 | } | 559 | } |
559 | if (GNUNET_OK != | 560 | if (GNUNET_OK != |
560 | GNUNET_BLOCK_group_serialize (pr->bg, &bf_nonce, &bf_data, &bf_size)) | 561 | GNUNET_BLOCK_group_serialize (pr->bg, |
562 | &bf_nonce, | ||
563 | &bf_data, | ||
564 | &bf_size)) | ||
561 | { | 565 | { |
562 | bf_size = 0; | 566 | bf_size = 0; |
563 | bf_data = NULL; | 567 | bf_data = NULL; |
@@ -765,11 +769,6 @@ struct ProcessReplyClosure | |||
765 | enum GNUNET_BLOCK_Type type; | 769 | enum GNUNET_BLOCK_Type type; |
766 | 770 | ||
767 | /** | 771 | /** |
768 | * Control flags for evaluation. | ||
769 | */ | ||
770 | enum GNUNET_BLOCK_EvaluationOptions eo; | ||
771 | |||
772 | /** | ||
773 | * How much was this reply worth to us? | 772 | * How much was this reply worth to us? |
774 | */ | 773 | */ |
775 | uint32_t priority; | 774 | uint32_t priority; |
@@ -850,7 +849,6 @@ process_reply (void *cls, | |||
850 | case GNUNET_BLOCK_REPLY_OK_MORE: | 849 | case GNUNET_BLOCK_REPLY_OK_MORE: |
851 | update_request_performance_data (prq, pr); | 850 | update_request_performance_data (prq, pr); |
852 | break; | 851 | break; |
853 | |||
854 | case GNUNET_BLOCK_REPLY_OK_LAST: | 852 | case GNUNET_BLOCK_REPLY_OK_LAST: |
855 | /* short cut: stop processing early, no BF-update, etc. */ | 853 | /* short cut: stop processing early, no BF-update, etc. */ |
856 | update_request_performance_data (prq, pr); | 854 | update_request_performance_data (prq, pr); |
@@ -885,7 +883,6 @@ process_reply (void *cls, | |||
885 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
886 | "Duplicate response, discarding.\n"); | 884 | "Duplicate response, discarding.\n"); |
887 | return GNUNET_YES; /* duplicate */ | 885 | return GNUNET_YES; /* duplicate */ |
888 | |||
889 | case GNUNET_BLOCK_REPLY_IRRELEVANT: | 886 | case GNUNET_BLOCK_REPLY_IRRELEVANT: |
890 | GNUNET_STATISTICS_update (GSF_stats, | 887 | GNUNET_STATISTICS_update (GSF_stats, |
891 | "# irrelevant replies discarded", | 888 | "# irrelevant replies discarded", |
@@ -894,8 +891,6 @@ process_reply (void *cls, | |||
894 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 891 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
895 | "Irrelevant response, ignoring.\n"); | 892 | "Irrelevant response, ignoring.\n"); |
896 | return GNUNET_YES; | 893 | return GNUNET_YES; |
897 | case GNUNET_BLOCK_REPLY_INVALID: | ||
898 | return GNUNET_YES; | ||
899 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: | 894 | case GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED: |
900 | GNUNET_break (0); /* bad installation? */ | 895 | GNUNET_break (0); /* bad installation? */ |
901 | return GNUNET_NO; | 896 | return GNUNET_NO; |
@@ -1127,8 +1122,9 @@ handle_dht_reply (void *cls, | |||
1127 | prq.expiration); | 1122 | prq.expiration); |
1128 | prq.size = size; | 1123 | prq.size = size; |
1129 | prq.type = type; | 1124 | prq.type = type; |
1130 | prq.eo = GNUNET_BLOCK_EO_NONE; | 1125 | process_reply (&prq, |
1131 | process_reply (&prq, key, pr); | 1126 | key, |
1127 | pr); | ||
1132 | if ((GNUNET_YES == active_to_migration) && | 1128 | if ((GNUNET_YES == active_to_migration) && |
1133 | (GNUNET_NO == test_put_load_too_high (prq.priority))) | 1129 | (GNUNET_NO == test_put_load_too_high (prq.priority))) |
1134 | { | 1130 | { |
@@ -1229,6 +1225,15 @@ cadet_reply_proc (void *cls, | |||
1229 | struct GNUNET_HashCode query; | 1225 | struct GNUNET_HashCode query; |
1230 | 1226 | ||
1231 | pr->cadet_request = NULL; | 1227 | pr->cadet_request = NULL; |
1228 | if (GNUNET_OK != | ||
1229 | GNUNET_BLOCK_check_block (GSF_block_ctx, | ||
1230 | type, | ||
1231 | data, | ||
1232 | data_size)) | ||
1233 | { | ||
1234 | GNUNET_break_op (0); | ||
1235 | return; | ||
1236 | } | ||
1232 | if (GNUNET_BLOCK_TYPE_ANY == type) | 1237 | if (GNUNET_BLOCK_TYPE_ANY == type) |
1233 | { | 1238 | { |
1234 | GNUNET_break (NULL == data); | 1239 | GNUNET_break (NULL == data); |
@@ -1247,7 +1252,11 @@ cadet_reply_proc (void *cls, | |||
1247 | return; | 1252 | return; |
1248 | } | 1253 | } |
1249 | if (GNUNET_YES != | 1254 | if (GNUNET_YES != |
1250 | GNUNET_BLOCK_get_key (GSF_block_ctx, type, data, data_size, &query)) | 1255 | GNUNET_BLOCK_get_key (GSF_block_ctx, |
1256 | type, | ||
1257 | data, | ||
1258 | data_size, | ||
1259 | &query)) | ||
1251 | { | 1260 | { |
1252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1261 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1253 | "Failed to derive key for block of type %d\n", | 1262 | "Failed to derive key for block of type %d\n", |
@@ -1268,8 +1277,9 @@ cadet_reply_proc (void *cls, | |||
1268 | prq.expiration); | 1277 | prq.expiration); |
1269 | prq.size = data_size; | 1278 | prq.size = data_size; |
1270 | prq.type = type; | 1279 | prq.type = type; |
1271 | prq.eo = GNUNET_BLOCK_EO_NONE; | 1280 | process_reply (&prq, |
1272 | process_reply (&prq, &query, pr); | 1281 | &query, |
1282 | pr); | ||
1273 | } | 1283 | } |
1274 | 1284 | ||
1275 | 1285 | ||
@@ -1611,7 +1621,11 @@ called_from_on_demand: | |||
1611 | prq.expiration = expiration; | 1621 | prq.expiration = expiration; |
1612 | prq.size = size; | 1622 | prq.size = size; |
1613 | if (GNUNET_OK != | 1623 | if (GNUNET_OK != |
1614 | GNUNET_BLOCK_get_key (GSF_block_ctx, type, data, size, &query)) | 1624 | GNUNET_BLOCK_get_key (GSF_block_ctx, |
1625 | type, | ||
1626 | data, | ||
1627 | size, | ||
1628 | &query)) | ||
1615 | { | 1629 | { |
1616 | GNUNET_break (0); | 1630 | GNUNET_break (0); |
1617 | GNUNET_DATASTORE_remove (GSF_dsh, | 1631 | GNUNET_DATASTORE_remove (GSF_dsh, |
@@ -1631,8 +1645,9 @@ called_from_on_demand: | |||
1631 | prq.anonymity_level = anonymity; | 1645 | prq.anonymity_level = anonymity; |
1632 | if ((0 == old_rf) && (0 == pr->public_data.results_found)) | 1646 | if ((0 == old_rf) && (0 == pr->public_data.results_found)) |
1633 | GSF_update_datastore_delay_ (pr->public_data.start_time); | 1647 | GSF_update_datastore_delay_ (pr->public_data.start_time); |
1634 | prq.eo = GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO; | 1648 | process_reply (&prq, |
1635 | process_reply (&prq, key, pr); | 1649 | key, |
1650 | pr); | ||
1636 | pr->local_result = prq.eval; | 1651 | pr->local_result = prq.eval; |
1637 | if (GNUNET_BLOCK_REPLY_OK_LAST == prq.eval) | 1652 | if (GNUNET_BLOCK_REPLY_OK_LAST == prq.eval) |
1638 | { | 1653 | { |
@@ -1720,7 +1735,8 @@ GSF_local_lookup_ (struct GSF_PendingRequest *pr, | |||
1720 | * @param put the actual message | 1735 | * @param put the actual message |
1721 | */ | 1736 | */ |
1722 | void | 1737 | void |
1723 | handle_p2p_put (void *cls, const struct PutMessage *put) | 1738 | handle_p2p_put (void *cls, |
1739 | const struct PutMessage *put) | ||
1724 | { | 1740 | { |
1725 | struct GSF_ConnectedPeer *cp = cls; | 1741 | struct GSF_ConnectedPeer *cp = cls; |
1726 | uint16_t msize; | 1742 | uint16_t msize; |
@@ -1746,7 +1762,20 @@ handle_p2p_put (void *cls, const struct PutMessage *put) | |||
1746 | GNUNET_TIME_UNIT_YEARS), | 1762 | GNUNET_TIME_UNIT_YEARS), |
1747 | expiration); | 1763 | expiration); |
1748 | if (GNUNET_OK != | 1764 | if (GNUNET_OK != |
1749 | GNUNET_BLOCK_get_key (GSF_block_ctx, type, &put[1], dsize, &query)) | 1765 | GNUNET_BLOCK_check_block (GSF_block_ctx, |
1766 | type, | ||
1767 | &put[1], | ||
1768 | dsize)) | ||
1769 | { | ||
1770 | GNUNET_break_op (0); | ||
1771 | return; | ||
1772 | } | ||
1773 | if (GNUNET_OK != | ||
1774 | GNUNET_BLOCK_get_key (GSF_block_ctx, | ||
1775 | type, | ||
1776 | &put[1], | ||
1777 | dsize, | ||
1778 | &query)) | ||
1750 | { | 1779 | { |
1751 | GNUNET_break_op (0); | 1780 | GNUNET_break_op (0); |
1752 | return; | 1781 | return; |
@@ -1764,7 +1793,6 @@ handle_p2p_put (void *cls, const struct PutMessage *put) | |||
1764 | prq.priority = 0; | 1793 | prq.priority = 0; |
1765 | prq.anonymity_level = UINT32_MAX; | 1794 | prq.anonymity_level = UINT32_MAX; |
1766 | prq.request_found = GNUNET_NO; | 1795 | prq.request_found = GNUNET_NO; |
1767 | prq.eo = GNUNET_BLOCK_EO_NONE; | ||
1768 | GNUNET_CONTAINER_multihashmap_get_multiple (pr_map, | 1796 | GNUNET_CONTAINER_multihashmap_get_multiple (pr_map, |
1769 | &query, | 1797 | &query, |
1770 | &process_reply, | 1798 | &process_reply, |
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 43380b3b6..029f95bc5 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c | |||
@@ -111,110 +111,6 @@ block_plugin_fs_create_group (void *cls, | |||
111 | 111 | ||
112 | 112 | ||
113 | /** | 113 | /** |
114 | * Function called to validate a reply or a request. For | ||
115 | * request evaluation, simply pass "NULL" for the reply_block. | ||
116 | * Note that it is assumed that the reply has already been | ||
117 | * matched to the key (and signatures checked) as it would | ||
118 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
119 | * | ||
120 | * @param cls closure | ||
121 | * @param ctx block context | ||
122 | * @param type block type | ||
123 | * @param bg group to use for evaluation | ||
124 | * @param eo control flags | ||
125 | * @param query original query (hash) | ||
126 | * @param xquery extrended query data (can be NULL, depending on type) | ||
127 | * @param xquery_size number of bytes in @a xquery | ||
128 | * @param reply_block response to validate | ||
129 | * @param reply_block_size number of bytes in @a reply_block | ||
130 | * @return characterization of result | ||
131 | */ | ||
132 | static enum GNUNET_BLOCK_EvaluationResult | ||
133 | block_plugin_fs_evaluate (void *cls, | ||
134 | struct GNUNET_BLOCK_Context *ctx, | ||
135 | enum GNUNET_BLOCK_Type type, | ||
136 | struct GNUNET_BLOCK_Group *bg, | ||
137 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
138 | const struct GNUNET_HashCode *query, | ||
139 | const void *xquery, | ||
140 | size_t xquery_size, | ||
141 | const void *reply_block, | ||
142 | size_t reply_block_size) | ||
143 | { | ||
144 | const struct UBlock *ub; | ||
145 | struct GNUNET_HashCode hc; | ||
146 | struct GNUNET_HashCode chash; | ||
147 | |||
148 | switch (type) | ||
149 | { | ||
150 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | ||
151 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | ||
152 | if (0 != xquery_size) | ||
153 | { | ||
154 | GNUNET_break_op (0); | ||
155 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
156 | } | ||
157 | if (NULL == reply_block) | ||
158 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
159 | return GNUNET_BLOCK_EVALUATION_OK_LAST; | ||
160 | |||
161 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | ||
162 | if (0 != xquery_size) | ||
163 | { | ||
164 | GNUNET_break_op (0); | ||
165 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
166 | } | ||
167 | if (NULL == reply_block) | ||
168 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
169 | |||
170 | if (reply_block_size < sizeof(struct UBlock)) | ||
171 | { | ||
172 | GNUNET_break_op (0); | ||
173 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
174 | } | ||
175 | ub = reply_block; | ||
176 | GNUNET_CRYPTO_hash (&ub->verification_key, | ||
177 | sizeof(ub->verification_key), | ||
178 | &hc); | ||
179 | if (0 != memcmp (&hc, | ||
180 | query, | ||
181 | sizeof(struct GNUNET_HashCode))) | ||
182 | { | ||
183 | GNUNET_break_op (0); | ||
184 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
185 | } | ||
186 | if (reply_block_size != ntohl (ub->purpose.size) + sizeof(struct | ||
187 | GNUNET_CRYPTO_EcdsaSignature)) | ||
188 | { | ||
189 | GNUNET_break_op (0); | ||
190 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
191 | } | ||
192 | if ((0 == (eo & GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO)) && | ||
193 | (GNUNET_OK != | ||
194 | GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK, | ||
195 | &ub->purpose, | ||
196 | &ub->signature, | ||
197 | &ub->verification_key))) | ||
198 | { | ||
199 | GNUNET_break_op (0); | ||
200 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
201 | } | ||
202 | GNUNET_CRYPTO_hash (reply_block, | ||
203 | reply_block_size, | ||
204 | &chash); | ||
205 | if (GNUNET_YES == | ||
206 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
207 | &chash)) | ||
208 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
209 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
210 | |||
211 | default: | ||
212 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | /** | ||
218 | * Function called to obtain the key for a block. | 114 | * Function called to obtain the key for a block. |
219 | * | 115 | * |
220 | * @param cls closure | 116 | * @param cls closure |
@@ -245,8 +141,11 @@ block_plugin_fs_get_key (void *cls, | |||
245 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | 141 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: |
246 | if (block_size < sizeof(struct UBlock)) | 142 | if (block_size < sizeof(struct UBlock)) |
247 | { | 143 | { |
248 | GNUNET_break (0); | 144 | GNUNET_break_op (0); |
249 | return GNUNET_SYSERR; | 145 | memset (key, |
146 | 0, | ||
147 | sizeof (*key)); | ||
148 | return GNUNET_OK; | ||
250 | } | 149 | } |
251 | ub = block; | 150 | ub = block; |
252 | GNUNET_CRYPTO_hash (&ub->verification_key, | 151 | GNUNET_CRYPTO_hash (&ub->verification_key, |
@@ -290,6 +189,7 @@ block_plugin_fs_check_query (void *cls, | |||
290 | } | 189 | } |
291 | return GNUNET_OK; | 190 | return GNUNET_OK; |
292 | default: | 191 | default: |
192 | GNUNET_break (0); | ||
293 | return GNUNET_SYSERR; | 193 | return GNUNET_SYSERR; |
294 | } | 194 | } |
295 | } | 195 | } |
@@ -300,7 +200,6 @@ block_plugin_fs_check_query (void *cls, | |||
300 | * | 200 | * |
301 | * @param cls closure | 201 | * @param cls closure |
302 | * @param type block type | 202 | * @param type block type |
303 | * @param query key for the block (hash), must match exactly | ||
304 | * @param block block data to validate | 203 | * @param block block data to validate |
305 | * @param block_size number of bytes in @a block | 204 | * @param block_size number of bytes in @a block |
306 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 205 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -308,7 +207,6 @@ block_plugin_fs_check_query (void *cls, | |||
308 | static enum GNUNET_GenericReturnValue | 207 | static enum GNUNET_GenericReturnValue |
309 | block_plugin_fs_check_block (void *cls, | 208 | block_plugin_fs_check_block (void *cls, |
310 | enum GNUNET_BLOCK_Type type, | 209 | enum GNUNET_BLOCK_Type type, |
311 | const struct GNUNET_HashCode *query, | ||
312 | const void *block, | 210 | const void *block, |
313 | size_t block_size) | 211 | size_t block_size) |
314 | { | 212 | { |
@@ -346,6 +244,7 @@ block_plugin_fs_check_block (void *cls, | |||
346 | return GNUNET_OK; | 244 | return GNUNET_OK; |
347 | } | 245 | } |
348 | default: | 246 | default: |
247 | GNUNET_break (0); | ||
349 | return GNUNET_SYSERR; | 248 | return GNUNET_SYSERR; |
350 | } | 249 | } |
351 | } | 250 | } |
@@ -396,6 +295,7 @@ block_plugin_fs_check_reply (void *cls, | |||
396 | return GNUNET_BLOCK_REPLY_OK_MORE; | 295 | return GNUNET_BLOCK_REPLY_OK_MORE; |
397 | } | 296 | } |
398 | default: | 297 | default: |
298 | GNUNET_break (0); | ||
399 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | 299 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
400 | } | 300 | } |
401 | } | 301 | } |
@@ -416,7 +316,6 @@ libgnunet_plugin_block_fs_init (void *cls) | |||
416 | struct GNUNET_BLOCK_PluginFunctions *api; | 316 | struct GNUNET_BLOCK_PluginFunctions *api; |
417 | 317 | ||
418 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 318 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
419 | api->evaluate = &block_plugin_fs_evaluate; | ||
420 | api->get_key = &block_plugin_fs_get_key; | 319 | api->get_key = &block_plugin_fs_get_key; |
421 | api->create_group = &block_plugin_fs_create_group; | 320 | api->create_group = &block_plugin_fs_create_group; |
422 | api->check_query = &block_plugin_fs_check_query; | 321 | api->check_query = &block_plugin_fs_check_query; |
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 315b4dbf3..d49e0c5c8 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -155,6 +155,7 @@ gnunet_dns2gns_LDADD = \ | |||
155 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | 155 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ |
156 | libgnunetgns.la \ | 156 | libgnunetgns.la \ |
157 | $(top_builddir)/src/util/libgnunetutil.la \ | 157 | $(top_builddir)/src/util/libgnunetutil.la \ |
158 | $(USE_VPN) \ | ||
158 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 159 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
159 | $(GN_LIBINTL) | 160 | $(GN_LIBINTL) |
160 | 161 | ||
@@ -218,7 +219,6 @@ gnunet_service_gns_LDADD = \ | |||
218 | $(top_builddir)/src/dht/libgnunetdht.la \ | 219 | $(top_builddir)/src/dht/libgnunetdht.la \ |
219 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ | 220 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ |
220 | $(LIBIDN) $(LIBIDN2) \ | 221 | $(LIBIDN) $(LIBIDN2) \ |
221 | $(USE_VPN) \ | ||
222 | $(GN_LIBINTL) | 222 | $(GN_LIBINTL) |
223 | 223 | ||
224 | 224 | ||
@@ -270,8 +270,7 @@ check_SCRIPTS = \ | |||
270 | test_gns_rel_expiration.sh\ | 270 | test_gns_rel_expiration.sh\ |
271 | test_gns_soa_lookup.sh\ | 271 | test_gns_soa_lookup.sh\ |
272 | test_gns_revocation.sh\ | 272 | test_gns_revocation.sh\ |
273 | test_gns_cname_lookup.sh\ | 273 | test_gns_redirect_lookup.sh |
274 | test_proxy.sh | ||
275 | 274 | ||
276 | if HAVE_GNUTLS | 275 | if HAVE_GNUTLS |
277 | if HAVE_LIBGNURL | 276 | if HAVE_LIBGNURL |
@@ -292,7 +291,26 @@ EXTRA_DIST = \ | |||
292 | zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ | 291 | zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ |
293 | zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ | 292 | zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ |
294 | zonefiles/test_zonekey \ | 293 | zonefiles/test_zonekey \ |
295 | $(check_SCRIPTS) \ | 294 | test_gns_lookup.sh \ |
295 | test_gns_config_lookup.sh \ | ||
296 | test_gns_ipv6_lookup.sh\ | ||
297 | test_gns_txt_lookup.sh\ | ||
298 | test_gns_caa_lookup.sh\ | ||
299 | test_gns_mx_lookup.sh \ | ||
300 | test_gns_gns2dns_lookup.sh \ | ||
301 | test_gns_gns2dns_zkey_lookup.sh \ | ||
302 | test_gns_gns2dns_cname_lookup.sh \ | ||
303 | test_gns_dht_lookup.sh\ | ||
304 | test_gns_delegated_lookup.sh \ | ||
305 | test_gns_at_lookup.sh\ | ||
306 | test_gns_zkey_lookup.sh\ | ||
307 | test_gns_rel_expiration.sh\ | ||
308 | test_gns_soa_lookup.sh\ | ||
309 | test_gns_revocation.sh\ | ||
310 | test_gns_redirect_lookup.sh\ | ||
311 | test_proxy.sh\ | ||
312 | test_plugin_rest_gns.sh\ | ||
313 | test_proxy.sh \ | ||
296 | $(pkgdata_DATA) \ | 314 | $(pkgdata_DATA) \ |
297 | test_gnunet_gns.sh.in | 315 | test_gnunet_gns.sh.in |
298 | 316 | ||
diff --git a/src/gns/gnunet-bcd.c b/src/gns/gnunet-bcd.c index 83efcfba5..60fe25945 100644 --- a/src/gns/gnunet-bcd.c +++ b/src/gns/gnunet-bcd.c | |||
@@ -419,6 +419,8 @@ create_response (void *cls, | |||
419 | "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n", | 419 | "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n", |
420 | line1, | 420 | line1, |
421 | line2); | 421 | line2); |
422 | GNUNET_free (line1); | ||
423 | GNUNET_free (line2); | ||
422 | } | 424 | } |
423 | 425 | ||
424 | fprintf (deffile, | 426 | fprintf (deffile, |
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c index 06f4c9841..46659cdda 100644 --- a/src/gns/gnunet-dns2gns.c +++ b/src/gns/gnunet-dns2gns.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <gnunet_dnsparser_lib.h> | 27 | #include <gnunet_dnsparser_lib.h> |
28 | #include <gnunet_gns_service.h> | 28 | #include <gnunet_gns_service.h> |
29 | #include <gnunet_dnsstub_lib.h> | 29 | #include <gnunet_dnsstub_lib.h> |
30 | #include "gnunet_vpn_service.h" | ||
30 | #include "gns.h" | 31 | #include "gns.h" |
31 | 32 | ||
32 | /** | 33 | /** |
@@ -35,6 +36,46 @@ | |||
35 | #define TIMEOUT GNUNET_TIME_UNIT_MINUTES | 36 | #define TIMEOUT GNUNET_TIME_UNIT_MINUTES |
36 | 37 | ||
37 | /** | 38 | /** |
39 | * Default timeout for VPN redirections. | ||
40 | */ | ||
41 | #define VPN_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30) | ||
42 | |||
43 | |||
44 | struct Request; | ||
45 | |||
46 | /** | ||
47 | * Closure for #vpn_allocation_cb. | ||
48 | */ | ||
49 | struct VpnContext | ||
50 | { | ||
51 | /** | ||
52 | * Which resolution process are we processing. | ||
53 | */ | ||
54 | struct Request *request; | ||
55 | |||
56 | /** | ||
57 | * Handle to the VPN request that we were performing. | ||
58 | */ | ||
59 | struct GNUNET_VPN_RedirectionRequest *vpn_request; | ||
60 | |||
61 | /** | ||
62 | * Number of records serialized in @e rd_data. | ||
63 | */ | ||
64 | unsigned int rd_count; | ||
65 | |||
66 | /** | ||
67 | * Serialized records. | ||
68 | */ | ||
69 | char *rd_data; | ||
70 | |||
71 | /** | ||
72 | * Number of bytes in @e rd_data. | ||
73 | */ | ||
74 | ssize_t rd_data_size; | ||
75 | }; | ||
76 | |||
77 | |||
78 | /** | ||
38 | * Data kept per request. | 79 | * Data kept per request. |
39 | */ | 80 | */ |
40 | struct Request | 81 | struct Request |
@@ -72,6 +113,11 @@ struct Request | |||
72 | struct GNUNET_SCHEDULER_Task *timeout_task; | 113 | struct GNUNET_SCHEDULER_Task *timeout_task; |
73 | 114 | ||
74 | /** | 115 | /** |
116 | * Vpn resulution context | ||
117 | */ | ||
118 | struct VpnContext *vpn_ctx; | ||
119 | |||
120 | /** | ||
75 | * Original UDP request message. | 121 | * Original UDP request message. |
76 | */ | 122 | */ |
77 | char *udp_msg; | 123 | char *udp_msg; |
@@ -90,6 +136,7 @@ struct Request | |||
90 | * ID of the original request. | 136 | * ID of the original request. |
91 | */ | 137 | */ |
92 | uint16_t original_request_id; | 138 | uint16_t original_request_id; |
139 | |||
93 | }; | 140 | }; |
94 | 141 | ||
95 | /** | 142 | /** |
@@ -109,6 +156,11 @@ static struct in6_addr address6; | |||
109 | struct GNUNET_GNS_Handle *gns; | 156 | struct GNUNET_GNS_Handle *gns; |
110 | 157 | ||
111 | /** | 158 | /** |
159 | * Our handle to the vpn service | ||
160 | */ | ||
161 | static struct GNUNET_VPN_Handle *vpn_handle; | ||
162 | |||
163 | /** | ||
112 | * Stub resolver | 164 | * Stub resolver |
113 | */ | 165 | */ |
114 | struct GNUNET_DNSSTUB_Context *dns_stub; | 166 | struct GNUNET_DNSSTUB_Context *dns_stub; |
@@ -183,6 +235,11 @@ do_shutdown (void *cls) | |||
183 | GNUNET_GNS_disconnect (gns); | 235 | GNUNET_GNS_disconnect (gns); |
184 | gns = NULL; | 236 | gns = NULL; |
185 | } | 237 | } |
238 | if (NULL != vpn_handle) | ||
239 | { | ||
240 | GNUNET_VPN_disconnect (vpn_handle); | ||
241 | vpn_handle = NULL; | ||
242 | } | ||
186 | if (NULL != dns_stub) | 243 | if (NULL != dns_stub) |
187 | { | 244 | { |
188 | GNUNET_DNSSTUB_stop (dns_stub); | 245 | GNUNET_DNSSTUB_stop (dns_stub); |
@@ -269,6 +326,7 @@ static void | |||
269 | do_timeout (void *cls) | 326 | do_timeout (void *cls) |
270 | { | 327 | { |
271 | struct Request *request = cls; | 328 | struct Request *request = cls; |
329 | struct VpnContext *vpn_ctx; | ||
272 | 330 | ||
273 | if (NULL != request->packet) | 331 | if (NULL != request->packet) |
274 | GNUNET_DNSPARSER_free_packet (request->packet); | 332 | GNUNET_DNSPARSER_free_packet (request->packet); |
@@ -277,6 +335,12 @@ do_timeout (void *cls) | |||
277 | if (NULL != request->dns_lookup) | 335 | if (NULL != request->dns_lookup) |
278 | GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup); | 336 | GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup); |
279 | GNUNET_free (request->udp_msg); | 337 | GNUNET_free (request->udp_msg); |
338 | if (NULL != (vpn_ctx = request->vpn_ctx)) | ||
339 | { | ||
340 | GNUNET_VPN_cancel_request (vpn_ctx->vpn_request); | ||
341 | GNUNET_free (vpn_ctx->rd_data); | ||
342 | GNUNET_free (vpn_ctx); | ||
343 | } | ||
280 | GNUNET_free (request); | 344 | GNUNET_free (request); |
281 | } | 345 | } |
282 | 346 | ||
@@ -321,6 +385,79 @@ dns_result_processor (void *cls, | |||
321 | send_response (request); | 385 | send_response (request); |
322 | } | 386 | } |
323 | 387 | ||
388 | /** | ||
389 | * Callback invoked from the VPN service once a redirection is | ||
390 | * available. Provides the IP address that can now be used to | ||
391 | * reach the requested destination. Replaces the "VPN" record | ||
392 | * with the respective A/AAAA record and continues processing. | ||
393 | * | ||
394 | * @param cls closure | ||
395 | * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; | ||
396 | * will match 'result_af' from the request | ||
397 | * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') | ||
398 | * that the VPN allocated for the redirection; | ||
399 | * traffic to this IP will now be redirected to the | ||
400 | * specified target peer; NULL on error | ||
401 | */ | ||
402 | static void | ||
403 | vpn_allocation_cb (void *cls, | ||
404 | int af, | ||
405 | const void *address) | ||
406 | { | ||
407 | struct VpnContext *vpn_ctx = cls; | ||
408 | struct Request *request = vpn_ctx->request; | ||
409 | struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count]; | ||
410 | unsigned int i; | ||
411 | |||
412 | vpn_ctx->vpn_request = NULL; | ||
413 | request->vpn_ctx = NULL; | ||
414 | GNUNET_assert (GNUNET_OK == | ||
415 | GNUNET_GNSRECORD_records_deserialize ( | ||
416 | (size_t) vpn_ctx->rd_data_size, | ||
417 | vpn_ctx->rd_data, | ||
418 | vpn_ctx->rd_count, | ||
419 | rd)); | ||
420 | for (i = 0; i < vpn_ctx->rd_count; i++) | ||
421 | { | ||
422 | if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type) | ||
423 | { | ||
424 | switch (af) | ||
425 | { | ||
426 | case AF_INET: | ||
427 | rd[i].record_type = GNUNET_DNSPARSER_TYPE_A; | ||
428 | rd[i].data_size = sizeof(struct in_addr); | ||
429 | rd[i].expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
430 | VPN_TIMEOUT).abs_value_us; | ||
431 | rd[i].flags = 0; | ||
432 | rd[i].data = address; | ||
433 | break; | ||
434 | |||
435 | case AF_INET6: | ||
436 | rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA; | ||
437 | rd[i].expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
438 | VPN_TIMEOUT).abs_value_us; | ||
439 | rd[i].flags = 0; | ||
440 | rd[i].data = address; | ||
441 | rd[i].data_size = sizeof(struct in6_addr); | ||
442 | break; | ||
443 | |||
444 | default: | ||
445 | GNUNET_assert (0); | ||
446 | } | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | GNUNET_assert (i < vpn_ctx->rd_count); | ||
451 | if (0 == vpn_ctx->rd_count) | ||
452 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
453 | _ ("VPN returned empty result for `%s'\n"), | ||
454 | request->packet->queries[0].name); | ||
455 | send_response (request); | ||
456 | GNUNET_free (vpn_ctx->rd_data); | ||
457 | GNUNET_free (vpn_ctx); | ||
458 | } | ||
459 | |||
460 | |||
324 | 461 | ||
325 | /** | 462 | /** |
326 | * Iterator called on obtained result for a GNS lookup. | 463 | * Iterator called on obtained result for a GNS lookup. |
@@ -339,6 +476,11 @@ result_processor (void *cls, | |||
339 | struct Request *request = cls; | 476 | struct Request *request = cls; |
340 | struct GNUNET_DNSPARSER_Packet *packet; | 477 | struct GNUNET_DNSPARSER_Packet *packet; |
341 | struct GNUNET_DNSPARSER_Record rec; | 478 | struct GNUNET_DNSPARSER_Record rec; |
479 | struct VpnContext *vpn_ctx; | ||
480 | const struct GNUNET_TUN_GnsVpnRecord *vpn; | ||
481 | const char *vname; | ||
482 | struct GNUNET_HashCode vhash; | ||
483 | int af; | ||
342 | 484 | ||
343 | request->lookup = NULL; | 485 | request->lookup = NULL; |
344 | if (GNUNET_NO == was_gns) | 486 | if (GNUNET_NO == was_gns) |
@@ -415,6 +557,67 @@ result_processor (void *cls, | |||
415 | packet->num_answers, | 557 | packet->num_answers, |
416 | rec); | 558 | rec); |
417 | break; | 559 | break; |
560 | case GNUNET_GNSRECORD_TYPE_VPN: | ||
561 | if ((GNUNET_DNSPARSER_TYPE_A != request->packet->queries[0].type) && | ||
562 | (GNUNET_DNSPARSER_TYPE_AAAA != request->packet->queries[0].type)) | ||
563 | break; | ||
564 | af = (GNUNET_DNSPARSER_TYPE_A == request->packet->queries[0].type) ? AF_INET : | ||
565 | AF_INET6; | ||
566 | if (sizeof(struct GNUNET_TUN_GnsVpnRecord) > | ||
567 | rd[i].data_size) | ||
568 | { | ||
569 | GNUNET_break_op (0); | ||
570 | break; | ||
571 | } | ||
572 | vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data; | ||
573 | vname = (const char *) &vpn[1]; | ||
574 | if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct | ||
575 | GNUNET_TUN_GnsVpnRecord) | ||
576 | ]) | ||
577 | { | ||
578 | GNUNET_break_op (0); | ||
579 | break; | ||
580 | } | ||
581 | GNUNET_TUN_service_name_to_hash (vname, | ||
582 | &vhash); | ||
583 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
584 | "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n", | ||
585 | GNUNET_i2s (&vpn->peer), | ||
586 | vname, | ||
587 | (int) af, | ||
588 | (int) ntohs (vpn->proto)); | ||
589 | vpn_ctx = GNUNET_new (struct VpnContext); | ||
590 | request->vpn_ctx = vpn_ctx; | ||
591 | vpn_ctx->request = request; | ||
592 | vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count, | ||
593 | rd); | ||
594 | if (vpn_ctx->rd_data_size < 0) | ||
595 | { | ||
596 | GNUNET_break_op (0); | ||
597 | GNUNET_free (vpn_ctx); | ||
598 | break; | ||
599 | } | ||
600 | vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size); | ||
601 | vpn_ctx->rd_count = rd_count; | ||
602 | GNUNET_assert (vpn_ctx->rd_data_size == | ||
603 | GNUNET_GNSRECORD_records_serialize (rd_count, | ||
604 | rd, | ||
605 | (size_t) vpn_ctx | ||
606 | ->rd_data_size, | ||
607 | vpn_ctx->rd_data)); | ||
608 | vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle, | ||
609 | af, | ||
610 | ntohs ( | ||
611 | vpn->proto), | ||
612 | &vpn->peer, | ||
613 | &vhash, | ||
614 | GNUNET_TIME_relative_to_absolute ( | ||
615 | VPN_TIMEOUT), | ||
616 | & | ||
617 | vpn_allocation_cb, | ||
618 | vpn_ctx); | ||
619 | return; | ||
620 | |||
418 | 621 | ||
419 | default: | 622 | default: |
420 | /* skip */ | 623 | /* skip */ |
@@ -641,6 +844,8 @@ run (void *cls, | |||
641 | NULL); | 844 | NULL); |
642 | if (NULL == (gns = GNUNET_GNS_connect (cfg))) | 845 | if (NULL == (gns = GNUNET_GNS_connect (cfg))) |
643 | return; | 846 | return; |
847 | if (NULL == (vpn_handle = GNUNET_VPN_connect (cfg))) | ||
848 | return; | ||
644 | GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128))); | 849 | GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128))); |
645 | if (GNUNET_OK != | 850 | if (GNUNET_OK != |
646 | GNUNET_DNSSTUB_add_dns_ip (dns_stub, | 851 | GNUNET_DNSSTUB_add_dns_ip (dns_stub, |
@@ -649,6 +854,8 @@ run (void *cls, | |||
649 | GNUNET_DNSSTUB_stop (dns_stub); | 854 | GNUNET_DNSSTUB_stop (dns_stub); |
650 | GNUNET_GNS_disconnect (gns); | 855 | GNUNET_GNS_disconnect (gns); |
651 | gns = NULL; | 856 | gns = NULL; |
857 | GNUNET_VPN_disconnect (vpn_handle); | ||
858 | vpn_handle = NULL; | ||
652 | return; | 859 | return; |
653 | } | 860 | } |
654 | 861 | ||
@@ -750,6 +957,8 @@ run (void *cls, | |||
750 | { | 957 | { |
751 | GNUNET_GNS_disconnect (gns); | 958 | GNUNET_GNS_disconnect (gns); |
752 | gns = NULL; | 959 | gns = NULL; |
960 | GNUNET_VPN_disconnect (vpn_handle); | ||
961 | vpn_handle = NULL; | ||
753 | GNUNET_DNSSTUB_stop (dns_stub); | 962 | GNUNET_DNSSTUB_stop (dns_stub); |
754 | dns_stub = NULL; | 963 | dns_stub = NULL; |
755 | return; | 964 | return; |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 5833f4d0b..b28236fed 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -420,15 +420,11 @@ handle_lookup (void *cls, | |||
420 | const struct LookupMessage *sh_msg) | 420 | const struct LookupMessage *sh_msg) |
421 | { | 421 | { |
422 | struct GnsClient *gc = cls; | 422 | struct GnsClient *gc = cls; |
423 | char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1]; | ||
424 | struct ClientLookupHandle *clh; | 423 | struct ClientLookupHandle *clh; |
425 | char *nameptr = name; | 424 | const char *name; |
426 | const char *utf_in; | ||
427 | 425 | ||
428 | GNUNET_SERVICE_client_continue (gc->client); | 426 | GNUNET_SERVICE_client_continue (gc->client); |
429 | utf_in = (const char *) &sh_msg[1]; | 427 | name = (const char *) &sh_msg[1]; |
430 | GNUNET_STRINGS_utf8_tolower (utf_in, | ||
431 | nameptr); | ||
432 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 428 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
433 | "Received LOOKUP `%s' message\n", | 429 | "Received LOOKUP `%s' message\n", |
434 | name); | 430 | name); |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 51e650b4f..72b228f33 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include "gns.h" | 52 | #include "gns.h" |
53 | #include "gnunet-service-gns.h" | 53 | #include "gnunet-service-gns.h" |
54 | #include "gnunet-service-gns_resolver.h" | 54 | #include "gnunet-service-gns_resolver.h" |
55 | #include "gnunet_vpn_service.h" | ||
56 | 55 | ||
57 | 56 | ||
58 | /** | 57 | /** |
@@ -68,11 +67,6 @@ | |||
68 | GNUNET_TIME_UNIT_SECONDS, 15) | 67 | GNUNET_TIME_UNIT_SECONDS, 15) |
69 | 68 | ||
70 | /** | 69 | /** |
71 | * Default timeout for VPN redirections. | ||
72 | */ | ||
73 | #define VPN_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30) | ||
74 | |||
75 | /** | ||
76 | * DHT replication level | 70 | * DHT replication level |
77 | */ | 71 | */ |
78 | #define DHT_GNS_REPLICATION_LEVEL 10 | 72 | #define DHT_GNS_REPLICATION_LEVEL 10 |
@@ -255,38 +249,6 @@ struct DnsResult | |||
255 | 249 | ||
256 | 250 | ||
257 | /** | 251 | /** |
258 | * Closure for #vpn_allocation_cb. | ||
259 | */ | ||
260 | struct VpnContext | ||
261 | { | ||
262 | /** | ||
263 | * Which resolution process are we processing. | ||
264 | */ | ||
265 | struct GNS_ResolverHandle *rh; | ||
266 | |||
267 | /** | ||
268 | * Handle to the VPN request that we were performing. | ||
269 | */ | ||
270 | struct GNUNET_VPN_RedirectionRequest *vpn_request; | ||
271 | |||
272 | /** | ||
273 | * Number of records serialized in @e rd_data. | ||
274 | */ | ||
275 | unsigned int rd_count; | ||
276 | |||
277 | /** | ||
278 | * Serialized records. | ||
279 | */ | ||
280 | char *rd_data; | ||
281 | |||
282 | /** | ||
283 | * Number of bytes in @e rd_data. | ||
284 | */ | ||
285 | ssize_t rd_data_size; | ||
286 | }; | ||
287 | |||
288 | |||
289 | /** | ||
290 | * Handle to a currently pending resolution. On result (positive or | 252 | * Handle to a currently pending resolution. On result (positive or |
291 | * negative) the #GNS_ResultProcessor is called. | 253 | * negative) the #GNS_ResultProcessor is called. |
292 | */ | 254 | */ |
@@ -322,10 +284,6 @@ struct GNS_ResolverHandle | |||
322 | */ | 284 | */ |
323 | struct GNUNET_DHT_GetHandle *get_handle; | 285 | struct GNUNET_DHT_GetHandle *get_handle; |
324 | 286 | ||
325 | /** | ||
326 | * Handle to a VPN request, NULL if none is active. | ||
327 | */ | ||
328 | struct VpnContext *vpn_ctx; | ||
329 | 287 | ||
330 | /** | 288 | /** |
331 | * Socket for a DNS request, NULL if none is active. | 289 | * Socket for a DNS request, NULL if none is active. |
@@ -463,11 +421,6 @@ struct CacheOps | |||
463 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; | 421 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; |
464 | 422 | ||
465 | /** | 423 | /** |
466 | * Our handle to the vpn service | ||
467 | */ | ||
468 | static struct GNUNET_VPN_Handle *vpn_handle; | ||
469 | |||
470 | /** | ||
471 | * Resolver handle to the dht | 424 | * Resolver handle to the dht |
472 | */ | 425 | */ |
473 | static struct GNUNET_DHT_Handle *dht_handle; | 426 | static struct GNUNET_DHT_Handle *dht_handle; |
@@ -1235,16 +1188,16 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh) | |||
1235 | 1188 | ||
1236 | 1189 | ||
1237 | /** | 1190 | /** |
1238 | * We encountered a CNAME record during our resolution. | 1191 | * We encountered a REDIRECT record during our resolution. |
1239 | * Merge it into our chain. | 1192 | * Merge it into our chain. |
1240 | * | 1193 | * |
1241 | * @param rh resolution we are performing | 1194 | * @param rh resolution we are performing |
1242 | * @param cname value of the cname record we got for the current | 1195 | * @param rname value of the redirect record we got for the current |
1243 | * authority chain tail | 1196 | * authority chain tail |
1244 | */ | 1197 | */ |
1245 | static void | 1198 | static void |
1246 | handle_gns_cname_result (struct GNS_ResolverHandle *rh, | 1199 | handle_gns_redirect_result (struct GNS_ResolverHandle *rh, |
1247 | const char *cname) | 1200 | const char *rname) |
1248 | { | 1201 | { |
1249 | size_t nlen; | 1202 | size_t nlen; |
1250 | char *res; | 1203 | char *res; |
@@ -1253,14 +1206,17 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1253 | int af; | 1206 | int af; |
1254 | struct GNUNET_IDENTITY_PublicKey zone; | 1207 | struct GNUNET_IDENTITY_PublicKey zone; |
1255 | 1208 | ||
1256 | nlen = strlen (cname); | 1209 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1257 | tld = GNS_get_tld (cname); | 1210 | "Handling GNS REDIRECT result `%s'\n", |
1211 | rname); | ||
1212 | nlen = strlen (rname); | ||
1213 | tld = GNS_get_tld (rname); | ||
1258 | if (0 == strcmp ("+", tld)) | 1214 | if (0 == strcmp ("+", tld)) |
1259 | { | 1215 | { |
1260 | /* CNAME resolution continues relative to current domain */ | 1216 | /* REDIRECT resolution continues relative to current domain */ |
1261 | if (0 == rh->name_resolution_pos) | 1217 | if (0 == rh->name_resolution_pos) |
1262 | { | 1218 | { |
1263 | res = GNUNET_strndup (cname, nlen - 2); | 1219 | res = GNUNET_strndup (rname, nlen - 2); |
1264 | rh->name_resolution_pos = nlen - 2; | 1220 | rh->name_resolution_pos = nlen - 2; |
1265 | } | 1221 | } |
1266 | else | 1222 | else |
@@ -1270,7 +1226,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1270 | (int) rh->name_resolution_pos, | 1226 | (int) rh->name_resolution_pos, |
1271 | rh->name, | 1227 | rh->name, |
1272 | (int) (nlen - 2), | 1228 | (int) (nlen - 2), |
1273 | cname); | 1229 | rname); |
1274 | rh->name_resolution_pos = strlen (res); | 1230 | rh->name_resolution_pos = strlen (res); |
1275 | } | 1231 | } |
1276 | GNUNET_free (rh->name); | 1232 | GNUNET_free (rh->name); |
@@ -1291,13 +1247,13 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1291 | } | 1247 | } |
1292 | if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)) | 1248 | if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)) |
1293 | { | 1249 | { |
1294 | /* CNAME resolution continues relative to current domain */ | 1250 | /* REDIRECT resolution continues relative to current domain */ |
1295 | if (0 == rh->name_resolution_pos) | 1251 | if (0 == rh->name_resolution_pos) |
1296 | { | 1252 | { |
1297 | GNUNET_asprintf (&res, | 1253 | GNUNET_asprintf (&res, |
1298 | "%.*s", | 1254 | "%.*s", |
1299 | (int) (strlen (cname) - (strlen (tld) + 1)), | 1255 | (int) (strlen (rname) - (strlen (tld) + 1)), |
1300 | cname); | 1256 | rname); |
1301 | } | 1257 | } |
1302 | else | 1258 | else |
1303 | { | 1259 | { |
@@ -1305,8 +1261,8 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1305 | "%.*s.%.*s", | 1261 | "%.*s.%.*s", |
1306 | (int) rh->name_resolution_pos, | 1262 | (int) rh->name_resolution_pos, |
1307 | rh->name, | 1263 | rh->name, |
1308 | (int) (strlen (cname) - (strlen (tld) + 1)), | 1264 | (int) (strlen (rname) - (strlen (tld) + 1)), |
1309 | cname); | 1265 | rname); |
1310 | } | 1266 | } |
1311 | rh->name_resolution_pos = strlen (res); | 1267 | rh->name_resolution_pos = strlen (res); |
1312 | GNUNET_free (rh->name); | 1268 | GNUNET_free (rh->name); |
@@ -1326,18 +1282,62 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, | |||
1326 | } | 1282 | } |
1327 | 1283 | ||
1328 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1284 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1329 | "Got CNAME `%s' from GNS for `%s'\n", | 1285 | "Got REDIRECT `%s' from GNS for `%s'\n", |
1330 | cname, | 1286 | rname, |
1331 | rh->name); | 1287 | rh->name); |
1332 | if (NULL != rh->std_resolve) | 1288 | if (NULL != rh->std_resolve) |
1333 | { | 1289 | { |
1334 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1290 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1335 | "Multiple CNAME results from GNS resolving `%s'! Not really allowed...\n", | 1291 | "Multiple REDIRECT results from GNS resolving `%s'! Not really allowed...\n", |
1336 | rh->name); | 1292 | rh->name); |
1337 | GNUNET_RESOLVER_request_cancel (rh->std_resolve); | 1293 | GNUNET_RESOLVER_request_cancel (rh->std_resolve); |
1338 | } | 1294 | } |
1339 | /* name is absolute, go to DNS */ | 1295 | /* name is absolute, go to DNS */ |
1340 | GNUNET_free (rh->name); | 1296 | GNUNET_free (rh->name); |
1297 | rh->name = GNUNET_strdup (rname); | ||
1298 | rh->name_resolution_pos = strlen (rh->name); | ||
1299 | switch (rh->record_type) | ||
1300 | { | ||
1301 | case GNUNET_DNSPARSER_TYPE_A: | ||
1302 | af = AF_INET; | ||
1303 | break; | ||
1304 | |||
1305 | case GNUNET_DNSPARSER_TYPE_AAAA: | ||
1306 | af = AF_INET6; | ||
1307 | break; | ||
1308 | |||
1309 | default: | ||
1310 | af = AF_UNSPEC; | ||
1311 | break; | ||
1312 | } | ||
1313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1314 | "Doing standard DNS lookup for `%s'\n", | ||
1315 | rh->name); | ||
1316 | |||
1317 | rh->std_resolve = GNUNET_RESOLVER_ip_get (rh->name, | ||
1318 | af, | ||
1319 | DNS_LOOKUP_TIMEOUT, | ||
1320 | &handle_dns_result, | ||
1321 | rh); | ||
1322 | } | ||
1323 | |||
1324 | |||
1325 | |||
1326 | /** | ||
1327 | * We encountered a CNAME record during our resolution. | ||
1328 | * Merge it into our chain. | ||
1329 | * | ||
1330 | * @param rh resolution we are performing | ||
1331 | * @param cname value of the cname record we got for the current | ||
1332 | * authority chain tail | ||
1333 | */ | ||
1334 | static void | ||
1335 | handle_gns_cname_result (struct GNS_ResolverHandle *rh, | ||
1336 | const char *cname) | ||
1337 | { | ||
1338 | int af; | ||
1339 | |||
1340 | GNUNET_free (rh->name); | ||
1341 | rh->name = GNUNET_strdup (cname); | 1341 | rh->name = GNUNET_strdup (cname); |
1342 | rh->name_resolution_pos = strlen (rh->name); | 1342 | rh->name_resolution_pos = strlen (rh->name); |
1343 | switch (rh->record_type) | 1343 | switch (rh->record_type) |
@@ -1379,80 +1379,6 @@ handle_gns_resolution_result (void *cls, | |||
1379 | const struct GNUNET_GNSRECORD_Data *rd); | 1379 | const struct GNUNET_GNSRECORD_Data *rd); |
1380 | 1380 | ||
1381 | 1381 | ||
1382 | /** | ||
1383 | * Callback invoked from the VPN service once a redirection is | ||
1384 | * available. Provides the IP address that can now be used to | ||
1385 | * reach the requested destination. Replaces the "VPN" record | ||
1386 | * with the respective A/AAAA record and continues processing. | ||
1387 | * | ||
1388 | * @param cls closure | ||
1389 | * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; | ||
1390 | * will match 'result_af' from the request | ||
1391 | * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') | ||
1392 | * that the VPN allocated for the redirection; | ||
1393 | * traffic to this IP will now be redirected to the | ||
1394 | * specified target peer; NULL on error | ||
1395 | */ | ||
1396 | static void | ||
1397 | vpn_allocation_cb (void *cls, | ||
1398 | int af, | ||
1399 | const void *address) | ||
1400 | { | ||
1401 | struct VpnContext *vpn_ctx = cls; | ||
1402 | struct GNS_ResolverHandle *rh = vpn_ctx->rh; | ||
1403 | struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count]; | ||
1404 | unsigned int i; | ||
1405 | |||
1406 | vpn_ctx->vpn_request = NULL; | ||
1407 | rh->vpn_ctx = NULL; | ||
1408 | GNUNET_assert (GNUNET_OK == | ||
1409 | GNUNET_GNSRECORD_records_deserialize ( | ||
1410 | (size_t) vpn_ctx->rd_data_size, | ||
1411 | vpn_ctx->rd_data, | ||
1412 | vpn_ctx->rd_count, | ||
1413 | rd)); | ||
1414 | for (i = 0; i < vpn_ctx->rd_count; i++) | ||
1415 | { | ||
1416 | if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type) | ||
1417 | { | ||
1418 | switch (af) | ||
1419 | { | ||
1420 | case AF_INET: | ||
1421 | rd[i].record_type = GNUNET_DNSPARSER_TYPE_A; | ||
1422 | rd[i].data_size = sizeof(struct in_addr); | ||
1423 | rd[i].expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
1424 | VPN_TIMEOUT).abs_value_us; | ||
1425 | rd[i].flags = 0; | ||
1426 | rd[i].data = address; | ||
1427 | break; | ||
1428 | |||
1429 | case AF_INET6: | ||
1430 | rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA; | ||
1431 | rd[i].expiration_time = GNUNET_TIME_relative_to_absolute ( | ||
1432 | VPN_TIMEOUT).abs_value_us; | ||
1433 | rd[i].flags = 0; | ||
1434 | rd[i].data = address; | ||
1435 | rd[i].data_size = sizeof(struct in6_addr); | ||
1436 | break; | ||
1437 | |||
1438 | default: | ||
1439 | GNUNET_assert (0); | ||
1440 | } | ||
1441 | break; | ||
1442 | } | ||
1443 | } | ||
1444 | GNUNET_assert (i < vpn_ctx->rd_count); | ||
1445 | if (0 == vpn_ctx->rd_count) | ||
1446 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1447 | _ ("VPN returned empty result for `%s'\n"), | ||
1448 | rh->name); | ||
1449 | handle_gns_resolution_result (rh, | ||
1450 | vpn_ctx->rd_count, | ||
1451 | rd); | ||
1452 | GNUNET_free (vpn_ctx->rd_data); | ||
1453 | GNUNET_free (vpn_ctx); | ||
1454 | } | ||
1455 | |||
1456 | 1382 | ||
1457 | /** | 1383 | /** |
1458 | * We have resolved one or more of the nameservers for a | 1384 | * We have resolved one or more of the nameservers for a |
@@ -1653,6 +1579,20 @@ handle_gns2dns_ip (void *cls, | |||
1653 | ac->authority_info.dns_authority.found = GNUNET_YES; | 1579 | ac->authority_info.dns_authority.found = GNUNET_YES; |
1654 | } | 1580 | } |
1655 | 1581 | ||
1582 | /** | ||
1583 | * We found a REDIRECT record, perform recursive resolution on it. | ||
1584 | * | ||
1585 | * @param rh resolution handle | ||
1586 | * @param rd record with CNAME to resolve recursively | ||
1587 | */ | ||
1588 | static void | ||
1589 | recursive_redirect_resolution (struct GNS_ResolverHandle *rh, | ||
1590 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1591 | { | ||
1592 | handle_gns_redirect_result (rh, | ||
1593 | rd->data); | ||
1594 | } | ||
1595 | |||
1656 | 1596 | ||
1657 | /** | 1597 | /** |
1658 | * We found a CNAME record, perform recursive resolution on it. | 1598 | * We found a CNAME record, perform recursive resolution on it. |
@@ -1956,11 +1896,6 @@ handle_gns_resolution_result (void *cls, | |||
1956 | { | 1896 | { |
1957 | struct GNS_ResolverHandle *rh = cls; | 1897 | struct GNS_ResolverHandle *rh = cls; |
1958 | char *cname; | 1898 | char *cname; |
1959 | struct VpnContext *vpn_ctx; | ||
1960 | const struct GNUNET_TUN_GnsVpnRecord *vpn; | ||
1961 | const char *vname; | ||
1962 | struct GNUNET_HashCode vhash; | ||
1963 | int af; | ||
1964 | char scratch[UINT16_MAX]; | 1899 | char scratch[UINT16_MAX]; |
1965 | size_t scratch_off; | 1900 | size_t scratch_off; |
1966 | size_t scratch_start; | 1901 | size_t scratch_start; |
@@ -2006,8 +1941,18 @@ handle_gns_resolution_result (void *cls, | |||
2006 | GNUNET_free (cname); | 1941 | GNUNET_free (cname); |
2007 | return; | 1942 | return; |
2008 | } | 1943 | } |
2009 | /* If A/AAAA was requested, but we got a VPN | 1944 | if ((rd_count > 0) && |
2010 | record, we convert it to A/AAAA using GNUnet VPN */ | 1945 | (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[0].record_type) && |
1946 | (GNUNET_GNSRECORD_TYPE_REDIRECT != rh->record_type)) | ||
1947 | { | ||
1948 | handle_gns_redirect_result (rh, | ||
1949 | rd[0].data); | ||
1950 | return; | ||
1951 | } | ||
1952 | |||
1953 | |||
1954 | /* If A/AAAA was requested, | ||
1955 | * but we got a GNS2DNS record */ | ||
2011 | if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) || | 1956 | if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) || |
2012 | (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type)) | 1957 | (GNUNET_DNSPARSER_TYPE_AAAA == rh->record_type)) |
2013 | { | 1958 | { |
@@ -2015,69 +1960,6 @@ handle_gns_resolution_result (void *cls, | |||
2015 | { | 1960 | { |
2016 | switch (rd[i].record_type) | 1961 | switch (rd[i].record_type) |
2017 | { | 1962 | { |
2018 | case GNUNET_GNSRECORD_TYPE_VPN: | ||
2019 | { | ||
2020 | af = (GNUNET_DNSPARSER_TYPE_A == rh->record_type) ? AF_INET : | ||
2021 | AF_INET6; | ||
2022 | if (sizeof(struct GNUNET_TUN_GnsVpnRecord) > | ||
2023 | rd[i].data_size) | ||
2024 | { | ||
2025 | GNUNET_break_op (0); | ||
2026 | fail_resolution (rh); | ||
2027 | return; | ||
2028 | } | ||
2029 | vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data; | ||
2030 | vname = (const char *) &vpn[1]; | ||
2031 | if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct | ||
2032 | GNUNET_TUN_GnsVpnRecord) | ||
2033 | ]) | ||
2034 | { | ||
2035 | GNUNET_break_op (0); | ||
2036 | fail_resolution (rh); | ||
2037 | return; | ||
2038 | } | ||
2039 | GNUNET_TUN_service_name_to_hash (vname, | ||
2040 | &vhash); | ||
2041 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2042 | "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n", | ||
2043 | GNUNET_i2s (&vpn->peer), | ||
2044 | vname, | ||
2045 | (int) af, | ||
2046 | (int) ntohs (vpn->proto)); | ||
2047 | vpn_ctx = GNUNET_new (struct VpnContext); | ||
2048 | rh->vpn_ctx = vpn_ctx; | ||
2049 | vpn_ctx->rh = rh; | ||
2050 | vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count, | ||
2051 | rd); | ||
2052 | if (vpn_ctx->rd_data_size < 0) | ||
2053 | { | ||
2054 | GNUNET_break_op (0); | ||
2055 | GNUNET_free (vpn_ctx); | ||
2056 | fail_resolution (rh); | ||
2057 | return; | ||
2058 | } | ||
2059 | vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size); | ||
2060 | vpn_ctx->rd_count = rd_count; | ||
2061 | GNUNET_assert (vpn_ctx->rd_data_size == | ||
2062 | GNUNET_GNSRECORD_records_serialize (rd_count, | ||
2063 | rd, | ||
2064 | (size_t) vpn_ctx | ||
2065 | ->rd_data_size, | ||
2066 | vpn_ctx->rd_data)); | ||
2067 | vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle, | ||
2068 | af, | ||
2069 | ntohs ( | ||
2070 | vpn->proto), | ||
2071 | &vpn->peer, | ||
2072 | &vhash, | ||
2073 | GNUNET_TIME_relative_to_absolute ( | ||
2074 | VPN_TIMEOUT), | ||
2075 | & | ||
2076 | vpn_allocation_cb, | ||
2077 | vpn_ctx); | ||
2078 | return; | ||
2079 | } | ||
2080 | |||
2081 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | 1963 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: |
2082 | { | 1964 | { |
2083 | /* delegation to DNS */ | 1965 | /* delegation to DNS */ |
@@ -2117,6 +1999,23 @@ handle_gns_resolution_result (void *cls, | |||
2117 | so we can free it afterwards. */ | 1999 | so we can free it afterwards. */ |
2118 | switch (rd[i].record_type) | 2000 | switch (rd[i].record_type) |
2119 | { | 2001 | { |
2002 | case GNUNET_GNSRECORD_TYPE_REDIRECT: | ||
2003 | { | ||
2004 | char *rname; | ||
2005 | rname = GNUNET_strndup (rd[i].data, rd[i].data_size); | ||
2006 | rname = translate_dot_plus (rh, rname); | ||
2007 | GNUNET_break (NULL != rname); | ||
2008 | scratch_start = scratch_off; | ||
2009 | memcpy (&scratch[scratch_start], rname, strlen (rname) + 1); | ||
2010 | scratch_off += strlen (rname) + 1; | ||
2011 | GNUNET_assert (rd_off < rd_count); | ||
2012 | rd_new[rd_off].data = &scratch[scratch_start]; | ||
2013 | rd_new[rd_off].data_size = scratch_off - scratch_start; | ||
2014 | rd_off++; | ||
2015 | GNUNET_free (rname); | ||
2016 | } | ||
2017 | break; | ||
2018 | |||
2120 | case GNUNET_DNSPARSER_TYPE_CNAME: | 2019 | case GNUNET_DNSPARSER_TYPE_CNAME: |
2121 | { | 2020 | { |
2122 | char *cname; | 2021 | char *cname; |
@@ -2380,6 +2279,12 @@ handle_gns_resolution_result (void *cls, | |||
2380 | 2279 | ||
2381 | switch (rd[0].record_type) | 2280 | switch (rd[0].record_type) |
2382 | { | 2281 | { |
2282 | case GNUNET_GNSRECORD_TYPE_REDIRECT: | ||
2283 | GNUNET_break_op (1 == rd_count); /* REDIRECT should be unique */ | ||
2284 | recursive_redirect_resolution (rh, | ||
2285 | &rd[0]); | ||
2286 | return; | ||
2287 | |||
2383 | case GNUNET_DNSPARSER_TYPE_CNAME: | 2288 | case GNUNET_DNSPARSER_TYPE_CNAME: |
2384 | GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ | 2289 | GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ |
2385 | recursive_cname_resolution (rh, | 2290 | recursive_cname_resolution (rh, |
@@ -2393,15 +2298,21 @@ handle_gns_resolution_result (void *cls, | |||
2393 | &rd[0]); | 2298 | &rd[0]); |
2394 | return; | 2299 | return; |
2395 | 2300 | ||
2396 | default: | 2301 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: |
2397 | if (GNUNET_OK == | 2302 | if (GNUNET_OK == |
2398 | recursive_gns2dns_resolution (rh, | 2303 | recursive_gns2dns_resolution (rh, |
2399 | rd_count, | 2304 | rd_count, |
2400 | rd)) | 2305 | rd)) |
2401 | return; | 2306 | return; |
2402 | break; | 2307 | break; |
2308 | default: | ||
2309 | if (GNUNET_YES != GNUNET_GNSRECORD_is_critical (rd[0].record_type)) | ||
2310 | return; | ||
2311 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2312 | _ ("Unable to process critical delegation record\n")); | ||
2313 | break; | ||
2403 | } | 2314 | } |
2404 | fail: | 2315 | fail: |
2405 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2316 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2406 | _ ("GNS lookup recursion failed (no delegation record found)\n")); | 2317 | _ ("GNS lookup recursion failed (no delegation record found)\n")); |
2407 | fail_resolution (rh); | 2318 | fail_resolution (rh); |
@@ -2618,6 +2529,13 @@ handle_namecache_block_response (void *cls, | |||
2618 | 2529 | ||
2619 | GNUNET_assert (NULL != rh->namecache_qe); | 2530 | GNUNET_assert (NULL != rh->namecache_qe); |
2620 | rh->namecache_qe = NULL; | 2531 | rh->namecache_qe = NULL; |
2532 | if (NULL == block) | ||
2533 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2534 | "No block found\n"); | ||
2535 | else | ||
2536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2537 | "Got block with expiration %s\n", | ||
2538 | GNUNET_STRINGS_absolute_time_to_string (GNUNET_GNSRECORD_block_get_expiration (block))); | ||
2621 | if (((GNUNET_GNS_LO_DEFAULT == rh->options) || | 2539 | if (((GNUNET_GNS_LO_DEFAULT == rh->options) || |
2622 | ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) && | 2540 | ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) && |
2623 | (ac != rh->ac_head))) && | 2541 | (ac != rh->ac_head))) && |
@@ -2916,7 +2834,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh) | |||
2916 | { | 2834 | { |
2917 | struct DnsResult *dr; | 2835 | struct DnsResult *dr; |
2918 | struct AuthorityChain *ac; | 2836 | struct AuthorityChain *ac; |
2919 | struct VpnContext *vpn_ctx; | ||
2920 | 2837 | ||
2921 | GNUNET_CONTAINER_DLL_remove (rlh_head, | 2838 | GNUNET_CONTAINER_DLL_remove (rlh_head, |
2922 | rlh_tail, | 2839 | rlh_tail, |
@@ -2981,12 +2898,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh) | |||
2981 | GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node); | 2898 | GNUNET_CONTAINER_heap_remove_node (rh->dht_heap_node); |
2982 | rh->dht_heap_node = NULL; | 2899 | rh->dht_heap_node = NULL; |
2983 | } | 2900 | } |
2984 | if (NULL != (vpn_ctx = rh->vpn_ctx)) | ||
2985 | { | ||
2986 | GNUNET_VPN_cancel_request (vpn_ctx->vpn_request); | ||
2987 | GNUNET_free (vpn_ctx->rd_data); | ||
2988 | GNUNET_free (vpn_ctx); | ||
2989 | } | ||
2990 | if (NULL != rh->namecache_qe) | 2901 | if (NULL != rh->namecache_qe) |
2991 | { | 2902 | { |
2992 | GNUNET_NAMECACHE_cancel (rh->namecache_qe); | 2903 | GNUNET_NAMECACHE_cancel (rh->namecache_qe); |
@@ -3046,7 +2957,6 @@ GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc, | |||
3046 | if (GNUNET_YES == disable_cache) | 2957 | if (GNUNET_YES == disable_cache) |
3047 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2958 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
3048 | "Namecache disabled\n"); | 2959 | "Namecache disabled\n"); |
3049 | vpn_handle = GNUNET_VPN_connect (cfg); | ||
3050 | } | 2960 | } |
3051 | 2961 | ||
3052 | 2962 | ||
@@ -3077,8 +2987,6 @@ GNS_resolver_done () | |||
3077 | } | 2987 | } |
3078 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); | 2988 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); |
3079 | dht_lookup_heap = NULL; | 2989 | dht_lookup_heap = NULL; |
3080 | GNUNET_VPN_disconnect (vpn_handle); | ||
3081 | vpn_handle = NULL; | ||
3082 | dht_handle = NULL; | 2990 | dht_handle = NULL; |
3083 | namecache_handle = NULL; | 2991 | namecache_handle = NULL; |
3084 | } | 2992 | } |
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index 407754a8c..fd9c99cb4 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.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, 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 |
@@ -92,98 +92,16 @@ block_plugin_gns_create_group (void *cls, | |||
92 | 92 | ||
93 | 93 | ||
94 | /** | 94 | /** |
95 | * Function called to validate a reply or a request. For | ||
96 | * request evaluation, simply pass "NULL" for the reply_block. | ||
97 | * Note that it is assumed that the reply has already been | ||
98 | * matched to the key (and signatures checked) as it would | ||
99 | * be done with the "get_key" function. | ||
100 | * | ||
101 | * @param cls closure | ||
102 | * @param ctx block context | ||
103 | * @param type block type | ||
104 | * @param bg block group to use for evaluation | ||
105 | * @param eo control flags | ||
106 | * @param query original query (hash) | ||
107 | * @param xquery extrended query data (can be NULL, depending on @a type) | ||
108 | * @param xquery_size number of bytes in @a xquery | ||
109 | * @param reply_block response to validate | ||
110 | * @param reply_block_size number of bytes in @a reply_block | ||
111 | * @return characterization of result | ||
112 | */ | ||
113 | static enum GNUNET_BLOCK_EvaluationResult | ||
114 | block_plugin_gns_evaluate (void *cls, | ||
115 | struct GNUNET_BLOCK_Context *ctx, | ||
116 | enum GNUNET_BLOCK_Type type, | ||
117 | struct GNUNET_BLOCK_Group *bg, | ||
118 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
119 | const struct GNUNET_HashCode *query, | ||
120 | const void *xquery, | ||
121 | size_t xquery_size, | ||
122 | const void *reply_block, | ||
123 | size_t reply_block_size) | ||
124 | { | ||
125 | const struct GNUNET_GNSRECORD_Block *block; | ||
126 | struct GNUNET_HashCode h; | ||
127 | struct GNUNET_HashCode chash; | ||
128 | |||
129 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | ||
130 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
131 | if (NULL == reply_block) | ||
132 | { | ||
133 | if (0 != xquery_size) | ||
134 | { | ||
135 | GNUNET_break_op (0); | ||
136 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
137 | } | ||
138 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
139 | } | ||
140 | |||
141 | /* this is a reply */ | ||
142 | if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | ||
143 | { | ||
144 | GNUNET_break_op (0); | ||
145 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
146 | } | ||
147 | block = reply_block; | ||
148 | if (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size) | ||
149 | { | ||
150 | GNUNET_break_op (0); | ||
151 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
152 | } | ||
153 | GNUNET_GNSRECORD_query_from_block (block, | ||
154 | &h); | ||
155 | if (0 != GNUNET_memcmp (&h, query)) | ||
156 | { | ||
157 | GNUNET_break_op (0); | ||
158 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
159 | } | ||
160 | if (GNUNET_OK != | ||
161 | GNUNET_GNSRECORD_block_verify (block)) | ||
162 | { | ||
163 | GNUNET_break_op (0); | ||
164 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
165 | } | ||
166 | GNUNET_CRYPTO_hash (reply_block, | ||
167 | reply_block_size, | ||
168 | &chash); | ||
169 | if (GNUNET_YES == | ||
170 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
171 | &chash)) | ||
172 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
173 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
174 | } | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Function called to obtain the key for a block. | 95 | * Function called to obtain the key for a block. |
96 | * If the @a block is malformed, the function should | ||
97 | * zero-out @a key and return #GNUNET_OK. | ||
179 | * | 98 | * |
180 | * @param cls closure | 99 | * @param cls closure |
181 | * @param type block type | 100 | * @param type block type |
182 | * @param reply_block block to get the key for | 101 | * @param reply_block block to get the key for |
183 | * @param reply_block_size number of bytes in @a reply_block | 102 | * @param reply_block_size number of bytes in @a reply_block |
184 | * @param key set to the key (query) for the given block | 103 | * @param key set to the key (query) for the given block |
185 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 104 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported, #GNUNET_NO 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 | */ | 105 | */ |
188 | static enum GNUNET_GenericReturnValue | 106 | static enum GNUNET_GenericReturnValue |
189 | block_plugin_gns_get_key (void *cls, | 107 | block_plugin_gns_get_key (void *cls, |
@@ -194,12 +112,18 @@ block_plugin_gns_get_key (void *cls, | |||
194 | { | 112 | { |
195 | const struct GNUNET_GNSRECORD_Block *block; | 113 | const struct GNUNET_GNSRECORD_Block *block; |
196 | 114 | ||
197 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 115 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) |
116 | { | ||
117 | GNUNET_break (0); | ||
198 | return GNUNET_SYSERR; | 118 | return GNUNET_SYSERR; |
119 | } | ||
199 | if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | 120 | if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) |
200 | { | 121 | { |
201 | GNUNET_break_op (0); | 122 | GNUNET_break_op (0); |
202 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | 123 | memset (key, |
124 | 0, | ||
125 | sizeof (*key)); | ||
126 | return GNUNET_OK; | ||
203 | } | 127 | } |
204 | block = reply_block; | 128 | block = reply_block; |
205 | GNUNET_GNSRECORD_query_from_block (block, | 129 | GNUNET_GNSRECORD_query_from_block (block, |
@@ -227,8 +151,11 @@ block_plugin_gns_check_query (void *cls, | |||
227 | const void *xquery, | 151 | const void *xquery, |
228 | size_t xquery_size) | 152 | size_t xquery_size) |
229 | { | 153 | { |
230 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 154 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) |
155 | { | ||
156 | GNUNET_break (0); | ||
231 | return GNUNET_SYSERR; | 157 | return GNUNET_SYSERR; |
158 | } | ||
232 | if (0 != xquery_size) | 159 | if (0 != xquery_size) |
233 | { | 160 | { |
234 | GNUNET_break_op (0); | 161 | GNUNET_break_op (0); |
@@ -243,7 +170,6 @@ block_plugin_gns_check_query (void *cls, | |||
243 | * | 170 | * |
244 | * @param cls closure | 171 | * @param cls closure |
245 | * @param type block type | 172 | * @param type block type |
246 | * @param query key for the block (hash), must match exactly | ||
247 | * @param block block data to validate | 173 | * @param block block data to validate |
248 | * @param block_size number of bytes in @a block | 174 | * @param block_size number of bytes in @a block |
249 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 175 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -251,14 +177,16 @@ block_plugin_gns_check_query (void *cls, | |||
251 | static enum GNUNET_GenericReturnValue | 177 | static enum GNUNET_GenericReturnValue |
252 | block_plugin_gns_check_block (void *cls, | 178 | block_plugin_gns_check_block (void *cls, |
253 | enum GNUNET_BLOCK_Type type, | 179 | enum GNUNET_BLOCK_Type type, |
254 | const struct GNUNET_HashCode *query, | ||
255 | const void *block, | 180 | const void *block, |
256 | size_t block_size) | 181 | size_t block_size) |
257 | { | 182 | { |
258 | const struct GNUNET_GNSRECORD_Block *gblock; | 183 | const struct GNUNET_GNSRECORD_Block *gblock; |
259 | 184 | ||
260 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 185 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) |
186 | { | ||
187 | GNUNET_break (0); | ||
261 | return GNUNET_SYSERR; | 188 | return GNUNET_SYSERR; |
189 | } | ||
262 | if (block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | 190 | if (block_size < sizeof(struct GNUNET_GNSRECORD_Block)) |
263 | { | 191 | { |
264 | GNUNET_break_op (0); | 192 | GNUNET_break_op (0); |
@@ -306,23 +234,16 @@ block_plugin_gns_check_reply (void *cls, | |||
306 | const void *reply_block, | 234 | const void *reply_block, |
307 | size_t reply_block_size) | 235 | size_t reply_block_size) |
308 | { | 236 | { |
309 | const struct GNUNET_GNSRECORD_Block *block; | 237 | const struct GNUNET_GNSRECORD_Block *block = reply_block; |
310 | struct GNUNET_HashCode chash; | 238 | struct GNUNET_HashCode chash; |
311 | 239 | ||
312 | if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) | 240 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) |
313 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
314 | /* this is a reply */ | ||
315 | if (reply_block_size < sizeof(struct GNUNET_GNSRECORD_Block)) | ||
316 | { | 241 | { |
317 | GNUNET_break_op (0); | 242 | GNUNET_break (0); |
318 | return GNUNET_BLOCK_REPLY_INVALID; | 243 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
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 | } | 244 | } |
245 | GNUNET_assert (reply_block_size >= sizeof(struct GNUNET_GNSRECORD_Block)); | ||
246 | GNUNET_assert (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size); | ||
326 | GNUNET_CRYPTO_hash (reply_block, | 247 | GNUNET_CRYPTO_hash (reply_block, |
327 | reply_block_size, | 248 | reply_block_size, |
328 | &chash); | 249 | &chash); |
@@ -347,7 +268,6 @@ libgnunet_plugin_block_gns_init (void *cls) | |||
347 | struct GNUNET_BLOCK_PluginFunctions *api; | 268 | struct GNUNET_BLOCK_PluginFunctions *api; |
348 | 269 | ||
349 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 270 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
350 | api->evaluate = &block_plugin_gns_evaluate; | ||
351 | api->get_key = &block_plugin_gns_get_key; | 271 | api->get_key = &block_plugin_gns_get_key; |
352 | api->create_group = &block_plugin_gns_create_group; | 272 | api->create_group = &block_plugin_gns_create_group; |
353 | api->check_query = &block_plugin_gns_check_query; | 273 | api->check_query = &block_plugin_gns_check_query; |
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 391144925..dc7ffa9b2 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -64,8 +64,7 @@ gns_value_to_string (void *cls, | |||
64 | return GNUNET_IDENTITY_public_key_to_string (&pk); | 64 | return GNUNET_IDENTITY_public_key_to_string (&pk); |
65 | 65 | ||
66 | case GNUNET_GNSRECORD_TYPE_NICK: | 66 | case GNUNET_GNSRECORD_TYPE_NICK: |
67 | return GNUNET_strndup (data, data_size); | 67 | case GNUNET_GNSRECORD_TYPE_REDIRECT: |
68 | |||
69 | case GNUNET_GNSRECORD_TYPE_LEHO: | 68 | case GNUNET_GNSRECORD_TYPE_LEHO: |
70 | return GNUNET_strndup (data, data_size); | 69 | return GNUNET_strndup (data, data_size); |
71 | 70 | ||
@@ -133,7 +132,9 @@ gns_value_to_string (void *cls, | |||
133 | GNUNET_free (ival); | 132 | GNUNET_free (ival); |
134 | return box_str; | 133 | return box_str; |
135 | } | 134 | } |
136 | 135 | case GNUNET_GNSRECORD_TYPE_TOMBSTONE: { | |
136 | return GNUNET_strdup (_("This is a memento of an older block for internal maintenance.")); | ||
137 | } | ||
137 | default: | 138 | default: |
138 | return NULL; | 139 | return NULL; |
139 | } | 140 | } |
@@ -184,16 +185,13 @@ gns_string_to_value (void *cls, | |||
184 | if (record_type != type) | 185 | if (record_type != type) |
185 | { | 186 | { |
186 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 187 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
187 | _("Record type does not match parsed record type\n")); | 188 | _ ("Record type does not match parsed record type\n")); |
188 | return GNUNET_SYSERR; | 189 | return GNUNET_SYSERR; |
189 | } | 190 | } |
190 | return GNUNET_OK; | 191 | return GNUNET_OK; |
191 | 192 | ||
192 | case GNUNET_GNSRECORD_TYPE_NICK: | 193 | case GNUNET_GNSRECORD_TYPE_NICK: |
193 | *data = GNUNET_strdup (s); | 194 | case GNUNET_GNSRECORD_TYPE_REDIRECT: |
194 | *data_size = strlen (s); | ||
195 | return GNUNET_OK; | ||
196 | |||
197 | case GNUNET_GNSRECORD_TYPE_LEHO: | 195 | case GNUNET_GNSRECORD_TYPE_LEHO: |
198 | *data = GNUNET_strdup (s); | 196 | *data = GNUNET_strdup (s); |
199 | *data_size = strlen (s); | 197 | *data_size = strlen (s); |
@@ -301,6 +299,12 @@ gns_string_to_value (void *cls, | |||
301 | GNUNET_free (bval); | 299 | GNUNET_free (bval); |
302 | return GNUNET_OK; | 300 | return GNUNET_OK; |
303 | } | 301 | } |
302 | case GNUNET_GNSRECORD_TYPE_TOMBSTONE: { | ||
303 | *data_size = 0; | ||
304 | *data = NULL; | ||
305 | return GNUNET_OK; | ||
306 | } | ||
307 | |||
304 | 308 | ||
305 | default: | 309 | default: |
306 | return GNUNET_SYSERR; | 310 | return GNUNET_SYSERR; |
@@ -317,12 +321,16 @@ static struct | |||
317 | const char *name; | 321 | const char *name; |
318 | uint32_t number; | 322 | uint32_t number; |
319 | } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY }, | 323 | } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY }, |
320 | { "EDKEY", GNUNET_GNSRECORD_TYPE_PKEY }, | 324 | { "EDKEY", GNUNET_GNSRECORD_TYPE_EDKEY }, |
321 | { "NICK", GNUNET_GNSRECORD_TYPE_NICK }, | 325 | { "NICK", GNUNET_GNSRECORD_TYPE_NICK }, |
322 | { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, | 326 | { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, |
323 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, | 327 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, |
324 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, | 328 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, |
325 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, | 329 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, |
330 | { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT }, | ||
331 | /* Tombstones should never be added manually | ||
332 | * so this makes sense, kind of */ | ||
333 | { "\u271E", GNUNET_GNSRECORD_TYPE_TOMBSTONE }, | ||
326 | { NULL, UINT32_MAX } }; | 334 | { NULL, UINT32_MAX } }; |
327 | 335 | ||
328 | 336 | ||
@@ -365,6 +373,19 @@ gns_number_to_typename (void *cls, uint32_t type) | |||
365 | } | 373 | } |
366 | 374 | ||
367 | 375 | ||
376 | static enum GNUNET_GenericReturnValue | ||
377 | gns_is_critical (void *cls, uint32_t type) | ||
378 | { | ||
379 | return ((type == GNUNET_GNSRECORD_TYPE_PKEY) || | ||
380 | (type == GNUNET_GNSRECORD_TYPE_EDKEY) || | ||
381 | (type == GNUNET_GNSRECORD_TYPE_GNS2DNS) || | ||
382 | (type == GNUNET_GNSRECORD_TYPE_REDIRECT) ? | ||
383 | GNUNET_YES : GNUNET_NO); | ||
384 | } | ||
385 | |||
386 | |||
387 | |||
388 | |||
368 | /** | 389 | /** |
369 | * Entry point for the plugin. | 390 | * Entry point for the plugin. |
370 | * | 391 | * |
@@ -381,6 +402,7 @@ libgnunet_plugin_gnsrecord_gns_init (void *cls) | |||
381 | api->string_to_value = &gns_string_to_value; | 402 | api->string_to_value = &gns_string_to_value; |
382 | api->typename_to_number = &gns_typename_to_number; | 403 | api->typename_to_number = &gns_typename_to_number; |
383 | api->number_to_typename = &gns_number_to_typename; | 404 | api->number_to_typename = &gns_number_to_typename; |
405 | api->is_critical = &gns_is_critical; | ||
384 | return api; | 406 | return api; |
385 | } | 407 | } |
386 | 408 | ||
diff --git a/src/gns/test_gns_cname_lookup.sh b/src/gns/test_gns_cname_lookup.sh deleted file mode 100755 index 3a189e1e2..000000000 --- a/src/gns/test_gns_cname_lookup.sh +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # This file is in the public domain. | ||
3 | trap "gnunet-arm -e -c test_gns_lookup.conf" INT | ||
4 | |||
5 | LOCATION=$(which gnunet-config) | ||
6 | if [ -z $LOCATION ] | ||
7 | then | ||
8 | LOCATION="gnunet-config" | ||
9 | fi | ||
10 | $LOCATION --version 1> /dev/null | ||
11 | if test $? != 0 | ||
12 | then | ||
13 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
14 | exit 77 | ||
15 | fi | ||
16 | |||
17 | # permissive DNS resolver we will use for the test | ||
18 | DNS_RESOLVER="8.8.8.8" | ||
19 | if ! nslookup gnunet.org $DNS_RESOLVER > /dev/null 2>&1 | ||
20 | then | ||
21 | echo "Cannot reach DNS, skipping test" | ||
22 | exit 77 | ||
23 | fi | ||
24 | |||
25 | |||
26 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | ||
27 | |||
28 | TEST_IP_PLUS="127.0.0.1" | ||
29 | TEST_IP_DNS="131.159.74.67" | ||
30 | TEST_RECORD_CNAME_SERVER="server" | ||
31 | TEST_RECORD_CNAME_PLUS="server.+" | ||
32 | TEST_RECORD_CNAME_DNS="gnunet.org" | ||
33 | TEST_RECORD_NAME_SERVER="server" | ||
34 | TEST_RECORD_NAME_PLUS="www" | ||
35 | TEST_RECORD_NAME_ZKEY="www2" | ||
36 | TEST_RECORD_NAME_DNS="www3" | ||
37 | MY_EGO="myego" | ||
38 | TEST_DOMAIN_PLUS="www.$MY_EGO" | ||
39 | TEST_DOMAIN_ZKEY="www2.$MY_EGO" | ||
40 | TEST_DOMAIN_DNS="www3.$MY_EGO" | ||
41 | which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" | ||
42 | |||
43 | gnunet-arm -s -c test_gns_lookup.conf | ||
44 | gnunet-identity -C $MY_EGO -c test_gns_lookup.conf | ||
45 | MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}') | ||
46 | TEST_RECORD_CNAME_ZKEY="server.${MY_EGO_PKEY}" | ||
47 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf | ||
48 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf | ||
49 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf | ||
50 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf | ||
51 | RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` | ||
52 | RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf` | ||
53 | RES_CNAME_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf` | ||
54 | RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS` | ||
55 | |||
56 | TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'` | ||
57 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf | ||
58 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf | ||
59 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf | ||
60 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf | ||
61 | gnunet-identity -D $MY_EGO -c test_gns_lookup.conf | ||
62 | gnunet-arm -e -c test_gns_lookup.conf | ||
63 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | ||
64 | |||
65 | # make cmp case-insensitive by converting to lower case first | ||
66 | RES_CNAME_RAW=`echo $RES_CNAME_RAW | tr [A-Z] [a-z]` | ||
67 | TESTEGOZONE=`echo $TESTEGOZONE | tr [A-Z] [a-z]` | ||
68 | if [ "$RES_CNAME_RAW" = "server.$TESTEGOZONE" ] | ||
69 | then | ||
70 | echo "PASS: CNAME resolution from GNS" | ||
71 | else | ||
72 | echo "FAIL: CNAME resolution from GNS, got $RES_CNAME_RAW, expected server.$TESTEGOZONE." | ||
73 | exit 1 | ||
74 | fi | ||
75 | |||
76 | if [ "$RES_CNAME" = "$TEST_IP_PLUS" ] | ||
77 | then | ||
78 | echo "PASS: IP resolution from GNS (.+)" | ||
79 | else | ||
80 | echo "FAIL: IP resolution from GNS (.+), got $RES_CNAME, expected $TEST_IP_PLUS." | ||
81 | exit 1 | ||
82 | fi | ||
83 | |||
84 | if [ "$RES_CNAME_ZKEY" = "$TEST_IP_PLUS" ] | ||
85 | then | ||
86 | echo "PASS: IP resolution from GNS (.zkey)" | ||
87 | else | ||
88 | echo "FAIL: IP resolution from GNS (.zkey), got $RES_CNAME, expected $TEST_IP_PLUS." | ||
89 | exit 1 | ||
90 | fi | ||
91 | |||
92 | if echo "$RES_CNAME_DNS" | grep "$TEST_IP_DNS" > /dev/null | ||
93 | then | ||
94 | echo "PASS: IP resolution from DNS" | ||
95 | exit 0 | ||
96 | else | ||
97 | echo "FAIL: IP resolution from DNS, got $RES_CNAME_DNS, expected $TEST_IP_DNS." | ||
98 | exit 1 | ||
99 | fi | ||
diff --git a/src/gns/test_gns_gns2dns_cname_lookup.sh b/src/gns/test_gns_gns2dns_cname_lookup.sh index ce1afacf4..9315f6b2f 100755 --- a/src/gns/test_gns_gns2dns_cname_lookup.sh +++ b/src/gns/test_gns_gns2dns_cname_lookup.sh | |||
@@ -16,9 +16,11 @@ fi | |||
16 | 16 | ||
17 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | 17 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` |
18 | # IP address of 'www.gnunet.org' | 18 | # IP address of 'www.gnunet.org' |
19 | TEST_IP="131.159.74.67" | 19 | TEST_IP="147.87.255.218" |
20 | # IP address of 'gnunet.org' | ||
21 | TEST_IPALT="131.159.74.67" | ||
20 | # IPv6 address of 'gnunet.org' | 22 | # IPv6 address of 'gnunet.org' |
21 | TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" | 23 | TEST_IP6="2a07:6b47:100:464::9357:ffdb" |
22 | 24 | ||
23 | # main label used during resolution | 25 | # main label used during resolution |
24 | TEST_RECORD_NAME="homepage" | 26 | TEST_RECORD_NAME="homepage" |
@@ -46,7 +48,7 @@ TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO" | |||
46 | which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" | 48 | which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" |
47 | 49 | ||
48 | gnunet-arm -s -c test_gns_lookup.conf | 50 | gnunet-arm -s -c test_gns_lookup.conf |
49 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` | 51 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org` |
50 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 52 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
51 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 53 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
52 | 54 | ||
@@ -59,6 +61,7 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECOR | |||
59 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS2 -e never -c test_gns_lookup.conf | 61 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS2 -e never -c test_gns_lookup.conf |
60 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS3 -e never -c test_gns_lookup.conf | 62 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS3 -e never -c test_gns_lookup.conf |
61 | 63 | ||
64 | gnunet-namestore -z $MY_EGO -D -c test_gns_lookup.conf | ||
62 | 65 | ||
63 | echo "EGOs:" | 66 | echo "EGOs:" |
64 | gnunet-identity -d | 67 | gnunet-identity -d |
diff --git a/src/gns/test_gns_gns2dns_lookup.sh b/src/gns/test_gns_gns2dns_lookup.sh index dcad594b3..240e441a4 100755 --- a/src/gns/test_gns_gns2dns_lookup.sh +++ b/src/gns/test_gns_gns2dns_lookup.sh | |||
@@ -17,9 +17,11 @@ rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | |||
17 | # IP address of 'docs.gnunet.org' | 17 | # IP address of 'docs.gnunet.org' |
18 | TEST_IP_ALT2="147.87.255.218" | 18 | TEST_IP_ALT2="147.87.255.218" |
19 | # IP address of 'www.gnunet.org' | 19 | # IP address of 'www.gnunet.org' |
20 | TEST_IP="131.159.74.67" | 20 | TEST_IP="147.87.255.218" |
21 | # IP address of 'gnunet.org' | ||
22 | TEST_IP_ALT="131.159.74.67" | ||
21 | # IPv6 address of 'gnunet.org' | 23 | # IPv6 address of 'gnunet.org' |
22 | TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" | 24 | TEST_IP6="2a07:6b47:100:464::9357:ffdb" |
23 | # permissive DNS resolver we will use for the test | 25 | # permissive DNS resolver we will use for the test |
24 | TEST_IP_GNS2DNS="8.8.8.8" | 26 | TEST_IP_GNS2DNS="8.8.8.8" |
25 | 27 | ||
@@ -49,7 +51,7 @@ which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" | |||
49 | 51 | ||
50 | gnunet-arm -s -c test_gns_lookup.conf | 52 | gnunet-arm -s -c test_gns_lookup.conf |
51 | 53 | ||
52 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` | 54 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org` |
53 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 55 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
54 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 56 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
55 | 57 | ||
@@ -69,7 +71,7 @@ gnunet-identity -d | |||
69 | # lookup 'www.gnunet.org', IPv4 | 71 | # lookup 'www.gnunet.org', IPv4 |
70 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` | 72 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` |
71 | # lookup 'www.gnunet.org', IPv6 | 73 | # lookup 'www.gnunet.org', IPv6 |
72 | RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf` | 74 | RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf | head -n1` |
73 | # lookup 'gnunet.org', IPv4 | 75 | # lookup 'gnunet.org', IPv4 |
74 | RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` | 76 | RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` |
75 | # lookup 'docs.gnunet.org', IPv4 | 77 | # lookup 'docs.gnunet.org', IPv4 |
@@ -91,7 +93,7 @@ else | |||
91 | ret=1 | 93 | ret=1 |
92 | fi | 94 | fi |
93 | 95 | ||
94 | if [ "$RES_IP6" = "$TEST_IP6" ] | 96 | if [ "${RES_IP6%?}" = "${TEST_IP6%?}" ] |
95 | then | 97 | then |
96 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." | 98 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." |
97 | else | 99 | else |
@@ -99,7 +101,7 @@ else | |||
99 | ret=1 | 101 | ret=1 |
100 | fi | 102 | fi |
101 | 103 | ||
102 | if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null | 104 | if echo "$RES_IP_ALT" | grep "$TEST_IP_ALT" > /dev/null |
103 | then | 105 | then |
104 | echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." | 106 | echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." |
105 | else | 107 | else |
diff --git a/src/gns/test_gns_gns2dns_zkey_lookup.sh b/src/gns/test_gns_gns2dns_zkey_lookup.sh index 1f8e34c42..a299c34b6 100755 --- a/src/gns/test_gns_gns2dns_zkey_lookup.sh +++ b/src/gns/test_gns_gns2dns_zkey_lookup.sh | |||
@@ -17,9 +17,11 @@ rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | |||
17 | # IP address of 'docs.gnunet.org' | 17 | # IP address of 'docs.gnunet.org' |
18 | TEST_IP_ALT2="147.87.255.218" | 18 | TEST_IP_ALT2="147.87.255.218" |
19 | # IP address of 'www.gnunet.org' | 19 | # IP address of 'www.gnunet.org' |
20 | TEST_IP="131.159.74.67" | 20 | TEST_IP="147.87.255.218" |
21 | # IP address of 'www.gnunet.org' | ||
22 | TEST_IP_ALT="131.159.74.67" | ||
21 | # IPv6 address of 'gnunet.org' | 23 | # IPv6 address of 'gnunet.org' |
22 | TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60" | 24 | TEST_IP6="2a07:6b47:100:464::9357:ffdb" |
23 | # permissive DNS resolver we will use for the test | 25 | # permissive DNS resolver we will use for the test |
24 | TEST_IP_GNS2DNS="8.8.8.8" | 26 | TEST_IP_GNS2DNS="8.8.8.8" |
25 | 27 | ||
@@ -46,7 +48,7 @@ which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" | |||
46 | 48 | ||
47 | gnunet-arm -s -c test_gns_lookup.conf | 49 | gnunet-arm -s -c test_gns_lookup.conf |
48 | 50 | ||
49 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org` | 51 | OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf www.gnunet.org` |
50 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 52 | echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
51 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } | 53 | echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; } |
52 | 54 | ||
@@ -66,7 +68,7 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECOR | |||
66 | # lookup 'www.gnunet.org', IPv4 | 68 | # lookup 'www.gnunet.org', IPv4 |
67 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` | 69 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf` |
68 | # lookup 'www.gnunet.org', IPv6 | 70 | # lookup 'www.gnunet.org', IPv6 |
69 | RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf` | 71 | RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf | head -n1` |
70 | # lookup 'gnunet.org', IPv4 | 72 | # lookup 'gnunet.org', IPv4 |
71 | RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` | 73 | RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf` |
72 | # lookup 'docs.gnunet.org', IPv4 | 74 | # lookup 'docs.gnunet.org', IPv4 |
@@ -88,7 +90,7 @@ else | |||
88 | ret=1 | 90 | ret=1 |
89 | fi | 91 | fi |
90 | 92 | ||
91 | if [ "$RES_IP6" = "$TEST_IP6" ] | 93 | if [ "${RES_IP6%?}" = "${TEST_IP6%?}" ] |
92 | then | 94 | then |
93 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." | 95 | echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6." |
94 | else | 96 | else |
@@ -96,7 +98,7 @@ else | |||
96 | ret=1 | 98 | ret=1 |
97 | fi | 99 | fi |
98 | 100 | ||
99 | if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null | 101 | if echo "$RES_IP_ALT" | grep "$TEST_IP_ALT" > /dev/null |
100 | then | 102 | then |
101 | echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." | 103 | echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT." |
102 | else | 104 | else |
diff --git a/src/gns/test_gns_redirect_lookup.sh b/src/gns/test_gns_redirect_lookup.sh new file mode 100755 index 000000000..dfe5087ef --- /dev/null +++ b/src/gns/test_gns_redirect_lookup.sh | |||
@@ -0,0 +1,100 @@ | |||
1 | #!/bin/sh | ||
2 | # This file is in the public domain. | ||
3 | trap "gnunet-arm -e -c test_gns_lookup.conf" INT | ||
4 | |||
5 | LOCATION=$(which gnunet-config) | ||
6 | if [ -z $LOCATION ] | ||
7 | then | ||
8 | LOCATION="gnunet-config" | ||
9 | fi | ||
10 | $LOCATION --version 1> /dev/null | ||
11 | if test $? != 0 | ||
12 | then | ||
13 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
14 | exit 77 | ||
15 | fi | ||
16 | |||
17 | # permissive DNS resolver we will use for the test | ||
18 | DNS_RESOLVER="8.8.8.8" | ||
19 | if ! nslookup gnunet.org $DNS_RESOLVER > /dev/null 2>&1 | ||
20 | then | ||
21 | echo "Cannot reach DNS, skipping test" | ||
22 | exit 77 | ||
23 | fi | ||
24 | |||
25 | |||
26 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | ||
27 | |||
28 | TEST_IP_PLUS="127.0.0.1" | ||
29 | TEST_IP_DNS="131.159.74.67" | ||
30 | TEST_RECORD_REDIRECT_SERVER="server" | ||
31 | TEST_RECORD_REDIRECT_PLUS="server.+" | ||
32 | TEST_RECORD_REDIRECT_DNS="gnunet.org" | ||
33 | TEST_RECORD_NAME_SERVER="server" | ||
34 | TEST_RECORD_NAME_PLUS="www" | ||
35 | TEST_RECORD_NAME_ZKEY="www2" | ||
36 | TEST_RECORD_NAME_DNS="www3" | ||
37 | MY_EGO="myego" | ||
38 | TEST_DOMAIN_PLUS="www.$MY_EGO" | ||
39 | TEST_DOMAIN_ZKEY="www2.$MY_EGO" | ||
40 | TEST_DOMAIN_DNS="www3.$MY_EGO" | ||
41 | which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" | ||
42 | |||
43 | gnunet-arm -s -c test_gns_lookup.conf | ||
44 | gnunet-identity -C $MY_EGO -c test_gns_lookup.conf | ||
45 | MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}') | ||
46 | TEST_RECORD_REDIRECT_ZKEY="server.${MY_EGO_PKEY}" | ||
47 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_DNS -t REDIRECT -V $TEST_RECORD_REDIRECT_DNS -e never -c test_gns_lookup.conf | ||
48 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t REDIRECT -V $TEST_RECORD_REDIRECT_PLUS -e never -c test_gns_lookup.conf | ||
49 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_ZKEY -t REDIRECT -V $TEST_RECORD_REDIRECT_ZKEY -e never -c test_gns_lookup.conf | ||
50 | gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_REDIRECT_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf | ||
51 | gnunet-namestore -D -z $MY_EGO | ||
52 | RES_REDIRECT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` | ||
53 | RES_REDIRECT_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t REDIRECT -c test_gns_lookup.conf` | ||
54 | RES_REDIRECT_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf` | ||
55 | RES_REDIRECT_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS` | ||
56 | |||
57 | TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'` | ||
58 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_DNS -t REDIRECT -V $TEST_RECORD_REDIRECT_DNS -e never -c test_gns_lookup.conf | ||
59 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_PLUS -t REDIRECT -V $TEST_RECORD_REDIRECT_PLUS -e never -c test_gns_lookup.conf | ||
60 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_ZKEY -t REDIRECT -V $TEST_RECORD_REDIRECT_ZKEY -e never -c test_gns_lookup.conf | ||
61 | gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_REDIRECT_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf | ||
62 | gnunet-identity -D $MY_EGO -c test_gns_lookup.conf | ||
63 | gnunet-arm -e -c test_gns_lookup.conf | ||
64 | rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME` | ||
65 | |||
66 | # make cmp case-insensitive by converting to lower case first | ||
67 | RES_REDIRECT_RAW=`echo $RES_REDIRECT_RAW | tr [A-Z] [a-z]` | ||
68 | TESTEGOZONE=`echo $TESTEGOZONE | tr [A-Z] [a-z]` | ||
69 | if [ "$RES_REDIRECT_RAW" = "server.$TESTEGOZONE" ] | ||
70 | then | ||
71 | echo "PASS: REDIRECT resolution from GNS" | ||
72 | else | ||
73 | echo "FAIL: REDIRECT resolution from GNS, got $RES_REDIRECT_RAW, expected server.$TESTEGOZONE." | ||
74 | exit 1 | ||
75 | fi | ||
76 | |||
77 | if [ "$RES_REDIRECT" = "$TEST_IP_PLUS" ] | ||
78 | then | ||
79 | echo "PASS: IP resolution from GNS (.+)" | ||
80 | else | ||
81 | echo "FAIL: IP resolution from GNS (.+), got $RES_REDIRECT, expected $TEST_IP_PLUS." | ||
82 | exit 1 | ||
83 | fi | ||
84 | |||
85 | if [ "$RES_REDIRECT_ZKEY" = "$TEST_IP_PLUS" ] | ||
86 | then | ||
87 | echo "PASS: IP resolution from GNS (.zkey)" | ||
88 | else | ||
89 | echo "FAIL: IP resolution from GNS (.zkey), got $RES_REDIRECT, expected $TEST_IP_PLUS." | ||
90 | exit 1 | ||
91 | fi | ||
92 | |||
93 | if echo "$RES_REDIRECT_DNS" | grep "$TEST_IP_DNS" > /dev/null | ||
94 | then | ||
95 | echo "PASS: IP resolution from DNS" | ||
96 | exit 0 | ||
97 | else | ||
98 | echo "FAIL: IP resolution from DNS, got $RES_REDIRECT_DNS, expected $TEST_IP_DNS." | ||
99 | exit 1 | ||
100 | fi | ||
diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am index 4308d9c1a..e2538b1a2 100644 --- a/src/gnsrecord/Makefile.am +++ b/src/gnsrecord/Makefile.am | |||
@@ -20,7 +20,6 @@ check_PROGRAMS = \ | |||
20 | test_gnsrecord_crypto \ | 20 | test_gnsrecord_crypto \ |
21 | test_gnsrecord_serialization \ | 21 | test_gnsrecord_serialization \ |
22 | test_gnsrecord_block_expiration \ | 22 | test_gnsrecord_block_expiration \ |
23 | test_gnsrecord_testvectors \ | ||
24 | perf_gnsrecord_crypto | 23 | perf_gnsrecord_crypto |
25 | 24 | ||
26 | if ENABLE_TEST_RUN | 25 | if ENABLE_TEST_RUN |
@@ -35,7 +34,8 @@ lib_LTLIBRARIES = \ | |||
35 | libgnunetgnsrecordjson.la | 34 | libgnunetgnsrecordjson.la |
36 | 35 | ||
37 | gnunet_gnsrecord_tvg_SOURCES = \ | 36 | gnunet_gnsrecord_tvg_SOURCES = \ |
38 | gnunet-gnsrecord-tvg.c | 37 | gnunet-gnsrecord-tvg.c \ |
38 | gnsrecord_crypto.h | ||
39 | gnunet_gnsrecord_tvg_LDADD = \ | 39 | gnunet_gnsrecord_tvg_LDADD = \ |
40 | $(top_builddir)/src/util/libgnunetutil.la \ | 40 | $(top_builddir)/src/util/libgnunetutil.la \ |
41 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 41 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
@@ -86,13 +86,13 @@ libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \ | |||
86 | EXTRA_DIST = \ | 86 | EXTRA_DIST = \ |
87 | $(check_SCRIPTS) | 87 | $(check_SCRIPTS) |
88 | 88 | ||
89 | test_gnsrecord_testvectors_SOURCES = \ | 89 | #test_gnsrecord_testvectors_SOURCES = \ |
90 | test_gnsrecord_testvectors.c | 90 | # test_gnsrecord_testvectors.c |
91 | test_gnsrecord_testvectors_LDADD = \ | 91 | #test_gnsrecord_testvectors_LDADD = \ |
92 | $(top_builddir)/src/testing/libgnunettesting.la \ | 92 | # $(top_builddir)/src/testing/libgnunettesting.la \ |
93 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 93 | # $(top_builddir)/src/identity/libgnunetidentity.la \ |
94 | libgnunetgnsrecord.la \ | 94 | # libgnunetgnsrecord.la \ |
95 | $(top_builddir)/src/util/libgnunetutil.la | 95 | # $(top_builddir)/src/util/libgnunetutil.la |
96 | 96 | ||
97 | 97 | ||
98 | test_gnsrecord_serialization_SOURCES = \ | 98 | test_gnsrecord_serialization_SOURCES = \ |
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c index e9994a868..52c480ef6 100644 --- a/src/gnsrecord/gnsrecord.c +++ b/src/gnsrecord/gnsrecord.c | |||
@@ -260,4 +260,25 @@ GNUNET_GNSRECORD_number_to_typename (uint32_t type) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | 262 | ||
263 | enum GNUNET_GenericReturnValue | ||
264 | GNUNET_GNSRECORD_is_critical (uint32_t type) | ||
265 | { | ||
266 | struct Plugin *plugin; | ||
267 | |||
268 | if (GNUNET_GNSRECORD_TYPE_ANY == type) | ||
269 | return GNUNET_NO; | ||
270 | init (); | ||
271 | for (unsigned int i = 0; i < num_plugins; i++) | ||
272 | { | ||
273 | plugin = gns_plugins[i]; | ||
274 | if (NULL == plugin->api->is_critical) | ||
275 | continue; | ||
276 | if (GNUNET_NO == plugin->api->is_critical (plugin->api->cls, type)) | ||
277 | continue; | ||
278 | return GNUNET_YES; | ||
279 | } | ||
280 | return GNUNET_NO; | ||
281 | } | ||
282 | |||
283 | |||
263 | /* end of gnsrecord.c */ | 284 | /* end of gnsrecord.c */ |
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index 890ddb011..ff92911de 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -223,7 +223,6 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
223 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | 223 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
224 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; | 224 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
225 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 225 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
226 | uint32_t rd_count_nbo; | ||
227 | struct GNUNET_TIME_Absolute now; | 226 | struct GNUNET_TIME_Absolute now; |
228 | 227 | ||
229 | if (payload_len < 0) | 228 | if (payload_len < 0) |
@@ -254,7 +253,6 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
254 | /* serialize */ | 253 | /* serialize */ |
255 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | 254 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); |
256 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | 255 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); |
257 | rd_count_nbo = htonl (rd_count); | ||
258 | { | 256 | { |
259 | char payload[payload_len]; | 257 | char payload[payload_len]; |
260 | 258 | ||
@@ -282,12 +280,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
282 | label, | 280 | label, |
283 | ecblock->expiration_time.abs_value_us__, | 281 | ecblock->expiration_time.abs_value_us__, |
284 | pkey); | 282 | pkey); |
285 | GNUNET_break (payload_len == | 283 | GNUNET_assert (payload_len == |
286 | ecdsa_symmetric_encrypt (payload, | 284 | ecdsa_symmetric_encrypt (payload, |
287 | payload_len, | 285 | payload_len, |
288 | skey, | 286 | skey, |
289 | ctr, | 287 | ctr, |
290 | &ecblock[1])); | 288 | &ecblock[1])); |
291 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len); | 289 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len); |
292 | } | 290 | } |
293 | if (GNUNET_OK != | 291 | if (GNUNET_OK != |
@@ -298,8 +296,10 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
298 | GNUNET_break (0); | 296 | GNUNET_break (0); |
299 | GNUNET_free (*block); | 297 | GNUNET_free (*block); |
300 | GNUNET_free (dkey); | 298 | GNUNET_free (dkey); |
299 | GNUNET_free (gnr_block); | ||
301 | return GNUNET_SYSERR; | 300 | return GNUNET_SYSERR; |
302 | } | 301 | } |
302 | GNUNET_free (gnr_block); | ||
303 | GNUNET_free (dkey); | 303 | GNUNET_free (dkey); |
304 | return GNUNET_OK; | 304 | return GNUNET_OK; |
305 | } | 305 | } |
@@ -348,7 +348,6 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
348 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | 348 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; |
349 | unsigned char skey[crypto_secretbox_KEYBYTES]; | 349 | unsigned char skey[crypto_secretbox_KEYBYTES]; |
350 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 350 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
351 | uint32_t rd_count_nbo; | ||
352 | struct GNUNET_TIME_Absolute now; | 351 | struct GNUNET_TIME_Absolute now; |
353 | 352 | ||
354 | if (payload_len < 0) | 353 | if (payload_len < 0) |
@@ -381,7 +380,6 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
381 | + payload_len + crypto_secretbox_MACBYTES); | 380 | + payload_len + crypto_secretbox_MACBYTES); |
382 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) | 381 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) |
383 | + payload_len + crypto_secretbox_MACBYTES); | 382 | + payload_len + crypto_secretbox_MACBYTES); |
384 | rd_count_nbo = htonl (rd_count); | ||
385 | { | 383 | { |
386 | char payload[payload_len]; | 384 | char payload[payload_len]; |
387 | 385 | ||
@@ -415,12 +413,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
415 | label, | 413 | label, |
416 | edblock->expiration_time.abs_value_us__, | 414 | edblock->expiration_time.abs_value_us__, |
417 | pkey); | 415 | pkey); |
418 | GNUNET_break (GNUNET_OK == | 416 | GNUNET_assert (GNUNET_OK == |
419 | eddsa_symmetric_encrypt (payload, | 417 | eddsa_symmetric_encrypt (payload, |
420 | payload_len, | 418 | payload_len, |
421 | skey, | 419 | skey, |
422 | nonce, | 420 | nonce, |
423 | &edblock[1])); | 421 | &edblock[1])); |
424 | GNUNET_memcpy (&gnr_block[1], &edblock[1], | 422 | GNUNET_memcpy (&gnr_block[1], &edblock[1], |
425 | payload_len + crypto_secretbox_MACBYTES); | 423 | payload_len + crypto_secretbox_MACBYTES); |
426 | 424 | ||
@@ -438,7 +436,7 @@ GNUNET_GNSRECORD_block_calculate_size (const struct | |||
438 | unsigned int rd_count) | 436 | unsigned int rd_count) |
439 | { | 437 | { |
440 | struct GNUNET_IDENTITY_PublicKey pkey; | 438 | struct GNUNET_IDENTITY_PublicKey pkey; |
441 | ssize_t res; | 439 | ssize_t res = -1; |
442 | 440 | ||
443 | GNUNET_IDENTITY_key_get_public (key, | 441 | GNUNET_IDENTITY_key_get_public (key, |
444 | &pkey); | 442 | &pkey); |
@@ -453,7 +451,7 @@ GNUNET_GNSRECORD_block_calculate_size (const struct | |||
453 | default: | 451 | default: |
454 | GNUNET_assert (0); | 452 | GNUNET_assert (0); |
455 | } | 453 | } |
456 | return -1; | 454 | return res; |
457 | 455 | ||
458 | } | 456 | } |
459 | 457 | ||
@@ -593,8 +591,9 @@ GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) | |||
593 | purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len); | 591 | purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len); |
594 | purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len); | 592 | purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len); |
595 | purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | 593 | purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); |
596 | GNUNET_memcpy (&purp[1], &block[1], payload_len); | 594 | GNUNET_memcpy (&purp[1], |
597 | 595 | &block[1], | |
596 | payload_len); | ||
598 | switch (ntohl (block->type)) | 597 | switch (ntohl (block->type)) |
599 | { | 598 | { |
600 | case GNUNET_GNSRECORD_TYPE_PKEY: | 599 | case GNUNET_GNSRECORD_TYPE_PKEY: |
@@ -650,10 +649,10 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block, | |||
650 | char payload[payload_len]; | 649 | char payload[payload_len]; |
651 | unsigned int rd_count; | 650 | unsigned int rd_count; |
652 | 651 | ||
653 | GNUNET_break (payload_len == | 652 | GNUNET_assert (payload_len == |
654 | ecdsa_symmetric_decrypt (&block[1], payload_len, | 653 | ecdsa_symmetric_decrypt (&block[1], payload_len, |
655 | key, ctr, | 654 | key, ctr, |
656 | payload)); | 655 | payload)); |
657 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, | 656 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, |
658 | payload); | 657 | payload); |
659 | if (rd_count > 2048) | 658 | if (rd_count > 2048) |
@@ -754,7 +753,6 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block, | |||
754 | GNUNET_GNSRECORD_RecordCallback proc, | 753 | GNUNET_GNSRECORD_RecordCallback proc, |
755 | void *proc_cls) | 754 | void *proc_cls) |
756 | { | 755 | { |
757 | const struct GNUNET_GNSRECORD_EddsaBlock *edblock = &block->eddsa_block; | ||
758 | size_t payload_len = ntohl (block->size) - sizeof (struct | 756 | size_t payload_len = ntohl (block->size) - sizeof (struct |
759 | GNUNET_GNSRECORD_Block); | 757 | GNUNET_GNSRECORD_Block); |
760 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | 758 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; |
@@ -776,10 +774,10 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block, | |||
776 | char payload[payload_len]; | 774 | char payload[payload_len]; |
777 | unsigned int rd_count; | 775 | unsigned int rd_count; |
778 | 776 | ||
779 | GNUNET_break (GNUNET_OK == | 777 | GNUNET_assert (GNUNET_OK == |
780 | eddsa_symmetric_decrypt (&block[1], payload_len, | 778 | eddsa_symmetric_decrypt (&block[1], payload_len, |
781 | key, nonce, | 779 | key, nonce, |
782 | payload)); | 780 | payload)); |
783 | payload_len -= crypto_secretbox_MACBYTES; | 781 | payload_len -= crypto_secretbox_MACBYTES; |
784 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, | 782 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, |
785 | payload); | 783 | payload); |
@@ -909,7 +907,7 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
909 | proc_cls); | 907 | proc_cls); |
910 | break; | 908 | break; |
911 | default: | 909 | default: |
912 | return GNUNET_SYSERR; | 910 | res = GNUNET_SYSERR; |
913 | } | 911 | } |
914 | GNUNET_free (norm_label); | 912 | GNUNET_free (norm_label); |
915 | return res; | 913 | return res; |
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c index 61604c730..54d8fb860 100644 --- a/src/gnsrecord/gnsrecord_misc.c +++ b/src/gnsrecord/gnsrecord_misc.c | |||
@@ -38,23 +38,26 @@ | |||
38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) | 38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) |
39 | 39 | ||
40 | char * | 40 | char * |
41 | GNUNET_GNSRECORD_string_to_lowercase (const char *src) | 41 | GNUNET_GNSRECORD_string_normalize (const char *src) |
42 | { | 42 | { |
43 | char *res; | 43 | /*FIXME: We may want to follow RFC5890/RFC5891 */ |
44 | 44 | return GNUNET_STRINGS_utf8_normalize (src); | |
45 | res = GNUNET_strdup (src); | ||
46 | GNUNET_STRINGS_utf8_tolower (src, res); | ||
47 | return res; | ||
48 | } | 45 | } |
49 | 46 | ||
50 | char * | 47 | enum GNUNET_GenericReturnValue |
51 | GNUNET_GNSRECORD_string_normalize (const char *src) | 48 | GNUNET_GNSRECORD_label_check (const char*label, char **emsg) |
52 | { | 49 | { |
53 | char *res; | 50 | if (NULL == label) |
54 | res = GNUNET_strdup (src); | 51 | { |
55 | GNUNET_STRINGS_utf8_tolower (src, res); | 52 | *emsg = GNUNET_strdup (_ ("Label is NULL which is not allowed\n")); |
56 | GNUNET_STRINGS_utf8_normalize (src, res); | 53 | return GNUNET_NO; |
57 | return res; | 54 | } |
55 | if (0 != strchr (label, '.')) | ||
56 | { | ||
57 | *emsg = GNUNET_strdup (_ ("Label contains `.' which is not allowed\n")); | ||
58 | return GNUNET_NO; | ||
59 | } | ||
60 | return GNUNET_OK; | ||
58 | } | 61 | } |
59 | 62 | ||
60 | /** | 63 | /** |
@@ -144,19 +147,11 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, | |||
144 | } | 147 | } |
145 | 148 | ||
146 | 149 | ||
147 | /** | ||
148 | * Returns the expiration time of the given block of records. The block | ||
149 | * expiration time is the expiration time of the record with smallest | ||
150 | * expiration time. | ||
151 | * | ||
152 | * @param rd_count number of records given in @a rd | ||
153 | * @param rd array of records | ||
154 | * @return absolute expiration time | ||
155 | */ | ||
156 | struct GNUNET_TIME_Absolute | 150 | struct GNUNET_TIME_Absolute |
157 | GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, | 151 | GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, |
158 | const struct | 152 | const struct |
159 | GNUNET_GNSRECORD_Data *rd) | 153 | GNUNET_GNSRECORD_Data *rd, |
154 | struct GNUNET_TIME_Absolute min) | ||
160 | { | 155 | { |
161 | struct GNUNET_TIME_Absolute expire; | 156 | struct GNUNET_TIME_Absolute expire; |
162 | struct GNUNET_TIME_Absolute at; | 157 | struct GNUNET_TIME_Absolute at; |
@@ -164,8 +159,8 @@ GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, | |||
164 | struct GNUNET_TIME_Absolute at_shadow; | 159 | struct GNUNET_TIME_Absolute at_shadow; |
165 | struct GNUNET_TIME_Relative rt_shadow; | 160 | struct GNUNET_TIME_Relative rt_shadow; |
166 | 161 | ||
167 | if (NULL == rd) | 162 | if (0 == rd_count) |
168 | return GNUNET_TIME_UNIT_ZERO_ABS; | 163 | return GNUNET_TIME_absolute_max (GNUNET_TIME_UNIT_ZERO_ABS, min); |
169 | expire = GNUNET_TIME_UNIT_FOREVER_ABS; | 164 | expire = GNUNET_TIME_UNIT_FOREVER_ABS; |
170 | for (unsigned int c = 0; c < rd_count; c++) | 165 | for (unsigned int c = 0; c < rd_count; c++) |
171 | { | 166 | { |
@@ -202,6 +197,7 @@ GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, | |||
202 | expire = GNUNET_TIME_absolute_min (at, | 197 | expire = GNUNET_TIME_absolute_min (at, |
203 | expire); | 198 | expire); |
204 | } | 199 | } |
200 | expire = GNUNET_TIME_absolute_max (expire, min); | ||
205 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 201 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
206 | "Determined expiration time for block with %u records to be %s\n", | 202 | "Determined expiration time for block with %u records to be %s\n", |
207 | rd_count, | 203 | rd_count, |
@@ -284,12 +280,24 @@ GNUNET_GNSRECORD_identity_from_data (const char *data, | |||
284 | { | 280 | { |
285 | if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type)) | 281 | if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type)) |
286 | return GNUNET_SYSERR; | 282 | return GNUNET_SYSERR; |
287 | if (data_size > sizeof (struct GNUNET_IDENTITY_PublicKey)) | 283 | switch (type) |
288 | return GNUNET_SYSERR; | 284 | { |
289 | return (GNUNET_IDENTITY_read_key_from_buffer (key, data, data_size) == | 285 | case GNUNET_GNSRECORD_TYPE_PKEY: |
290 | data_size? | 286 | if (data_size > sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) |
291 | GNUNET_OK : | 287 | return GNUNET_SYSERR; |
292 | GNUNET_SYSERR); | 288 | memcpy (&key->ecdsa_key, data, data_size); |
289 | break; | ||
290 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
291 | if (data_size > sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) | ||
292 | return GNUNET_SYSERR; | ||
293 | memcpy (&key->eddsa_key, data, data_size); | ||
294 | break; | ||
295 | default: | ||
296 | return GNUNET_NO; | ||
297 | } | ||
298 | key->type = htonl (type); | ||
299 | |||
300 | return GNUNET_YES; | ||
293 | } | 301 | } |
294 | 302 | ||
295 | 303 | ||
@@ -302,16 +310,11 @@ GNUNET_GNSRECORD_data_from_identity (const struct | |||
302 | { | 310 | { |
303 | char *tmp; | 311 | char *tmp; |
304 | *type = ntohl (key->type); | 312 | *type = ntohl (key->type); |
305 | *data_size = GNUNET_IDENTITY_key_get_length (key); | 313 | *data_size = GNUNET_IDENTITY_key_get_length (key) - sizeof (key->type); |
306 | if (0 == *data_size) | 314 | if (0 == *data_size) |
307 | return GNUNET_SYSERR; | 315 | return GNUNET_SYSERR; |
308 | tmp = GNUNET_malloc (*data_size); | 316 | tmp = GNUNET_malloc (*data_size); |
309 | if (GNUNET_IDENTITY_write_key_to_buffer (key, tmp, *data_size) | 317 | memcpy (tmp, ((char*) key) + sizeof (key->type), *data_size); |
310 | != *data_size) { | ||
311 | GNUNET_free (tmp); | ||
312 | *data_size = 0; | ||
313 | return GNUNET_SYSERR; | ||
314 | } | ||
315 | *data = tmp; | 318 | *data = tmp; |
316 | return GNUNET_OK; | 319 | return GNUNET_OK; |
317 | } | 320 | } |
@@ -406,5 +409,176 @@ GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd, | |||
406 | 409 | ||
407 | } | 410 | } |
408 | 411 | ||
412 | enum GNUNET_GenericReturnValue | ||
413 | GNUNET_GNSRECORD_normalize_record_set (const char *label, | ||
414 | const struct | ||
415 | GNUNET_GNSRECORD_Data *rd, | ||
416 | unsigned int rd_count, | ||
417 | struct GNUNET_GNSRECORD_Data * | ||
418 | rd_public, | ||
419 | unsigned int *rd_count_public, | ||
420 | struct GNUNET_TIME_Absolute *expiry, | ||
421 | int include_private, | ||
422 | char **emsg) | ||
423 | { | ||
424 | struct GNUNET_TIME_Absolute now; | ||
425 | struct GNUNET_TIME_Absolute minimum_expiration; | ||
426 | int have_zone_delegation = GNUNET_NO; | ||
427 | int have_gns2dns = GNUNET_NO; | ||
428 | int have_other = GNUNET_NO; | ||
429 | int have_redirect = GNUNET_NO; | ||
430 | int have_empty_label = (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, label)); | ||
431 | unsigned int rd_count_tmp; | ||
432 | |||
433 | minimum_expiration = GNUNET_TIME_UNIT_ZERO_ABS; | ||
434 | now = GNUNET_TIME_absolute_get (); | ||
435 | rd_count_tmp = 0; | ||
436 | for (unsigned int i = 0; i < rd_count; i++) | ||
437 | { | ||
438 | /* Ignore the tombstone. For maintenance only. Remember expiration time. */ | ||
439 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
440 | { | ||
441 | minimum_expiration.abs_value_us = rd[i].expiration_time; | ||
442 | continue; | ||
443 | } | ||
444 | /* No NICK records unless empty label */ | ||
445 | if (have_empty_label && | ||
446 | (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type)) | ||
447 | continue; | ||
448 | |||
449 | /** | ||
450 | * Check for delegation and redirect consistency. | ||
451 | * Note that we check for consistency BEFORE we filter for | ||
452 | * private records ON PURPOSE. | ||
453 | * We also want consistent record sets in our local zone(s). | ||
454 | * The only exception is the tombstone (above) which we ignore | ||
455 | * for the consistency check(s). | ||
456 | * FIXME: What about shadow records? Should we ignore them? | ||
457 | */ | ||
458 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) | ||
459 | { | ||
460 | /* No delegation records under empty label*/ | ||
461 | if (have_empty_label) | ||
462 | { | ||
463 | *emsg = GNUNET_strdup (_ ( | ||
464 | "Zone delegation record not allowed in apex.")); | ||
465 | return GNUNET_SYSERR; | ||
466 | } | ||
467 | if ((GNUNET_YES == have_other) || | ||
468 | (GNUNET_YES == have_redirect) || | ||
469 | (GNUNET_YES == have_gns2dns)) | ||
470 | { | ||
471 | *emsg = GNUNET_strdup (_ ( | ||
472 | "Zone delegation record set contains mutually exclusive records.")); | ||
473 | return GNUNET_SYSERR; | ||
474 | } | ||
475 | have_zone_delegation = GNUNET_YES; | ||
476 | } | ||
477 | else if (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[i].record_type) | ||
478 | { | ||
479 | if (GNUNET_YES == have_redirect) | ||
480 | { | ||
481 | *emsg = GNUNET_strdup (_ ( | ||
482 | "Multiple REDIRECT records.")); | ||
483 | return GNUNET_SYSERR; | ||
484 | |||
485 | } | ||
486 | if ((GNUNET_YES == have_other) || | ||
487 | (GNUNET_YES == have_zone_delegation) || | ||
488 | (GNUNET_YES == have_gns2dns)) | ||
489 | { | ||
490 | *emsg = GNUNET_strdup (_ ( | ||
491 | "Redirection record set conains mutually exclusive records.")); | ||
492 | return GNUNET_SYSERR; | ||
493 | } | ||
494 | /* No redirection records under empty label*/ | ||
495 | if (have_empty_label) | ||
496 | { | ||
497 | *emsg = GNUNET_strdup (_ ( | ||
498 | "Redirection records not allowed in apex.")); | ||
499 | return GNUNET_SYSERR; | ||
500 | } | ||
501 | have_redirect = GNUNET_YES; | ||
502 | } | ||
503 | else if (GNUNET_GNSRECORD_TYPE_GNS2DNS == rd[i].record_type) | ||
504 | { | ||
505 | /* No gns2dns records under empty label*/ | ||
506 | if (have_empty_label) | ||
507 | { | ||
508 | *emsg = GNUNET_strdup (_ ( | ||
509 | "Redirection records not allowed in apex..")); | ||
510 | return GNUNET_SYSERR; | ||
511 | } | ||
512 | if ((GNUNET_YES == have_other) || | ||
513 | (GNUNET_YES == have_redirect) || | ||
514 | (GNUNET_YES == have_zone_delegation)) | ||
515 | { | ||
516 | *emsg = GNUNET_strdup (_ ( | ||
517 | "Redirection record set conains mutually exclusive records.")); | ||
518 | return GNUNET_SYSERR; | ||
519 | } | ||
520 | have_gns2dns = GNUNET_YES; | ||
521 | } | ||
522 | else | ||
523 | { | ||
524 | /* Some other record. | ||
525 | * Not allowed for zone delegations or redirections */ | ||
526 | if ((GNUNET_YES == have_zone_delegation) || | ||
527 | (GNUNET_YES == have_redirect) || | ||
528 | (GNUNET_YES == have_gns2dns)) | ||
529 | { | ||
530 | *emsg = GNUNET_strdup (_ ( | ||
531 | "Mutually exclusive records.")); | ||
532 | return GNUNET_SYSERR; | ||
533 | } | ||
534 | have_other = GNUNET_YES; | ||
535 | } | ||
536 | |||
537 | /* Ignore private records for public record set */ | ||
538 | |||
539 | if ((GNUNET_NO == include_private) && | ||
540 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))) | ||
541 | continue; | ||
542 | /* Skip expired records */ | ||
543 | if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && | ||
544 | (rd[i].expiration_time < now.abs_value_us)) | ||
545 | continue; /* record already expired, skip it */ | ||
546 | rd_public[rd_count_tmp] = rd[i]; | ||
547 | /* Make sure critical record types are marked as such */ | ||
548 | if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type)) | ||
549 | rd_public[rd_count_tmp].flags |= GNUNET_GNSRECORD_RF_CRITICAL; | ||
550 | rd_count_tmp++; | ||
551 | } | ||
552 | |||
553 | *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_count_tmp, | ||
554 | rd_public, | ||
555 | minimum_expiration); | ||
556 | *rd_count_public = rd_count_tmp; | ||
557 | return GNUNET_OK; | ||
558 | } | ||
559 | |||
560 | enum GNUNET_GenericReturnValue | ||
561 | GNUNET_GNSRECORD_convert_records_for_export (const char *label, | ||
562 | const struct | ||
563 | GNUNET_GNSRECORD_Data *rd, | ||
564 | unsigned int rd_count, | ||
565 | struct GNUNET_GNSRECORD_Data * | ||
566 | rd_public, | ||
567 | unsigned int *rd_count_public, | ||
568 | struct GNUNET_TIME_Absolute *expiry, | ||
569 | char **emsg) | ||
570 | { | ||
571 | return GNUNET_GNSRECORD_normalize_record_set (label, | ||
572 | rd, | ||
573 | rd_count, | ||
574 | rd_public, | ||
575 | rd_count_public, | ||
576 | expiry, | ||
577 | GNUNET_NO, | ||
578 | emsg); | ||
579 | |||
580 | } | ||
581 | |||
582 | |||
409 | 583 | ||
410 | /* end of gnsrecord_misc.c */ | 584 | /* end of gnsrecord_misc.c */ |
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c index f9b83e48b..87de32066 100644 --- a/src/gnsrecord/gnunet-gnsrecord-tvg.c +++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c | |||
@@ -33,9 +33,6 @@ | |||
33 | #include <inttypes.h> | 33 | #include <inttypes.h> |
34 | #include "gnsrecord_crypto.h" | 34 | #include "gnsrecord_crypto.h" |
35 | 35 | ||
36 | #define TEST_RECORD_LABEL "test" | ||
37 | #define TEST_RECORD_A "1.2.3.4" | ||
38 | #define TEST_RRCOUNT 2 | ||
39 | 36 | ||
40 | static char *d_pkey = | 37 | static char *d_pkey = |
41 | "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98"; | 38 | "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98"; |
@@ -43,7 +40,9 @@ static char *d_pkey = | |||
43 | static char *d_edkey = | 40 | static char *d_edkey = |
44 | "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65"; | 41 | "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65"; |
45 | 42 | ||
46 | int parsehex (char *src, char *dst, size_t dstlen, int invert) | 43 | |
44 | static int | ||
45 | parsehex (char *src, char *dst, size_t dstlen, int invert) | ||
47 | { | 46 | { |
48 | char *line = src; | 47 | char *line = src; |
49 | char *data = line; | 48 | char *data = line; |
@@ -83,6 +82,7 @@ print_bytes_ (void *buf, | |||
83 | printf ("\n"); | 82 | printf ("\n"); |
84 | } | 83 | } |
85 | 84 | ||
85 | |||
86 | static void | 86 | static void |
87 | print_bytes (void *buf, | 87 | print_bytes (void *buf, |
88 | size_t buf_len, | 88 | size_t buf_len, |
@@ -95,7 +95,7 @@ print_bytes (void *buf, | |||
95 | static void | 95 | static void |
96 | print_record (const struct GNUNET_GNSRECORD_Data *rd) | 96 | print_record (const struct GNUNET_GNSRECORD_Data *rd) |
97 | { | 97 | { |
98 | 98 | uint16_t flags = htons (rd->flags); | |
99 | fprintf (stdout, | 99 | fprintf (stdout, |
100 | "EXPIRATION: %" PRIu64 "\n", rd->expiration_time); | 100 | "EXPIRATION: %" PRIu64 "\n", rd->expiration_time); |
101 | fprintf (stdout, | 101 | fprintf (stdout, |
@@ -103,7 +103,9 @@ print_record (const struct GNUNET_GNSRECORD_Data *rd) | |||
103 | fprintf (stdout, | 103 | fprintf (stdout, |
104 | "TYPE: %d\n", rd->record_type); | 104 | "TYPE: %d\n", rd->record_type); |
105 | fprintf (stdout, | 105 | fprintf (stdout, |
106 | "FLAGS: %d\n", rd->flags); | 106 | "FLAGS: "); |
107 | print_bytes ((void*) &flags, sizeof (flags), 8); | ||
108 | printf ("\n"); | ||
107 | fprintf (stdout, | 109 | fprintf (stdout, |
108 | "DATA:\n"); | 110 | "DATA:\n"); |
109 | print_bytes ((char*) rd->data, rd->data_size, 8); | 111 | print_bytes ((char*) rd->data, rd->data_size, 8); |
@@ -120,15 +122,9 @@ print_record (const struct GNUNET_GNSRECORD_Data *rd) | |||
120 | * @param cfg configuration | 122 | * @param cfg configuration |
121 | */ | 123 | */ |
122 | static void | 124 | static void |
123 | run_pkey (void) | 125 | run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) |
124 | { | 126 | { |
125 | struct GNUNET_GNSRECORD_Data rd[2]; | ||
126 | struct GNUNET_TIME_Absolute expire; | 127 | struct GNUNET_TIME_Absolute expire; |
127 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
128 | struct GNUNET_TIME_Absolute exp1; | ||
129 | struct GNUNET_TIME_Absolute exp2; | ||
130 | struct GNUNET_TIME_Relative delta1; | ||
131 | struct GNUNET_TIME_Relative delta2; | ||
132 | struct GNUNET_GNSRECORD_Block *rrblock; | 128 | struct GNUNET_GNSRECORD_Block *rrblock; |
133 | char *bdata; | 129 | char *bdata; |
134 | struct GNUNET_IDENTITY_PrivateKey id_priv; | 130 | struct GNUNET_IDENTITY_PrivateKey id_priv; |
@@ -136,24 +132,12 @@ run_pkey (void) | |||
136 | struct GNUNET_IDENTITY_PrivateKey pkey_data_p; | 132 | struct GNUNET_IDENTITY_PrivateKey pkey_data_p; |
137 | struct GNUNET_IDENTITY_PublicKey pkey_data; | 133 | struct GNUNET_IDENTITY_PublicKey pkey_data; |
138 | struct GNUNET_HashCode query; | 134 | struct GNUNET_HashCode query; |
139 | void *data; | ||
140 | size_t data_size; | ||
141 | char *rdata; | 135 | char *rdata; |
142 | size_t rdata_size; | 136 | size_t rdata_size; |
143 | uint32_t rd_count_nbo; | ||
144 | char ztld[128]; | 137 | char ztld[128]; |
145 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | 138 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
146 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; | 139 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
147 | 140 | ||
148 | /* | ||
149 | * Make two different expiration times | ||
150 | */ | ||
151 | GNUNET_STRINGS_fancy_time_to_absolute ("2048-01-23 10:51:34", | ||
152 | &exp1); | ||
153 | GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01", | ||
154 | &exp2); | ||
155 | |||
156 | |||
157 | id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 141 | id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
158 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); | 142 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); |
159 | parsehex (d_pkey, | 143 | parsehex (d_pkey, |
@@ -168,13 +152,14 @@ run_pkey (void) | |||
168 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1); | 152 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1); |
169 | fprintf (stdout, "\n"); | 153 | fprintf (stdout, "\n"); |
170 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); | 154 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); |
155 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); | ||
171 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); | 156 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); |
172 | GNUNET_STRINGS_data_to_string (&id_pub, | 157 | GNUNET_STRINGS_data_to_string (&id_pub, |
173 | GNUNET_IDENTITY_key_get_length (&id_pub), | 158 | GNUNET_IDENTITY_key_get_length (&id_pub), |
174 | ztld, | 159 | ztld, |
175 | sizeof (ztld)); | 160 | sizeof (ztld)); |
176 | fprintf (stdout, "\n"); | 161 | fprintf (stdout, "\n"); |
177 | fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n"); | 162 | fprintf (stdout, "zTLD:\n"); |
178 | fprintf (stdout, "%s\n", ztld); | 163 | fprintf (stdout, "%s\n", ztld); |
179 | fprintf (stdout, "\n"); | 164 | fprintf (stdout, "\n"); |
180 | 165 | ||
@@ -183,39 +168,31 @@ run_pkey (void) | |||
183 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, | 168 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, |
184 | &pkey_data); | 169 | &pkey_data); |
185 | fprintf (stdout, | 170 | fprintf (stdout, |
186 | "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT); | 171 | "Label: %s\nRRCOUNT: %d\n\n", label, rd_count); |
187 | memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2); | ||
188 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value ( | ||
189 | GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size)); | ||
190 | rd[0].data = data; | ||
191 | rd[0].data_size = data_size; | ||
192 | rd[0].expiration_time = exp1.abs_value_us; | ||
193 | rd[0].record_type = GNUNET_DNSPARSER_TYPE_A; | ||
194 | fprintf (stdout, "Record #0\n"); | ||
195 | print_record (&rd[0]); | ||
196 | 172 | ||
197 | rd[1].data = "Some nick"; | 173 | for (int i = 0; i < rd_count; i++) |
198 | rd[1].data_size = sizeof (struct GNUNET_IDENTITY_PublicKey); | 174 | { |
199 | rd[1].expiration_time = exp2.abs_value_us; | 175 | fprintf (stdout, "Record #%d\n", i); |
200 | rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK; | 176 | print_record (&rd[i]); |
201 | rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; | 177 | } |
202 | fprintf (stdout, "Record #1\n"); | ||
203 | print_record (&rd[1]); | ||
204 | 178 | ||
205 | rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT, | 179 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
206 | rd); | 180 | rd); |
207 | rdata = GNUNET_malloc (rdata_size); | 181 | rdata = GNUNET_malloc (rdata_size); |
208 | GNUNET_GNSRECORD_records_serialize (2, | 182 | GNUNET_GNSRECORD_records_serialize (rd_count, |
209 | rd, | 183 | rd, |
210 | rdata_size, | 184 | (size_t) rdata_size, |
211 | rdata); | 185 | rdata); |
212 | fprintf (stdout, "RDATA:\n"); | 186 | fprintf (stdout, "RDATA:\n"); |
213 | print_bytes (rdata, rdata_size, 8); | 187 | print_bytes (rdata, |
188 | (size_t) rdata_size, | ||
189 | 8); | ||
214 | fprintf (stdout, "\n"); | 190 | fprintf (stdout, "\n"); |
215 | expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT, rd); | 191 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, rd, |
192 | GNUNET_TIME_UNIT_ZERO_ABS); | ||
216 | GNR_derive_block_aes_key (ctr, | 193 | GNR_derive_block_aes_key (ctr, |
217 | skey, | 194 | skey, |
218 | TEST_RECORD_LABEL, | 195 | label, |
219 | GNUNET_TIME_absolute_hton ( | 196 | GNUNET_TIME_absolute_hton ( |
220 | expire).abs_value_us__, | 197 | expire).abs_value_us__, |
221 | &id_pub.ecdsa_key); | 198 | &id_pub.ecdsa_key); |
@@ -227,25 +204,26 @@ run_pkey (void) | |||
227 | print_bytes (skey, sizeof (skey), 8); | 204 | print_bytes (skey, sizeof (skey), 8); |
228 | fprintf (stdout, "\n"); | 205 | fprintf (stdout, "\n"); |
229 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, | 206 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, |
230 | TEST_RECORD_LABEL, | 207 | label, |
231 | &query); | 208 | &query); |
232 | fprintf (stdout, "Storage key (q):\n"); | 209 | fprintf (stdout, "Storage key (q):\n"); |
233 | print_bytes (&query, sizeof (query), 8); | 210 | print_bytes (&query, sizeof (query), 8); |
234 | fprintf (stdout, "\n"); | 211 | fprintf (stdout, "\n"); |
235 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, | 212 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, |
236 | expire, | 213 | expire, |
237 | TEST_RECORD_LABEL, | 214 | label, |
238 | rd, | 215 | rd, |
239 | TEST_RRCOUNT, | 216 | rd_count, |
240 | &rrblock)); | 217 | &rrblock)); |
241 | size_t bdata_size = ntohl(rrblock->size) - sizeof (struct GNUNET_GNSRECORD_Block); | 218 | size_t bdata_size = ntohl (rrblock->size) - sizeof (struct |
219 | GNUNET_GNSRECORD_Block); | ||
242 | 220 | ||
243 | bdata = (char*) &(&rrblock->ecdsa_block)[1]; | 221 | bdata = (char*) &(&rrblock->ecdsa_block)[1]; |
244 | fprintf (stdout, "BDATA:\n"); | 222 | fprintf (stdout, "BDATA:\n"); |
245 | print_bytes (bdata, bdata_size, 8); | 223 | print_bytes (bdata, bdata_size, 8); |
246 | fprintf (stdout, "\n"); | 224 | fprintf (stdout, "\n"); |
247 | fprintf (stdout, "RRBLOCK:\n"); | 225 | fprintf (stdout, "RRBLOCK:\n"); |
248 | print_bytes (rrblock, ntohl(rrblock->size), 8); | 226 | print_bytes (rrblock, ntohl (rrblock->size), 8); |
249 | fprintf (stdout, "\n"); | 227 | fprintf (stdout, "\n"); |
250 | GNUNET_free (rdata); | 228 | GNUNET_free (rdata); |
251 | } | 229 | } |
@@ -260,15 +238,9 @@ run_pkey (void) | |||
260 | * @param cfg configuration | 238 | * @param cfg configuration |
261 | */ | 239 | */ |
262 | static void | 240 | static void |
263 | run_edkey (void) | 241 | run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label) |
264 | { | 242 | { |
265 | struct GNUNET_GNSRECORD_Data rd[2]; | ||
266 | struct GNUNET_TIME_Absolute expire; | 243 | struct GNUNET_TIME_Absolute expire; |
267 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | ||
268 | struct GNUNET_TIME_Absolute exp1; | ||
269 | struct GNUNET_TIME_Absolute exp2; | ||
270 | struct GNUNET_TIME_Relative delta1; | ||
271 | struct GNUNET_TIME_Relative delta2; | ||
272 | struct GNUNET_GNSRECORD_Block *rrblock; | 244 | struct GNUNET_GNSRECORD_Block *rrblock; |
273 | char *bdata; | 245 | char *bdata; |
274 | struct GNUNET_IDENTITY_PrivateKey id_priv; | 246 | struct GNUNET_IDENTITY_PrivateKey id_priv; |
@@ -276,23 +248,13 @@ run_edkey (void) | |||
276 | struct GNUNET_IDENTITY_PrivateKey pkey_data_p; | 248 | struct GNUNET_IDENTITY_PrivateKey pkey_data_p; |
277 | struct GNUNET_IDENTITY_PublicKey pkey_data; | 249 | struct GNUNET_IDENTITY_PublicKey pkey_data; |
278 | struct GNUNET_HashCode query; | 250 | struct GNUNET_HashCode query; |
279 | void *data; | ||
280 | size_t data_size; | ||
281 | char *rdata; | 251 | char *rdata; |
282 | size_t rdata_size; | 252 | size_t rdata_size; |
283 | uint32_t rd_count_nbo; | 253 | |
284 | char ztld[128]; | 254 | char ztld[128]; |
285 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | 255 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; |
286 | unsigned char skey[crypto_secretbox_KEYBYTES]; | 256 | unsigned char skey[crypto_secretbox_KEYBYTES]; |
287 | 257 | ||
288 | /* | ||
289 | * Make two different expiration times | ||
290 | */ | ||
291 | GNUNET_STRINGS_fancy_time_to_absolute ("%2048-01-23 10:51:34", | ||
292 | &exp1); | ||
293 | GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01", | ||
294 | &exp2); | ||
295 | |||
296 | id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 258 | id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
297 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); | 259 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); |
298 | GNUNET_IDENTITY_key_get_public (&id_priv, | 260 | GNUNET_IDENTITY_key_get_public (&id_priv, |
@@ -311,13 +273,14 @@ run_edkey (void) | |||
311 | GNUNET_CRYPTO_EddsaPrivateKey), 8); | 273 | GNUNET_CRYPTO_EddsaPrivateKey), 8); |
312 | fprintf (stdout, "\n"); | 274 | fprintf (stdout, "\n"); |
313 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); | 275 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); |
276 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); | ||
314 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); | 277 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); |
315 | GNUNET_STRINGS_data_to_string (&id_pub, | 278 | GNUNET_STRINGS_data_to_string (&id_pub, |
316 | GNUNET_IDENTITY_key_get_length (&id_pub), | 279 | GNUNET_IDENTITY_key_get_length (&id_pub), |
317 | ztld, | 280 | ztld, |
318 | sizeof (ztld)); | 281 | sizeof (ztld)); |
319 | fprintf (stdout, "\n"); | 282 | fprintf (stdout, "\n"); |
320 | fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n"); | 283 | fprintf (stdout, "zTLD:\n"); |
321 | fprintf (stdout, "%s\n", ztld); | 284 | fprintf (stdout, "%s\n", ztld); |
322 | fprintf (stdout, "\n"); | 285 | fprintf (stdout, "\n"); |
323 | 286 | ||
@@ -326,40 +289,33 @@ run_edkey (void) | |||
326 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, | 289 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, |
327 | &pkey_data); | 290 | &pkey_data); |
328 | fprintf (stdout, | 291 | fprintf (stdout, |
329 | "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT); | 292 | "Label: %s\nRRCOUNT: %d\n\n", label, rd_count); |
330 | memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2); | ||
331 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value ( | ||
332 | GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size)); | ||
333 | rd[0].data = data; | ||
334 | rd[0].data_size = data_size; | ||
335 | rd[0].expiration_time = exp1.abs_value_us; | ||
336 | rd[0].record_type = GNUNET_DNSPARSER_TYPE_A; | ||
337 | fprintf (stdout, "Record #0\n"); | ||
338 | print_record (&rd[0]); | ||
339 | 293 | ||
340 | rd[1].data = "My Nick"; | 294 | for (int i = 0; i < rd_count; i++) |
341 | rd[1].data_size = sizeof (struct GNUNET_IDENTITY_PublicKey); | 295 | { |
342 | rd[1].expiration_time = exp2.abs_value_us; | 296 | fprintf (stdout, "Record #%d\n", i); |
343 | rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK; | 297 | print_record (&rd[i]); |
344 | rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; | 298 | } |
345 | fprintf (stdout, "Record #1\n"); | ||
346 | print_record (&rd[1]); | ||
347 | 299 | ||
348 | rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT, | 300 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
349 | rd); | 301 | rd); |
350 | expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT, | 302 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, |
351 | rd); | 303 | rd, |
352 | rdata = GNUNET_malloc (rdata_size); | 304 | GNUNET_TIME_UNIT_ZERO_ABS); |
353 | GNUNET_GNSRECORD_records_serialize (2, | 305 | GNUNET_assert (0 < rdata_size); |
306 | rdata = GNUNET_malloc ((size_t) rdata_size); | ||
307 | GNUNET_GNSRECORD_records_serialize (rd_count, | ||
354 | rd, | 308 | rd, |
355 | rdata_size, | 309 | (size_t) rdata_size, |
356 | rdata); | 310 | rdata); |
357 | fprintf (stdout, "RDATA:\n"); | 311 | fprintf (stdout, "RDATA:\n"); |
358 | print_bytes (rdata, rdata_size, 8); | 312 | print_bytes (rdata, |
313 | (size_t) rdata_size, | ||
314 | 8); | ||
359 | fprintf (stdout, "\n"); | 315 | fprintf (stdout, "\n"); |
360 | GNR_derive_block_xsalsa_key (nonce, | 316 | GNR_derive_block_xsalsa_key (nonce, |
361 | skey, | 317 | skey, |
362 | TEST_RECORD_LABEL, | 318 | label, |
363 | GNUNET_TIME_absolute_hton ( | 319 | GNUNET_TIME_absolute_hton ( |
364 | expire).abs_value_us__, | 320 | expire).abs_value_us__, |
365 | &id_pub.eddsa_key); | 321 | &id_pub.eddsa_key); |
@@ -370,7 +326,7 @@ run_edkey (void) | |||
370 | print_bytes (skey, sizeof (skey), 8); | 326 | print_bytes (skey, sizeof (skey), 8); |
371 | fprintf (stdout, "\n"); | 327 | fprintf (stdout, "\n"); |
372 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, | 328 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, |
373 | TEST_RECORD_LABEL, | 329 | label, |
374 | &query); | 330 | &query); |
375 | fprintf (stdout, "Storage key (q):\n"); | 331 | fprintf (stdout, "Storage key (q):\n"); |
376 | print_bytes (&query, sizeof (query), 8); | 332 | print_bytes (&query, sizeof (query), 8); |
@@ -378,18 +334,19 @@ run_edkey (void) | |||
378 | 334 | ||
379 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, | 335 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, |
380 | expire, | 336 | expire, |
381 | TEST_RECORD_LABEL, | 337 | label, |
382 | rd, | 338 | rd, |
383 | TEST_RRCOUNT, | 339 | rd_count, |
384 | &rrblock)); | 340 | &rrblock)); |
385 | size_t bdata_size = ntohl(rrblock->size) - sizeof (struct GNUNET_GNSRECORD_Block); | 341 | size_t bdata_size = ntohl (rrblock->size) - sizeof (struct |
342 | GNUNET_GNSRECORD_Block); | ||
386 | 343 | ||
387 | bdata = (char*) &(&rrblock->eddsa_block)[1]; | 344 | bdata = (char*) &(&rrblock->eddsa_block)[1]; |
388 | fprintf (stdout, "BDATA:\n"); | 345 | fprintf (stdout, "BDATA:\n"); |
389 | print_bytes (bdata, bdata_size, 8); | 346 | print_bytes (bdata, bdata_size, 8); |
390 | fprintf (stdout, "\n"); | 347 | fprintf (stdout, "\n"); |
391 | fprintf (stdout, "RRBLOCK:\n"); | 348 | fprintf (stdout, "RRBLOCK:\n"); |
392 | print_bytes (rrblock, ntohl(rrblock->size), 8); | 349 | print_bytes (rrblock, ntohl (rrblock->size), 8); |
393 | fprintf (stdout, "\n"); | 350 | fprintf (stdout, "\n"); |
394 | GNUNET_free (rdata); | 351 | GNUNET_free (rdata); |
395 | } | 352 | } |
@@ -409,8 +366,67 @@ run (void *cls, | |||
409 | const char *cfgfile, | 366 | const char *cfgfile, |
410 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 367 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
411 | { | 368 | { |
412 | run_pkey (); | 369 | struct GNUNET_GNSRECORD_Data rd_pkey; |
413 | run_edkey (); | 370 | struct GNUNET_GNSRECORD_Data rd[3]; |
371 | struct GNUNET_TIME_Absolute exp1; | ||
372 | struct GNUNET_TIME_Absolute exp2; | ||
373 | struct GNUNET_TIME_Relative exp3; | ||
374 | size_t pkey_data_size; | ||
375 | size_t ip_data_size; | ||
376 | char *pkey_data; | ||
377 | char *ip_data; | ||
378 | |||
379 | /* | ||
380 | * Make different expiration times | ||
381 | */ | ||
382 | GNUNET_STRINGS_fancy_time_to_absolute ("2048-01-23 10:51:34", | ||
383 | &exp1); | ||
384 | GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01", | ||
385 | &exp2); | ||
386 | GNUNET_STRINGS_fancy_time_to_relative ("100y", | ||
387 | &exp3); | ||
388 | |||
389 | |||
390 | memset (&rd_pkey, 0, sizeof (struct GNUNET_GNSRECORD_Data)); | ||
391 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value ( | ||
392 | GNUNET_GNSRECORD_TYPE_PKEY, | ||
393 | "000G0011WESGZY9VRV9NNJ66W3GKNZFZF56BFD2BQF3MHMJST2G2GKDYGG", | ||
394 | (void**) &pkey_data, | ||
395 | &pkey_data_size)); | ||
396 | rd_pkey.data = pkey_data; | ||
397 | rd_pkey.data_size = pkey_data_size; | ||
398 | rd_pkey.expiration_time = exp1.abs_value_us; | ||
399 | rd_pkey.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | ||
400 | rd_pkey.flags = GNUNET_GNSRECORD_RF_CRITICAL; | ||
401 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value ( | ||
402 | GNUNET_DNSPARSER_TYPE_AAAA, | ||
403 | "::dead:beef", | ||
404 | (void**) &ip_data, | ||
405 | &ip_data_size)); | ||
406 | |||
407 | rd[0].data = ip_data; | ||
408 | rd[0].data_size = ip_data_size; | ||
409 | rd[0].expiration_time = exp1.abs_value_us; | ||
410 | rd[0].record_type = GNUNET_DNSPARSER_TYPE_AAAA; | ||
411 | rd[0].flags = GNUNET_GNSRECORD_RF_NONE; | ||
412 | |||
413 | rd[1].data = "\u611b\u79f0"; | ||
414 | rd[1].data_size = strlen (rd[1].data); | ||
415 | rd[1].expiration_time = exp2.abs_value_us; | ||
416 | rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK; | ||
417 | rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; | ||
418 | |||
419 | rd[2].data = "Hello World"; | ||
420 | rd[2].data_size = strlen (rd[2].data); | ||
421 | rd[2].expiration_time = exp3.rel_value_us; | ||
422 | rd[2].record_type = GNUNET_DNSPARSER_TYPE_TXT; | ||
423 | rd[2].flags = GNUNET_GNSRECORD_RF_SUPPLEMENTAL | ||
424 | | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
425 | |||
426 | run_pkey (&rd_pkey, 1, "testdelegation"); | ||
427 | run_pkey (rd, 3, "namesystem"); | ||
428 | run_edkey (&rd_pkey, 1, "testdelegation"); | ||
429 | run_edkey (rd, 3, "namesystem"); | ||
414 | } | 430 | } |
415 | 431 | ||
416 | 432 | ||
diff --git a/src/gnsrecord/perf_gnsrecord_crypto.c b/src/gnsrecord/perf_gnsrecord_crypto.c index d9a3c20cf..6b5f84235 100644 --- a/src/gnsrecord/perf_gnsrecord_crypto.c +++ b/src/gnsrecord/perf_gnsrecord_crypto.c | |||
@@ -90,12 +90,12 @@ run (void *cls, | |||
90 | start_time = GNUNET_TIME_absolute_get (); | 90 | start_time = GNUNET_TIME_absolute_get (); |
91 | for (unsigned int i = 0; i < ROUNDS; i++) | 91 | for (unsigned int i = 0; i < ROUNDS; i++) |
92 | { | 92 | { |
93 | GNUNET_assert (NULL != (block = | 93 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (&privkey, |
94 | GNUNET_GNSRECORD_block_create2 (&privkey, | ||
95 | expire, | 94 | expire, |
96 | s_name, | 95 | s_name, |
97 | s_rd, | 96 | s_rd, |
98 | RECORDS))); | 97 | RECORDS, |
98 | &block)); | ||
99 | GNUNET_GNSRECORD_query_from_private_key (&privkey, | 99 | GNUNET_GNSRECORD_query_from_private_key (&privkey, |
100 | s_name, | 100 | s_name, |
101 | &query); | 101 | &query); |
diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c index 123c59905..649133cd1 100644 --- a/src/gnsrecord/plugin_gnsrecord_dns.c +++ b/src/gnsrecord/plugin_gnsrecord_dns.c | |||
@@ -773,6 +773,12 @@ dns_number_to_typename (void *cls, uint32_t type) | |||
773 | } | 773 | } |
774 | 774 | ||
775 | 775 | ||
776 | static enum GNUNET_GenericReturnValue | ||
777 | dns_is_critical (void *cls, uint32_t type) | ||
778 | { | ||
779 | return GNUNET_NO; | ||
780 | } | ||
781 | |||
776 | /** | 782 | /** |
777 | * Entry point for the plugin. | 783 | * Entry point for the plugin. |
778 | * | 784 | * |
@@ -789,6 +795,7 @@ libgnunet_plugin_gnsrecord_dns_init (void *cls) | |||
789 | api->string_to_value = &dns_string_to_value; | 795 | api->string_to_value = &dns_string_to_value; |
790 | api->typename_to_number = &dns_typename_to_number; | 796 | api->typename_to_number = &dns_typename_to_number; |
791 | api->number_to_typename = &dns_number_to_typename; | 797 | api->number_to_typename = &dns_number_to_typename; |
798 | api->is_critical = &dns_is_critical; | ||
792 | return api; | 799 | return api; |
793 | } | 800 | } |
794 | 801 | ||
diff --git a/src/gnsrecord/test_gnsrecord_block_expiration.c b/src/gnsrecord/test_gnsrecord_block_expiration.c index b53d7d7e8..d14ce3914 100644 --- a/src/gnsrecord/test_gnsrecord_block_expiration.c +++ b/src/gnsrecord/test_gnsrecord_block_expiration.c | |||
@@ -72,7 +72,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
72 | 72 | ||
73 | GNUNET_assert (expiration_abs.abs_value_us == | 73 | GNUNET_assert (expiration_abs.abs_value_us == |
74 | GNUNET_GNSRECORD_record_get_expiration_time (2, | 74 | GNUNET_GNSRECORD_record_get_expiration_time (2, |
75 | rd).abs_value_us); | 75 | rd, |
76 | GNUNET_TIME_UNIT_ZERO_ABS).abs_value_us); | ||
76 | 77 | ||
77 | rd[1].expiration_time = expiration_abs_shadow.abs_value_us; | 78 | rd[1].expiration_time = expiration_abs_shadow.abs_value_us; |
78 | rd[1].record_type = TEST_RECORD_TYPE; | 79 | rd[1].record_type = TEST_RECORD_TYPE; |
@@ -83,7 +84,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
83 | 84 | ||
84 | GNUNET_assert (expiration_abs_shadow.abs_value_us == | 85 | GNUNET_assert (expiration_abs_shadow.abs_value_us == |
85 | GNUNET_GNSRECORD_record_get_expiration_time (2, | 86 | GNUNET_GNSRECORD_record_get_expiration_time (2, |
86 | rd).abs_value_us); | 87 | rd, |
88 | GNUNET_TIME_UNIT_ZERO_ABS).abs_value_us); | ||
87 | res = 0; | 89 | res = 0; |
88 | } | 90 | } |
89 | 91 | ||
diff --git a/src/gnsrecord/test_gnsrecord_testvectors.c b/src/gnsrecord/test_gnsrecord_testvectors.c index 153c56261..bb4922417 100644 --- a/src/gnsrecord/test_gnsrecord_testvectors.c +++ b/src/gnsrecord/test_gnsrecord_testvectors.c | |||
@@ -10,16 +10,16 @@ | |||
10 | 10 | ||
11 | 11 | ||
12 | static char *d = | 12 | static char *d = |
13 | "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98"; | 13 | "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98"; |
14 | 14 | ||
15 | 15 | ||
16 | static char *zid = | 16 | static char *zid = |
17 | "00010000677c477d2d93097c85b195c6f96d84ff61f5982c2c4fe02d5a11fedfb0c2901f"; | 17 | "00010000677c477d2d93097c85b195c6f96d84ff61f5982c2c4fe02d5a11fedfb0c2901f"; |
18 | 18 | ||
19 | #define RRCOUNT 2 | 19 | #define RRCOUNT 2 |
20 | #define LABEL "test" | 20 | #define LABEL "namesystem" |
21 | 21 | ||
22 | #define R0_EXPIRATION 14888744139323793 | 22 | #define R0_EXPIRATION |
23 | #define R0_DATA_SIZE 4 | 23 | #define R0_DATA_SIZE 4 |
24 | #define R0_TYPE 1 | 24 | #define R0_TYPE 1 |
25 | #define R0_FLAGS 0 | 25 | #define R0_FLAGS 0 |
@@ -31,12 +31,12 @@ static char *zid = | |||
31 | #define R1_TYPE 65536 | 31 | #define R1_TYPE 65536 |
32 | #define R1_FLAGS 2 | 32 | #define R1_FLAGS 2 |
33 | #define R1_DATA \ | 33 | #define R1_DATA \ |
34 | "000100000e601be42eb57fb4697610cf3a3b18347b65a33f025b5b174abefb30807bfecf" | 34 | "000100000e601be42eb57fb4697610cf3a3b18347b65a33f025b5b174abefb30807bfecf" |
35 | 35 | ||
36 | #define R1_RRBLOCK \ | 36 | #define R1_RRBLOCK \ |
37 | "000100008e16da87203b5159c5538e9b765742e968c54af9afbc0890dc80205ad14c84e107b0c115fc0089aa38b9c7ab9cbe1d77040d282a51a2ad493f61f3495f02d8170fe473a55ec6bdf9a509ab1701ffc37ea3bb4cac4a672520986df96e67cc1a73000000940000000f0034e53be193799100e4837eb5d04f92903de4b5234e8ccac5736c9793379a59c33375fc8951aca2eb7aad067bf9af60bf26758646a17f5e5c3b6215f94079545b1c4d4f1b2ebb22c2b4dad44126817b6f001530d476401dd67ac0148554e806353da9e4298079f3e1b16942c48d90c4360c61238c40d9d52911aea52cc0037ac7160bb3cf5b2f4a722fd96b" | 37 | "000100008e16da87203b5159c5538e9b765742e968c54af9afbc0890dc80205ad14c84e107b0c115fc0089aa38b9c7ab9cbe1d77040d282a51a2ad493f61f3495f02d8170fe473a55ec6bdf9a509ab1701ffc37ea3bb4cac4a672520986df96e67cc1a73000000940000000f0034e53be193799100e4837eb5d04f92903de4b5234e8ccac5736c9793379a59c33375fc8951aca2eb7aad067bf9af60bf26758646a17f5e5c3b6215f94079545b1c4d4f1b2ebb22c2b4dad44126817b6f001530d476401dd67ac0148554e806353da9e4298079f3e1b16942c48d90c4360c61238c40d9d52911aea52cc0037ac7160bb3cf5b2f4a722fd96b" |
38 | 38 | ||
39 | int parsehex(char *src, char *dst, size_t dstlen, int invert) | 39 | int parsehex (char *src, char *dst, size_t dstlen, int invert) |
40 | { | 40 | { |
41 | char *line = src; | 41 | char *line = src; |
42 | char *data = line; | 42 | char *data = line; |
@@ -44,7 +44,8 @@ int parsehex(char *src, char *dst, size_t dstlen, int invert) | |||
44 | int read_byte; | 44 | int read_byte; |
45 | int data_len = 0; | 45 | int data_len = 0; |
46 | 46 | ||
47 | while (sscanf(data, " %02x%n", &read_byte, &off) == 1) { | 47 | while (sscanf (data, " %02x%n", &read_byte, &off) == 1) |
48 | { | ||
48 | if (invert) | 49 | if (invert) |
49 | dst[dstlen - 1 - data_len++] = read_byte; | 50 | dst[dstlen - 1 - data_len++] = read_byte; |
50 | else | 51 | else |
@@ -62,8 +63,8 @@ res_checker (void *cls, | |||
62 | int r1_found = 0; | 63 | int r1_found = 0; |
63 | char r0_data[R0_DATA_SIZE]; | 64 | char r0_data[R0_DATA_SIZE]; |
64 | char r1_data[R1_DATA_SIZE]; | 65 | char r1_data[R1_DATA_SIZE]; |
65 | parsehex(R0_DATA, (char*)r0_data, 0, 0); | 66 | parsehex (R0_DATA, (char*) r0_data, 0, 0); |
66 | parsehex(R1_DATA, (char*)r1_data, 0, 0); | 67 | parsehex (R1_DATA, (char*) r1_data, 0, 0); |
67 | GNUNET_assert (rd_count == RRCOUNT); | 68 | GNUNET_assert (rd_count == RRCOUNT); |
68 | for (int i = 0; i < RRCOUNT; i++) | 69 | for (int i = 0; i < RRCOUNT; i++) |
69 | { | 70 | { |
@@ -104,7 +105,7 @@ res_checker (void *cls, | |||
104 | 105 | ||
105 | 106 | ||
106 | int | 107 | int |
107 | main() | 108 | main () |
108 | { | 109 | { |
109 | struct GNUNET_IDENTITY_PrivateKey priv; | 110 | struct GNUNET_IDENTITY_PrivateKey priv; |
110 | struct GNUNET_IDENTITY_PublicKey pub; | 111 | struct GNUNET_IDENTITY_PublicKey pub; |
@@ -112,13 +113,15 @@ main() | |||
112 | struct GNUNET_GNSRECORD_Block *rrblock; | 113 | struct GNUNET_GNSRECORD_Block *rrblock; |
113 | char *bdata; | 114 | char *bdata; |
114 | 115 | ||
115 | parsehex(d,(char*)&priv.ecdsa_key, sizeof (priv.ecdsa_key), 1); | 116 | parsehex (d,(char*) &priv.ecdsa_key, sizeof (priv.ecdsa_key), 1); |
116 | priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 117 | priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
117 | parsehex(zid,(char*)&pub_parsed, 0, 0); | 118 | parsehex (zid,(char*) &pub_parsed, 0, 0); |
118 | GNUNET_IDENTITY_key_get_public(&priv, &pub); | 119 | GNUNET_IDENTITY_key_get_public (&priv, &pub); |
119 | GNUNET_assert (0 == memcmp (&pub, &pub_parsed, sizeof (pub))); | 120 | GNUNET_assert (0 == memcmp (&pub, &pub_parsed, sizeof (pub))); |
120 | rrblock = GNUNET_malloc (strlen (R1_RRBLOCK) / 2); | 121 | rrblock = GNUNET_malloc (strlen (R1_RRBLOCK) / 2); |
121 | parsehex(R1_RRBLOCK, (char*)rrblock, 0, 0); | 122 | parsehex (R1_RRBLOCK, (char*) rrblock, 0, 0); |
123 | GNUNET_assert (GNUNET_YES | ||
124 | == GNUNET_GNSRECORD_is_critical (GNUNET_GNSRECORD_TYPE_PKEY)); | ||
122 | GNUNET_GNSRECORD_block_decrypt (rrblock, | 125 | GNUNET_GNSRECORD_block_decrypt (rrblock, |
123 | &pub_parsed, | 126 | &pub_parsed, |
124 | LABEL, | 127 | LABEL, |
diff --git a/src/hello/.gitignore b/src/hello/.gitignore index bb49ceb20..d175d148e 100644 --- a/src/hello/.gitignore +++ b/src/hello/.gitignore | |||
@@ -1,3 +1,5 @@ | |||
1 | gnunet-hello | 1 | gnunet-hello |
2 | test_friend_hello | 2 | test_friend_hello |
3 | test_hello | 3 | test_hello |
4 | test_hello-uri | ||
5 | test_hello-ng | ||
diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am index 6a250e42f..c04b85106 100644 --- a/src/hello/Makefile.am +++ b/src/hello/Makefile.am | |||
@@ -11,7 +11,8 @@ lib_LTLIBRARIES = libgnunethello.la | |||
11 | libgnunethello_la_SOURCES = \ | 11 | libgnunethello_la_SOURCES = \ |
12 | hello.c \ | 12 | hello.c \ |
13 | address.c \ | 13 | address.c \ |
14 | hello-ng.c | 14 | hello-ng.c \ |
15 | hello-uri.c | ||
15 | libgnunethello_la_LIBADD = \ | 16 | libgnunethello_la_LIBADD = \ |
16 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ | 17 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ |
17 | $(LTLIBINTL) | 18 | $(LTLIBINTL) |
@@ -24,6 +25,7 @@ noinst_PROGRAMS = \ | |||
24 | 25 | ||
25 | check_PROGRAMS = \ | 26 | check_PROGRAMS = \ |
26 | test_hello \ | 27 | test_hello \ |
28 | test_hello-uri \ | ||
27 | test_friend_hello \ | 29 | test_friend_hello \ |
28 | test_hello-ng | 30 | test_hello-ng |
29 | 31 | ||
@@ -36,25 +38,32 @@ test_hello_SOURCES = \ | |||
36 | test_hello.c | 38 | test_hello.c |
37 | test_hello_LDADD = \ | 39 | test_hello_LDADD = \ |
38 | libgnunethello.la \ | 40 | libgnunethello.la \ |
39 | $(top_builddir)/src/util/libgnunetutil.la | 41 | $(top_builddir)/src/util/libgnunetutil.la |
40 | 42 | ||
41 | test_hello_ng_SOURCES = \ | 43 | test_hello_ng_SOURCES = \ |
42 | test_hello-ng.c | 44 | test_hello-ng.c |
43 | test_hello_ng_LDADD = \ | 45 | test_hello_ng_LDADD = \ |
44 | libgnunethello.la \ | 46 | libgnunethello.la \ |
45 | $(top_builddir)/src/util/libgnunetutil.la | 47 | $(top_builddir)/src/util/libgnunetutil.la |
48 | |||
49 | test_hello_uri_SOURCES = \ | ||
50 | test_hello-uri.c | ||
51 | test_hello_uri_LDADD = \ | ||
52 | libgnunethello.la \ | ||
53 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
54 | -lgcrypt | ||
46 | 55 | ||
47 | 56 | ||
48 | test_friend_hello_SOURCES = \ | 57 | test_friend_hello_SOURCES = \ |
49 | test_friend_hello.c | 58 | test_friend_hello.c |
50 | test_friend_hello_LDADD = \ | 59 | test_friend_hello_LDADD = \ |
51 | libgnunethello.la \ | 60 | libgnunethello.la \ |
52 | $(top_builddir)/src/util/libgnunetutil.la | 61 | $(top_builddir)/src/util/libgnunetutil.la |
53 | 62 | ||
54 | gnunet_hello_SOURCES = \ | 63 | gnunet_hello_SOURCES = \ |
55 | gnunet-hello.c | 64 | gnunet-hello.c |
56 | gnunet_hello_LDADD = \ | 65 | gnunet_hello_LDADD = \ |
57 | libgnunethello.la \ | 66 | libgnunethello.la \ |
58 | $(top_builddir)/src/util/libgnunetutil.la | 67 | $(top_builddir)/src/util/libgnunetutil.la |
59 | gnunet_hello_LDFLAGS = \ | 68 | gnunet_hello_LDFLAGS = \ |
60 | $(GN_LIBINTL) | 69 | $(GN_LIBINTL) |
diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c new file mode 100644 index 000000000..bacaf697e --- /dev/null +++ b/src/hello/hello-uri.c | |||
@@ -0,0 +1,891 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 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 | * @file hello/hello-uri.c | ||
23 | * @brief helper library for handling URI-based HELLOs | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * Note: | ||
27 | * - Current API does not support deserializing HELLO of | ||
28 | * another peer and then serializing it into another | ||
29 | * format (we always require the private key). | ||
30 | * Not sure if we need this, but if we do, we need | ||
31 | * to extend the builder and the API. | ||
32 | * - Current API does not allow overriding the default | ||
33 | * HELLO expiration time. We may want to add a function | ||
34 | * that does this to create bootstrap HELLOs shipped with | ||
35 | * the TGZ. | ||
36 | */ | ||
37 | #include "platform.h" | ||
38 | #include "gnunet_signatures.h" | ||
39 | #include "gnunet_hello_uri_lib.h" | ||
40 | #include "gnunet_protocols.h" | ||
41 | #include "gnunet_util_lib.h" | ||
42 | |||
43 | |||
44 | GNUNET_NETWORK_STRUCT_BEGIN | ||
45 | |||
46 | /** | ||
47 | * Message signed as part of a HELLO block/URL. | ||
48 | */ | ||
49 | struct HelloSignaturePurpose | ||
50 | { | ||
51 | /** | ||
52 | * Purpose must be #GNUNET_SIGNATURE_PURPOSE_HELLO | ||
53 | */ | ||
54 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
55 | |||
56 | /** | ||
57 | * When does the signature expire? | ||
58 | */ | ||
59 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
60 | |||
61 | /** | ||
62 | * Hash over all addresses. | ||
63 | */ | ||
64 | struct GNUNET_HashCode h_addrs; | ||
65 | |||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * Message used when gossiping HELLOs between peers. | ||
70 | */ | ||
71 | struct HelloUriMessage | ||
72 | { | ||
73 | /** | ||
74 | * Type must be #GNUNET_MESSAGE_TYPE_HELLO_URI | ||
75 | */ | ||
76 | struct GNUNET_MessageHeader header; | ||
77 | |||
78 | /** | ||
79 | * Reserved. 0. | ||
80 | */ | ||
81 | uint16_t reserved GNUNET_PACKED; | ||
82 | |||
83 | /** | ||
84 | * Number of URLs encoded after the end of the struct, in NBO. | ||
85 | */ | ||
86 | uint16_t url_counter GNUNET_PACKED; | ||
87 | |||
88 | /* followed by a 'block' */ | ||
89 | }; | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Start of a 'block'. | ||
94 | */ | ||
95 | struct BlockHeader | ||
96 | { | ||
97 | /** | ||
98 | * Public key of the peer. | ||
99 | */ | ||
100 | struct GNUNET_PeerIdentity pid; | ||
101 | |||
102 | /** | ||
103 | * Signature over the block, of purpose #GNUNET_SIGNATURE_PURPOSE_HELLO. | ||
104 | */ | ||
105 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
106 | |||
107 | /** | ||
108 | * When does the HELLO expire? | ||
109 | */ | ||
110 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Message used when a DHT provides its HELLO to direct | ||
117 | * neighbours. | ||
118 | */ | ||
119 | struct DhtHelloMessage | ||
120 | { | ||
121 | /** | ||
122 | * Type must be #GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO | ||
123 | */ | ||
124 | struct GNUNET_MessageHeader header; | ||
125 | |||
126 | /** | ||
127 | * Reserved. 0. | ||
128 | */ | ||
129 | uint16_t reserved GNUNET_PACKED; | ||
130 | |||
131 | /** | ||
132 | * Number of URLs encoded after the end of the struct, in NBO. | ||
133 | */ | ||
134 | uint16_t url_counter GNUNET_PACKED; | ||
135 | |||
136 | /** | ||
137 | * Signature over the block, of purpose #GNUNET_SIGNATURE_PURPOSE_HELLO. | ||
138 | */ | ||
139 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
140 | |||
141 | /** | ||
142 | * When does the HELLO expire? | ||
143 | */ | ||
144 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
145 | |||
146 | /* followed by the serialized addresses of the 'block' */ | ||
147 | }; | ||
148 | |||
149 | |||
150 | GNUNET_NETWORK_STRUCT_END | ||
151 | |||
152 | |||
153 | /** | ||
154 | * Address of a peer. | ||
155 | */ | ||
156 | struct Address | ||
157 | { | ||
158 | /** | ||
159 | * Kept in a DLL. | ||
160 | */ | ||
161 | struct Address *next; | ||
162 | |||
163 | /** | ||
164 | * Kept in a DLL. | ||
165 | */ | ||
166 | struct Address *prev; | ||
167 | |||
168 | /** | ||
169 | * Actual URI, allocated at the end of this struct. | ||
170 | */ | ||
171 | const char *uri; | ||
172 | |||
173 | /** | ||
174 | * Length of @a uri including 0-terminator. | ||
175 | */ | ||
176 | size_t uri_len; | ||
177 | }; | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Context for building (or parsing) HELLO URIs. | ||
182 | */ | ||
183 | struct GNUNET_HELLO_Builder | ||
184 | { | ||
185 | /** | ||
186 | * Public key of the peer. | ||
187 | */ | ||
188 | struct GNUNET_PeerIdentity pid; | ||
189 | |||
190 | /** | ||
191 | * Head of the addresses DLL. | ||
192 | */ | ||
193 | struct Address *a_head; | ||
194 | |||
195 | /** | ||
196 | * Tail of the addresses DLL. | ||
197 | */ | ||
198 | struct Address *a_tail; | ||
199 | |||
200 | /** | ||
201 | * Length of the @a a_head DLL. | ||
202 | */ | ||
203 | unsigned int a_length; | ||
204 | |||
205 | }; | ||
206 | |||
207 | |||
208 | /** | ||
209 | * Compute @a hash over addresses in @a builder. | ||
210 | * | ||
211 | * @param builder the builder to hash addresses of | ||
212 | * @param[out] hash where to write the hash | ||
213 | */ | ||
214 | static void | ||
215 | hash_addresses (const struct GNUNET_HELLO_Builder *builder, | ||
216 | struct GNUNET_HashCode *hash) | ||
217 | { | ||
218 | struct GNUNET_HashContext *hc; | ||
219 | |||
220 | hc = GNUNET_CRYPTO_hash_context_start (); | ||
221 | for (struct Address *a = builder->a_head; | ||
222 | NULL != a; | ||
223 | a = a->next) | ||
224 | { | ||
225 | GNUNET_CRYPTO_hash_context_read (hc, | ||
226 | a->uri, | ||
227 | a->uri_len); | ||
228 | } | ||
229 | GNUNET_CRYPTO_hash_context_finish (hc, | ||
230 | hash); | ||
231 | |||
232 | } | ||
233 | |||
234 | |||
235 | /** | ||
236 | * Create HELLO signature. | ||
237 | * | ||
238 | * @param builder the builder to use | ||
239 | * @param et expiration time to sign | ||
240 | * @param priv key to sign with | ||
241 | * @param[out] sig where to write the signature | ||
242 | */ | ||
243 | static void | ||
244 | sign_hello (const struct GNUNET_HELLO_Builder *builder, | ||
245 | struct GNUNET_TIME_Timestamp et, | ||
246 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | ||
247 | struct GNUNET_CRYPTO_EddsaSignature *sig) | ||
248 | { | ||
249 | struct HelloSignaturePurpose hsp = { | ||
250 | .purpose.size = htonl (sizeof (hsp)), | ||
251 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO), | ||
252 | .expiration_time = GNUNET_TIME_absolute_hton (et.abs_time) | ||
253 | }; | ||
254 | |||
255 | hash_addresses (builder, | ||
256 | &hsp.h_addrs); | ||
257 | GNUNET_CRYPTO_eddsa_sign (priv, | ||
258 | &hsp, | ||
259 | sig); | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Verify HELLO signature. | ||
265 | * | ||
266 | * @param builder the builder to use | ||
267 | * @param et expiration time to verify | ||
268 | * @param sig signature to verify | ||
269 | * @return #GNUNET_OK if everything is ok, #GNUNET_NO if the | ||
270 | * HELLO expired, #GNUNET_SYSERR if the signature is wrong | ||
271 | */ | ||
272 | static enum GNUNET_GenericReturnValue | ||
273 | verify_hello (const struct GNUNET_HELLO_Builder *builder, | ||
274 | struct GNUNET_TIME_Absolute et, | ||
275 | const struct GNUNET_CRYPTO_EddsaSignature *sig) | ||
276 | { | ||
277 | struct HelloSignaturePurpose hsp = { | ||
278 | .purpose.size = htonl (sizeof (hsp)), | ||
279 | .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO), | ||
280 | .expiration_time = GNUNET_TIME_absolute_hton (et) | ||
281 | }; | ||
282 | |||
283 | hash_addresses (builder, | ||
284 | &hsp.h_addrs); | ||
285 | if (GNUNET_OK != | ||
286 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_HELLO, | ||
287 | &hsp, | ||
288 | sig, | ||
289 | &builder->pid.public_key)) | ||
290 | { | ||
291 | GNUNET_break_op (0); | ||
292 | return GNUNET_SYSERR; | ||
293 | } | ||
294 | if (GNUNET_TIME_absolute_is_past (et)) | ||
295 | return GNUNET_NO; | ||
296 | return GNUNET_OK; | ||
297 | } | ||
298 | |||
299 | |||
300 | struct GNUNET_HELLO_Builder * | ||
301 | GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid) | ||
302 | { | ||
303 | struct GNUNET_HELLO_Builder *builder; | ||
304 | |||
305 | builder = GNUNET_new (struct GNUNET_HELLO_Builder); | ||
306 | builder->pid = *pid; | ||
307 | return builder; | ||
308 | } | ||
309 | |||
310 | |||
311 | void | ||
312 | GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder) | ||
313 | { | ||
314 | struct Address *a; | ||
315 | |||
316 | while (NULL != (a = builder->a_head)) | ||
317 | { | ||
318 | GNUNET_CONTAINER_DLL_remove (builder->a_head, | ||
319 | builder->a_tail, | ||
320 | a); | ||
321 | builder->a_length--; | ||
322 | GNUNET_free (a); | ||
323 | } | ||
324 | GNUNET_assert (0 == builder->a_length); | ||
325 | GNUNET_free (builder); | ||
326 | } | ||
327 | |||
328 | |||
329 | struct GNUNET_HELLO_Builder * | ||
330 | GNUNET_HELLO_builder_from_msg (const struct GNUNET_MessageHeader *msg) | ||
331 | { | ||
332 | const struct HelloUriMessage *h; | ||
333 | uint16_t size = ntohs (msg->size); | ||
334 | |||
335 | if (GNUNET_MESSAGE_TYPE_HELLO_URI != ntohs (msg->type)) | ||
336 | { | ||
337 | GNUNET_break (0); | ||
338 | return NULL; | ||
339 | } | ||
340 | if (sizeof (struct HelloUriMessage) > size) | ||
341 | { | ||
342 | GNUNET_break_op (0); | ||
343 | return NULL; | ||
344 | } | ||
345 | h = (const struct HelloUriMessage *) msg; | ||
346 | size -= sizeof (*h); | ||
347 | return GNUNET_HELLO_builder_from_block (&h[1], | ||
348 | size); | ||
349 | } | ||
350 | |||
351 | |||
352 | struct GNUNET_HELLO_Builder * | ||
353 | GNUNET_HELLO_builder_from_block (const void *block, | ||
354 | size_t block_size) | ||
355 | { | ||
356 | const struct BlockHeader *bh = block; | ||
357 | struct GNUNET_HELLO_Builder *b; | ||
358 | |||
359 | if (block_size < sizeof (*bh)) | ||
360 | { | ||
361 | GNUNET_break_op (0); | ||
362 | return NULL; | ||
363 | } | ||
364 | b = GNUNET_HELLO_builder_new (&bh->pid); | ||
365 | block += sizeof (*bh); | ||
366 | block_size -= sizeof (*bh); | ||
367 | while (block_size > 0) | ||
368 | { | ||
369 | const void *end = memchr (block, | ||
370 | '\0', | ||
371 | block_size); | ||
372 | |||
373 | if (NULL == end) | ||
374 | { | ||
375 | GNUNET_break_op (0); | ||
376 | GNUNET_HELLO_builder_free (b); | ||
377 | return NULL; | ||
378 | } | ||
379 | if (GNUNET_OK != | ||
380 | GNUNET_HELLO_builder_add_address (b, | ||
381 | block)) | ||
382 | { | ||
383 | GNUNET_break_op (0); | ||
384 | GNUNET_HELLO_builder_free (b); | ||
385 | return NULL; | ||
386 | } | ||
387 | end++; | ||
388 | block_size -= (end - block); | ||
389 | block = end; | ||
390 | } | ||
391 | { | ||
392 | enum GNUNET_GenericReturnValue ret; | ||
393 | |||
394 | ret = verify_hello (b, | ||
395 | GNUNET_TIME_absolute_ntoh (bh->expiration_time), | ||
396 | &bh->sig); | ||
397 | GNUNET_break (GNUNET_SYSERR != ret); | ||
398 | if (GNUNET_OK != ret) | ||
399 | { | ||
400 | GNUNET_HELLO_builder_free (b); | ||
401 | return NULL; | ||
402 | } | ||
403 | } | ||
404 | return b; | ||
405 | } | ||
406 | |||
407 | |||
408 | struct GNUNET_HELLO_Builder * | ||
409 | GNUNET_HELLO_builder_from_url (const char *url) | ||
410 | { | ||
411 | const char *q; | ||
412 | const char *s1; | ||
413 | const char *s2; | ||
414 | struct GNUNET_PeerIdentity pid; | ||
415 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
416 | struct GNUNET_TIME_Absolute et; | ||
417 | size_t len; | ||
418 | struct GNUNET_HELLO_Builder *b; | ||
419 | |||
420 | if (0 != strncasecmp (url, | ||
421 | "gnunet://hello/", | ||
422 | strlen ("gnunet://hello/"))) | ||
423 | return NULL; | ||
424 | url += strlen ("gnunet://hello/"); | ||
425 | s1 = strchr (url, '/'); | ||
426 | if (NULL == s1) | ||
427 | { | ||
428 | GNUNET_break_op (0); | ||
429 | return NULL; | ||
430 | } | ||
431 | s2 = strchr (s1 + 1, '/'); | ||
432 | if (NULL == s1) | ||
433 | { | ||
434 | GNUNET_break_op (0); | ||
435 | return NULL; | ||
436 | } | ||
437 | q = strchr (url, '?'); | ||
438 | if (NULL == q) | ||
439 | q = url + strlen (url); | ||
440 | if (GNUNET_OK != | ||
441 | GNUNET_STRINGS_string_to_data (url, | ||
442 | s1 - url, | ||
443 | &pid, | ||
444 | sizeof(pid))) | ||
445 | { | ||
446 | GNUNET_break_op (0); | ||
447 | return NULL; | ||
448 | } | ||
449 | if (GNUNET_OK != | ||
450 | GNUNET_STRINGS_string_to_data (s1 + 1, | ||
451 | s2 - (s1 + 1), | ||
452 | &sig, | ||
453 | sizeof(sig))) | ||
454 | { | ||
455 | GNUNET_break_op (0); | ||
456 | return NULL; | ||
457 | } | ||
458 | { | ||
459 | unsigned long long sec; | ||
460 | char dummy = '?'; | ||
461 | |||
462 | if ( (0 == sscanf (s2 + 1, | ||
463 | "%llu%c", | ||
464 | &sec, | ||
465 | &dummy)) || | ||
466 | ('?' != dummy) ) | ||
467 | { | ||
468 | GNUNET_break_op (0); | ||
469 | return NULL; | ||
470 | } | ||
471 | et = GNUNET_TIME_absolute_from_s (sec); | ||
472 | } | ||
473 | |||
474 | b = GNUNET_HELLO_builder_new (&pid); | ||
475 | len = strlen (q); | ||
476 | while (len > 0) | ||
477 | { | ||
478 | const char *eq; | ||
479 | const char *amp; | ||
480 | char *addr = NULL; | ||
481 | char *uri; | ||
482 | |||
483 | /* skip ?/& separator */ | ||
484 | len--; | ||
485 | q++; | ||
486 | eq = strchr (q, '='); | ||
487 | if ( (eq == q) || | ||
488 | (NULL == eq) ) | ||
489 | { | ||
490 | GNUNET_break_op (0); | ||
491 | GNUNET_HELLO_builder_free (b); | ||
492 | return NULL; | ||
493 | } | ||
494 | amp = strchr (eq, '&'); | ||
495 | if (NULL == amp) | ||
496 | amp = &q[len]; | ||
497 | GNUNET_STRINGS_urldecode (eq + 1, | ||
498 | amp - (eq + 1), | ||
499 | &addr); | ||
500 | if ( (NULL == addr) || | ||
501 | (0 == strlen (addr)) ) | ||
502 | { | ||
503 | GNUNET_free (addr); | ||
504 | GNUNET_break_op (0); | ||
505 | GNUNET_HELLO_builder_free (b); | ||
506 | return NULL; | ||
507 | } | ||
508 | GNUNET_asprintf (&uri, | ||
509 | "%.*s://%s", | ||
510 | (int) (eq - q), | ||
511 | q, | ||
512 | addr); | ||
513 | GNUNET_free (addr); | ||
514 | if (GNUNET_OK != | ||
515 | GNUNET_HELLO_builder_add_address (b, | ||
516 | uri)) | ||
517 | { | ||
518 | GNUNET_break_op (0); | ||
519 | GNUNET_free (uri); | ||
520 | GNUNET_HELLO_builder_free (b); | ||
521 | return NULL; | ||
522 | } | ||
523 | GNUNET_free (uri); | ||
524 | /* move to next URL */ | ||
525 | len -= (amp - q); | ||
526 | q = amp; | ||
527 | } | ||
528 | |||
529 | { | ||
530 | enum GNUNET_GenericReturnValue ret; | ||
531 | |||
532 | ret = verify_hello (b, | ||
533 | et, | ||
534 | &sig); | ||
535 | GNUNET_break (GNUNET_SYSERR != ret); | ||
536 | if (GNUNET_OK != ret) | ||
537 | { | ||
538 | GNUNET_HELLO_builder_free (b); | ||
539 | return NULL; | ||
540 | } | ||
541 | } | ||
542 | return b; | ||
543 | } | ||
544 | |||
545 | |||
546 | struct GNUNET_MQ_Envelope * | ||
547 | GNUNET_HELLO_builder_to_env (const struct GNUNET_HELLO_Builder *builder, | ||
548 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
549 | { | ||
550 | struct GNUNET_MQ_Envelope *env; | ||
551 | struct HelloUriMessage *msg; | ||
552 | size_t blen; | ||
553 | |||
554 | if (builder->a_length > UINT16_MAX) | ||
555 | { | ||
556 | GNUNET_break (0); | ||
557 | return NULL; | ||
558 | } | ||
559 | blen = 0; | ||
560 | GNUNET_assert (GNUNET_NO == | ||
561 | GNUNET_HELLO_builder_to_block (builder, | ||
562 | priv, | ||
563 | NULL, | ||
564 | &blen)); | ||
565 | env = GNUNET_MQ_msg_extra (msg, | ||
566 | blen, | ||
567 | GNUNET_MESSAGE_TYPE_HELLO_URI); | ||
568 | msg->url_counter = htonl ((uint16_t) builder->a_length); | ||
569 | GNUNET_assert (GNUNET_OK == | ||
570 | GNUNET_HELLO_builder_to_block (builder, | ||
571 | priv, | ||
572 | &msg[1], | ||
573 | &blen)); | ||
574 | return env; | ||
575 | } | ||
576 | |||
577 | |||
578 | struct GNUNET_MessageHeader * | ||
579 | GNUNET_HELLO_builder_to_dht_hello_msg ( | ||
580 | const struct GNUNET_HELLO_Builder *builder, | ||
581 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
582 | { | ||
583 | struct DhtHelloMessage *msg; | ||
584 | size_t blen; | ||
585 | |||
586 | if (builder->a_length > UINT16_MAX) | ||
587 | { | ||
588 | GNUNET_break (0); | ||
589 | return NULL; | ||
590 | } | ||
591 | blen = 0; | ||
592 | GNUNET_assert (GNUNET_NO == | ||
593 | GNUNET_HELLO_builder_to_block (builder, | ||
594 | priv, | ||
595 | NULL, | ||
596 | &blen)); | ||
597 | GNUNET_assert (blen < UINT16_MAX); | ||
598 | GNUNET_assert (blen >= sizeof (struct BlockHeader)); | ||
599 | { | ||
600 | char buf[blen] GNUNET_ALIGN; | ||
601 | const struct BlockHeader *block = (const struct BlockHeader *) buf; | ||
602 | |||
603 | GNUNET_assert (GNUNET_OK == | ||
604 | GNUNET_HELLO_builder_to_block (builder, | ||
605 | priv, | ||
606 | buf, | ||
607 | &blen)); | ||
608 | msg = GNUNET_malloc (sizeof (*msg) | ||
609 | + blen | ||
610 | - sizeof (*block)); | ||
611 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO); | ||
612 | msg->header.size = htons (sizeof (*msg) | ||
613 | + blen | ||
614 | - sizeof (*block)); | ||
615 | memcpy (&msg[1], | ||
616 | &block[1], | ||
617 | blen - sizeof (*block)); | ||
618 | msg->sig = block->sig; | ||
619 | msg->expiration_time = block->expiration_time; | ||
620 | } | ||
621 | msg->url_counter = htonl ((uint16_t) builder->a_length); | ||
622 | return &msg->header; | ||
623 | } | ||
624 | |||
625 | |||
626 | char * | ||
627 | GNUNET_HELLO_builder_to_url (const struct GNUNET_HELLO_Builder *builder, | ||
628 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
629 | { | ||
630 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
631 | struct GNUNET_TIME_Timestamp et; | ||
632 | char *result; | ||
633 | char *pids; | ||
634 | char *sigs; | ||
635 | const char *sep = "?"; | ||
636 | |||
637 | et = GNUNET_TIME_relative_to_timestamp (GNUNET_HELLO_ADDRESS_EXPIRATION); | ||
638 | sign_hello (builder, | ||
639 | et, | ||
640 | priv, | ||
641 | &sig); | ||
642 | pids = GNUNET_STRINGS_data_to_string_alloc (&builder->pid, | ||
643 | sizeof (builder->pid)); | ||
644 | sigs = GNUNET_STRINGS_data_to_string_alloc (&sig, | ||
645 | sizeof (sig)); | ||
646 | GNUNET_asprintf (&result, | ||
647 | "gnunet://hello/%s/%s/%llu", | ||
648 | pids, | ||
649 | sigs, | ||
650 | (unsigned long long) GNUNET_TIME_timestamp_to_s (et)); | ||
651 | GNUNET_free (sigs); | ||
652 | GNUNET_free (pids); | ||
653 | for (struct Address *a = builder->a_head; | ||
654 | NULL != a; | ||
655 | a = a->next) | ||
656 | { | ||
657 | char *ue; | ||
658 | char *tmp; | ||
659 | int pfx_len; | ||
660 | const char *eou; | ||
661 | |||
662 | eou = strstr (a->uri, | ||
663 | "://"); | ||
664 | if (NULL == eou) | ||
665 | { | ||
666 | GNUNET_break (0); | ||
667 | GNUNET_free (result); | ||
668 | return NULL; | ||
669 | } | ||
670 | pfx_len = eou - a->uri; | ||
671 | eou += 3; | ||
672 | GNUNET_STRINGS_urlencode (eou, | ||
673 | a->uri_len - 4 - pfx_len, | ||
674 | &ue); | ||
675 | GNUNET_asprintf (&tmp, | ||
676 | "%s%s%.*s=%s", | ||
677 | result, | ||
678 | sep, | ||
679 | pfx_len, | ||
680 | a->uri, | ||
681 | ue); | ||
682 | GNUNET_free (ue); | ||
683 | GNUNET_free (result); | ||
684 | result = tmp; | ||
685 | sep = "&"; | ||
686 | } | ||
687 | return result; | ||
688 | } | ||
689 | |||
690 | |||
691 | enum GNUNET_GenericReturnValue | ||
692 | GNUNET_HELLO_builder_to_block (const struct GNUNET_HELLO_Builder *builder, | ||
693 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | ||
694 | void *block, | ||
695 | size_t *block_size) | ||
696 | { | ||
697 | struct BlockHeader bh; | ||
698 | size_t needed = sizeof (bh); | ||
699 | char *pos; | ||
700 | struct GNUNET_TIME_Timestamp et; | ||
701 | |||
702 | for (struct Address *a = builder->a_head; | ||
703 | NULL != a; | ||
704 | a = a->next) | ||
705 | { | ||
706 | GNUNET_assert (needed + a->uri_len > needed); | ||
707 | needed += a->uri_len; | ||
708 | } | ||
709 | if ( (NULL == block) || | ||
710 | (needed < *block_size) ) | ||
711 | { | ||
712 | *block_size = needed; | ||
713 | return GNUNET_NO; | ||
714 | } | ||
715 | bh.pid = builder->pid; | ||
716 | et = GNUNET_TIME_relative_to_timestamp (GNUNET_HELLO_ADDRESS_EXPIRATION); | ||
717 | bh.expiration_time = GNUNET_TIME_absolute_hton (et.abs_time); | ||
718 | sign_hello (builder, | ||
719 | et, | ||
720 | priv, | ||
721 | &bh.sig); | ||
722 | memcpy (block, | ||
723 | &bh, | ||
724 | sizeof (bh)); | ||
725 | pos = block + sizeof (bh); | ||
726 | for (struct Address *a = builder->a_head; | ||
727 | NULL != a; | ||
728 | a = a->next) | ||
729 | { | ||
730 | memcpy (pos, | ||
731 | a->uri, | ||
732 | a->uri_len); | ||
733 | pos += a->uri_len; | ||
734 | } | ||
735 | *block_size = needed; | ||
736 | return GNUNET_OK; | ||
737 | } | ||
738 | |||
739 | |||
740 | enum GNUNET_GenericReturnValue | ||
741 | GNUNET_HELLO_builder_add_address (struct GNUNET_HELLO_Builder *builder, | ||
742 | const char *address) | ||
743 | { | ||
744 | size_t alen = strlen (address) + 1; | ||
745 | struct Address *a; | ||
746 | const char *e; | ||
747 | |||
748 | if (NULL == (e = strstr (address, | ||
749 | "://"))) | ||
750 | { | ||
751 | GNUNET_break_op (0); | ||
752 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
753 | "Invalid address `%s'\n", | ||
754 | address); | ||
755 | return GNUNET_SYSERR; | ||
756 | } | ||
757 | if (e == address) | ||
758 | { | ||
759 | GNUNET_break_op (0); | ||
760 | return GNUNET_SYSERR; | ||
761 | } | ||
762 | for (const char *p = address; p != e; p++) | ||
763 | if ( (! isalpha ((unsigned char) *p)) && | ||
764 | ('+' != *p) ) | ||
765 | { | ||
766 | GNUNET_break_op (0); | ||
767 | return GNUNET_SYSERR; | ||
768 | } | ||
769 | /* check for duplicates */ | ||
770 | for (a = builder->a_head; | ||
771 | NULL != a; | ||
772 | a = a->next) | ||
773 | if (0 == strcmp (address, | ||
774 | a->uri)) | ||
775 | return GNUNET_NO; | ||
776 | a = GNUNET_malloc (sizeof (struct Address) + alen); | ||
777 | a->uri_len = alen; | ||
778 | memcpy (&a[1], | ||
779 | address, | ||
780 | alen); | ||
781 | a->uri = (const char *) &a[1]; | ||
782 | GNUNET_CONTAINER_DLL_insert_tail (builder->a_head, | ||
783 | builder->a_tail, | ||
784 | a); | ||
785 | builder->a_length++; | ||
786 | return GNUNET_OK; | ||
787 | } | ||
788 | |||
789 | |||
790 | enum GNUNET_GenericReturnValue | ||
791 | GNUNET_HELLO_builder_del_address (struct GNUNET_HELLO_Builder *builder, | ||
792 | const char *address) | ||
793 | { | ||
794 | struct Address *a; | ||
795 | |||
796 | /* check for duplicates */ | ||
797 | for (a = builder->a_head; | ||
798 | NULL != a; | ||
799 | a = a->next) | ||
800 | if (0 == strcmp (address, | ||
801 | a->uri)) | ||
802 | break; | ||
803 | if (NULL == a) | ||
804 | return GNUNET_NO; | ||
805 | GNUNET_CONTAINER_DLL_remove (builder->a_head, | ||
806 | builder->a_tail, | ||
807 | a); | ||
808 | builder->a_length--; | ||
809 | GNUNET_free (a); | ||
810 | return GNUNET_OK; | ||
811 | } | ||
812 | |||
813 | |||
814 | void | ||
815 | GNUNET_HELLO_builder_iterate (const struct GNUNET_HELLO_Builder *builder, | ||
816 | struct GNUNET_PeerIdentity *pid, | ||
817 | GNUNET_HELLO_UriCallback uc, | ||
818 | void *uc_cls) | ||
819 | { | ||
820 | struct Address *nxt; | ||
821 | |||
822 | *pid = builder->pid; | ||
823 | if (NULL == uc) | ||
824 | return; | ||
825 | for (struct Address *a = builder->a_head; | ||
826 | NULL != a; | ||
827 | a = nxt) | ||
828 | { | ||
829 | nxt = a->next; | ||
830 | uc (uc_cls, | ||
831 | a->uri); | ||
832 | } | ||
833 | } | ||
834 | |||
835 | |||
836 | enum GNUNET_GenericReturnValue | ||
837 | GNUNET_HELLO_dht_msg_to_block (const struct GNUNET_MessageHeader *hello, | ||
838 | const struct GNUNET_PeerIdentity *pid, | ||
839 | void **block, | ||
840 | size_t *block_size, | ||
841 | struct GNUNET_TIME_Absolute *block_expiration) | ||
842 | { | ||
843 | const struct DhtHelloMessage *msg | ||
844 | = (const struct DhtHelloMessage *) hello; | ||
845 | uint16_t len = ntohs (hello->size); | ||
846 | struct BlockHeader *bh; | ||
847 | struct GNUNET_HELLO_Builder *b; | ||
848 | enum GNUNET_GenericReturnValue ret; | ||
849 | |||
850 | if (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO != ntohs (hello->type)) | ||
851 | { | ||
852 | GNUNET_break (0); | ||
853 | return GNUNET_SYSERR; | ||
854 | } | ||
855 | if (len < sizeof (*msg)) | ||
856 | { | ||
857 | GNUNET_break_op (0); | ||
858 | return GNUNET_SYSERR; | ||
859 | } | ||
860 | len -= sizeof (*msg); | ||
861 | *block_size = len + sizeof (*bh); | ||
862 | *block = GNUNET_malloc (*block_size); | ||
863 | bh = *block; | ||
864 | bh->pid = *pid; | ||
865 | bh->sig = msg->sig; | ||
866 | bh->expiration_time = msg->expiration_time; | ||
867 | *block_expiration = GNUNET_TIME_absolute_ntoh (msg->expiration_time); | ||
868 | memcpy (&bh[1], | ||
869 | &msg[1], | ||
870 | len); | ||
871 | b = GNUNET_HELLO_builder_from_block (*block, | ||
872 | *block_size); | ||
873 | if (NULL == b) | ||
874 | { | ||
875 | GNUNET_break_op (0); | ||
876 | GNUNET_free (*block); | ||
877 | *block_size = 0; | ||
878 | return GNUNET_SYSERR; | ||
879 | } | ||
880 | ret = verify_hello (b, | ||
881 | *block_expiration, | ||
882 | &msg->sig); | ||
883 | GNUNET_HELLO_builder_free (b); | ||
884 | if (GNUNET_SYSERR == ret) | ||
885 | { | ||
886 | GNUNET_free (*block); | ||
887 | *block_size = 0; | ||
888 | return GNUNET_SYSERR; | ||
889 | } | ||
890 | return ret; | ||
891 | } | ||
diff --git a/src/hello/test_hello-ng.c b/src/hello/test_hello-ng.c index e6b1d42a0..4ace9439f 100644 --- a/src/hello/test_hello-ng.c +++ b/src/hello/test_hello-ng.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 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 | */ | ||
1 | #include "platform.h" | 20 | #include "platform.h" |
2 | #include "gnunet_util_lib.h" | 21 | #include "gnunet_util_lib.h" |
3 | #include "gnunet_nt_lib.h" | 22 | #include "gnunet_nt_lib.h" |
@@ -23,12 +42,12 @@ main (int argc, | |||
23 | GNUNET_NT_LAN, | 42 | GNUNET_NT_LAN, |
24 | t, | 43 | t, |
25 | &privKey, | 44 | &privKey, |
26 | (void**)&res, | 45 | (void**) &res, |
27 | &res_len); | 46 | &res_len); |
28 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 47 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
29 | "%s\n", res); | 48 | "%s\n", res); |
30 | GNUNET_assert (NULL != | 49 | GNUNET_assert (NULL != |
31 | GNUNET_HELLO_extract_address ((void**)res, | 50 | GNUNET_HELLO_extract_address ((void**) res, |
32 | res_len, | 51 | res_len, |
33 | &pid, | 52 | &pid, |
34 | &nt, | 53 | &nt, |
diff --git a/src/hello/test_hello-uri.c b/src/hello/test_hello-uri.c new file mode 100644 index 000000000..7e70d6763 --- /dev/null +++ b/src/hello/test_hello-uri.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 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 | * @file hello/test_hello-uri.c | ||
22 | * @brief test for helper library for handling URI-based HELLOs | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_signatures.h" | ||
27 | #include "gnunet_hello_uri_lib.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Check for expected URIs. | ||
33 | * | ||
34 | * @param cls a `unsigned int*`, bitmask set to found URIs | ||
35 | * @param uri URI to check for | ||
36 | */ | ||
37 | static void | ||
38 | check_uris (void *cls, | ||
39 | const char *uri) | ||
40 | { | ||
41 | unsigned int *found = cls; | ||
42 | |||
43 | if (0 == strcmp (uri, | ||
44 | "test://address")) | ||
45 | *found |= 1; | ||
46 | else if (0 == strcmp (uri, | ||
47 | "test://more")) | ||
48 | *found |= 2; | ||
49 | else | ||
50 | *found = (unsigned int) -1; | ||
51 | } | ||
52 | |||
53 | |||
54 | int | ||
55 | main (int argc, | ||
56 | char *argv[]) | ||
57 | { | ||
58 | struct GNUNET_PeerIdentity pid; | ||
59 | struct GNUNET_HELLO_Builder *b; | ||
60 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
61 | |||
62 | GNUNET_log_setup ("test-hell-uri", | ||
63 | "WARNING", | ||
64 | NULL); | ||
65 | GNUNET_CRYPTO_eddsa_key_create (&priv); | ||
66 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
67 | &pid.public_key); | ||
68 | b = GNUNET_HELLO_builder_new (&pid); | ||
69 | GNUNET_assert (GNUNET_SYSERR == | ||
70 | GNUNET_HELLO_builder_add_address (b, | ||
71 | "invalid")); | ||
72 | GNUNET_assert (GNUNET_SYSERR == | ||
73 | GNUNET_HELLO_builder_add_address (b, | ||
74 | "i%v://bla")); | ||
75 | GNUNET_assert (GNUNET_SYSERR == | ||
76 | GNUNET_HELLO_builder_add_address (b, | ||
77 | "://empty")); | ||
78 | GNUNET_assert (GNUNET_OK == | ||
79 | GNUNET_HELLO_builder_add_address (b, | ||
80 | "test://address")); | ||
81 | GNUNET_assert (GNUNET_NO == | ||
82 | GNUNET_HELLO_builder_add_address (b, | ||
83 | "test://address")); | ||
84 | GNUNET_assert (GNUNET_OK == | ||
85 | GNUNET_HELLO_builder_add_address (b, | ||
86 | "test://more")); | ||
87 | { | ||
88 | void *block; | ||
89 | size_t block_size = 0; | ||
90 | struct GNUNET_HELLO_Builder *b2; | ||
91 | struct GNUNET_PeerIdentity p2; | ||
92 | unsigned int found; | ||
93 | |||
94 | GNUNET_assert (GNUNET_NO == | ||
95 | GNUNET_HELLO_builder_to_block (b, | ||
96 | &priv, | ||
97 | NULL, | ||
98 | &block_size)); | ||
99 | GNUNET_assert (GNUNET_NO == | ||
100 | GNUNET_HELLO_builder_to_block (b, | ||
101 | &priv, | ||
102 | NULL, | ||
103 | &block_size)); | ||
104 | GNUNET_assert (0 != block_size); | ||
105 | block = GNUNET_malloc (block_size); | ||
106 | GNUNET_assert (GNUNET_OK == | ||
107 | GNUNET_HELLO_builder_to_block (b, | ||
108 | &priv, | ||
109 | block, | ||
110 | &block_size)); | ||
111 | b2 = GNUNET_HELLO_builder_from_block (block, | ||
112 | block_size); | ||
113 | GNUNET_free (block); | ||
114 | GNUNET_assert (NULL != b2); | ||
115 | found = 0; | ||
116 | GNUNET_HELLO_builder_iterate (b2, | ||
117 | &p2, | ||
118 | &check_uris, | ||
119 | &found); | ||
120 | GNUNET_assert (3 == found); | ||
121 | GNUNET_assert (0 == | ||
122 | GNUNET_memcmp (&p2, | ||
123 | &pid)); | ||
124 | GNUNET_HELLO_builder_free (b2); | ||
125 | } | ||
126 | |||
127 | { | ||
128 | char *url; | ||
129 | struct GNUNET_HELLO_Builder *b2; | ||
130 | struct GNUNET_PeerIdentity p2; | ||
131 | unsigned int found; | ||
132 | |||
133 | url = GNUNET_HELLO_builder_to_url (b, | ||
134 | &priv); | ||
135 | b2 = GNUNET_HELLO_builder_from_url (url); | ||
136 | GNUNET_free (url); | ||
137 | GNUNET_assert (NULL != b2); | ||
138 | found = 0; | ||
139 | GNUNET_HELLO_builder_iterate (b2, | ||
140 | &p2, | ||
141 | &check_uris, | ||
142 | &found); | ||
143 | GNUNET_assert (3 == found); | ||
144 | GNUNET_assert (0 == | ||
145 | GNUNET_memcmp (&p2, | ||
146 | &pid)); | ||
147 | GNUNET_HELLO_builder_free (b2); | ||
148 | } | ||
149 | |||
150 | { | ||
151 | struct GNUNET_MQ_Envelope *env; | ||
152 | struct GNUNET_HELLO_Builder *b2; | ||
153 | struct GNUNET_PeerIdentity p2; | ||
154 | unsigned int found; | ||
155 | |||
156 | env = GNUNET_HELLO_builder_to_env (b, | ||
157 | &priv); | ||
158 | b2 = GNUNET_HELLO_builder_from_msg (GNUNET_MQ_env_get_msg (env)); | ||
159 | GNUNET_free (env); | ||
160 | GNUNET_assert (NULL != b2); | ||
161 | found = 0; | ||
162 | GNUNET_HELLO_builder_iterate (b2, | ||
163 | &p2, | ||
164 | &check_uris, | ||
165 | &found); | ||
166 | GNUNET_assert (3 == found); | ||
167 | GNUNET_assert (0 == | ||
168 | GNUNET_memcmp (&p2, | ||
169 | &pid)); | ||
170 | GNUNET_HELLO_builder_free (b2); | ||
171 | } | ||
172 | |||
173 | GNUNET_HELLO_builder_free (b); | ||
174 | |||
175 | GNUNET_CRYPTO_mpi_print_unsigned (priv.d, | ||
176 | sizeof (priv.d), | ||
177 | GCRYMPI_CONST_ONE); | ||
178 | priv.d[0] &= 248; | ||
179 | priv.d[31] &= 127; | ||
180 | priv.d[31] |= 64; | ||
181 | { | ||
182 | char *buf; | ||
183 | |||
184 | buf = GNUNET_STRINGS_data_to_string_alloc (&priv, | ||
185 | sizeof (priv)); | ||
186 | fprintf (stderr, | ||
187 | "PK: %s\n", | ||
188 | buf); | ||
189 | GNUNET_free (buf); | ||
190 | } | ||
191 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
192 | &pid.public_key); | ||
193 | b = GNUNET_HELLO_builder_new (&pid); | ||
194 | GNUNET_assert (GNUNET_OK == | ||
195 | GNUNET_HELLO_builder_add_address (b, | ||
196 | "a://first")); | ||
197 | GNUNET_assert (GNUNET_OK == | ||
198 | GNUNET_HELLO_builder_add_address (b, | ||
199 | "b://second")); | ||
200 | { | ||
201 | char *url; | ||
202 | |||
203 | url = GNUNET_HELLO_builder_to_url (b, | ||
204 | &priv); | ||
205 | fprintf (stderr, | ||
206 | "TV: %s\n", | ||
207 | url); | ||
208 | GNUNET_free (url); | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.c b/src/hostlist/gnunet-daemon-hostlist_client.c index 44966d3de..1f7d4cc35 100644 --- a/src/hostlist/gnunet-daemon-hostlist_client.c +++ b/src/hostlist/gnunet-daemon-hostlist_client.c | |||
@@ -1635,7 +1635,11 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
1635 | "PROXY_TYPE", | 1635 | "PROXY_TYPE", |
1636 | &proxytype_str)) | 1636 | &proxytype_str)) |
1637 | { | 1637 | { |
1638 | GNUNET_STRINGS_utf8_toupper (proxytype_str, proxytype_str); | 1638 | if (GNUNET_OK != GNUNET_STRINGS_utf8_toupper (proxytype_str, |
1639 | proxytype_str)) | ||
1640 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1641 | "Unable to convert `%s' to UTF-8 uppercase\n", | ||
1642 | proxytype_str); | ||
1639 | proxy_type = CURLPROXY_HTTP; | 1643 | proxy_type = CURLPROXY_HTTP; |
1640 | if (0 == strcmp (proxytype_str, "HTTP")) | 1644 | if (0 == strcmp (proxytype_str, "HTTP")) |
1641 | proxy_type = CURLPROXY_HTTP; | 1645 | proxy_type = CURLPROXY_HTTP; |
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am index e535c208a..5a2110974 100644 --- a/src/identity/Makefile.am +++ b/src/identity/Makefile.am | |||
@@ -95,6 +95,7 @@ test_identity_defaults_LDADD = \ | |||
95 | $(top_builddir)/src/util/libgnunetutil.la | 95 | $(top_builddir)/src/util/libgnunetutil.la |
96 | 96 | ||
97 | EXTRA_DIST = \ | 97 | EXTRA_DIST = \ |
98 | test_identity.conf | 98 | test_identity.conf \ |
99 | test_identity_messages.sh | ||
99 | 100 | ||
100 | 101 | ||
diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c index 2bb4b0897..51f897557 100644 --- a/src/identity/gnunet-service-identity.c +++ b/src/identity/gnunet-service-identity.c | |||
@@ -489,8 +489,7 @@ handle_get_default_message (void *cls, | |||
489 | char *identifier; | 489 | char *identifier; |
490 | 490 | ||
491 | name = GNUNET_strdup ((const char *) &gdm[1]); | 491 | name = GNUNET_strdup ((const char *) &gdm[1]); |
492 | GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], | 492 | GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], name); |
493 | name); | ||
494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 493 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
495 | "Received GET_DEFAULT for service `%s' from client\n", | 494 | "Received GET_DEFAULT for service `%s' from client\n", |
496 | name); | 495 | name); |
diff --git a/src/include/Makefile.am b/src/include/Makefile.am index e4b02b8ee..8808f6802 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am | |||
@@ -57,6 +57,7 @@ gnunetinclude_HEADERS = \ | |||
57 | gnunet_gnsrecord_plugin.h \ | 57 | gnunet_gnsrecord_plugin.h \ |
58 | gnu_name_system_record_types.h \ | 58 | gnu_name_system_record_types.h \ |
59 | gnunet_hello_lib.h \ | 59 | gnunet_hello_lib.h \ |
60 | gnunet_hello_uri_lib.h \ | ||
60 | gnunet_helper_lib.h \ | 61 | gnunet_helper_lib.h \ |
61 | gnunet_identity_service.h \ | 62 | gnunet_identity_service.h \ |
62 | gnunet_abe_lib.h \ | 63 | gnunet_abe_lib.h \ |
diff --git a/src/include/gnunet_block_group_lib.h b/src/include/gnunet_block_group_lib.h index 6cb601757..b03e913c6 100644 --- a/src/include/gnunet_block_group_lib.h +++ b/src/include/gnunet_block_group_lib.h | |||
@@ -94,7 +94,7 @@ GNUNET_BLOCK_GROUP_bf_create (void *cls, | |||
94 | * @return #GNUNET_YES if @a hc is (likely) a duplicate | 94 | * @return #GNUNET_YES if @a hc is (likely) a duplicate |
95 | * #GNUNET_NO if @a hc was definitively not in @bg (but now is) | 95 | * #GNUNET_NO if @a hc was definitively not in @bg (but now is) |
96 | */ | 96 | */ |
97 | int | 97 | enum GNUNET_GenericReturnValue |
98 | GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg, | 98 | GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg, |
99 | const struct GNUNET_HashCode *hc); | 99 | const struct GNUNET_HashCode *hc); |
100 | 100 | ||
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h index 5640209a6..515b8256c 100644 --- a/src/include/gnunet_block_lib.h +++ b/src/include/gnunet_block_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010 GNUnet e.V. | 3 | Copyright (C) 2010, 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 |
@@ -119,6 +119,12 @@ enum GNUNET_BLOCK_Type | |||
119 | GNUNET_BLOCK_TYPE_REVOCATION = 12, | 119 | GNUNET_BLOCK_TYPE_REVOCATION = 12, |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * Type of a block that contains a DHT-NG HELLO for a peer (for | ||
123 | * DHT and CADET find-peer operations). | ||
124 | */ | ||
125 | GNUNET_BLOCK_TYPE_DHT_URL_HELLO = 13, | ||
126 | |||
127 | /** | ||
122 | * Block to store a cadet regex state | 128 | * Block to store a cadet regex state |
123 | */ | 129 | */ |
124 | GNUNET_BLOCK_TYPE_REGEX = 22, | 130 | GNUNET_BLOCK_TYPE_REGEX = 22, |
@@ -156,108 +162,35 @@ enum GNUNET_BLOCK_Type | |||
156 | 162 | ||
157 | 163 | ||
158 | /** | 164 | /** |
159 | * Flags that can be set to control the evaluation. | ||
160 | * @deprecated | ||
161 | */ | ||
162 | enum GNUNET_BLOCK_EvaluationOptions | ||
163 | { | ||
164 | /** | ||
165 | * Default behavior. | ||
166 | */ | ||
167 | GNUNET_BLOCK_EO_NONE = 0, | ||
168 | |||
169 | /** | ||
170 | * The block is obtained from the local database, skip cryptographic | ||
171 | * checks. | ||
172 | */ | ||
173 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO = 1 | ||
174 | }; | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Possible ways for how a block may relate to a query. | 165 | * Possible ways for how a block may relate to a query. |
179 | * @deprecated | ||
180 | */ | 166 | */ |
181 | enum GNUNET_BLOCK_EvaluationResult | 167 | enum GNUNET_BLOCK_ReplyEvaluationResult |
182 | { | 168 | { |
183 | /** | ||
184 | * Valid result, and there may be more. | ||
185 | */ | ||
186 | GNUNET_BLOCK_EVALUATION_OK_MORE = 0, | ||
187 | 169 | ||
188 | /** | 170 | /** |
189 | * Last possible valid result. | 171 | * Specified block type not supported by any plugin. |
190 | */ | 172 | */ |
191 | GNUNET_BLOCK_EVALUATION_OK_LAST = 1, | 173 | GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED = -1, |
192 | 174 | ||
193 | /** | 175 | /** |
194 | * Valid result, but suppressed because it is a duplicate. | 176 | * Valid result, but suppressed because it is a duplicate. |
195 | */ | 177 | */ |
196 | GNUNET_BLOCK_EVALUATION_OK_DUPLICATE = 2, | 178 | GNUNET_BLOCK_REPLY_OK_DUPLICATE = 0, |
197 | |||
198 | /** | ||
199 | * Block does not match query (invalid result) | ||
200 | */ | ||
201 | GNUNET_BLOCK_EVALUATION_RESULT_INVALID = 3, | ||
202 | 179 | ||
203 | /** | 180 | /** |
204 | * Block does not match xquery (valid result, not relevant for the request) | 181 | * Block does not match xquery (valid result, not relevant for the request) |
205 | */ | 182 | */ |
206 | GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT = 4, | 183 | GNUNET_BLOCK_REPLY_IRRELEVANT = 1, |
207 | |||
208 | /** | ||
209 | * Query is valid, no reply given. | ||
210 | */ | ||
211 | GNUNET_BLOCK_EVALUATION_REQUEST_VALID = 10, | ||
212 | |||
213 | /** | ||
214 | * Query format does not match block type (invalid query). For | ||
215 | * example, xquery not given or xquery_size not appropriate for | ||
216 | * type. | ||
217 | */ | ||
218 | GNUNET_BLOCK_EVALUATION_REQUEST_INVALID = 11, | ||
219 | |||
220 | /** | ||
221 | * Specified block type not supported by this plugin. | ||
222 | */ | ||
223 | GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED = 20 | ||
224 | }; | ||
225 | |||
226 | |||
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 | 184 | ||
237 | /** | 185 | /** |
238 | * Valid result, and there may be more. | 186 | * Valid result, and there may be more. |
239 | */ | 187 | */ |
240 | GNUNET_BLOCK_REPLY_OK_MORE = 1, | 188 | GNUNET_BLOCK_REPLY_OK_MORE = 2, |
241 | 189 | ||
242 | /** | 190 | /** |
243 | * Last possible valid result. | 191 | * Last possible valid result. |
244 | */ | 192 | */ |
245 | GNUNET_BLOCK_REPLY_OK_LAST = 2, | 193 | GNUNET_BLOCK_REPLY_OK_LAST = 3 |
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 | 194 | ||
262 | }; | 195 | }; |
263 | 196 | ||
@@ -356,44 +289,12 @@ GNUNET_BLOCK_group_destroy (struct GNUNET_BLOCK_Group *bg); | |||
356 | 289 | ||
357 | 290 | ||
358 | /** | 291 | /** |
359 | * Function called to validate a reply or a request. For | 292 | * Function called to validate if a reply is good for a |
360 | * request evaluation, simply pass "NULL" for the @a reply_block. | 293 | * particular query. |
361 | * Note that it is assumed that the reply has already been | ||
362 | * matched to the key (and signatures checked) as it would | ||
363 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
364 | * | ||
365 | * @param ctx block contxt | ||
366 | * @param type block type | ||
367 | * @param group block group to use for evaluation | ||
368 | * @param eo evaluation options to control evaluation | ||
369 | * @param query original query (hash) | ||
370 | * @param xquery extrended query data (can be NULL, depending on type) | ||
371 | * @param xquery_size number of bytes in @a xquery | ||
372 | * @param reply_block response to validate | ||
373 | * @param reply_block_size number of bytes in @a reply_block | ||
374 | * @return characterization of result | ||
375 | * @deprecated | ||
376 | */ | ||
377 | enum GNUNET_BLOCK_EvaluationResult | ||
378 | GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | ||
379 | enum GNUNET_BLOCK_Type type, | ||
380 | struct GNUNET_BLOCK_Group *group, | ||
381 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
382 | const struct GNUNET_HashCode *query, | ||
383 | const void *xquery, | ||
384 | size_t xquery_size, | ||
385 | const void *reply_block, | ||
386 | size_t reply_block_size); | ||
387 | |||
388 | |||
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 | * | 294 | * |
394 | * @param ctx block contxt | 295 | * @param ctx block contxt |
395 | * @param type block type | 296 | * @param type block type |
396 | * @param group block group to use for evaluation | 297 | * @param[in,out] group block group to use for evaluation |
397 | * @param query original query (hash) | 298 | * @param query original query (hash) |
398 | * @param xquery extrended query data (can be NULL, depending on type) | 299 | * @param xquery extrended query data (can be NULL, depending on type) |
399 | * @param xquery_size number of bytes in @a xquery | 300 | * @param xquery_size number of bytes in @a xquery |
@@ -436,7 +337,6 @@ GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, | |||
436 | * | 337 | * |
437 | * @param ctx block contxt | 338 | * @param ctx block contxt |
438 | * @param type block type | 339 | * @param type block type |
439 | * @param query query key (hash) | ||
440 | * @param block payload to put | 340 | * @param block payload to put |
441 | * @param block_size number of bytes in @a block | 341 | * @param block_size number of bytes in @a block |
442 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, | 342 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not, |
@@ -445,13 +345,14 @@ GNUNET_BLOCK_check_query (struct GNUNET_BLOCK_Context *ctx, | |||
445 | enum GNUNET_GenericReturnValue | 345 | enum GNUNET_GenericReturnValue |
446 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | 346 | GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, |
447 | enum GNUNET_BLOCK_Type type, | 347 | enum GNUNET_BLOCK_Type type, |
448 | const struct GNUNET_HashCode *query, | ||
449 | const void *block, | 348 | const void *block, |
450 | size_t block_size); | 349 | size_t block_size); |
451 | 350 | ||
452 | 351 | ||
453 | /** | 352 | /** |
454 | * Function called to obtain the key for a block. | 353 | * Function called to obtain the @a key for a @a block. |
354 | * If the @a block is malformed, the function should | ||
355 | * zero-out @a key and return #GNUNET_OK. | ||
455 | * | 356 | * |
456 | * @param ctx block context | 357 | * @param ctx block context |
457 | * @param type block type | 358 | * @param type block type |
@@ -459,9 +360,8 @@ GNUNET_BLOCK_check_block (struct GNUNET_BLOCK_Context *ctx, | |||
459 | * @param block_size number of bytes in @a block | 360 | * @param block_size number of bytes in @a block |
460 | * @param key set to the key (query) for the given block | 361 | * @param key set to the key (query) for the given block |
461 | * @return #GNUNET_YES on success, | 362 | * @return #GNUNET_YES on success, |
462 | * #GNUNET_NO if the block is malformed | 363 | * #GNUNET_NO if extracting a key from a block of this @a type does not work |
463 | * #GNUNET_SYSERR if type not supported | 364 | * #GNUNET_SYSERR if @a type not supported |
464 | * (or if extracting a key from a block of this type does not work) | ||
465 | */ | 365 | */ |
466 | enum GNUNET_GenericReturnValue | 366 | enum GNUNET_GenericReturnValue |
467 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | 367 | GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, |
diff --git a/src/include/gnunet_block_plugin.h b/src/include/gnunet_block_plugin.h index 2c9a3839d..1fa7ccf8b 100644 --- a/src/include/gnunet_block_plugin.h +++ b/src/include/gnunet_block_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) 2010,2013,2017 GNUnet e.V. | 3 | Copyright (C) 2010, 2013, 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 |
@@ -163,43 +163,9 @@ typedef struct GNUNET_BLOCK_Group * | |||
163 | 163 | ||
164 | 164 | ||
165 | /** | 165 | /** |
166 | * Function called to validate a reply or a request. For | ||
167 | * request evaluation, simply pass "NULL" for the @a reply_block. | ||
168 | * Note that it is assumed that the reply has already been | ||
169 | * matched to the key (and signatures checked) as it would | ||
170 | * be done with the "get_key" function. | ||
171 | * | ||
172 | * @param cls closure | ||
173 | * @param ctx block context | ||
174 | * @param type block type | ||
175 | * @param group which block group to use for evaluation | ||
176 | * @param eo evaluation options to control evaluation | ||
177 | * @param query original query (hash) | ||
178 | * @param xquery extrended query data (can be NULL, depending on type) | ||
179 | * @param xquery_size number of bytes in @a xquery | ||
180 | * @param reply_block response to validate | ||
181 | * @param reply_block_size number of bytes in @a reply_block | ||
182 | * @return characterization of result | ||
183 | * @deprecated | ||
184 | */ | ||
185 | typedef enum GNUNET_BLOCK_EvaluationResult | ||
186 | (*GNUNET_BLOCK_EvaluationFunction)(void *cls, | ||
187 | struct GNUNET_BLOCK_Context *ctx, | ||
188 | enum GNUNET_BLOCK_Type type, | ||
189 | struct GNUNET_BLOCK_Group *group, | ||
190 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
191 | const struct GNUNET_HashCode *query, | ||
192 | const void *xquery, | ||
193 | size_t xquery_size, | ||
194 | const void *reply_block, | ||
195 | size_t reply_block_size); | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Function called to validate a query. | 166 | * Function called to validate a query. |
200 | * | 167 | * |
201 | * @param cls closure | 168 | * @param cls closure |
202 | * @param ctx block context | ||
203 | * @param type block type | 169 | * @param type block type |
204 | * @param query original query (hash) | 170 | * @param query original query (hash) |
205 | * @param xquery extrended query data (can be NULL, depending on type) | 171 | * @param xquery extrended query data (can be NULL, depending on type) |
@@ -215,19 +181,17 @@ typedef enum GNUNET_GenericReturnValue | |||
215 | 181 | ||
216 | 182 | ||
217 | /** | 183 | /** |
218 | * Function called to validate a block for storage. | 184 | * Function called to validate a @a block for storage. |
219 | * | 185 | * |
220 | * @param cls closure | 186 | * @param cls closure |
221 | * @param type block type | 187 | * @param type block type |
222 | * @param query key for the block (hash), must match exactly | ||
223 | * @param block block data to validate | 188 | * @param block block data to validate |
224 | * @param block_size number of bytes in @a block | 189 | * @param block_size number of bytes in @a block |
225 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 190 | * @return #GNUNET_OK if the @a block is fine, #GNUNET_NO if not, #GNUNET_SYSERR if the @a type is not supported |
226 | */ | 191 | */ |
227 | typedef enum GNUNET_GenericReturnValue | 192 | typedef enum GNUNET_GenericReturnValue |
228 | (*GNUNET_BLOCK_BlockEvaluationFunction)(void *cls, | 193 | (*GNUNET_BLOCK_BlockEvaluationFunction)(void *cls, |
229 | enum GNUNET_BLOCK_Type type, | 194 | enum GNUNET_BLOCK_Type type, |
230 | const struct GNUNET_HashCode *query, | ||
231 | const void *block, | 195 | const void *block, |
232 | size_t block_size); | 196 | size_t block_size); |
233 | 197 | ||
@@ -260,17 +224,18 @@ typedef enum GNUNET_BLOCK_ReplyEvaluationResult | |||
260 | 224 | ||
261 | 225 | ||
262 | /** | 226 | /** |
263 | * Function called to obtain the key for a block. | 227 | * Function called to obtain the @a key for a block. |
228 | * If the @a block is malformed, the function should | ||
229 | * zero-out @a key and return #GNUNET_OK. | ||
264 | * | 230 | * |
265 | * @param cls closure | 231 | * @param cls closure |
266 | * @param type block type | 232 | * @param type block type |
267 | * @param block block to get the key for | 233 | * @param block block to get the @a key for |
268 | * @param block_size number of bytes in @a block | 234 | * @param block_size number of bytes in @a block |
269 | * @param[out] key set to the key (query) for the given block | 235 | * @param[out] key set to the key (query) for the given block |
270 | * @return #GNUNET_YES on success, | 236 | * @return #GNUNET_YES on success, |
271 | * #GNUNET_NO if the block is malformed | 237 | * #GNUNET_NO if extracting a key for this @a type does not work |
272 | * #GNUNET_SYSERR if type not supported | 238 | * #GNUNET_SYSERR if @a type not supported |
273 | * (or if extracting a key from a block of this type does not work) | ||
274 | */ | 239 | */ |
275 | typedef enum GNUNET_GenericReturnValue | 240 | typedef enum GNUNET_GenericReturnValue |
276 | (*GNUNET_BLOCK_GetKeyFunction) (void *cls, | 241 | (*GNUNET_BLOCK_GetKeyFunction) (void *cls, |
@@ -297,14 +262,6 @@ struct GNUNET_BLOCK_PluginFunctions | |||
297 | const enum GNUNET_BLOCK_Type *types; | 262 | const enum GNUNET_BLOCK_Type *types; |
298 | 263 | ||
299 | /** | 264 | /** |
300 | * Main function of a block plugin. Allows us to check if a | ||
301 | * block matches a query. | ||
302 | * | ||
303 | * @param deprecated | ||
304 | */ | ||
305 | GNUNET_BLOCK_EvaluationFunction evaluate; | ||
306 | |||
307 | /** | ||
308 | * Obtain the key for a given block (if possible). | 265 | * Obtain the key for a given block (if possible). |
309 | */ | 266 | */ |
310 | GNUNET_BLOCK_GetKeyFunction get_key; | 267 | GNUNET_BLOCK_GetKeyFunction get_key; |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 4472d3ee8..9bcd99c7b 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -623,6 +623,31 @@ GNUNET_abort_ (void) GNUNET_NORETURN; | |||
623 | 623 | ||
624 | 624 | ||
625 | /** | 625 | /** |
626 | * Convert a buffer to an 8-character string | ||
627 | * representative of the contents. This is used | ||
628 | * for logging binary data when debugging. | ||
629 | * | ||
630 | * @param buf buffer to log | ||
631 | * @param buf_size number of bytes in @a buf | ||
632 | * @return text representation of buf, valid until next | ||
633 | * call to this function | ||
634 | */ | ||
635 | const char * | ||
636 | GNUNET_b2s (const void *buf, | ||
637 | size_t buf_size); | ||
638 | |||
639 | |||
640 | /** | ||
641 | * Convert a fixed-sized object to a string using | ||
642 | * #GNUNET_b2s(). | ||
643 | * | ||
644 | * @param obj address of object to convert | ||
645 | * @return string representing the binary obj buffer | ||
646 | */ | ||
647 | #define GNUNET_B2S(obj) GNUNET_b2s ((obj), sizeof (*(obj))) | ||
648 | |||
649 | |||
650 | /** | ||
626 | * @ingroup logging | 651 | * @ingroup logging |
627 | * Ignore the next @a n calls to the log function. | 652 | * Ignore the next @a n calls to the log function. |
628 | * | 653 | * |
@@ -1240,7 +1265,7 @@ GNUNET_is_zero_ (const void *a, | |||
1240 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise | 1265 | * @return GNUNET_YES if a is zero, GNUNET_NO otherwise |
1241 | */ | 1266 | */ |
1242 | #define GNUNET_is_zero(a) \ | 1267 | #define GNUNET_is_zero(a) \ |
1243 | GNUNET_is_zero_ (a, sizeof (*a)) | 1268 | GNUNET_is_zero_ ((a), sizeof (*(a))) |
1244 | 1269 | ||
1245 | 1270 | ||
1246 | /** | 1271 | /** |
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 1ab135d80..72d783148 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -307,7 +307,7 @@ struct GNUNET_CRYPTO_SymmetricSessionKey | |||
307 | /** | 307 | /** |
308 | * Type of a nonce used for challenges. | 308 | * Type of a nonce used for challenges. |
309 | */ | 309 | */ |
310 | struct ChallengeNonceP | 310 | struct GNUNET_CRYPTO_ChallengeNonceP |
311 | { | 311 | { |
312 | /** | 312 | /** |
313 | * The value of the nonce. Note that this is NOT a hash. | 313 | * The value of the nonce. Note that this is NOT a hash. |
@@ -2551,9 +2551,9 @@ GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv); | |||
2551 | * @param[out] pub where to write the public key | 2551 | * @param[out] pub where to write the public key |
2552 | */ | 2552 | */ |
2553 | void | 2553 | void |
2554 | GNUNET_CRYPTO_cs_private_key_get_public (const struct | 2554 | GNUNET_CRYPTO_cs_private_key_get_public ( |
2555 | GNUNET_CRYPTO_CsPrivateKey *priv, | 2555 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
2556 | struct GNUNET_CRYPTO_CsPublicKey *pub); | 2556 | struct GNUNET_CRYPTO_CsPublicKey *pub); |
2557 | 2557 | ||
2558 | 2558 | ||
2559 | /** | 2559 | /** |
@@ -2565,11 +2565,13 @@ GNUNET_CRYPTO_cs_private_key_get_public (const struct | |||
2565 | * Comment: Can be done in one HKDF shot and split output. | 2565 | * Comment: Can be done in one HKDF shot and split output. |
2566 | * | 2566 | * |
2567 | * @param nonce is a random nonce | 2567 | * @param nonce is a random nonce |
2568 | * @param seed seed to use in derivation | ||
2568 | * @param lts is a long-term-secret in form of a private key | 2569 | * @param lts is a long-term-secret in form of a private key |
2569 | * @param[out] r array containing derived secrets r0 and r1 | 2570 | * @param[out] r array containing derived secrets r0 and r1 |
2570 | */ | 2571 | */ |
2571 | void | 2572 | void |
2572 | GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, | 2573 | GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, |
2574 | const char *seed, | ||
2573 | const struct GNUNET_CRYPTO_CsPrivateKey *lts, | 2575 | const struct GNUNET_CRYPTO_CsPrivateKey *lts, |
2574 | struct GNUNET_CRYPTO_CsRSecret r[2]); | 2576 | struct GNUNET_CRYPTO_CsRSecret r[2]); |
2575 | 2577 | ||
@@ -2595,10 +2597,9 @@ GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | |||
2595 | * @param[out] bs array containing the two derived blinding secrets | 2597 | * @param[out] bs array containing the two derived blinding secrets |
2596 | */ | 2598 | */ |
2597 | void | 2599 | void |
2598 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct | 2600 | GNUNET_CRYPTO_cs_blinding_secrets_derive ( |
2599 | GNUNET_CRYPTO_CsNonce *blind_seed, | 2601 | const struct GNUNET_CRYPTO_CsNonce *blind_seed, |
2600 | struct GNUNET_CRYPTO_CsBlindingSecret | 2602 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]); |
2601 | bs[2]); | ||
2602 | 2603 | ||
2603 | 2604 | ||
2604 | /** | 2605 | /** |
@@ -2614,15 +2615,14 @@ GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct | |||
2614 | * @param[out] blinded_r_pub array of the two blinded R | 2615 | * @param[out] blinded_r_pub array of the two blinded R |
2615 | */ | 2616 | */ |
2616 | void | 2617 | void |
2617 | GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret | 2618 | GNUNET_CRYPTO_cs_calc_blinded_c ( |
2618 | bs[2], | 2619 | const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], |
2619 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], | 2620 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], |
2620 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 2621 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
2621 | const void *msg, | 2622 | const void *msg, |
2622 | size_t msg_len, | 2623 | size_t msg_len, |
2623 | struct GNUNET_CRYPTO_CsC blinded_c[2], | 2624 | struct GNUNET_CRYPTO_CsC blinded_c[2], |
2624 | struct GNUNET_CRYPTO_CsRPublic | 2625 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2]); |
2625 | blinded_r_pub[2]); | ||
2626 | 2626 | ||
2627 | 2627 | ||
2628 | /** | 2628 | /** |
@@ -2642,13 +2642,12 @@ GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret | |||
2642 | * @return 0 or 1 for b (see Clause Blind Signature Scheme) | 2642 | * @return 0 or 1 for b (see Clause Blind Signature Scheme) |
2643 | */ | 2643 | */ |
2644 | unsigned int | 2644 | unsigned int |
2645 | GNUNET_CRYPTO_cs_sign_derive (const struct GNUNET_CRYPTO_CsPrivateKey *priv, | 2645 | GNUNET_CRYPTO_cs_sign_derive ( |
2646 | const struct GNUNET_CRYPTO_CsRSecret r[2], | 2646 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
2647 | const struct GNUNET_CRYPTO_CsC c[2], | 2647 | const struct GNUNET_CRYPTO_CsRSecret r[2], |
2648 | const struct GNUNET_CRYPTO_CsNonce *nonce, | 2648 | const struct GNUNET_CRYPTO_CsC c[2], |
2649 | struct GNUNET_CRYPTO_CsBlindS * | 2649 | const struct GNUNET_CRYPTO_CsNonce *nonce, |
2650 | blinded_signature_scalar | 2650 | struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar); |
2651 | ); | ||
2652 | 2651 | ||
2653 | 2652 | ||
2654 | /** | 2653 | /** |
@@ -2659,10 +2658,10 @@ GNUNET_CRYPTO_cs_sign_derive (const struct GNUNET_CRYPTO_CsPrivateKey *priv, | |||
2659 | * @param[out] signature_scalar where to write the unblinded signature | 2658 | * @param[out] signature_scalar where to write the unblinded signature |
2660 | */ | 2659 | */ |
2661 | void | 2660 | void |
2662 | GNUNET_CRYPTO_cs_unblind (const struct | 2661 | GNUNET_CRYPTO_cs_unblind ( |
2663 | GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, | 2662 | const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, |
2664 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, | 2663 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, |
2665 | struct GNUNET_CRYPTO_CsS *signature_scalar); | 2664 | struct GNUNET_CRYPTO_CsS *signature_scalar); |
2666 | 2665 | ||
2667 | 2666 | ||
2668 | /** | 2667 | /** |
diff --git a/src/include/gnunet_datacache_lib.h b/src/include/gnunet_datacache_lib.h index 11076e3e7..737a5c845 100644 --- a/src/include/gnunet_datacache_lib.h +++ b/src/include/gnunet_datacache_lib.h | |||
@@ -154,6 +154,7 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
154 | * | 154 | * |
155 | * @param h handle to the datacache | 155 | * @param h handle to the datacache |
156 | * @param key area of the keyspace to look into | 156 | * @param key area of the keyspace to look into |
157 | * @param type entries of which type are relevant? | ||
157 | * @param num_results number of results that should be returned to @a iter | 158 | * @param num_results number of results that should be returned to @a iter |
158 | * @param iter maybe NULL (to just count) | 159 | * @param iter maybe NULL (to just count) |
159 | * @param iter_cls closure for @a iter | 160 | * @param iter_cls closure for @a iter |
@@ -162,6 +163,7 @@ GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h, | |||
162 | unsigned int | 163 | unsigned int |
163 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, | 164 | GNUNET_DATACACHE_get_closest (struct GNUNET_DATACACHE_Handle *h, |
164 | const struct GNUNET_HashCode *key, | 165 | const struct GNUNET_HashCode *key, |
166 | enum GNUNET_BLOCK_Type type, | ||
165 | unsigned int num_results, | 167 | unsigned int num_results, |
166 | GNUNET_DATACACHE_Iterator iter, | 168 | GNUNET_DATACACHE_Iterator iter, |
167 | void *iter_cls); | 169 | void *iter_cls); |
diff --git a/src/include/gnunet_datacache_plugin.h b/src/include/gnunet_datacache_plugin.h index 24570be72..34bf5f277 100644 --- a/src/include/gnunet_datacache_plugin.h +++ b/src/include/gnunet_datacache_plugin.h | |||
@@ -158,14 +158,16 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
158 | 158 | ||
159 | 159 | ||
160 | /** | 160 | /** |
161 | * Iterate over the results that are "close" to a particular key in | 161 | * Iterate over the results that are "close" to a particular key in the |
162 | * the datacache. "close" is defined as numerically larger than @a | 162 | * datacache. "close" is defined as returning the @a num_results that are |
163 | * key (when interpreted as a circular address space), with small | 163 | * numerically closest and larger than @a key and also @a num_results that |
164 | * distance. | 164 | * are numerically lower than @a key. Thus, the maximum number of results |
165 | * returned is actually twice @a num_results. | ||
165 | * | 166 | * |
166 | * @param cls closure (internal context for the plugin) | 167 | * @param cls closure (internal context for the plugin) |
167 | * @param key area of the keyspace to look into | 168 | * @param key area of the keyspace to look into |
168 | * @param num_results number of results that should be returned to @a iter | 169 | * @param type desired block type for the replies |
170 | * @param num_results half the number of results that should be returned to @a iter | ||
169 | * @param iter maybe NULL (to just count) | 171 | * @param iter maybe NULL (to just count) |
170 | * @param iter_cls closure for @a iter | 172 | * @param iter_cls closure for @a iter |
171 | * @return the number of results found | 173 | * @return the number of results found |
@@ -173,6 +175,7 @@ struct GNUNET_DATACACHE_PluginFunctions | |||
173 | unsigned int | 175 | unsigned int |
174 | (*get_closest) (void *cls, | 176 | (*get_closest) (void *cls, |
175 | const struct GNUNET_HashCode *key, | 177 | const struct GNUNET_HashCode *key, |
178 | enum GNUNET_BLOCK_Type type, | ||
176 | unsigned int num_results, | 179 | unsigned int num_results, |
177 | GNUNET_DATACACHE_Iterator iter, | 180 | GNUNET_DATACACHE_Iterator iter, |
178 | void *iter_cls); | 181 | void *iter_cls); |
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index 768b19fb1..22b659d66 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h | |||
@@ -101,14 +101,14 @@ enum GNUNET_DHT_RouteOption | |||
101 | GNUNET_DHT_RO_RECORD_ROUTE = 2, | 101 | GNUNET_DHT_RO_RECORD_ROUTE = 2, |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * This is a 'FIND-PEER' request, so approximate results are fine. | 104 | * Approximate results are fine. |
105 | */ | 105 | */ |
106 | GNUNET_DHT_RO_FIND_PEER = 4, | 106 | GNUNET_DHT_RO_FIND_APPROXIMATE = 4, |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * Flag given to monitors if this was the last hop for a GET/PUT. | 109 | * Flag given to monitors if this was the last hop for a GET/PUT. |
110 | * This is only used for internal processing. | 110 | * This is only used for internal processing. |
111 | */ | 111 | */ |
112 | GNUNET_DHT_RO_LAST_HOP = 65535 | 112 | GNUNET_DHT_RO_LAST_HOP = 65535 |
113 | }; | 113 | }; |
114 | 114 | ||
@@ -131,11 +131,6 @@ struct GNUNET_DHT_HopSignature | |||
131 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | 131 | struct GNUNET_TIME_AbsoluteNBO expiration_time; |
132 | 132 | ||
133 | /** | 133 | /** |
134 | * Key of the block. | ||
135 | */ | ||
136 | struct GNUNET_HashCode key; | ||
137 | |||
138 | /** | ||
139 | * Hash over the payload of the block. | 134 | * Hash over the payload of the block. |
140 | */ | 135 | */ |
141 | struct GNUNET_HashCode h_data; | 136 | struct GNUNET_HashCode h_data; |
@@ -181,6 +176,7 @@ struct GNUNET_DHT_PathElement | |||
181 | 176 | ||
182 | }; | 177 | }; |
183 | 178 | ||
179 | |||
184 | GNUNET_NETWORK_STRUCT_END | 180 | GNUNET_NETWORK_STRUCT_END |
185 | 181 | ||
186 | /** | 182 | /** |
@@ -266,7 +262,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph); | |||
266 | * | 262 | * |
267 | * @param cls closure | 263 | * @param cls closure |
268 | * @param exp when will this value expire | 264 | * @param exp when will this value expire |
269 | * @param key key of the result | 265 | * @param query_hash key of the query |
270 | * @param get_path peers on reply path (or NULL if not recorded) | 266 | * @param get_path peers on reply path (or NULL if not recorded) |
271 | * [0] = datastore's first neighbor, [length - 1] = local peer | 267 | * [0] = datastore's first neighbor, [length - 1] = local peer |
272 | * @param get_path_length number of entries in @a get_path | 268 | * @param get_path_length number of entries in @a get_path |
@@ -282,7 +278,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph); | |||
282 | typedef void | 278 | typedef void |
283 | (*GNUNET_DHT_GetIterator) (void *cls, | 279 | (*GNUNET_DHT_GetIterator) (void *cls, |
284 | struct GNUNET_TIME_Absolute exp, | 280 | struct GNUNET_TIME_Absolute exp, |
285 | const struct GNUNET_HashCode *key, | 281 | const struct GNUNET_HashCode *query_hash, |
286 | const struct GNUNET_DHT_PathElement *get_path, | 282 | const struct GNUNET_DHT_PathElement *get_path, |
287 | unsigned int get_path_length, | 283 | unsigned int get_path_length, |
288 | const struct GNUNET_DHT_PathElement *put_path, | 284 | const struct GNUNET_DHT_PathElement *put_path, |
@@ -487,7 +483,6 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, | |||
487 | * the last signature on the path is never verified as that is the slot where | 483 | * the last signature on the path is never verified as that is the slot where |
488 | * our peer (@a me) would need to sign. | 484 | * our peer (@a me) would need to sign. |
489 | * | 485 | * |
490 | * @param key key of the data (not necessarily the query hash) | ||
491 | * @param data payload (the block) | 486 | * @param data payload (the block) |
492 | * @param data_size number of bytes in @a data | 487 | * @param data_size number of bytes in @a data |
493 | * @param exp_time expiration time of @a data | 488 | * @param exp_time expiration time of @a data |
@@ -501,8 +496,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path, | |||
501 | * @a get_path_len + @a put_path_len - 1 if no signature was valid | 496 | * @a get_path_len + @a put_path_len - 1 if no signature was valid |
502 | */ | 497 | */ |
503 | unsigned int | 498 | unsigned int |
504 | GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, | 499 | GNUNET_DHT_verify_path (const void *data, |
505 | const void *data, | ||
506 | size_t data_size, | 500 | size_t data_size, |
507 | struct GNUNET_TIME_Absolute exp_time, | 501 | struct GNUNET_TIME_Absolute exp_time, |
508 | const struct GNUNET_DHT_PathElement *put_path, | 502 | const struct GNUNET_DHT_PathElement *put_path, |
@@ -512,6 +506,63 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, | |||
512 | const struct GNUNET_PeerIdentity *me); | 506 | const struct GNUNET_PeerIdentity *me); |
513 | 507 | ||
514 | 508 | ||
509 | /** | ||
510 | * Handle to get a HELLO URL from the DHT for manual bootstrapping. | ||
511 | */ | ||
512 | struct GNUNET_DHT_HelloGetHandle; | ||
513 | |||
514 | |||
515 | /** | ||
516 | * Signature called with the result of a HELLO GET operation. | ||
517 | * | ||
518 | * @param cls closure | ||
519 | * @param hello_url the resulting HELLO URL, NULL on error | ||
520 | */ | ||
521 | typedef void | ||
522 | (*GNUNET_DHT_HelloGetCallback)(void *cls, | ||
523 | const char *hello_url); | ||
524 | |||
525 | |||
526 | /** | ||
527 | * Obtain HELLO URL of the DHT identified by @a dht_handle. | ||
528 | * | ||
529 | * @param dht_handle DHT to query | ||
530 | * @param cb function to call with the result | ||
531 | * @param cb_cls closure for @a cb | ||
532 | * @return NULL on failure | ||
533 | */ | ||
534 | struct GNUNET_DHT_HelloGetHandle * | ||
535 | GNUNET_DHT_hello_get (struct GNUNET_DHT_Handle *dht_handle, | ||
536 | GNUNET_DHT_HelloGetCallback cb, | ||
537 | void *cb_cls); | ||
538 | |||
539 | |||
540 | /** | ||
541 | * Cancel hello get operation. | ||
542 | * | ||
543 | * @param[in] hgh operation to cancel. | ||
544 | */ | ||
545 | void | ||
546 | GNUNET_DHT_hello_get_cancel (struct GNUNET_DHT_HelloGetHandle *hgh); | ||
547 | |||
548 | |||
549 | /** | ||
550 | * Offer HELLO URL of the DHT identified by @a dht_handle. | ||
551 | * Callback may be invoked once, only way to cancel is to | ||
552 | * disconnect @a dht_handle. | ||
553 | * | ||
554 | * @param dht_handle DHT to query | ||
555 | * @param url URL with a HELLO to offer to the DHT | ||
556 | * @param cb function called when done | ||
557 | * @param cb_cls closure for @a cb | ||
558 | */ | ||
559 | void | ||
560 | GNUNET_DHT_hello_offer (struct GNUNET_DHT_Handle *dht_handle, | ||
561 | const char *url, | ||
562 | GNUNET_SCHEDULER_TaskCallback cb, | ||
563 | void *cb_cls); | ||
564 | |||
565 | |||
515 | #if 0 /* keep Emacsens' auto-indent happy */ | 566 | #if 0 /* keep Emacsens' auto-indent happy */ |
516 | { | 567 | { |
517 | #endif | 568 | #endif |
diff --git a/src/include/gnunet_dhtu_plugin.h b/src/include/gnunet_dhtu_plugin.h index 2c97d5848..fa0b5f667 100644 --- a/src/include/gnunet_dhtu_plugin.h +++ b/src/include/gnunet_dhtu_plugin.h | |||
@@ -59,15 +59,6 @@ struct GNUNET_DHTU_PreferenceHandle; | |||
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Key used to identify peer's position in the DHT. | ||
63 | */ | ||
64 | struct GNUNET_DHTU_HashKey | ||
65 | { | ||
66 | struct GNUNET_HashCode sha512; | ||
67 | }; | ||
68 | |||
69 | |||
70 | /** | ||
71 | * The datastore service will pass a pointer to a struct | 62 | * The datastore service will pass a pointer to a struct |
72 | * of this type as the first and only argument to the | 63 | * of this type as the first and only argument to the |
73 | * entry point of each datastore plugin. | 64 | * entry point of each datastore plugin. |
@@ -88,7 +79,6 @@ struct GNUNET_DHTU_PluginEnvironment | |||
88 | * Function to call with new addresses of this peer. | 79 | * Function to call with new addresses of this peer. |
89 | * | 80 | * |
90 | * @param cls the closure | 81 | * @param cls the closure |
91 | * @param key hash position of this address in the DHT | ||
92 | * @param address address under which we are likely reachable, | 82 | * @param address address under which we are likely reachable, |
93 | * pointer will remain valid until @e address_del_cb is called; to be used for HELLOs. Example: "ip+udp://1.1.1.1:2086/" | 83 | * pointer will remain valid until @e address_del_cb is called; to be used for HELLOs. Example: "ip+udp://1.1.1.1:2086/" |
94 | * @param source handle for sending from this address, NULL if we can only receive | 84 | * @param source handle for sending from this address, NULL if we can only receive |
@@ -96,7 +86,6 @@ struct GNUNET_DHTU_PluginEnvironment | |||
96 | */ | 86 | */ |
97 | void | 87 | void |
98 | (*address_add_cb)(void *cls, | 88 | (*address_add_cb)(void *cls, |
99 | struct GNUNET_DHTU_HashKey *key, | ||
100 | const char *address, | 89 | const char *address, |
101 | struct GNUNET_DHTU_Source *source, | 90 | struct GNUNET_DHTU_Source *source, |
102 | void **ctx); | 91 | void **ctx); |
@@ -128,20 +117,19 @@ struct GNUNET_DHTU_PluginEnvironment | |||
128 | * that peer. | 117 | * that peer. |
129 | * | 118 | * |
130 | * @param cls the closure | 119 | * @param cls the closure |
131 | * @param pk public key of the target, | ||
132 | * pointer will remain valid until @e disconnect_cb is called | ||
133 | * @para peer_id hash position of the peer, | ||
134 | * pointer will remain valid until @e disconnect_cb is called | ||
135 | * @param target handle to the target, | 120 | * @param target handle to the target, |
136 | * pointer will remain valid until @e disconnect_cb is called | 121 | * pointer will remain valid until @e disconnect_cb is called |
122 | * @para pid peer identity, | ||
123 | * pointer will remain valid until @e disconnect_cb is called | ||
137 | * @param[out] ctx storage space for DHT to use in association with this target | 124 | * @param[out] ctx storage space for DHT to use in association with this target |
138 | */ | 125 | */ |
139 | void | 126 | void |
140 | (*connect_cb)(void *cls, | 127 | (*connect_cb)(void *cls, |
141 | struct GNUNET_DHTU_Target *target, | 128 | struct GNUNET_DHTU_Target *target, |
142 | struct GNUNET_DHTU_HashKey *key, | 129 | const struct GNUNET_PeerIdentity *pid, |
143 | void **ctx); | 130 | void **ctx); |
144 | 131 | ||
132 | |||
145 | /** | 133 | /** |
146 | * Function to call when we disconnected from a peer and can henceforth | 134 | * Function to call when we disconnected from a peer and can henceforth |
147 | * cannot transmit to that peer anymore. | 135 | * cannot transmit to that peer anymore. |
@@ -185,10 +173,12 @@ struct GNUNET_DHTU_PluginFunctions | |||
185 | * Request creation of a session with a peer at the given @a address. | 173 | * Request creation of a session with a peer at the given @a address. |
186 | * | 174 | * |
187 | * @param cls closure (internal context for the plugin) | 175 | * @param cls closure (internal context for the plugin) |
188 | * @param address target address to connect to | 176 | * @param pid target identity of the peer to connect to |
177 | * @param address target address URI to connect to | ||
189 | */ | 178 | */ |
190 | void | 179 | void |
191 | (*try_connect) (void *cls, | 180 | (*try_connect) (void *cls, |
181 | const struct GNUNET_PeerIdentity *pid, | ||
192 | const char *address); | 182 | const char *address); |
193 | 183 | ||
194 | 184 | ||
@@ -205,7 +195,7 @@ struct GNUNET_DHTU_PluginFunctions | |||
205 | struct GNUNET_DHTU_Target *target); | 195 | struct GNUNET_DHTU_Target *target); |
206 | 196 | ||
207 | /** | 197 | /** |
208 | * Do no long request underlay to keep the connection alive. | 198 | * Do no longer request underlay to keep the connection alive. |
209 | * | 199 | * |
210 | * @param cls closure | 200 | * @param cls closure |
211 | * @param target connection to keep alive | 201 | * @param target connection to keep alive |
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index 686035e2c..96936bad2 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h | |||
@@ -1729,7 +1729,7 @@ GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s); | |||
1729 | * @return "filename" field of the structure (can be NULL) | 1729 | * @return "filename" field of the structure (can be NULL) |
1730 | */ | 1730 | */ |
1731 | const char * | 1731 | const char * |
1732 | GNUNET_FS_file_information_get_filename (struct GNUNET_FS_FileInformation *s); | 1732 | GNUNET_FS_file_information_get_filename (const struct GNUNET_FS_FileInformation *s); |
1733 | 1733 | ||
1734 | 1734 | ||
1735 | /** | 1735 | /** |
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 3f6c9b9aa..5c06f8045 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h | |||
@@ -48,12 +48,6 @@ extern "C" { | |||
48 | 48 | ||
49 | 49 | ||
50 | /** | 50 | /** |
51 | * String we use to indicate an empty label (top-level | ||
52 | * entry in the zone). DNS uses "@", so do we. | ||
53 | */ | ||
54 | #define GNUNET_GNS_EMPTY_LABEL_AT "@" | ||
55 | |||
56 | /** | ||
57 | * Connection to the GNS service. | 51 | * Connection to the GNS service. |
58 | */ | 52 | */ |
59 | struct GNUNET_GNS_Handle; | 53 | struct GNUNET_GNS_Handle; |
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index fdbac3cf5..51dd5972d 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h | |||
@@ -44,6 +44,12 @@ extern "C" { | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * String we use to indicate an empty label (top-level | ||
48 | * entry in the zone). DNS uses "@", so do we. | ||
49 | */ | ||
50 | #define GNUNET_GNS_EMPTY_LABEL_AT "@" | ||
51 | |||
52 | /** | ||
47 | * Maximum size of a value that can be stored in a GNS block. | 53 | * Maximum size of a value that can be stored in a GNS block. |
48 | */ | 54 | */ |
49 | #define GNUNET_GNSRECORD_MAX_BLOCK_SIZE (63 * 1024) | 55 | #define GNUNET_GNSRECORD_MAX_BLOCK_SIZE (63 * 1024) |
@@ -299,8 +305,6 @@ struct GNUNET_GNSRECORD_ReverseRecord | |||
299 | /* followed by the name the delegator uses to refer to our namespace */ | 305 | /* followed by the name the delegator uses to refer to our namespace */ |
300 | }; | 306 | }; |
301 | 307 | ||
302 | GNUNET_NETWORK_STRUCT_END | ||
303 | |||
304 | 308 | ||
305 | /** | 309 | /** |
306 | * Process a records that were decrypted from a block. | 310 | * Process a records that were decrypted from a block. |
@@ -427,7 +431,8 @@ GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd); | |||
427 | 431 | ||
428 | 432 | ||
429 | /** | 433 | /** |
430 | * Normalize a UTF-8 string to UTF-8 NFC | 434 | * Normalize a UTF-8 string to a GNS name |
435 | * | ||
431 | * @param src source string | 436 | * @param src source string |
432 | * @return converted result | 437 | * @return converted result |
433 | */ | 438 | */ |
@@ -436,15 +441,6 @@ GNUNET_GNSRECORD_string_normalize (const char *src); | |||
436 | 441 | ||
437 | 442 | ||
438 | /** | 443 | /** |
439 | * Convert a UTF-8 string to UTF-8 lowercase | ||
440 | * @param src source string | ||
441 | * @return converted result | ||
442 | */ | ||
443 | char * | ||
444 | GNUNET_GNSRECORD_string_to_lowercase (const char *src); | ||
445 | |||
446 | |||
447 | /** | ||
448 | * Convert a zone to a string (for printing debug messages). | 444 | * Convert a zone to a string (for printing debug messages). |
449 | * This is one of the very few calls in the entire API that is | 445 | * This is one of the very few calls in the entire API that is |
450 | * NOT reentrant! | 446 | * NOT reentrant! |
@@ -616,11 +612,14 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, | |||
616 | * | 612 | * |
617 | * @param rd_count number of records given in @a rd | 613 | * @param rd_count number of records given in @a rd |
618 | * @param rd array of records | 614 | * @param rd array of records |
615 | * @param min minimum expiration time | ||
619 | * @return absolute expiration time | 616 | * @return absolute expiration time |
620 | */ | 617 | */ |
621 | struct GNUNET_TIME_Absolute | 618 | struct GNUNET_TIME_Absolute |
622 | GNUNET_GNSRECORD_record_get_expiration_time ( | 619 | GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, |
623 | unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); | 620 | const struct |
621 | GNUNET_GNSRECORD_Data *rd, | ||
622 | struct GNUNET_TIME_Absolute min); | ||
624 | 623 | ||
625 | 624 | ||
626 | /** | 625 | /** |
@@ -700,6 +699,77 @@ GNUNET_GNSRECORD_data_from_identity (const struct | |||
700 | enum GNUNET_GenericReturnValue | 699 | enum GNUNET_GenericReturnValue |
701 | GNUNET_GNSRECORD_is_zonekey_type (uint32_t type); | 700 | GNUNET_GNSRECORD_is_zonekey_type (uint32_t type); |
702 | 701 | ||
702 | /** | ||
703 | * Check if this type is a critical record. | ||
704 | * | ||
705 | * @param type the type to check | ||
706 | * @return GNUNET_YES if it is critical. | ||
707 | */ | ||
708 | enum GNUNET_GenericReturnValue | ||
709 | GNUNET_GNSRECORD_is_critical (uint32_t type); | ||
710 | |||
711 | /** | ||
712 | * Normalize namestore records: Check for consistency and | ||
713 | * expirations. Purge expired records. Returns a "clean" record set. | ||
714 | * Also returns the minimum expiration time this block should be | ||
715 | * published under. | ||
716 | * Also checks rules with respect to labels (e.g. no delegations under | ||
717 | * the empty label) | ||
718 | * | ||
719 | * @param label the label under which this set (supposed to be) stored. | ||
720 | * @param rd input records | ||
721 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
722 | * @param rd_public where to write the converted records | ||
723 | * @param rd_public_count number of records written to @a rd_public | ||
724 | * @param min_expiry the minimum expiration of this set | ||
725 | * @param include_private GNUNET_YES if private records should be included. | ||
726 | * @param emsg the error message if something went wrong | ||
727 | * @return GNUNET_OK if set could be normalized and is consistent | ||
728 | */ | ||
729 | enum GNUNET_GenericReturnValue | ||
730 | GNUNET_GNSRECORD_normalize_record_set (const char *label, | ||
731 | const struct GNUNET_GNSRECORD_Data *rd, | ||
732 | unsigned int rd_count, | ||
733 | struct GNUNET_GNSRECORD_Data *rd_public, | ||
734 | unsigned int *rd_count_public, | ||
735 | struct GNUNET_TIME_Absolute *min_expiry, | ||
736 | int include_private, | ||
737 | char **emsg); | ||
738 | |||
739 | |||
740 | /** | ||
741 | * Convert namestore records from the internal format to that | ||
742 | * suitable for publication (removes private records). | ||
743 | * | ||
744 | * @param label the label under which this set is (supposed to be) published. | ||
745 | * @param rd input records | ||
746 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
747 | * @param rd_public where to write the converted records | ||
748 | * @param rd_public_count number of records written to @a rd_public | ||
749 | * @param expiry the expiration of the block | ||
750 | * @param emsg the error message if something went wrong | ||
751 | * @return GNUNET_OK if set is consistent and can be exported | ||
752 | */ | ||
753 | enum GNUNET_GenericReturnValue | ||
754 | GNUNET_GNSRECORD_convert_records_for_export (const char *label, | ||
755 | const struct | ||
756 | GNUNET_GNSRECORD_Data *rd, | ||
757 | unsigned int rd_count, | ||
758 | struct GNUNET_GNSRECORD_Data * | ||
759 | rd_public, | ||
760 | unsigned int *rd_count_public, | ||
761 | struct GNUNET_TIME_Absolute *expiry, | ||
762 | char **emsg); | ||
763 | |||
764 | /** | ||
765 | * Check label for invalid characters. | ||
766 | * | ||
767 | * @param label the label to check | ||
768 | * @param emsg an error message (NULL if label is valid). Will be allocated. | ||
769 | * @return GNUNET_OK if label is valid. | ||
770 | */ | ||
771 | enum GNUNET_GenericReturnValue | ||
772 | GNUNET_GNSRECORD_label_check (const char*label, char **emsg); | ||
703 | 773 | ||
704 | #if 0 /* keep Emacsens' auto-indent happy */ | 774 | #if 0 /* keep Emacsens' auto-indent happy */ |
705 | { | 775 | { |
diff --git a/src/include/gnunet_gnsrecord_plugin.h b/src/include/gnunet_gnsrecord_plugin.h index aec22c3af..84b7c3c23 100644 --- a/src/include/gnunet_gnsrecord_plugin.h +++ b/src/include/gnunet_gnsrecord_plugin.h | |||
@@ -105,6 +105,18 @@ typedef const char * | |||
105 | (*GNUNET_GNSRECORD_NumberToTypenameFunction) (void *cls, | 105 | (*GNUNET_GNSRECORD_NumberToTypenameFunction) (void *cls, |
106 | uint32_t type); | 106 | uint32_t type); |
107 | 107 | ||
108 | /** | ||
109 | * Function called to check for critical records. | ||
110 | * | ||
111 | * @param cls closure | ||
112 | * @param type number of a type to check | ||
113 | * @return GNUNET_YES if critical, otherwise GNUNET_NO | ||
114 | */ | ||
115 | typedef enum GNUNET_GenericReturnValue | ||
116 | (*GNUNET_GNSRECORD_IsCriticalFunction) (void *cls, | ||
117 | uint32_t type); | ||
118 | |||
119 | |||
108 | 120 | ||
109 | /** | 121 | /** |
110 | * Each plugin is required to return a pointer to a struct of this | 122 | * Each plugin is required to return a pointer to a struct of this |
@@ -136,6 +148,11 @@ struct GNUNET_GNSRECORD_PluginFunctions | |||
136 | * Number to typename. | 148 | * Number to typename. |
137 | */ | 149 | */ |
138 | GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename; | 150 | GNUNET_GNSRECORD_NumberToTypenameFunction number_to_typename; |
151 | |||
152 | /** | ||
153 | * Is critical. | ||
154 | */ | ||
155 | GNUNET_GNSRECORD_IsCriticalFunction is_critical; | ||
139 | }; | 156 | }; |
140 | 157 | ||
141 | /** @} */ /* end of group */ | 158 | /** @} */ /* end of group */ |
diff --git a/src/include/gnunet_hello_uri_lib.h b/src/include/gnunet_hello_uri_lib.h new file mode 100644 index 000000000..c109a151a --- /dev/null +++ b/src/include/gnunet_hello_uri_lib.h | |||
@@ -0,0 +1,248 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 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 | * @file | ||
24 | * Helper library for handling HELLO URIs | ||
25 | * | ||
26 | * @defgroup hello_uri Hello_Uri library | ||
27 | * Helper library for handling HELLO URIs | ||
28 | * | ||
29 | * @{ | ||
30 | */ | ||
31 | |||
32 | #ifndef GNUNET_HELLO_URI_LIB_H | ||
33 | #define GNUNET_HELLO_URI_LIB_H | ||
34 | |||
35 | #ifdef __cplusplus | ||
36 | extern "C" { | ||
37 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
38 | } | ||
39 | #endif | ||
40 | #endif | ||
41 | |||
42 | #include "gnunet_util_lib.h" | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Context for building (or parsing) HELLO URIs. | ||
47 | */ | ||
48 | struct GNUNET_HELLO_Builder; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * For how long are HELLO signatures valid? | ||
53 | */ | ||
54 | #define GNUNET_HELLO_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply ( \ | ||
55 | GNUNET_TIME_UNIT_DAYS, 2) | ||
56 | |||
57 | |||
58 | /** | ||
59 | * Allocate builder. | ||
60 | * | ||
61 | * @param pid peer the builder is for | ||
62 | * @return new builder | ||
63 | */ | ||
64 | struct GNUNET_HELLO_Builder * | ||
65 | GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid); | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Release resources of a @a builder. | ||
70 | * | ||
71 | * @param[in] builder to free | ||
72 | */ | ||
73 | void | ||
74 | GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder); | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Parse @a msg into builder. | ||
79 | * | ||
80 | * @param msg message to parse | ||
81 | * @return builder, NULL on failure | ||
82 | */ | ||
83 | struct GNUNET_HELLO_Builder * | ||
84 | GNUNET_HELLO_builder_from_msg (const struct GNUNET_MessageHeader *msg); | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Parse @a block into builder. | ||
89 | * | ||
90 | * @param block DHT block to parse | ||
91 | * @param block_size number of bytes in @a block | ||
92 | * @return builder, NULL on failure | ||
93 | */ | ||
94 | struct GNUNET_HELLO_Builder * | ||
95 | GNUNET_HELLO_builder_from_block (const void *block, | ||
96 | size_t block_size); | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Parse GNUnet HELLO @a url into builder. | ||
101 | * | ||
102 | * @param url URL to parse | ||
103 | * @return builder, NULL on failure | ||
104 | */ | ||
105 | struct GNUNET_HELLO_Builder * | ||
106 | GNUNET_HELLO_builder_from_url (const char *url); | ||
107 | |||
108 | |||
109 | /** | ||
110 | * Generate envelope with GNUnet HELLO message (including | ||
111 | * peer ID) from a @a builder | ||
112 | * | ||
113 | * @param builder builder to serialize | ||
114 | * @param priv private key to use to sign the result | ||
115 | * @return HELLO message matching @a builder | ||
116 | */ | ||
117 | struct GNUNET_MQ_Envelope * | ||
118 | GNUNET_HELLO_builder_to_env (const struct GNUNET_HELLO_Builder *builder, | ||
119 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Generate DHT HELLO message (without peer ID) from a @a builder | ||
124 | * | ||
125 | * @param builder builder to serialize | ||
126 | * @param priv private key to use to sign the result | ||
127 | * @return HELLO message matching @a builder | ||
128 | */ | ||
129 | struct GNUNET_MessageHeader * | ||
130 | GNUNET_HELLO_builder_to_dht_hello_msg ( | ||
131 | const struct GNUNET_HELLO_Builder *builder, | ||
132 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Generate GNUnet HELLO URI from a @a builder | ||
137 | * | ||
138 | * @param builder builder to serialize | ||
139 | * @param priv private key to use to sign the result | ||
140 | * @return hello URI | ||
141 | */ | ||
142 | char * | ||
143 | GNUNET_HELLO_builder_to_url (const struct GNUNET_HELLO_Builder *builder, | ||
144 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); | ||
145 | |||
146 | /** | ||
147 | * Generate DHT block from a @a builder | ||
148 | * | ||
149 | * @param builder the builder to serialize | ||
150 | * @param priv private key to use to sign the result | ||
151 | * @param[out] block where to write the block, NULL to only calculate @a block_size | ||
152 | * @param[in,out] block_size input is number of bytes available in @a block, | ||
153 | * output is number of bytes needed in @a block | ||
154 | * @return #GNUNET_OK on success, #GNUNET_NO if @a block_size was too small | ||
155 | * or if @a block was NULL | ||
156 | */ | ||
157 | enum GNUNET_GenericReturnValue | ||
158 | GNUNET_HELLO_builder_to_block (const struct GNUNET_HELLO_Builder *builder, | ||
159 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | ||
160 | void *block, | ||
161 | size_t *block_size); | ||
162 | |||
163 | |||
164 | /** | ||
165 | * Add individual @a address to the @a builder | ||
166 | * | ||
167 | * @param[in,out] builder to update | ||
168 | * @param address address URI to add | ||
169 | * @return #GNUNET_OK on success, #GNUNET_NO if @a address was already | ||
170 | * in @a builder | ||
171 | */ | ||
172 | enum GNUNET_GenericReturnValue | ||
173 | GNUNET_HELLO_builder_add_address (struct GNUNET_HELLO_Builder *builder, | ||
174 | const char *address); | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Remove individual @a address from the @a builder | ||
179 | * | ||
180 | * @param[in,out] builder to update | ||
181 | * @param address address URI to remove | ||
182 | * @return #GNUNET_OK on success, #GNUNET_NO if @a address was not | ||
183 | * in @a builder | ||
184 | */ | ||
185 | enum GNUNET_GenericReturnValue | ||
186 | GNUNET_HELLO_builder_del_address (struct GNUNET_HELLO_Builder *builder, | ||
187 | const char *address); | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Callback function used to extract URIs from a builder. | ||
192 | * | ||
193 | * @param cls closure | ||
194 | * @param uri one of the URIs | ||
195 | */ | ||
196 | typedef void | ||
197 | (*GNUNET_HELLO_UriCallback) (void *cls, | ||
198 | const char *uri); | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Iterate over URIs in a builder. | ||
203 | * | ||
204 | * @param builder builder to iterate over | ||
205 | * @param[out] pid set to the peer the @a builder is for | ||
206 | * @param uc callback invoked for each URI, can be NULL | ||
207 | * @param uc_cls closure for @a addrgen | ||
208 | */ | ||
209 | void | ||
210 | GNUNET_HELLO_builder_iterate (const struct GNUNET_HELLO_Builder *builder, | ||
211 | struct GNUNET_PeerIdentity *pid, | ||
212 | GNUNET_HELLO_UriCallback uc, | ||
213 | void *uc_cls); | ||
214 | |||
215 | |||
216 | /** | ||
217 | * Convert a DHT @a hello message to a HELLO @a block. | ||
218 | * | ||
219 | * @param hello the HELLO message | ||
220 | * @param pid peer that created the @a hello | ||
221 | * @param[out] block set to the HELLO block | ||
222 | * @param[out] block_size set to number of bytes in @a block | ||
223 | * @param[out] block_expiration set to expiration time of @a block | ||
224 | * @return #GNUNET_OK on success, | ||
225 | * #GNUNET_NO if the @a hello is expired (@a block is set!) | ||
226 | * #GNUNET_SYSERR if @a hello is invalid (@a block will be set to NULL) | ||
227 | */ | ||
228 | enum GNUNET_GenericReturnValue | ||
229 | GNUNET_HELLO_dht_msg_to_block (const struct GNUNET_MessageHeader *hello, | ||
230 | const struct GNUNET_PeerIdentity *pid, | ||
231 | void **block, | ||
232 | size_t *block_size, | ||
233 | struct GNUNET_TIME_Absolute *block_expiration); | ||
234 | |||
235 | |||
236 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
237 | { | ||
238 | #endif | ||
239 | #ifdef __cplusplus | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | /* ifndef GNUNET_HELLO_URI_LIB_H */ | ||
244 | #endif | ||
245 | |||
246 | /** @} */ /* end of group */ | ||
247 | |||
248 | /* end of gnunet_hello_uri_lib.h */ | ||
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 7d101196c..6e73a3365 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -48,10 +48,10 @@ struct GNUNET_JSON_Specification; | |||
48 | * @return #GNUNET_SYSERR on error, | 48 | * @return #GNUNET_SYSERR on error, |
49 | * #GNUNET_OK on success | 49 | * #GNUNET_OK on success |
50 | */ | 50 | */ |
51 | typedef int | 51 | typedef enum GNUNET_GenericReturnValue |
52 | (*GNUNET_JSON_Parser) (void *cls, | 52 | (*GNUNET_JSON_Parser)(void *cls, |
53 | json_t *root, | 53 | json_t *root, |
54 | struct GNUNET_JSON_Specification *spec); | 54 | struct GNUNET_JSON_Specification *spec); |
55 | 55 | ||
56 | 56 | ||
57 | /** | 57 | /** |
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index 2482b97a5..619b81aed 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h | |||
@@ -134,6 +134,39 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h, | |||
134 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | 134 | GNUNET_NAMESTORE_ContinuationWithStatus cont, |
135 | void *cont_cls); | 135 | void *cont_cls); |
136 | 136 | ||
137 | /** | ||
138 | * Store an item in the namestore. If the item is already present, | ||
139 | * it is replaced with the new record. Use an empty array to | ||
140 | * remove all records under the given name. | ||
141 | * | ||
142 | * The continuation is called after the value has been stored in the | ||
143 | * database. Monitors may be notified asynchronously (basically with | ||
144 | * a buffer). However, if any monitor is consistently too slow to | ||
145 | * keep up with the changes, calling @a cont will be delayed until the | ||
146 | * monitors do keep up. | ||
147 | * | ||
148 | * @param h handle to the namestore | ||
149 | * @param pkey private key of the zone | ||
150 | * @param label name that is being mapped | ||
151 | * @param rd_count number of records in the 'rd' array | ||
152 | * @param rd array of records with data to store | ||
153 | * @param is_zonemaster update tombstones, do not process monitors | ||
154 | * @param cont continuation to call when done | ||
155 | * @param cont_cls closure for @a cont | ||
156 | * @return handle to abort the request | ||
157 | */ | ||
158 | struct GNUNET_NAMESTORE_QueueEntry * | ||
159 | GNUNET_NAMESTORE_records_store_ (struct GNUNET_NAMESTORE_Handle *h, | ||
160 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
161 | const char *label, | ||
162 | unsigned int rd_count, | ||
163 | const struct GNUNET_GNSRECORD_Data *rd, | ||
164 | int is_zonemaster, | ||
165 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
166 | void *cont_cls); | ||
167 | |||
168 | |||
169 | |||
137 | 170 | ||
138 | /** | 171 | /** |
139 | * Process a record that was stored in the namestore. | 172 | * Process a record that was stored in the namestore. |
@@ -179,6 +212,61 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h, | |||
179 | 212 | ||
180 | 213 | ||
181 | /** | 214 | /** |
215 | * Open a record set for editing. | ||
216 | * Retrieves an exclusive lock on this set. | ||
217 | * Must be commited using @a GNUNET_NAMESTORE_records_commit | ||
218 | * | ||
219 | * @param h handle to the namestore | ||
220 | * @param pkey private key of the zone | ||
221 | * @param label name that is being mapped | ||
222 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
223 | * the handle is afterwards invalid | ||
224 | * @param error_cb_cls closure for @a error_cb | ||
225 | * @param rm function to call with the result (with 0 records if we don't have that label) | ||
226 | * @param rm_cls closure for @a rm | ||
227 | * @return handle to abort the request | ||
228 | */ | ||
229 | struct GNUNET_NAMESTORE_QueueEntry * | ||
230 | GNUNET_NAMESTORE_records_open (struct GNUNET_NAMESTORE_Handle *h, | ||
231 | const struct | ||
232 | GNUNET_IDENTITY_PrivateKey *pkey, | ||
233 | const char *label, | ||
234 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
235 | void *error_cb_cls, | ||
236 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
237 | void *rm_cls); | ||
238 | |||
239 | /** | ||
240 | * Commit the record set to the namestore. | ||
241 | * Releases the lock on the record set. | ||
242 | * Use an empty array to | ||
243 | * remove all records under the given name. | ||
244 | * | ||
245 | * The continuation is called after the value has been stored in the | ||
246 | * database. Monitors may be notified asynchronously (basically with | ||
247 | * a buffer). However, if any monitor is consistently too slow to | ||
248 | * keep up with the changes, calling @a cont will be delayed until the | ||
249 | * monitors do keep up. | ||
250 | * | ||
251 | * @param h handle to the namestore | ||
252 | * @param pkey private key of the zone | ||
253 | * @param label name that is being mapped | ||
254 | * @param rd_count number of records in the 'rd' array | ||
255 | * @param rd array of records with data to store | ||
256 | * @param cont continuation to call when done | ||
257 | * @param cont_cls closure for @a cont | ||
258 | * @return handle to abort the request | ||
259 | */ | ||
260 | struct GNUNET_NAMESTORE_QueueEntry * | ||
261 | GNUNET_NAMESTORE_records_commit (struct GNUNET_NAMESTORE_Handle *h, | ||
262 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
263 | const char *label, | ||
264 | unsigned int rd_count, | ||
265 | const struct GNUNET_GNSRECORD_Data *rd, | ||
266 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
267 | void *cont_cls); | ||
268 | |||
269 | /** | ||
182 | * Look for an existing PKEY delegation record for a given public key. | 270 | * Look for an existing PKEY delegation record for a given public key. |
183 | * Returns at most one result to the processor. | 271 | * Returns at most one result to the processor. |
184 | * | 272 | * |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 9e278eb92..f2892e125 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -153,10 +153,10 @@ extern "C" { | |||
153 | ******************************************************************************/ | 153 | ******************************************************************************/ |
154 | 154 | ||
155 | /** | 155 | /** |
156 | * Previously used for HELLO messages used for communicating peer addresses. | 156 | * Latest HELLO messages used for communicating peer addresses. |
157 | * Managed by libgnunethello. | 157 | * Managed by libgnunethello. |
158 | */ | 158 | */ |
159 | #define GNUNET_MESSAGE_TYPE_HELLO_LEGACY 16 | 159 | #define GNUNET_MESSAGE_TYPE_HELLO_URI 16 |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * HELLO message with friend only flag used for communicating peer addresses. | 162 | * HELLO message with friend only flag used for communicating peer addresses. |
@@ -660,13 +660,26 @@ extern "C" { | |||
660 | #define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN 156 | 660 | #define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN 156 |
661 | 661 | ||
662 | /** | 662 | /** |
663 | * DHT wants to use CORE to transmit data. | 663 | * HELLO advertising a neighbours addresses. |
664 | */ | 664 | */ |
665 | #define GNUNET_MESSAGE_TYPE_DHT_CORE 143 | 665 | #define GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO 157 |
666 | 666 | ||
667 | /** | 667 | /** |
668 | * Further X-VINE DHT messages continued from 880 | 668 | * Encapsulation of DHT messages in CORE service. |
669 | */ | 669 | */ |
670 | #define GNUNET_MESSAGE_TYPE_DHT_CORE 158 | ||
671 | |||
672 | /** | ||
673 | * HELLO URL send between client and service (in | ||
674 | * either direction). | ||
675 | */ | ||
676 | #define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL 159 | ||
677 | |||
678 | /** | ||
679 | * Client requests DHT service's HELLO URL. | ||
680 | */ | ||
681 | #define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET 161 | ||
682 | |||
670 | 683 | ||
671 | /******************************************************************************* | 684 | /******************************************************************************* |
672 | * HOSTLIST message types | 685 | * HOSTLIST message types |
@@ -1796,7 +1809,6 @@ extern "C" { | |||
1796 | #define GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL 710 | 1809 | #define GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL 710 |
1797 | 1810 | ||
1798 | 1811 | ||
1799 | |||
1800 | /******************************************************************************* | 1812 | /******************************************************************************* |
1801 | * SETI message types | 1813 | * SETI message types |
1802 | ******************************************************************************/ | 1814 | ******************************************************************************/ |
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 9dd2f733e..bb8577b7a 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -159,14 +159,12 @@ GNUNET_STRINGS_to_utf8 (const char *input, | |||
159 | 159 | ||
160 | /** | 160 | /** |
161 | * Normalize the utf-8 input string to NFC. | 161 | * Normalize the utf-8 input string to NFC. |
162 | * Output needs to be allocated appropriately. | ||
163 | * | 162 | * |
164 | * @param input input string | 163 | * @param input input string |
165 | * @param output output buffer | 164 | * @return result (freshly allocated) or NULL on error. |
166 | */ | 165 | */ |
167 | void | 166 | char* |
168 | GNUNET_STRINGS_utf8_normalize (const char *input, | 167 | GNUNET_STRINGS_utf8_normalize (const char *input); |
169 | char *output); | ||
170 | 168 | ||
171 | 169 | ||
172 | /** | 170 | /** |
@@ -192,8 +190,9 @@ GNUNET_STRINGS_from_utf8 (const char *input, | |||
192 | * | 190 | * |
193 | * @param input input string | 191 | * @param input input string |
194 | * @param output output buffer | 192 | * @param output output buffer |
193 | * @return GNUNET_OK on success | ||
195 | */ | 194 | */ |
196 | void | 195 | enum GNUNET_GenericReturnValue |
197 | GNUNET_STRINGS_utf8_tolower (const char *input, | 196 | GNUNET_STRINGS_utf8_tolower (const char *input, |
198 | char *output); | 197 | char *output); |
199 | 198 | ||
@@ -204,8 +203,9 @@ GNUNET_STRINGS_utf8_tolower (const char *input, | |||
204 | * | 203 | * |
205 | * @param input input string | 204 | * @param input input string |
206 | * @param output output buffer | 205 | * @param output output buffer |
206 | * @return GNUNET_OK on success | ||
207 | */ | 207 | */ |
208 | void | 208 | enum GNUNET_GenericReturnValue |
209 | GNUNET_STRINGS_utf8_toupper (const char *input, | 209 | GNUNET_STRINGS_utf8_toupper (const char *input, |
210 | char *output); | 210 | char *output); |
211 | 211 | ||
@@ -458,7 +458,7 @@ GNUNET_STRINGS_base64url_decode (const char *data, | |||
458 | * | 458 | * |
459 | * @param data the data to encode | 459 | * @param data the data to encode |
460 | * @param len the length of the input | 460 | * @param len the length of the input |
461 | * @param output where to write the output (*output should be NULL, | 461 | * @param[out] out where to write the output (*output should be NULL, |
462 | * is allocated) | 462 | * is allocated) |
463 | * @return the size of the output | 463 | * @return the size of the output |
464 | */ | 464 | */ |
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h index b14439462..96413c3cc 100644 --- a/src/include/gnunet_time_lib.h +++ b/src/include/gnunet_time_lib.h | |||
@@ -762,11 +762,22 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch); | |||
762 | * | 762 | * |
763 | * @param s_after_epoch seconds after epoch to convert | 763 | * @param s_after_epoch seconds after epoch to convert |
764 | * @return converted time value | 764 | * @return converted time value |
765 | */struct GNUNET_TIME_Timestamp | 765 | */ |
766 | struct GNUNET_TIME_Timestamp | ||
766 | GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch); | 767 | GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch); |
767 | 768 | ||
768 | 769 | ||
769 | /** | 770 | /** |
771 | * Convert timestamp to number of seconds after the UNIX epoch. | ||
772 | * | ||
773 | * @param ts timestamp to convert | ||
774 | * @return converted time value | ||
775 | */ | ||
776 | uint64_t | ||
777 | GNUNET_TIME_timestamp_to_s (struct GNUNET_TIME_Timestamp ts); | ||
778 | |||
779 | |||
780 | /** | ||
770 | * Convert absolute time from network byte order. | 781 | * Convert absolute time from network byte order. |
771 | * | 782 | * |
772 | * @param a time to convert | 783 | * @param a time to convert |
diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 296f56104..cc1ca3e97 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c | |||
@@ -31,6 +31,12 @@ GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[]) | |||
31 | { | 31 | { |
32 | json_t *ret; | 32 | json_t *ret; |
33 | 33 | ||
34 | if (NULL == spec[0].field_name) | ||
35 | { | ||
36 | ret = spec[0].object; | ||
37 | spec[0].object = NULL; | ||
38 | return ret; | ||
39 | } | ||
34 | ret = json_object (); | 40 | ret = json_object (); |
35 | GNUNET_assert (NULL != ret); | 41 | GNUNET_assert (NULL != ret); |
36 | for (unsigned int i = 0; | 42 | for (unsigned int i = 0; |
diff --git a/src/messenger/gnunet-service-messenger.c b/src/messenger/gnunet-service-messenger.c index 546f4c0d2..31bffec18 100644 --- a/src/messenger/gnunet-service-messenger.c +++ b/src/messenger/gnunet-service-messenger.c | |||
@@ -170,9 +170,7 @@ handle_room_close (void *cls, | |||
170 | 170 | ||
171 | if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key))) | 171 | if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key))) |
172 | { | 172 | { |
173 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (msg_client->handle, &(msg->key)); | 173 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room succeeded: %s\n", GNUNET_h2s (&(msg->key))); |
174 | |||
175 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room with member id: %s\n", GNUNET_sh2s (member_id)); | ||
176 | 174 | ||
177 | struct GNUNET_MESSENGER_RoomMessage *response; | 175 | struct GNUNET_MESSENGER_RoomMessage *response; |
178 | struct GNUNET_MQ_Envelope *env; | 176 | struct GNUNET_MQ_Envelope *env; |
diff --git a/src/messenger/gnunet-service-messenger_member_session.c b/src/messenger/gnunet-service-messenger_member_session.c index 846dbbe2b..6bd1d24b8 100644 --- a/src/messenger/gnunet-service-messenger_member_session.c +++ b/src/messenger/gnunet-service-messenger_member_session.c | |||
@@ -84,6 +84,9 @@ check_member_session_completion (struct GNUNET_MESSENGER_MemberSession *session) | |||
84 | { | 84 | { |
85 | GNUNET_assert (session); | 85 | GNUNET_assert (session); |
86 | 86 | ||
87 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Check session history (%s) for completion.\n", | ||
88 | GNUNET_sh2s(get_member_session_id(session))); | ||
89 | |||
87 | if (!session->messages.tail) | 90 | if (!session->messages.tail) |
88 | { | 91 | { |
89 | session->completed = GNUNET_YES; | 92 | session->completed = GNUNET_YES; |
@@ -142,7 +145,10 @@ check_member_session_completion (struct GNUNET_MESSENGER_MemberSession *session) | |||
142 | completion: | 145 | completion: |
143 | if (GNUNET_YES == is_member_session_completed(session)) | 146 | if (GNUNET_YES == is_member_session_completed(session)) |
144 | { | 147 | { |
145 | GNUNET_CONTAINER_multihashmap_destroy (session->history); | 148 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Completed session history (%s)\n", |
149 | GNUNET_sh2s(get_member_session_id(session))); | ||
150 | |||
151 | GNUNET_CONTAINER_multihashmap_clear (session->history); | ||
146 | 152 | ||
147 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store(session->member->store); | 153 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store(session->member->store); |
148 | 154 | ||
diff --git a/src/messenger/gnunet-service-messenger_room.c b/src/messenger/gnunet-service-messenger_room.c index 7f2fd0ca6..7a20d2191 100644 --- a/src/messenger/gnunet-service-messenger_room.c +++ b/src/messenger/gnunet-service-messenger_room.c | |||
@@ -92,14 +92,14 @@ static void | |||
92 | handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room); | 92 | handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room); |
93 | 93 | ||
94 | void | 94 | void |
95 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room) | 95 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room, |
96 | int deletion) | ||
96 | { | 97 | { |
97 | GNUNET_assert(room); | 98 | GNUNET_assert(room); |
98 | 99 | ||
99 | if (room->idle) | 100 | if (room->idle) |
100 | { | 101 | { |
101 | GNUNET_SCHEDULER_cancel (room->idle); | 102 | GNUNET_SCHEDULER_cancel (room->idle); |
102 | |||
103 | room->idle = NULL; | 103 | room->idle = NULL; |
104 | } | 104 | } |
105 | 105 | ||
@@ -107,18 +107,22 @@ destroy_room (struct GNUNET_MESSENGER_SrvRoom *room) | |||
107 | GNUNET_CADET_close_port (room->port); | 107 | GNUNET_CADET_close_port (room->port); |
108 | 108 | ||
109 | GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_destroy_tunnels, NULL); | 109 | GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_destroy_tunnels, NULL); |
110 | |||
111 | handle_room_messages (room); | 110 | handle_room_messages (room); |
112 | 111 | ||
113 | if (room->service->dir) | 112 | if (!(room->service->dir)) |
113 | goto skip_saving; | ||
114 | |||
115 | if (GNUNET_YES == deletion) | ||
116 | remove_room (room); | ||
117 | else | ||
114 | save_room (room); | 118 | save_room (room); |
115 | 119 | ||
120 | skip_saving: | ||
116 | clear_member_store (get_room_member_store(room)); | 121 | clear_member_store (get_room_member_store(room)); |
117 | clear_message_store (get_room_message_store(room)); | 122 | clear_message_store (get_room_message_store(room)); |
118 | clear_operation_store(get_room_operation_store(room)); | 123 | clear_operation_store(get_room_operation_store(room)); |
119 | 124 | ||
120 | GNUNET_CONTAINER_multipeermap_destroy (room->tunnels); | 125 | GNUNET_CONTAINER_multipeermap_destroy (room->tunnels); |
121 | |||
122 | clear_list_tunnels (&(room->basement)); | 126 | clear_list_tunnels (&(room->basement)); |
123 | clear_message_state(&(room->state)); | 127 | clear_message_state(&(room->state)); |
124 | 128 | ||
@@ -1221,6 +1225,20 @@ save_room (struct GNUNET_MESSENGER_SrvRoom *room) | |||
1221 | GNUNET_free(room_dir); | 1225 | GNUNET_free(room_dir); |
1222 | } | 1226 | } |
1223 | 1227 | ||
1228 | void | ||
1229 | remove_room (struct GNUNET_MESSENGER_SrvRoom *room) | ||
1230 | { | ||
1231 | GNUNET_assert(room); | ||
1232 | |||
1233 | char *room_dir; | ||
1234 | get_room_data_subdir (room, &room_dir); | ||
1235 | |||
1236 | if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES)) | ||
1237 | GNUNET_DISK_directory_remove(room_dir); | ||
1238 | |||
1239 | GNUNET_free(room_dir); | ||
1240 | } | ||
1241 | |||
1224 | static void | 1242 | static void |
1225 | remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room, | 1243 | remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room, |
1226 | struct GNUNET_MESSENGER_MemberSession *session) | 1244 | struct GNUNET_MESSENGER_MemberSession *session) |
diff --git a/src/messenger/gnunet-service-messenger_room.h b/src/messenger/gnunet-service-messenger_room.h index 4b3811104..58edc4121 100644 --- a/src/messenger/gnunet-service-messenger_room.h +++ b/src/messenger/gnunet-service-messenger_room.h | |||
@@ -95,10 +95,15 @@ create_room (struct GNUNET_MESSENGER_SrvHandle *handle, | |||
95 | /** | 95 | /** |
96 | * Destroys a room and frees its memory fully. | 96 | * Destroys a room and frees its memory fully. |
97 | * | 97 | * |
98 | * The <i>deletion</i> flag should only be set to #GNUNET_YES if the | ||
99 | * room gets dropped by the service, otherwise #GNUNET_NO. | ||
100 | * | ||
98 | * @param[in/out] room Room | 101 | * @param[in/out] room Room |
102 | * @param[in] deletion Flag to indicate context of destruction | ||
99 | */ | 103 | */ |
100 | void | 104 | void |
101 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room); | 105 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room, |
106 | int deletion); | ||
102 | 107 | ||
103 | /** | 108 | /** |
104 | * Returns the used member store of a given <i>room</i>. | 109 | * Returns the used member store of a given <i>room</i>. |
@@ -364,4 +369,12 @@ load_room (struct GNUNET_MESSENGER_SrvRoom *room); | |||
364 | void | 369 | void |
365 | save_room (struct GNUNET_MESSENGER_SrvRoom *room); | 370 | save_room (struct GNUNET_MESSENGER_SrvRoom *room); |
366 | 371 | ||
372 | /** | ||
373 | * Removes the configuration for a given <i>room</i> of a service. | ||
374 | * | ||
375 | * @param[in] room Room | ||
376 | */ | ||
377 | void | ||
378 | remove_room (struct GNUNET_MESSENGER_SrvRoom *room); | ||
379 | |||
367 | #endif //GNUNET_SERVICE_MESSENGER_ROOM_H | 380 | #endif //GNUNET_SERVICE_MESSENGER_ROOM_H |
diff --git a/src/messenger/gnunet-service-messenger_service.c b/src/messenger/gnunet-service-messenger_service.c index b53b72af8..83d7632d8 100644 --- a/src/messenger/gnunet-service-messenger_service.c +++ b/src/messenger/gnunet-service-messenger_service.c | |||
@@ -94,7 +94,7 @@ iterate_destroy_rooms (void *cls, | |||
94 | void *value) | 94 | void *value) |
95 | { | 95 | { |
96 | struct GNUNET_MESSENGER_SrvRoom *room = value; | 96 | struct GNUNET_MESSENGER_SrvRoom *room = value; |
97 | destroy_room (room); | 97 | destroy_room (room, GNUNET_NO); |
98 | return GNUNET_YES; | 98 | return GNUNET_YES; |
99 | } | 99 | } |
100 | 100 | ||
@@ -220,7 +220,7 @@ open_service_room (struct GNUNET_MESSENGER_Service *service, | |||
220 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | 220 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) |
221 | return GNUNET_YES; | 221 | return GNUNET_YES; |
222 | 222 | ||
223 | destroy_room (room); | 223 | destroy_room (room, GNUNET_YES); |
224 | return GNUNET_NO; | 224 | return GNUNET_NO; |
225 | } | 225 | } |
226 | 226 | ||
@@ -253,7 +253,7 @@ entry_service_room (struct GNUNET_MESSENGER_Service *service, | |||
253 | } | 253 | } |
254 | else | 254 | else |
255 | { | 255 | { |
256 | destroy_room (room); | 256 | destroy_room (room, GNUNET_YES); |
257 | return GNUNET_NO; | 257 | return GNUNET_NO; |
258 | } | 258 | } |
259 | 259 | ||
@@ -287,7 +287,7 @@ close_service_room (struct GNUNET_MESSENGER_Service *service, | |||
287 | { | 287 | { |
288 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (service->rooms, key, room)) | 288 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (service->rooms, key, room)) |
289 | { | 289 | { |
290 | destroy_room (room); | 290 | destroy_room (room, GNUNET_YES); |
291 | return GNUNET_YES; | 291 | return GNUNET_YES; |
292 | } | 292 | } |
293 | else | 293 | else |
diff --git a/src/messenger/messenger.conf.in b/src/messenger/messenger.conf.in index 6b54550ea..ef0544681 100644 --- a/src/messenger/messenger.conf.in +++ b/src/messenger/messenger.conf.in | |||
@@ -1,12 +1,12 @@ | |||
1 | [messenger] | 1 | [messenger] |
2 | START_ON_DEMAND = YES | 2 | START_ON_DEMAND = @START_ON_DEMAND@ |
3 | RUN_PER_USER = YES | 3 | RUN_PER_USER = YES |
4 | PORT = 2097 | 4 | @JAVAPORT@PORT = 2125 |
5 | HOSTNAME = localhost | 5 | HOSTNAME = localhost |
6 | BINARY = gnunet-service-messenger | 6 | BINARY = gnunet-service-messenger |
7 | ACCEPT_FROM = 127.0.0.1; | 7 | ACCEPT_FROM = 127.0.0.1; |
8 | ACCEPT_FROM6 = ::1; | 8 | ACCEPT_FROM6 = ::1; |
9 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-messenger.sock | 9 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-messenger.sock |
10 | UNIX_MATCH_UID = NO | 10 | UNIX_MATCH_UID = NO |
11 | UNIX_MATCH_GID = YES | 11 | UNIX_MATCH_GID = YES |
12 | 12 | ||
diff --git a/src/messenger/messenger_api_message.c b/src/messenger/messenger_api_message.c index 496c98dbf..3814def70 100644 --- a/src/messenger/messenger_api_message.c +++ b/src/messenger/messenger_api_message.c | |||
@@ -219,6 +219,10 @@ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind) | |||
219 | case GNUNET_MESSENGER_KIND_PRIVATE: | 219 | case GNUNET_MESSENGER_KIND_PRIVATE: |
220 | length += member_size(struct GNUNET_MESSENGER_Message, body.privacy.key); | 220 | length += member_size(struct GNUNET_MESSENGER_Message, body.privacy.key); |
221 | break; | 221 | break; |
222 | case GNUNET_MESSENGER_KIND_DELETE: | ||
223 | length += member_size(struct GNUNET_MESSENGER_Message, body.deletion.hash); | ||
224 | length += member_size(struct GNUNET_MESSENGER_Message, body.deletion.delay); | ||
225 | break; | ||
222 | default: | 226 | default: |
223 | break; | 227 | break; |
224 | } | 228 | } |
@@ -445,6 +449,10 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | |||
445 | encode_step(buffer, offset, &(body->privacy.key)); | 449 | encode_step(buffer, offset, &(body->privacy.key)); |
446 | encode_step_ext(buffer, offset, body->privacy.data, min(length - offset, body->privacy.length)); | 450 | encode_step_ext(buffer, offset, body->privacy.data, min(length - offset, body->privacy.length)); |
447 | break; | 451 | break; |
452 | case GNUNET_MESSENGER_KIND_DELETE: | ||
453 | encode_step(buffer, offset, &(body->deletion.hash)); | ||
454 | encode_step(buffer, offset, &(body->deletion.delay)); | ||
455 | break; | ||
448 | default: | 456 | default: |
449 | break; | 457 | break; |
450 | } | 458 | } |
@@ -616,6 +624,10 @@ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, | |||
616 | body->privacy.length = (length - offset); | 624 | body->privacy.length = (length - offset); |
617 | decode_step_malloc(buffer, offset, body->privacy.data, length - offset, 0); | 625 | decode_step_malloc(buffer, offset, body->privacy.data, length - offset, 0); |
618 | break; | 626 | break; |
627 | case GNUNET_MESSENGER_KIND_DELETE: | ||
628 | decode_step(buffer, offset, &(body->deletion.hash)); | ||
629 | decode_step(buffer, offset, &(body->deletion.delay)); | ||
630 | break; | ||
619 | default: | 631 | default: |
620 | *kind = GNUNET_MESSENGER_KIND_UNKNOWN; | 632 | *kind = GNUNET_MESSENGER_KIND_UNKNOWN; |
621 | break; | 633 | break; |
diff --git a/src/namecache/test_namecache_api_cache_block.c b/src/namecache/test_namecache_api_cache_block.c index 310c4de42..6188fb014 100644 --- a/src/namecache/test_namecache_api_cache_block.c +++ b/src/namecache/test_namecache_api_cache_block.c | |||
@@ -187,9 +187,10 @@ run (void *cls, | |||
187 | rd.data = GNUNET_malloc (TEST_RECORD_DATALEN); | 187 | rd.data = GNUNET_malloc (TEST_RECORD_DATALEN); |
188 | rd.flags = 0; | 188 | rd.flags = 0; |
189 | memset ((char *) rd.data, 'a', TEST_RECORD_DATALEN); | 189 | memset ((char *) rd.data, 'a', TEST_RECORD_DATALEN); |
190 | block = GNUNET_GNSRECORD_block_create (&privkey, | 190 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&privkey, |
191 | GNUNET_TIME_UNIT_FOREVER_ABS, | 191 | GNUNET_TIME_UNIT_FOREVER_ABS, |
192 | name, &rd, 1); | 192 | name, &rd, 1, |
193 | &block)); | ||
193 | if (NULL == block) | 194 | if (NULL == block) |
194 | { | 195 | { |
195 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 196 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 51708dd67..2441b864a 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am | |||
@@ -39,6 +39,7 @@ if HAVE_SQLITE | |||
39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la | 39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la |
40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ | 40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ |
41 | test_namestore_api_store_sqlite \ | 41 | test_namestore_api_store_sqlite \ |
42 | test_namestore_api_store_locking_sqlite \ | ||
42 | test_namestore_api_store_update_sqlite \ | 43 | test_namestore_api_store_update_sqlite \ |
43 | test_namestore_api_zone_iteration_sqlite \ | 44 | test_namestore_api_zone_iteration_sqlite \ |
44 | test_namestore_api_remove_sqlite \ | 45 | test_namestore_api_remove_sqlite \ |
@@ -249,6 +250,16 @@ test_namestore_api_store_sqlite_LDADD = \ | |||
249 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 250 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
250 | libgnunetnamestore.la | 251 | libgnunetnamestore.la |
251 | 252 | ||
253 | test_namestore_api_store_locking_sqlite_SOURCES = \ | ||
254 | test_namestore_api_store_locking.c | ||
255 | test_namestore_api_store_locking_sqlite_LDADD = \ | ||
256 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
257 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
258 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
259 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
260 | libgnunetnamestore.la | ||
261 | |||
262 | |||
252 | test_namestore_api_store_postgres_SOURCES = \ | 263 | test_namestore_api_store_postgres_SOURCES = \ |
253 | test_namestore_api_store.c | 264 | test_namestore_api_store.c |
254 | test_namestore_api_store_postgres_LDADD = \ | 265 | test_namestore_api_store_postgres_LDADD = \ |
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 852d99608..af40f2dbe 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c | |||
@@ -33,6 +33,12 @@ | |||
33 | #include <gnunet_gns_service.h> | 33 | #include <gnunet_gns_service.h> |
34 | #include <gnunet_namestore_service.h> | 34 | #include <gnunet_namestore_service.h> |
35 | 35 | ||
36 | /** | ||
37 | * The upper bound for the zone iteration interval | ||
38 | * (per record). | ||
39 | */ | ||
40 | #define WARN_RELATIVE_EXPIRATION_LIMIT GNUNET_TIME_relative_multiply ( \ | ||
41 | GNUNET_TIME_UNIT_MINUTES, 15) | ||
36 | 42 | ||
37 | /** | 43 | /** |
38 | * Entry in record set for bulk processing. | 44 | * Entry in record set for bulk processing. |
@@ -430,6 +436,8 @@ display_record (const char *rname, | |||
430 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 436 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && |
431 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) | 437 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) |
432 | continue; | 438 | continue; |
439 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
440 | continue; | ||
433 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) | 441 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) |
434 | continue; | 442 | continue; |
435 | have_record = GNUNET_YES; | 443 | have_record = GNUNET_YES; |
@@ -447,6 +455,8 @@ display_record (const char *rname, | |||
447 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 455 | if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && |
448 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) | 456 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT))) |
449 | continue; | 457 | continue; |
458 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
459 | continue; | ||
450 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) | 460 | if ((type != rd[i].record_type) && (GNUNET_GNSRECORD_TYPE_ANY != type)) |
451 | continue; | 461 | continue; |
452 | typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); | 462 | typestr = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); |
@@ -649,28 +659,6 @@ get_existing_record (void *cls, | |||
649 | { | 659 | { |
650 | switch (rd[i].record_type) | 660 | switch (rd[i].record_type) |
651 | { | 661 | { |
652 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
653 | fprintf ( | ||
654 | stderr, | ||
655 | _ ( | ||
656 | "A %s record exists already under `%s', no other records can be added.\n"), | ||
657 | "CNAME", | ||
658 | rec_name); | ||
659 | ret = 1; | ||
660 | test_finished (); | ||
661 | return; | ||
662 | |||
663 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
664 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
665 | fprintf ( | ||
666 | stderr, | ||
667 | _ ( | ||
668 | "A zone key record exists already under `%s', no other records can be added.\n"), | ||
669 | rec_name); | ||
670 | ret = 1; | ||
671 | test_finished (); | ||
672 | return; | ||
673 | |||
674 | case GNUNET_DNSPARSER_TYPE_SOA: | 662 | case GNUNET_DNSPARSER_TYPE_SOA: |
675 | if (GNUNET_DNSPARSER_TYPE_SOA == type) | 663 | if (GNUNET_DNSPARSER_TYPE_SOA == type) |
676 | { | 664 | { |
@@ -686,51 +674,6 @@ get_existing_record (void *cls, | |||
686 | break; | 674 | break; |
687 | } | 675 | } |
688 | } | 676 | } |
689 | switch (type) | ||
690 | { | ||
691 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
692 | if (0 != rd_count) | ||
693 | { | ||
694 | fprintf (stderr, | ||
695 | _ ( | ||
696 | "Records already exist under `%s', cannot add `%s' record.\n"), | ||
697 | rec_name, | ||
698 | "CNAME"); | ||
699 | ret = 1; | ||
700 | test_finished (); | ||
701 | return; | ||
702 | } | ||
703 | break; | ||
704 | |||
705 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
706 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
707 | if (0 != rd_count) | ||
708 | { | ||
709 | fprintf (stderr, | ||
710 | _ ( | ||
711 | "Records already exist under `%s', cannot add record.\n"), | ||
712 | rec_name); | ||
713 | ret = 1; | ||
714 | test_finished (); | ||
715 | return; | ||
716 | } | ||
717 | break; | ||
718 | |||
719 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | ||
720 | for (unsigned int i = 0; i < rd_count; i++) | ||
721 | if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type) | ||
722 | { | ||
723 | fprintf ( | ||
724 | stderr, | ||
725 | _ ( | ||
726 | "Non-GNS2DNS records already exist under `%s', cannot add GNS2DNS record.\n"), | ||
727 | rec_name); | ||
728 | ret = 1; | ||
729 | test_finished (); | ||
730 | return; | ||
731 | } | ||
732 | break; | ||
733 | } | ||
734 | memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data)); | 677 | memset (rdn, 0, sizeof(struct GNUNET_GNSRECORD_Data)); |
735 | GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data)); | 678 | GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof(struct GNUNET_GNSRECORD_Data)); |
736 | rde = &rdn[0]; | 679 | rde = &rdn[0]; |
@@ -929,6 +872,13 @@ parse_expiration (const char *expirationstring, | |||
929 | { | 872 | { |
930 | *etime_is_rel = GNUNET_YES; | 873 | *etime_is_rel = GNUNET_YES; |
931 | *etime = etime_rel.rel_value_us; | 874 | *etime = etime_rel.rel_value_us; |
875 | if (GNUNET_TIME_relative_cmp (etime_rel, <, WARN_RELATIVE_EXPIRATION_LIMIT)) | ||
876 | { | ||
877 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
878 | "Relative expiration times of less than %s are not recommended. To improve availability, consider increasing this value.\n", | ||
879 | GNUNET_STRINGS_relative_time_to_string ( | ||
880 | WARN_RELATIVE_EXPIRATION_LIMIT, GNUNET_NO)); | ||
881 | } | ||
932 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 882 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
933 | "Storing record with relative expiration time of %s\n", | 883 | "Storing record with relative expiration time of %s\n", |
934 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); | 884 | GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO)); |
@@ -1212,8 +1162,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1212 | char sname[64]; | 1162 | char sname[64]; |
1213 | struct GNUNET_IDENTITY_PublicKey pkey; | 1163 | struct GNUNET_IDENTITY_PublicKey pkey; |
1214 | 1164 | ||
1215 | memset(sh, 0, 105); | 1165 | memset (sh, 0, 105); |
1216 | memset(sname, 0, 64); | 1166 | memset (sname, 0, 64); |
1217 | 1167 | ||
1218 | if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) || | 1168 | if ((2 != (sscanf (uri, "gnunet://gns/%58s/%63s", sh, sname))) || |
1219 | (GNUNET_OK != | 1169 | (GNUNET_OK != |
@@ -1286,15 +1236,6 @@ identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | |||
1286 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 1236 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
1287 | 1237 | ||
1288 | el = NULL; | 1238 | el = NULL; |
1289 | if ((NULL != name) && (0 != strchr (name, '.'))) | ||
1290 | { | ||
1291 | fprintf (stderr, | ||
1292 | _ ("Label `%s' contains `.' which is not allowed\n"), | ||
1293 | name); | ||
1294 | GNUNET_SCHEDULER_shutdown (); | ||
1295 | ret = -1; | ||
1296 | return; | ||
1297 | } | ||
1298 | 1239 | ||
1299 | if (NULL == ego) | 1240 | if (NULL == ego) |
1300 | { | 1241 | { |
@@ -1705,13 +1646,13 @@ main (int argc, char *const *argv) | |||
1705 | NULL))) | 1646 | NULL))) |
1706 | { | 1647 | { |
1707 | GNUNET_free_nz ((void *) argv); | 1648 | GNUNET_free_nz ((void *) argv); |
1708 | //FIXME | 1649 | // FIXME |
1709 | //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); | 1650 | // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); |
1710 | return lret; | 1651 | return lret; |
1711 | } | 1652 | } |
1712 | GNUNET_free_nz ((void *) argv); | 1653 | GNUNET_free_nz ((void *) argv); |
1713 | //FIXME | 1654 | // FIXME |
1714 | //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); | 1655 | // GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); |
1715 | return ret; | 1656 | return ret; |
1716 | } | 1657 | } |
1717 | 1658 | ||
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 9b2d9b6f3..d735822fb 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c | |||
@@ -121,6 +121,23 @@ struct ZoneIteration | |||
121 | int send_end; | 121 | int send_end; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /** | ||
125 | * Lock on a record set | ||
126 | */ | ||
127 | struct RecordsLock | ||
128 | { | ||
129 | /* DLL */ | ||
130 | struct RecordsLock *prev; | ||
131 | |||
132 | /* DLL */ | ||
133 | struct RecordsLock *next; | ||
134 | |||
135 | /* Hash of the locked label */ | ||
136 | struct GNUNET_HashCode label_hash; | ||
137 | |||
138 | /* Client locking the zone */ | ||
139 | struct NamestoreClient *client; | ||
140 | }; | ||
124 | 141 | ||
125 | /** | 142 | /** |
126 | * A namestore client | 143 | * A namestore client |
@@ -394,6 +411,16 @@ static struct StoreActivity *sa_head; | |||
394 | static struct StoreActivity *sa_tail; | 411 | static struct StoreActivity *sa_tail; |
395 | 412 | ||
396 | /** | 413 | /** |
414 | * Head of the DLL of record set locks | ||
415 | */ | ||
416 | static struct RecordsLock *locks_head; | ||
417 | |||
418 | /** | ||
419 | * Tail of the DLL of record set locks | ||
420 | */ | ||
421 | static struct RecordsLock *locks_tail; | ||
422 | |||
423 | /** | ||
397 | * Notification context shared by all monitors. | 424 | * Notification context shared by all monitors. |
398 | */ | 425 | */ |
399 | static struct GNUNET_NotificationContext *monitor_nc; | 426 | static struct GNUNET_NotificationContext *monitor_nc; |
@@ -420,6 +447,7 @@ static void | |||
420 | cleanup_task (void *cls) | 447 | cleanup_task (void *cls) |
421 | { | 448 | { |
422 | struct CacheOperation *cop; | 449 | struct CacheOperation *cop; |
450 | struct RecordsLock *lock; | ||
423 | 451 | ||
424 | (void) cls; | 452 | (void) cls; |
425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); | 453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); |
@@ -431,6 +459,14 @@ cleanup_task (void *cls) | |||
431 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | 459 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); |
432 | GNUNET_free (cop); | 460 | GNUNET_free (cop); |
433 | } | 461 | } |
462 | while (NULL != (lock = locks_head)) | ||
463 | { | ||
464 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
465 | locks_tail, | ||
466 | lock); | ||
467 | GNUNET_free (lock); | ||
468 | } | ||
469 | |||
434 | if (NULL != namecache) | 470 | if (NULL != namecache) |
435 | { | 471 | { |
436 | GNUNET_NAMECACHE_disconnect (namecache); | 472 | GNUNET_NAMECACHE_disconnect (namecache); |
@@ -808,7 +844,8 @@ send_lookup_response (struct NamestoreClient *nc, | |||
808 | * @param rid client's request ID | 844 | * @param rid client's request ID |
809 | */ | 845 | */ |
810 | static void | 846 | static void |
811 | send_store_response (struct NamestoreClient *nc, int res, uint32_t rid) | 847 | send_store_response (struct NamestoreClient *nc, int res, const char*emsg, |
848 | uint32_t rid) | ||
812 | { | 849 | { |
813 | struct GNUNET_MQ_Envelope *env; | 850 | struct GNUNET_MQ_Envelope *env; |
814 | struct RecordStoreResponseMessage *rcr_msg; | 851 | struct RecordStoreResponseMessage *rcr_msg; |
@@ -820,10 +857,17 @@ send_store_response (struct NamestoreClient *nc, int res, uint32_t rid) | |||
820 | "Store requests completed", | 857 | "Store requests completed", |
821 | 1, | 858 | 1, |
822 | GNUNET_NO); | 859 | GNUNET_NO); |
823 | env = GNUNET_MQ_msg (rcr_msg, | 860 | env = GNUNET_MQ_msg_extra (rcr_msg, |
824 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE); | 861 | (NULL != emsg) ? strlen (emsg) + 1 : 0, |
862 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE); | ||
825 | rcr_msg->gns_header.r_id = htonl (rid); | 863 | rcr_msg->gns_header.r_id = htonl (rid); |
826 | rcr_msg->op_result = htonl (res); | 864 | rcr_msg->op_result = htonl (res); |
865 | rcr_msg->reserved = htons (0); | ||
866 | if (NULL != emsg) | ||
867 | { | ||
868 | rcr_msg->emsg_len = htons (strlen (emsg) + 1); | ||
869 | memcpy (&rcr_msg[1], emsg, strlen (emsg) + 1); | ||
870 | } | ||
827 | GNUNET_MQ_send (nc->mq, env); | 871 | GNUNET_MQ_send (nc->mq, env); |
828 | } | 872 | } |
829 | 873 | ||
@@ -874,7 +918,7 @@ finish_cache_operation (void *cls, int32_t success, const char *emsg) | |||
874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); | 918 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); |
875 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | 919 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); |
876 | if (NULL != cop->nc) | 920 | if (NULL != cop->nc) |
877 | send_store_response (cop->nc, success, cop->rid); | 921 | send_store_response (cop->nc, success, emsg, cop->rid); |
878 | if (NULL != (zi = cop->zi)) | 922 | if (NULL != (zi = cop->zi)) |
879 | { | 923 | { |
880 | zi->cache_ops--; | 924 | zi->cache_ops--; |
@@ -910,29 +954,40 @@ refresh_block (struct NamestoreClient *nc, | |||
910 | const struct GNUNET_GNSRECORD_Data *rd) | 954 | const struct GNUNET_GNSRECORD_Data *rd) |
911 | { | 955 | { |
912 | struct GNUNET_GNSRECORD_Block *block; | 956 | struct GNUNET_GNSRECORD_Block *block; |
957 | struct GNUNET_GNSRECORD_Data rd_clean[rd_count]; | ||
913 | struct CacheOperation *cop; | 958 | struct CacheOperation *cop; |
914 | struct GNUNET_IDENTITY_PublicKey pkey; | 959 | struct GNUNET_IDENTITY_PublicKey pkey; |
915 | struct GNUNET_GNSRECORD_Data *nick; | 960 | struct GNUNET_GNSRECORD_Data *nick; |
916 | struct GNUNET_GNSRECORD_Data *res; | 961 | struct GNUNET_GNSRECORD_Data *res; |
917 | unsigned int res_count; | 962 | unsigned int res_count; |
963 | unsigned int rd_count_clean; | ||
918 | struct GNUNET_TIME_Absolute exp_time; | 964 | struct GNUNET_TIME_Absolute exp_time; |
919 | 965 | ||
966 | /** Do not block-cache tombstones */ | ||
967 | rd_count_clean = 0; | ||
968 | for (int i = 0; i < rd_count; i++) | ||
969 | { | ||
970 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
971 | continue; | ||
972 | rd_clean[rd_count_clean++] = rd[i]; | ||
973 | } | ||
974 | |||
920 | nick = get_nick_record (zone_key); | 975 | nick = get_nick_record (zone_key); |
921 | res_count = rd_count; | 976 | res_count = rd_count_clean; |
922 | res = (struct GNUNET_GNSRECORD_Data *) rd; /* fixme: a bit unclean... */ | 977 | res = (struct GNUNET_GNSRECORD_Data *) rd_clean; /* fixme: a bit unclean... */ |
923 | if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) | 978 | if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) |
924 | { | 979 | { |
925 | nick->flags = | 980 | nick->flags = |
926 | (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; | 981 | (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; |
927 | merge_with_nick_records (nick, rd_count, rd, &res_count, &res); | 982 | merge_with_nick_records (nick, rd_count_clean, rd_clean, &res_count, &res); |
928 | } | 983 | } |
929 | if (NULL != nick) | 984 | if (NULL != nick) |
930 | GNUNET_free (nick); | 985 | GNUNET_free (nick); |
931 | if (0 == res_count) | 986 | if (0 == res_count) |
932 | { | 987 | { |
933 | if (NULL != nc) | 988 | if (NULL != nc) |
934 | send_store_response (nc, GNUNET_OK, rid); | 989 | send_store_response (nc, GNUNET_OK, NULL, rid); |
935 | if (rd != res) | 990 | if (rd_clean != res) |
936 | GNUNET_free (res); | 991 | GNUNET_free (res); |
937 | return; /* no data, no need to update cache */ | 992 | return; /* no data, no need to update cache */ |
938 | } | 993 | } |
@@ -943,20 +998,21 @@ refresh_block (struct NamestoreClient *nc, | |||
943 | 1, | 998 | 1, |
944 | GNUNET_NO); | 999 | GNUNET_NO); |
945 | if (NULL != nc) | 1000 | if (NULL != nc) |
946 | send_store_response (nc, GNUNET_OK, rid); | 1001 | send_store_response (nc, GNUNET_OK, NULL, rid); |
947 | if (rd != res) | 1002 | if (rd_clean != res) |
948 | GNUNET_free (res); | 1003 | GNUNET_free (res); |
949 | return; | 1004 | return; |
950 | } | 1005 | } |
951 | exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res); | 1006 | exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res, |
1007 | GNUNET_TIME_UNIT_ZERO_ABS); | ||
952 | if (cache_keys) | 1008 | if (cache_keys) |
953 | GNUNET_assert (GNUNET_OK == | 1009 | GNUNET_assert (GNUNET_OK == |
954 | GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, | 1010 | GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, |
955 | res, res_count, &block)); | 1011 | res, res_count, &block)); |
956 | else | 1012 | else |
957 | GNUNET_assert (GNUNET_OK == | 1013 | GNUNET_assert (GNUNET_OK == |
958 | GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, | 1014 | GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, |
959 | res, res_count, &block)); | 1015 | res, res_count, &block)); |
960 | GNUNET_assert (NULL != block); | 1016 | GNUNET_assert (NULL != block); |
961 | GNUNET_IDENTITY_key_get_public (zone_key, &pkey); | 1017 | GNUNET_IDENTITY_key_get_public (zone_key, &pkey); |
962 | GNUNET_log ( | 1018 | GNUNET_log ( |
@@ -974,7 +1030,7 @@ refresh_block (struct NamestoreClient *nc, | |||
974 | cop->nc = nc; | 1030 | cop->nc = nc; |
975 | cop->zi = zi; | 1031 | cop->zi = zi; |
976 | if (NULL != zi) | 1032 | if (NULL != zi) |
977 | zi->cache_ops++; | 1033 | zi->cache_ops ++; |
978 | cop->rid = rid; | 1034 | cop->rid = rid; |
979 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); | 1035 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); |
980 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, | 1036 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, |
@@ -982,7 +1038,7 @@ refresh_block (struct NamestoreClient *nc, | |||
982 | &finish_cache_operation, | 1038 | &finish_cache_operation, |
983 | cop); | 1039 | cop); |
984 | GNUNET_free (block); | 1040 | GNUNET_free (block); |
985 | if (rd != res) | 1041 | if (rd_clean != res) |
986 | GNUNET_free (res); | 1042 | GNUNET_free (res); |
987 | } | 1043 | } |
988 | 1044 | ||
@@ -1098,6 +1154,7 @@ client_disconnect_cb (void *cls, | |||
1098 | struct NamestoreClient *nc = app_ctx; | 1154 | struct NamestoreClient *nc = app_ctx; |
1099 | struct ZoneIteration *no; | 1155 | struct ZoneIteration *no; |
1100 | struct CacheOperation *cop; | 1156 | struct CacheOperation *cop; |
1157 | struct RecordsLock *lock; | ||
1101 | 1158 | ||
1102 | (void) cls; | 1159 | (void) cls; |
1103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); | 1160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); |
@@ -1148,6 +1205,15 @@ client_disconnect_cb (void *cls, | |||
1148 | for (cop = cop_head; NULL != cop; cop = cop->next) | 1205 | for (cop = cop_head; NULL != cop; cop = cop->next) |
1149 | if (nc == cop->nc) | 1206 | if (nc == cop->nc) |
1150 | cop->nc = NULL; | 1207 | cop->nc = NULL; |
1208 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1209 | { | ||
1210 | if (nc != lock->client) | ||
1211 | continue; | ||
1212 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1213 | locks_tail, | ||
1214 | lock); | ||
1215 | GNUNET_free (lock); | ||
1216 | } | ||
1151 | GNUNET_free (nc); | 1217 | GNUNET_free (nc); |
1152 | } | 1218 | } |
1153 | 1219 | ||
@@ -1341,6 +1407,105 @@ check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1341 | return GNUNET_OK; | 1407 | return GNUNET_OK; |
1342 | } | 1408 | } |
1343 | 1409 | ||
1410 | static void | ||
1411 | calculate_lock_hash (const char *label, | ||
1412 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1413 | struct GNUNET_HashCode *result) | ||
1414 | { | ||
1415 | struct GNUNET_HashContext *hctx; | ||
1416 | |||
1417 | hctx = GNUNET_CRYPTO_hash_context_start (); | ||
1418 | GNUNET_CRYPTO_hash_context_read (hctx, label, strlen (label)); | ||
1419 | GNUNET_CRYPTO_hash_context_read (hctx, zone, | ||
1420 | sizeof (*zone)); | ||
1421 | GNUNET_CRYPTO_hash_context_finish (hctx, result); | ||
1422 | } | ||
1423 | |||
1424 | /** | ||
1425 | * Release a lock on a record set. | ||
1426 | * Does nothing if lock not held. | ||
1427 | * | ||
1428 | * @param label the label of the record set | ||
1429 | * @param zone the zone | ||
1430 | * @param nc the client releasing the lock | ||
1431 | */ | ||
1432 | static void | ||
1433 | NST_label_lock_release (const char *label, | ||
1434 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1435 | const struct NamestoreClient *nc) | ||
1436 | { | ||
1437 | struct GNUNET_HashCode label_hash; | ||
1438 | struct RecordsLock *lock; | ||
1439 | |||
1440 | calculate_lock_hash (label, zone, &label_hash); | ||
1441 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1442 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1443 | break; | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1445 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1446 | if (NULL == lock) | ||
1447 | return; | ||
1448 | if (lock->client != nc) | ||
1449 | { | ||
1450 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1451 | "Lock is held by other client on `%s'\n", label); | ||
1452 | return; | ||
1453 | } | ||
1454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1455 | "Unocking %s\n", GNUNET_h2s (&label_hash)); | ||
1456 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1457 | locks_tail, | ||
1458 | lock); | ||
1459 | GNUNET_free (lock); | ||
1460 | } | ||
1461 | |||
1462 | /** | ||
1463 | * Get/set a lock on a record set. | ||
1464 | * May be called multiple times but will | ||
1465 | * not aquire additional locks. | ||
1466 | * | ||
1467 | * @param the label of the record set | ||
1468 | * @param the zone | ||
1469 | * @param the client doing the locking | ||
1470 | * @return GNUNET_YES if lock retrieved or set already. | ||
1471 | */ | ||
1472 | static enum GNUNET_GenericReturnValue | ||
1473 | NST_label_lock (const char *label, | ||
1474 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1475 | struct NamestoreClient *nc) | ||
1476 | { | ||
1477 | struct GNUNET_HashCode label_hash; | ||
1478 | struct RecordsLock *lock; | ||
1479 | |||
1480 | calculate_lock_hash (label, zone, &label_hash); | ||
1481 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1482 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1483 | break; | ||
1484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1485 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1486 | if (NULL != lock) | ||
1487 | { | ||
1488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1489 | "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes"); | ||
1490 | if (lock->client != nc) | ||
1491 | { | ||
1492 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1493 | "Lock is held by other client on `%s'\n", label); | ||
1494 | return GNUNET_NO; | ||
1495 | } | ||
1496 | return GNUNET_YES; | ||
1497 | } | ||
1498 | lock = GNUNET_new (struct RecordsLock); | ||
1499 | lock->client = nc; | ||
1500 | memcpy (&lock->label_hash, &label_hash, sizeof (label_hash)); | ||
1501 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1502 | "Locking %s\n", GNUNET_h2s (&label_hash)); | ||
1503 | GNUNET_CONTAINER_DLL_insert (locks_head, | ||
1504 | locks_tail, | ||
1505 | lock); | ||
1506 | return GNUNET_YES; | ||
1507 | } | ||
1508 | |||
1344 | 1509 | ||
1345 | /** | 1510 | /** |
1346 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message | 1511 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message |
@@ -1355,13 +1520,14 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1355 | struct GNUNET_MQ_Envelope *env; | 1520 | struct GNUNET_MQ_Envelope *env; |
1356 | struct LabelLookupResponseMessage *llr_msg; | 1521 | struct LabelLookupResponseMessage *llr_msg; |
1357 | struct RecordLookupContext rlc; | 1522 | struct RecordLookupContext rlc; |
1523 | struct RecordsLock *lock; | ||
1524 | struct GNUNET_HashCode label_hash; | ||
1358 | const char *name_tmp; | 1525 | const char *name_tmp; |
1359 | char *res_name; | 1526 | char *res_name; |
1360 | char *conv_name; | 1527 | char *conv_name; |
1361 | uint32_t name_len; | 1528 | uint32_t name_len; |
1362 | int res; | 1529 | int res; |
1363 | 1530 | ||
1364 | name_len = ntohl (ll_msg->label_len); | ||
1365 | name_tmp = (const char *) &ll_msg[1]; | 1531 | name_tmp = (const char *) &ll_msg[1]; |
1366 | GNUNET_SERVICE_client_continue (nc->client); | 1532 | GNUNET_SERVICE_client_continue (nc->client); |
1367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1533 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1377,6 +1543,29 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1377 | GNUNET_SERVICE_client_drop (nc->client); | 1543 | GNUNET_SERVICE_client_drop (nc->client); |
1378 | return; | 1544 | return; |
1379 | } | 1545 | } |
1546 | name_len = strlen (conv_name) + 1; | ||
1547 | if (GNUNET_YES == ntohl (ll_msg->locking)) | ||
1548 | { | ||
1549 | if (GNUNET_NO == NST_label_lock (conv_name, &ll_msg->zone, nc)) | ||
1550 | { | ||
1551 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1552 | "Lock is held by other client on `%s'\n", conv_name); | ||
1553 | env = | ||
1554 | GNUNET_MQ_msg_extra (llr_msg, | ||
1555 | name_len, | ||
1556 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE); | ||
1557 | llr_msg->gns_header.r_id = ll_msg->gns_header.r_id; | ||
1558 | llr_msg->private_key = ll_msg->zone; | ||
1559 | llr_msg->name_len = htons (name_len); | ||
1560 | llr_msg->rd_count = htons (0); | ||
1561 | llr_msg->rd_len = htons (0); | ||
1562 | llr_msg->found = htons (GNUNET_SYSERR); | ||
1563 | GNUNET_memcpy (&llr_msg[1], conv_name, name_len); | ||
1564 | GNUNET_MQ_send (nc->mq, env); | ||
1565 | GNUNET_free (conv_name); | ||
1566 | return; | ||
1567 | } | ||
1568 | } | ||
1380 | rlc.label = conv_name; | 1569 | rlc.label = conv_name; |
1381 | rlc.found = GNUNET_NO; | 1570 | rlc.found = GNUNET_NO; |
1382 | rlc.res_rd_count = 0; | 1571 | rlc.res_rd_count = 0; |
@@ -1388,7 +1577,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1388 | conv_name, | 1577 | conv_name, |
1389 | &lookup_it, | 1578 | &lookup_it, |
1390 | &rlc); | 1579 | &rlc); |
1391 | GNUNET_free (conv_name); | ||
1392 | env = | 1580 | env = |
1393 | GNUNET_MQ_msg_extra (llr_msg, | 1581 | GNUNET_MQ_msg_extra (llr_msg, |
1394 | name_len + rlc.rd_ser_len, | 1582 | name_len + rlc.rd_ser_len, |
@@ -1400,16 +1588,18 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1400 | llr_msg->rd_len = htons (rlc.rd_ser_len); | 1588 | llr_msg->rd_len = htons (rlc.rd_ser_len); |
1401 | res_name = (char *) &llr_msg[1]; | 1589 | res_name = (char *) &llr_msg[1]; |
1402 | if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res)) | 1590 | if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res)) |
1403 | llr_msg->found = ntohs (GNUNET_YES); | 1591 | llr_msg->found = htons (GNUNET_YES); |
1404 | else | 1592 | else |
1405 | llr_msg->found = ntohs (GNUNET_NO); | 1593 | llr_msg->found = htons (GNUNET_NO); |
1406 | GNUNET_memcpy (&llr_msg[1], name_tmp, name_len); | 1594 | GNUNET_memcpy (&llr_msg[1], conv_name, name_len); |
1407 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); | 1595 | GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len); |
1408 | GNUNET_MQ_send (nc->mq, env); | 1596 | GNUNET_MQ_send (nc->mq, env); |
1409 | GNUNET_free (rlc.res_rd); | 1597 | GNUNET_free (rlc.res_rd); |
1598 | GNUNET_free (conv_name); | ||
1410 | } | 1599 | } |
1411 | 1600 | ||
1412 | 1601 | ||
1602 | |||
1413 | /** | 1603 | /** |
1414 | * Checks a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message | 1604 | * Checks a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message |
1415 | * | 1605 | * |
@@ -1452,6 +1642,45 @@ check_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1452 | 1642 | ||
1453 | 1643 | ||
1454 | /** | 1644 | /** |
1645 | * Check if set contains a tombstone, store if necessary | ||
1646 | * | ||
1647 | * @param cls a `struct GNUNET_GNSRECORD_Data **` for storing the nick (if found) | ||
1648 | * @param seq sequence number of the record, MUST NOT BE ZERO | ||
1649 | * @param private_key the private key of the zone (unused) | ||
1650 | * @param label should be #GNUNET_GNS_EMPTY_LABEL_AT | ||
1651 | * @param rd_count number of records in @a rd | ||
1652 | * @param rd records stored under @a label in the zone | ||
1653 | */ | ||
1654 | static void | ||
1655 | get_block_exp_existing (void *cls, | ||
1656 | uint64_t seq, | ||
1657 | const struct | ||
1658 | GNUNET_IDENTITY_PrivateKey *private_key, | ||
1659 | const char *label, | ||
1660 | unsigned int rd_count, | ||
1661 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1662 | { | ||
1663 | struct GNUNET_TIME_Absolute *exp = cls; | ||
1664 | struct GNUNET_GNSRECORD_Data rd_pub[rd_count]; | ||
1665 | unsigned int rd_pub_count; | ||
1666 | char *emsg; | ||
1667 | |||
1668 | if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label, | ||
1669 | rd, | ||
1670 | rd_count, | ||
1671 | rd_pub, | ||
1672 | &rd_pub_count, | ||
1673 | exp, | ||
1674 | &emsg)) | ||
1675 | { | ||
1676 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1677 | "%s\n", emsg); | ||
1678 | GNUNET_free (emsg); | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | |||
1683 | /** | ||
1455 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message | 1684 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message |
1456 | * | 1685 | * |
1457 | * @param cls client sending the message | 1686 | * @param cls client sending the message |
@@ -1470,37 +1699,75 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1470 | unsigned int rd_count; | 1699 | unsigned int rd_count; |
1471 | int res; | 1700 | int res; |
1472 | struct StoreActivity *sa; | 1701 | struct StoreActivity *sa; |
1702 | struct RecordsLock *lock; | ||
1703 | struct GNUNET_HashCode label_hash; | ||
1704 | struct GNUNET_TIME_Absolute existing_block_exp; | ||
1705 | struct GNUNET_TIME_Absolute new_block_exp; | ||
1473 | 1706 | ||
1474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1707 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1475 | "Received NAMESTORE_RECORD_STORE message\n"); | 1708 | "Received NAMESTORE_RECORD_STORE message\n"); |
1709 | existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | ||
1710 | new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | ||
1476 | rid = ntohl (rp_msg->gns_header.r_id); | 1711 | rid = ntohl (rp_msg->gns_header.r_id); |
1477 | name_len = ntohs (rp_msg->name_len); | 1712 | name_len = ntohs (rp_msg->name_len); |
1478 | rd_count = ntohs (rp_msg->rd_count); | 1713 | rd_count = ntohs (rp_msg->rd_count); |
1479 | rd_ser_len = ntohs (rp_msg->rd_len); | 1714 | rd_ser_len = ntohs (rp_msg->rd_len); |
1480 | GNUNET_break (0 == ntohs (rp_msg->reserved)); | ||
1481 | name_tmp = (const char *) &rp_msg[1]; | 1715 | name_tmp = (const char *) &rp_msg[1]; |
1482 | rd_ser = &name_tmp[name_len]; | 1716 | rd_ser = &name_tmp[name_len]; |
1483 | { | 1717 | { |
1484 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; | 1718 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; |
1485 | 1719 | char *emsg; | |
1486 | if (GNUNET_OK != | ||
1487 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd)) | ||
1488 | { | ||
1489 | GNUNET_break (0); | ||
1490 | GNUNET_SERVICE_client_drop (nc->client); | ||
1491 | return; | ||
1492 | } | ||
1493 | 1720 | ||
1494 | /* Extracting and converting private key */ | 1721 | /* Extracting and converting private key */ |
1495 | conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp); | 1722 | conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp); |
1496 | if (NULL == conv_name) | 1723 | if (NULL == conv_name) |
1497 | { | 1724 | { |
1498 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1725 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1499 | "Error converting name `%s'\n", | 1726 | "Error normalizing name `%s'\n", |
1500 | name_tmp); | 1727 | name_tmp); |
1501 | GNUNET_SERVICE_client_drop (nc->client); | 1728 | send_store_response (nc, GNUNET_SYSERR, _ ("Error normalizing name."), |
1729 | rid); | ||
1730 | GNUNET_SERVICE_client_continue (nc->client); | ||
1731 | return; | ||
1732 | } | ||
1733 | |||
1734 | /* Check name for validity */ | ||
1735 | if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg)) | ||
1736 | { | ||
1737 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1738 | "Label invalid: `%s'\n", | ||
1739 | emsg); | ||
1740 | send_store_response (nc, GNUNET_SYSERR, emsg, rid); | ||
1741 | GNUNET_free (emsg); | ||
1742 | GNUNET_free (conv_name); | ||
1743 | GNUNET_SERVICE_client_continue (nc->client); | ||
1744 | return; | ||
1745 | } | ||
1746 | |||
1747 | if (GNUNET_OK != | ||
1748 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd)) | ||
1749 | { | ||
1750 | send_store_response (nc, GNUNET_SYSERR, | ||
1751 | _ ("Error deserializing records."), rid); | ||
1752 | GNUNET_free (conv_name); | ||
1753 | GNUNET_SERVICE_client_continue (nc->client); | ||
1502 | return; | 1754 | return; |
1503 | } | 1755 | } |
1756 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1757 | { | ||
1758 | if (GNUNET_NO == NST_label_lock (conv_name, &rp_msg->private_key, nc)) | ||
1759 | { | ||
1760 | send_store_response (nc, GNUNET_SYSERR, _ ("Record set locked."), rid); | ||
1761 | GNUNET_SERVICE_client_continue (nc->client); | ||
1762 | GNUNET_free (conv_name); | ||
1763 | return; | ||
1764 | } | ||
1765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1766 | "Client has lock on `%s', continuing.\n", conv_name); | ||
1767 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1768 | NST_label_lock_release (conv_name, &rp_msg->private_key, nc); | ||
1769 | } | ||
1770 | |||
1504 | GNUNET_STATISTICS_update (statistics, | 1771 | GNUNET_STATISTICS_update (statistics, |
1505 | "Well-formed store requests received", | 1772 | "Well-formed store requests received", |
1506 | 1, | 1773 | 1, |
@@ -1509,12 +1776,12 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1509 | "Creating %u records for name `%s'\n", | 1776 | "Creating %u records for name `%s'\n", |
1510 | (unsigned int) rd_count, | 1777 | (unsigned int) rd_count, |
1511 | conv_name); | 1778 | conv_name); |
1512 | if ((0 == rd_count) && | 1779 | if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls, |
1513 | (GNUNET_NO == GSN_database->lookup_records (GSN_database->cls, | ||
1514 | &rp_msg->private_key, | 1780 | &rp_msg->private_key, |
1515 | conv_name, | 1781 | conv_name, |
1516 | NULL, | 1782 | &get_block_exp_existing, |
1517 | 0))) | 1783 | &existing_block_exp)) && |
1784 | (rd_count == 0)) | ||
1518 | { | 1785 | { |
1519 | /* This name does not exist, so cannot be removed */ | 1786 | /* This name does not exist, so cannot be removed */ |
1520 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1787 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1525,9 +1792,18 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1525 | else | 1792 | else |
1526 | { | 1793 | { |
1527 | /* remove "NICK" records, unless this is for the | 1794 | /* remove "NICK" records, unless this is for the |
1528 | #GNUNET_GNS_EMPTY_LABEL_AT label */ | 1795 | #GNUNET_GNS_EMPTY_LABEL_AT label |
1796 | We may need one additional record later for tombstone. | ||
1797 | FIXME: Since we must normalize the record set (check for | ||
1798 | consistency etc) we have to iterate the set twice. | ||
1799 | May be inefficient. | ||
1800 | We cannot really move the nick caching into GNSRECORD. | ||
1801 | */ | ||
1529 | struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)]; | 1802 | struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)]; |
1803 | struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1]; | ||
1530 | unsigned int rd_clean_off; | 1804 | unsigned int rd_clean_off; |
1805 | unsigned int rd_nf_count; | ||
1806 | char *emsg; | ||
1531 | int have_nick; | 1807 | int have_nick; |
1532 | 1808 | ||
1533 | rd_clean_off = 0; | 1809 | rd_clean_off = 0; |
@@ -1535,6 +1811,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1535 | for (unsigned int i = 0; i < rd_count; i++) | 1811 | for (unsigned int i = 0; i < rd_count; i++) |
1536 | { | 1812 | { |
1537 | rd_clean[rd_clean_off] = rd[i]; | 1813 | rd_clean[rd_clean_off] = rd[i]; |
1814 | |||
1538 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || | 1815 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || |
1539 | (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) | 1816 | (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) |
1540 | rd_clean_off++; | 1817 | rd_clean_off++; |
@@ -1546,6 +1823,38 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1546 | have_nick = GNUNET_YES; | 1823 | have_nick = GNUNET_YES; |
1547 | } | 1824 | } |
1548 | } | 1825 | } |
1826 | if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (conv_name, | ||
1827 | rd_clean, | ||
1828 | rd_clean_off, | ||
1829 | rd_nf, | ||
1830 | &rd_nf_count, | ||
1831 | &new_block_exp, | ||
1832 | GNUNET_YES, | ||
1833 | &emsg)) | ||
1834 | { | ||
1835 | send_store_response (nc, GNUNET_SYSERR, emsg, rid); | ||
1836 | GNUNET_free (emsg); | ||
1837 | GNUNET_SERVICE_client_continue (nc->client); | ||
1838 | GNUNET_free (conv_name); | ||
1839 | return; | ||
1840 | } | ||
1841 | /* | ||
1842 | * If existing_block_exp is 0, then there was not record set | ||
1843 | * and no tombstone. | ||
1844 | * Otherwise, if the existing block expiration is after the | ||
1845 | * new block expiration would be, we need to add a tombstone | ||
1846 | * or update it. | ||
1847 | */ | ||
1848 | if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp)) | ||
1849 | { | ||
1850 | rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; | ||
1851 | rd_nf[rd_nf_count].expiration_time = | ||
1852 | existing_block_exp.abs_value_us; | ||
1853 | rd_nf[rd_nf_count].data = NULL; | ||
1854 | rd_nf[rd_nf_count].data_size = 0; | ||
1855 | rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE; | ||
1856 | rd_nf_count++; | ||
1857 | } | ||
1549 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && | 1858 | if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && |
1550 | (GNUNET_NO == have_nick)) | 1859 | (GNUNET_NO == have_nick)) |
1551 | { | 1860 | { |
@@ -1555,19 +1864,18 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1555 | res = GSN_database->store_records (GSN_database->cls, | 1864 | res = GSN_database->store_records (GSN_database->cls, |
1556 | &rp_msg->private_key, | 1865 | &rp_msg->private_key, |
1557 | conv_name, | 1866 | conv_name, |
1558 | rd_clean_off, | 1867 | rd_nf_count, |
1559 | rd_clean); | 1868 | rd_nf); |
1560 | } | 1869 | } |
1561 | 1870 | ||
1562 | if (GNUNET_OK != res) | 1871 | if (GNUNET_OK != res) |
1563 | { | 1872 | { |
1564 | /* store not successful, not need to tell monitors */ | 1873 | /* store not successful, no need to tell monitors */ |
1565 | send_store_response (nc, res, rid); | 1874 | send_store_response (nc, res, _ ("Store failed"), rid); |
1566 | GNUNET_SERVICE_client_continue (nc->client); | 1875 | GNUNET_SERVICE_client_continue (nc->client); |
1567 | GNUNET_free (conv_name); | 1876 | GNUNET_free (conv_name); |
1568 | return; | 1877 | return; |
1569 | } | 1878 | } |
1570 | |||
1571 | sa = GNUNET_malloc (sizeof(struct StoreActivity) | 1879 | sa = GNUNET_malloc (sizeof(struct StoreActivity) |
1572 | + ntohs (rp_msg->gns_header.header.size)); | 1880 | + ntohs (rp_msg->gns_header.header.size)); |
1573 | GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); | 1881 | GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); |
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index fd9a8ed47..0f3ffa837 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h | |||
@@ -68,6 +68,11 @@ struct RecordStoreMessage | |||
68 | struct GNUNET_TIME_AbsoluteNBO expire; | 68 | struct GNUNET_TIME_AbsoluteNBO expire; |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * Unock the label with this request. | ||
72 | */ | ||
73 | uint32_t locking GNUNET_PACKED; | ||
74 | |||
75 | /** | ||
71 | * Name length | 76 | * Name length |
72 | */ | 77 | */ |
73 | uint16_t name_len GNUNET_PACKED; | 78 | uint16_t name_len GNUNET_PACKED; |
@@ -83,7 +88,7 @@ struct RecordStoreMessage | |||
83 | uint16_t rd_count GNUNET_PACKED; | 88 | uint16_t rd_count GNUNET_PACKED; |
84 | 89 | ||
85 | /** | 90 | /** |
86 | * always zero (for alignment) | 91 | * Reserved for alignment. |
87 | */ | 92 | */ |
88 | uint16_t reserved GNUNET_PACKED; | 93 | uint16_t reserved GNUNET_PACKED; |
89 | 94 | ||
@@ -113,6 +118,20 @@ struct RecordStoreResponseMessage | |||
113 | * #GNUNET_SYSERR on failure, #GNUNET_OK on success | 118 | * #GNUNET_SYSERR on failure, #GNUNET_OK on success |
114 | */ | 119 | */ |
115 | int32_t op_result GNUNET_PACKED; | 120 | int32_t op_result GNUNET_PACKED; |
121 | |||
122 | /** | ||
123 | * Error message length | ||
124 | */ | ||
125 | uint16_t emsg_len GNUNET_PACKED; | ||
126 | |||
127 | /** | ||
128 | * Reserved for alignment. | ||
129 | */ | ||
130 | uint16_t reserved GNUNET_PACKED; | ||
131 | |||
132 | /** | ||
133 | * Followed by error message | ||
134 | */ | ||
116 | }; | 135 | }; |
117 | 136 | ||
118 | 137 | ||
@@ -132,6 +151,11 @@ struct LabelLookupMessage | |||
132 | uint32_t label_len GNUNET_PACKED; | 151 | uint32_t label_len GNUNET_PACKED; |
133 | 152 | ||
134 | /** | 153 | /** |
154 | * Lock the label with this lookup | ||
155 | */ | ||
156 | uint32_t locking GNUNET_PACKED; | ||
157 | |||
158 | /** | ||
135 | * The private key of the zone to look up in | 159 | * The private key of the zone to look up in |
136 | */ | 160 | */ |
137 | struct GNUNET_IDENTITY_PrivateKey zone; | 161 | struct GNUNET_IDENTITY_PrivateKey zone; |
@@ -171,7 +195,7 @@ struct LabelLookupResponseMessage | |||
171 | * Was the label found in the database?? | 195 | * Was the label found in the database?? |
172 | * #GNUNET_YES or #GNUNET_NO | 196 | * #GNUNET_YES or #GNUNET_NO |
173 | */ | 197 | */ |
174 | uint16_t found GNUNET_PACKED; | 198 | int16_t found GNUNET_PACKED; |
175 | 199 | ||
176 | /** | 200 | /** |
177 | * The private key of the authority. | 201 | * The private key of the authority. |
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index b24db9b26..a7380bbde 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c | |||
@@ -346,6 +346,44 @@ check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count) | |||
346 | return GNUNET_OK; | 346 | return GNUNET_OK; |
347 | } | 347 | } |
348 | 348 | ||
349 | /** | ||
350 | * Handle an incoming message of type | ||
351 | * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE | ||
352 | * | ||
353 | * @param cls | ||
354 | * @param msg the message we received | ||
355 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
356 | */ | ||
357 | static int | ||
358 | check_record_store_response (void *cls, | ||
359 | const struct RecordStoreResponseMessage *msg) | ||
360 | { | ||
361 | const char *emsg; | ||
362 | size_t msg_len; | ||
363 | size_t emsg_len; | ||
364 | |||
365 | (void) cls; | ||
366 | msg_len = ntohs (msg->gns_header.header.size); | ||
367 | emsg_len = ntohs (msg->emsg_len); | ||
368 | if (0 != ntohs (msg->reserved)) | ||
369 | { | ||
370 | GNUNET_break (0); | ||
371 | return GNUNET_SYSERR; | ||
372 | } | ||
373 | if (msg_len != sizeof(struct RecordStoreResponseMessage) + emsg_len) | ||
374 | { | ||
375 | GNUNET_break (0); | ||
376 | return GNUNET_SYSERR; | ||
377 | } | ||
378 | emsg = (const char *) &msg[1]; | ||
379 | if ((0 != emsg_len) && ('\0' != emsg[emsg_len - 1])) | ||
380 | { | ||
381 | GNUNET_break (0); | ||
382 | return GNUNET_SYSERR; | ||
383 | } | ||
384 | return GNUNET_OK; | ||
385 | } | ||
386 | |||
349 | 387 | ||
350 | /** | 388 | /** |
351 | * Handle an incoming message of type | 389 | * Handle an incoming message of type |
@@ -364,19 +402,16 @@ handle_record_store_response (void *cls, | |||
364 | const char *emsg; | 402 | const char *emsg; |
365 | 403 | ||
366 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); | 404 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); |
405 | emsg = (const char *) &msg[1]; | ||
367 | res = ntohl (msg->op_result); | 406 | res = ntohl (msg->op_result); |
368 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 407 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
369 | "Received RECORD_STORE_RESPONSE with result %d\n", | 408 | "Received RECORD_STORE_RESPONSE with result %d\n", |
370 | res); | 409 | res); |
371 | /* TODO: add actual error message from namestore to response... */ | ||
372 | if (GNUNET_SYSERR == res) | ||
373 | emsg = _ ("Namestore failed to store record\n"); | ||
374 | else | ||
375 | emsg = NULL; | ||
376 | if (NULL == qe) | 410 | if (NULL == qe) |
377 | return; | 411 | return; |
378 | if (NULL != qe->cont) | 412 | if (NULL != qe->cont) |
379 | qe->cont (qe->cont_cls, res, emsg); | 413 | qe->cont (qe->cont_cls, res, |
414 | (GNUNET_OK == res) ? NULL : emsg); | ||
380 | free_qe (qe); | 415 | free_qe (qe); |
381 | } | 416 | } |
382 | 417 | ||
@@ -444,8 +479,10 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
444 | size_t name_len; | 479 | size_t name_len; |
445 | size_t rd_len; | 480 | size_t rd_len; |
446 | unsigned int rd_count; | 481 | unsigned int rd_count; |
482 | int16_t found = (int16_t) ntohs (msg->found); | ||
447 | 483 | ||
448 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT\n"); | 484 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n", |
485 | found); | ||
449 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); | 486 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); |
450 | if (NULL == qe) | 487 | if (NULL == qe) |
451 | return; | 488 | return; |
@@ -453,7 +490,7 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
453 | rd_count = ntohs (msg->rd_count); | 490 | rd_count = ntohs (msg->rd_count); |
454 | name_len = ntohs (msg->name_len); | 491 | name_len = ntohs (msg->name_len); |
455 | name = (const char *) &msg[1]; | 492 | name = (const char *) &msg[1]; |
456 | if (GNUNET_NO == ntohs (msg->found)) | 493 | if (GNUNET_NO == found) |
457 | { | 494 | { |
458 | /* label was not in namestore */ | 495 | /* label was not in namestore */ |
459 | if (NULL != qe->proc) | 496 | if (NULL != qe->proc) |
@@ -461,6 +498,13 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
461 | free_qe (qe); | 498 | free_qe (qe); |
462 | return; | 499 | return; |
463 | } | 500 | } |
501 | if (GNUNET_SYSERR == found) | ||
502 | { | ||
503 | if (NULL != qe->error_cb) | ||
504 | qe->error_cb (qe->error_cb_cls); | ||
505 | free_qe (qe); | ||
506 | return; | ||
507 | } | ||
464 | 508 | ||
465 | rd_tmp = &name[name_len]; | 509 | rd_tmp = &name[name_len]; |
466 | { | 510 | { |
@@ -775,7 +819,7 @@ static void | |||
775 | reconnect (struct GNUNET_NAMESTORE_Handle *h) | 819 | reconnect (struct GNUNET_NAMESTORE_Handle *h) |
776 | { | 820 | { |
777 | struct GNUNET_MQ_MessageHandler handlers[] = | 821 | struct GNUNET_MQ_MessageHandler handlers[] = |
778 | { GNUNET_MQ_hd_fixed_size (record_store_response, | 822 | { GNUNET_MQ_hd_var_size (record_store_response, |
779 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, | 823 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, |
780 | struct RecordStoreResponseMessage, | 824 | struct RecordStoreResponseMessage, |
781 | h), | 825 | h), |
@@ -969,30 +1013,16 @@ warn_delay (void *cls) | |||
969 | GNUNET_NAMESTORE_cancel (qe); | 1013 | GNUNET_NAMESTORE_cancel (qe); |
970 | } | 1014 | } |
971 | 1015 | ||
972 | |||
973 | /** | ||
974 | * Store an item in the namestore. If the item is already present, | ||
975 | * it is replaced with the new record. Use an empty array to | ||
976 | * remove all records under the given name. | ||
977 | * | ||
978 | * @param h handle to the namestore | ||
979 | * @param pkey private key of the zone | ||
980 | * @param label name that is being mapped (at most 255 characters long) | ||
981 | * @param rd_count number of records in the @a rd array | ||
982 | * @param rd array of records with data to store | ||
983 | * @param cont continuation to call when done | ||
984 | * @param cont_cls closure for @a cont | ||
985 | * @return handle to abort the request | ||
986 | */ | ||
987 | struct GNUNET_NAMESTORE_QueueEntry * | 1016 | struct GNUNET_NAMESTORE_QueueEntry * |
988 | GNUNET_NAMESTORE_records_store ( | 1017 | records_store_ ( |
989 | struct GNUNET_NAMESTORE_Handle *h, | 1018 | struct GNUNET_NAMESTORE_Handle *h, |
990 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1019 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
991 | const char *label, | 1020 | const char *label, |
992 | unsigned int rd_count, | 1021 | unsigned int rd_count, |
993 | const struct GNUNET_GNSRECORD_Data *rd, | 1022 | const struct GNUNET_GNSRECORD_Data *rd, |
994 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | 1023 | GNUNET_NAMESTORE_ContinuationWithStatus cont, |
995 | void *cont_cls) | 1024 | void *cont_cls, |
1025 | int locking) | ||
996 | { | 1026 | { |
997 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1027 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
998 | struct GNUNET_MQ_Envelope *env; | 1028 | struct GNUNET_MQ_Envelope *env; |
@@ -1037,8 +1067,9 @@ GNUNET_NAMESTORE_records_store ( | |||
1037 | msg->name_len = htons (name_len); | 1067 | msg->name_len = htons (name_len); |
1038 | msg->rd_count = htons (rd_count); | 1068 | msg->rd_count = htons (rd_count); |
1039 | msg->rd_len = htons (rd_ser_len); | 1069 | msg->rd_len = htons (rd_ser_len); |
1040 | msg->reserved = htons (0); | 1070 | msg->reserved = ntohs(0); |
1041 | msg->private_key = *pkey; | 1071 | msg->private_key = *pkey; |
1072 | msg->locking = htonl (locking); | ||
1042 | 1073 | ||
1043 | name_tmp = (char *) &msg[1]; | 1074 | name_tmp = (char *) &msg[1]; |
1044 | GNUNET_memcpy (name_tmp, label, name_len); | 1075 | GNUNET_memcpy (name_tmp, label, name_len); |
@@ -1070,28 +1101,45 @@ GNUNET_NAMESTORE_records_store ( | |||
1070 | return qe; | 1101 | return qe; |
1071 | } | 1102 | } |
1072 | 1103 | ||
1104 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1105 | GNUNET_NAMESTORE_records_store ( | ||
1106 | struct GNUNET_NAMESTORE_Handle *h, | ||
1107 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1108 | const char *label, | ||
1109 | unsigned int rd_count, | ||
1110 | const struct GNUNET_GNSRECORD_Data *rd, | ||
1111 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
1112 | void *cont_cls) | ||
1113 | { | ||
1114 | return records_store_ (h, pkey, label, | ||
1115 | rd_count, rd, cont, cont_cls, GNUNET_NO); | ||
1116 | } | ||
1117 | |||
1118 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1119 | GNUNET_NAMESTORE_records_commit ( | ||
1120 | struct GNUNET_NAMESTORE_Handle *h, | ||
1121 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1122 | const char *label, | ||
1123 | unsigned int rd_count, | ||
1124 | const struct GNUNET_GNSRECORD_Data *rd, | ||
1125 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
1126 | void *cont_cls) | ||
1127 | { | ||
1128 | return records_store_ (h, pkey, label, | ||
1129 | rd_count, rd, cont, cont_cls, GNUNET_YES); | ||
1130 | } | ||
1131 | |||
1073 | 1132 | ||
1074 | /** | ||
1075 | * Lookup an item in the namestore. | ||
1076 | * | ||
1077 | * @param h handle to the namestore | ||
1078 | * @param pkey private key of the zone | ||
1079 | * @param label name that is being mapped (at most 255 characters long) | ||
1080 | * @param error_cb function to call on error (i.e. disconnect) | ||
1081 | * @param error_cb_cls closure for @a error_cb | ||
1082 | * @param rm function to call with the result (with 0 records if we don't have that label) | ||
1083 | * @param rm_cls closure for @a rm | ||
1084 | * @return handle to abort the request | ||
1085 | */ | ||
1086 | struct GNUNET_NAMESTORE_QueueEntry * | 1133 | struct GNUNET_NAMESTORE_QueueEntry * |
1087 | GNUNET_NAMESTORE_records_lookup ( | 1134 | records_lookup_ ( |
1088 | struct GNUNET_NAMESTORE_Handle *h, | 1135 | struct GNUNET_NAMESTORE_Handle *h, |
1089 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1136 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1090 | const char *label, | 1137 | const char *label, |
1091 | GNUNET_SCHEDULER_TaskCallback error_cb, | 1138 | GNUNET_SCHEDULER_TaskCallback error_cb, |
1092 | void *error_cb_cls, | 1139 | void *error_cb_cls, |
1093 | GNUNET_NAMESTORE_RecordMonitor rm, | 1140 | GNUNET_NAMESTORE_RecordMonitor rm, |
1094 | void *rm_cls) | 1141 | void *rm_cls, |
1142 | int locking) | ||
1095 | { | 1143 | { |
1096 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1144 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
1097 | struct GNUNET_MQ_Envelope *env; | 1145 | struct GNUNET_MQ_Envelope *env; |
@@ -1119,6 +1167,7 @@ GNUNET_NAMESTORE_records_lookup ( | |||
1119 | msg->gns_header.r_id = htonl (qe->op_id); | 1167 | msg->gns_header.r_id = htonl (qe->op_id); |
1120 | msg->zone = *pkey; | 1168 | msg->zone = *pkey; |
1121 | msg->label_len = htonl (label_len); | 1169 | msg->label_len = htonl (label_len); |
1170 | msg->locking = htonl (locking); | ||
1122 | GNUNET_memcpy (&msg[1], label, label_len); | 1171 | GNUNET_memcpy (&msg[1], label, label_len); |
1123 | if (NULL == h->mq) | 1172 | if (NULL == h->mq) |
1124 | qe->env = env; | 1173 | qe->env = env; |
@@ -1127,22 +1176,34 @@ GNUNET_NAMESTORE_records_lookup ( | |||
1127 | return qe; | 1176 | return qe; |
1128 | } | 1177 | } |
1129 | 1178 | ||
1179 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1180 | GNUNET_NAMESTORE_records_lookup ( | ||
1181 | struct GNUNET_NAMESTORE_Handle *h, | ||
1182 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1183 | const char *label, | ||
1184 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1185 | void *error_cb_cls, | ||
1186 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
1187 | void *rm_cls) | ||
1188 | { | ||
1189 | return records_lookup_ (h, pkey, label, | ||
1190 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_NO); | ||
1191 | } | ||
1192 | |||
1193 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1194 | GNUNET_NAMESTORE_records_open ( | ||
1195 | struct GNUNET_NAMESTORE_Handle *h, | ||
1196 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1197 | const char *label, | ||
1198 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1199 | void *error_cb_cls, | ||
1200 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
1201 | void *rm_cls) | ||
1202 | { | ||
1203 | return records_lookup_ (h, pkey, label, | ||
1204 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_YES); | ||
1205 | } | ||
1130 | 1206 | ||
1131 | /** | ||
1132 | * Look for an existing PKEY delegation record for a given public key. | ||
1133 | * Returns at most one result to the processor. | ||
1134 | * | ||
1135 | * @param h handle to the namestore | ||
1136 | * @param zone public key of the zone to look up in, never NULL | ||
1137 | * @param value_zone public key of the target zone (value), never NULL | ||
1138 | * @param error_cb function to call on error (i.e. disconnect) | ||
1139 | * @param error_cb_cls closure for @a error_cb | ||
1140 | * @param proc function to call on the matching records, or with | ||
1141 | * NULL (rd_count == 0) if there are no matching records | ||
1142 | * @param proc_cls closure for @a proc | ||
1143 | * @return a handle that can be used to | ||
1144 | * cancel | ||
1145 | */ | ||
1146 | struct GNUNET_NAMESTORE_QueueEntry * | 1207 | struct GNUNET_NAMESTORE_QueueEntry * |
1147 | GNUNET_NAMESTORE_zone_to_name ( | 1208 | GNUNET_NAMESTORE_zone_to_name ( |
1148 | struct GNUNET_NAMESTORE_Handle *h, | 1209 | struct GNUNET_NAMESTORE_Handle *h, |
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 7cb9b7ed0..0b3aac84f 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -329,6 +329,11 @@ namestore_sqlite_store_records (void *cls, | |||
329 | 0, | 329 | 0, |
330 | sizeof(pkey)); | 330 | sizeof(pkey)); |
331 | for (unsigned int i = 0; i < rd_count; i++) | 331 | for (unsigned int i = 0; i < rd_count; i++) |
332 | { | ||
333 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
334 | "Checking if `%d' is zonekey type\n", | ||
335 | rd[i].record_type); | ||
336 | |||
332 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) | 337 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) |
333 | { | 338 | { |
334 | GNUNET_break (GNUNET_YES == | 339 | GNUNET_break (GNUNET_YES == |
@@ -336,8 +341,13 @@ namestore_sqlite_store_records (void *cls, | |||
336 | rd[i].data_size, | 341 | rd[i].data_size, |
337 | rd[i].record_type, | 342 | rd[i].record_type, |
338 | &pkey)); | 343 | &pkey)); |
344 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
345 | "Storing delegation zone record value `%s'\n", | ||
346 | GNUNET_GNSRECORD_z2s (&pkey)); | ||
347 | |||
339 | break; | 348 | break; |
340 | } | 349 | } |
350 | } | ||
341 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 351 | rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
342 | UINT64_MAX); | 352 | UINT64_MAX); |
343 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, | 353 | data_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
diff --git a/src/namestore/test_namestore_api_lookup_nick.c b/src/namestore/test_namestore_api_lookup_nick.c index 6ce969c9b..7decf39f8 100644 --- a/src/namestore/test_namestore_api_lookup_nick.c +++ b/src/namestore/test_namestore_api_lookup_nick.c | |||
@@ -262,12 +262,12 @@ nick_cont (void *cls, int32_t success, const char *emsg) | |||
262 | "Nick added : %s\n", | 262 | "Nick added : %s\n", |
263 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); | 263 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); |
264 | 264 | ||
265 | rd_orig.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; | 265 | rd_orig.expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; |
266 | rd_orig.record_type = TEST_RECORD_TYPE; | 266 | rd_orig.record_type = TEST_RECORD_TYPE; |
267 | rd_orig.data_size = TEST_RECORD_DATALEN; | 267 | rd_orig.data_size = TEST_RECORD_DATALEN; |
268 | record_data = GNUNET_malloc (TEST_RECORD_DATALEN); | 268 | record_data = GNUNET_malloc (TEST_RECORD_DATALEN); |
269 | rd_orig.data = record_data; | 269 | rd_orig.data = record_data; |
270 | rd_orig.flags = 0; | 270 | rd_orig.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
271 | memset ((char *) rd_orig.data, 'a', TEST_RECORD_DATALEN); | 271 | memset ((char *) rd_orig.data, 'a', TEST_RECORD_DATALEN); |
272 | 272 | ||
273 | nsqe = GNUNET_NAMESTORE_records_store (nsh, &privkey, | 273 | nsqe = GNUNET_NAMESTORE_records_store (nsh, &privkey, |
diff --git a/src/namestore/test_namestore_api_lookup_public.c b/src/namestore/test_namestore_api_lookup_public.c index 5e3e7bbd8..cd69b96ef 100644 --- a/src/namestore/test_namestore_api_lookup_public.c +++ b/src/namestore/test_namestore_api_lookup_public.c | |||
@@ -188,7 +188,7 @@ run (void *cls, | |||
188 | struct GNUNET_TESTING_Peer *peer) | 188 | struct GNUNET_TESTING_Peer *peer) |
189 | { | 189 | { |
190 | struct GNUNET_GNSRECORD_Data rd; | 190 | struct GNUNET_GNSRECORD_Data rd; |
191 | const char *name = "dummy.dummy.gnunet"; | 191 | const char *name = "dummy"; |
192 | 192 | ||
193 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 193 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
194 | &endbadly, | 194 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_lookup_shadow.c b/src/namestore/test_namestore_api_lookup_shadow.c index 79fa4c9c6..8f47d1280 100644 --- a/src/namestore/test_namestore_api_lookup_shadow.c +++ b/src/namestore/test_namestore_api_lookup_shadow.c | |||
@@ -223,7 +223,7 @@ run (void *cls, | |||
223 | struct GNUNET_TESTING_Peer *peer) | 223 | struct GNUNET_TESTING_Peer *peer) |
224 | { | 224 | { |
225 | struct GNUNET_GNSRECORD_Data rd; | 225 | struct GNUNET_GNSRECORD_Data rd; |
226 | const char *name = "dummy.dummy.gnunet"; | 226 | const char *name = "dummy"; |
227 | 227 | ||
228 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 228 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
229 | &endbadly, | 229 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_lookup_shadow_filter.c b/src/namestore/test_namestore_api_lookup_shadow_filter.c index 4fc197750..0bcd130f9 100644 --- a/src/namestore/test_namestore_api_lookup_shadow_filter.c +++ b/src/namestore/test_namestore_api_lookup_shadow_filter.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT | 33 | #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT |
34 | 34 | ||
35 | #define TEST_NAME "dummy.dummy.gnunet" | 35 | #define TEST_NAME "gnunet" |
36 | #define TEST_RECORD_DATALEN 123 | 36 | #define TEST_RECORD_DATALEN 123 |
37 | #define TEST_RECORD_DATA 'a' | 37 | #define TEST_RECORD_DATA 'a' |
38 | #define TEST_SHADOW_RECORD_DATA 'b' | 38 | #define TEST_SHADOW_RECORD_DATA 'b' |
diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c index b6254e531..e8124c595 100644 --- a/src/namestore/test_namestore_api_remove.c +++ b/src/namestore/test_namestore_api_remove.c | |||
@@ -153,7 +153,7 @@ run (void *cls, | |||
153 | struct GNUNET_TESTING_Peer *peer) | 153 | struct GNUNET_TESTING_Peer *peer) |
154 | { | 154 | { |
155 | struct GNUNET_GNSRECORD_Data rd; | 155 | struct GNUNET_GNSRECORD_Data rd; |
156 | const char *name = "dummy.dummy.gnunet"; | 156 | const char *name = "dummy"; |
157 | 157 | ||
158 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 158 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
159 | &endbadly, | 159 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c index e66992909..958ea4bf2 100644 --- a/src/namestore/test_namestore_api_remove_not_existing_record.c +++ b/src/namestore/test_namestore_api_remove_not_existing_record.c | |||
@@ -127,7 +127,7 @@ run (void *cls, | |||
127 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 127 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
128 | struct GNUNET_TESTING_Peer *peer) | 128 | struct GNUNET_TESTING_Peer *peer) |
129 | { | 129 | { |
130 | const char *name = "dummy.dummy.gnunet"; | 130 | const char *name = "dummy"; |
131 | 131 | ||
132 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 132 | endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
133 | &endbadly, | 133 | &endbadly, |
diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c index 3fd10e4a1..1e2f8248b 100644 --- a/src/namestore/test_namestore_api_zone_to_name.c +++ b/src/namestore/test_namestore_api_zone_to_name.c | |||
@@ -216,11 +216,11 @@ run (void *cls, | |||
216 | { | 216 | { |
217 | struct GNUNET_GNSRECORD_Data rd; | 217 | struct GNUNET_GNSRECORD_Data rd; |
218 | 218 | ||
219 | rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; | 219 | rd.expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; |
220 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | 220 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; |
221 | rd.data_size = GNUNET_IDENTITY_key_get_length (&s_zone_value); | 221 | rd.data_size = sizeof (s_zone_value.ecdsa_key); |
222 | rd.data = &s_zone_value; | 222 | rd.data = &s_zone_value.ecdsa_key; |
223 | rd.flags = 0; | 223 | rd.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
224 | 224 | ||
225 | nsh = GNUNET_NAMESTORE_connect (cfg); | 225 | nsh = GNUNET_NAMESTORE_connect (cfg); |
226 | GNUNET_break (NULL != nsh); | 226 | GNUNET_break (NULL != nsh); |
@@ -230,7 +230,7 @@ run (void *cls, | |||
230 | 1, | 230 | 1, |
231 | &rd, | 231 | &rd, |
232 | &put_cont, | 232 | &put_cont, |
233 | NULL); | 233 | s_name); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/src/namestore/test_namestore_delete.sh b/src/namestore/test_namestore_delete.sh index 44ea1e66c..b861a4bc0 100755 --- a/src/namestore/test_namestore_delete.sh +++ b/src/namestore/test_namestore_delete.sh | |||
@@ -61,15 +61,7 @@ for LINE in $OUTPUT ; | |||
61 | stop_peer | 61 | stop_peer |
62 | 62 | ||
63 | 63 | ||
64 | if [ $FOUND_NAME = false -a $FOUND_IP != false ] | 64 | if [ $FOUND_IP = true ] |
65 | then | ||
66 | echo "PASS: Delete name in namestore" | ||
67 | exit 0 | ||
68 | elif [ $FOUND_NAME = true ] | ||
69 | then | ||
70 | echo "FAIL: Delete name in namestore: name returned" | ||
71 | exit 1 | ||
72 | elif [ $FOUND_IP = true ] | ||
73 | then | 65 | then |
74 | echo "FAIL: Delete name in namestore: IP returned" | 66 | echo "FAIL: Delete name in namestore: IP returned" |
75 | exit 1 | 67 | exit 1 |
diff --git a/src/namestore/test_plugin_rest_namestore.sh b/src/namestore/test_plugin_rest_namestore.sh index 8a45cebf5..50b3c8c12 100755 --- a/src/namestore/test_plugin_rest_namestore.sh +++ b/src/namestore/test_plugin_rest_namestore.sh | |||
@@ -78,15 +78,16 @@ curl_delete () { | |||
78 | 78 | ||
79 | TEST_ID="test" | 79 | TEST_ID="test" |
80 | gnunet-arm -s -c test_namestore_api.conf | 80 | gnunet-arm -s -c test_namestore_api.conf |
81 | gnunet-arm -i rest -c test_namestore_api.conf | ||
82 | #Test GET | 81 | #Test GET |
83 | gnunet-identity -C $TEST_ID -c test_namestore_api.conf | 82 | gnunet-identity -C $TEST_ID -c test_namestore_api.conf |
84 | test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" | 83 | test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" |
85 | name=$TEST_ID | 84 | name=$TEST_ID |
86 | public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" | 85 | public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" |
87 | echo "$name $public" | 86 | echo "$name $public" |
88 | valgrind gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | 87 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf |
89 | #curl_get "${namestore_link}" "HTTP/1.1 200 OK" | 88 | sleep 1 |
89 | gnunet-arm -i rest -c test_namestore_api.conf | ||
90 | sleep 1 | ||
90 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" | 91 | curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" |
91 | curl_get "${namestore_link}/$public" "error" | 92 | curl_get "${namestore_link}/$public" "error" |
92 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf | 93 | gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf |
@@ -128,9 +129,6 @@ gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/ | |||
128 | #Test DELETE | 129 | #Test DELETE |
129 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | 130 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf |
130 | curl_delete "${namestore_link}/$name/test_entry" "HTTP/1.1 204" | 131 | curl_delete "${namestore_link}/$name/test_entry" "HTTP/1.1 204" |
131 | curl_delete "${namestore_link}/$name/test_entry" "error" | ||
132 | gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf | ||
133 | curl_delete "${namestore_link}/$public/test_entry" "error" | ||
134 | 132 | ||
135 | gnunet-arm -e -c test_namestore_api.conf | 133 | gnunet-arm -e -c test_namestore_api.conf |
136 | exit 0; | 134 | exit 0; |
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index f41473f9f..bc6b835c9 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c | |||
@@ -1550,7 +1550,6 @@ GNUNET_RECLAIM_ticket_issue ( | |||
1550 | struct IssueTicketMessage *tim; | 1550 | struct IssueTicketMessage *tim; |
1551 | size_t attr_len; | 1551 | size_t attr_len; |
1552 | 1552 | ||
1553 | fprintf (stderr, "Issuing ticket\n"); | ||
1554 | op = GNUNET_new (struct GNUNET_RECLAIM_Operation); | 1553 | op = GNUNET_new (struct GNUNET_RECLAIM_Operation); |
1555 | op->h = h; | 1554 | op->h = h; |
1556 | op->ti_cb = cb; | 1555 | op->ti_cb = cb; |
diff --git a/src/reclaim/test_reclaim.conf b/src/reclaim/test_reclaim.conf index ec19056e4..2dc53fe81 100644 --- a/src/reclaim/test_reclaim.conf +++ b/src/reclaim/test_reclaim.conf | |||
@@ -15,7 +15,7 @@ PLUGINS = | |||
15 | 15 | ||
16 | [reclaim] | 16 | [reclaim] |
17 | START_ON_DEMAND = YES | 17 | START_ON_DEMAND = YES |
18 | TICKET_REFRESH_INTERVAL = 15s | 18 | TICKET_REFRESH_INTERVAL = 30 s |
19 | #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=$GNUNET_TMP/idplog | 19 | #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=$GNUNET_TMP/idplog |
20 | 20 | ||
21 | [gns] | 21 | [gns] |
diff --git a/src/reclaim/test_reclaim_consume.sh b/src/reclaim/test_reclaim_consume.sh index 9186d3cb1..c012862c3 100755 --- a/src/reclaim/test_reclaim_consume.sh +++ b/src/reclaim/test_reclaim_consume.sh | |||
@@ -32,12 +32,14 @@ TEST_KEY=$(gnunet-identity -d -e testego -q -c test_reclaim.conf) | |||
32 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf | 32 | gnunet-reclaim -e testego -a email -V john@doe.gnu -c test_reclaim.conf |
33 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf | 33 | gnunet-reclaim -e testego -a name -V John -c test_reclaim.conf |
34 | TICKET=$(gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}') | 34 | TICKET=$(gnunet-reclaim -e testego -i "email,name" -r $SUBJECT_KEY -c test_reclaim.conf | awk '{print $1}') |
35 | gnunet-reclaim -e rpego -C $TICKET -c test_reclaim.conf >/dev/null 2>&1 | 35 | gnunet-reclaim -e rpego -C $TICKET -c test_reclaim.conf #>/dev/null 2>&1 |
36 | 36 | ||
37 | if test $? != 0 | 37 | RES=$? |
38 | gnunet-identity -D testego -c test_reclaim.conf | ||
39 | gnunet-identity -D rpego -c test_reclaim.conf | ||
40 | gnunet-arm -e -c test_reclaim.conf | ||
41 | if test $RES != 0 | ||
38 | then | 42 | then |
39 | "Failed." | 43 | echo "Failed." |
40 | exit 1 | ||
41 | fi | 44 | fi |
42 | #curl http://localhost:7776/reclaim/tickets/testego | 45 | |
43 | gnunet-arm -e -c test_reclaim.conf | ||
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index 0953830ab..61442ac10 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -93,242 +93,6 @@ block_plugin_regex_create_group (void *cls, | |||
93 | 93 | ||
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Function called to validate a reply or a request of type | ||
97 | * #GNUNET_BLOCK_TYPE_REGEX. | ||
98 | * For request evaluation, pass "NULL" for the reply_block. | ||
99 | * Note that it is assumed that the reply has already been | ||
100 | * matched to the key (and signatures checked) as it would | ||
101 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
102 | * | ||
103 | * @param cls closure | ||
104 | * @param type block type | ||
105 | * @param bg block group to evaluate against | ||
106 | * @param eo control flags | ||
107 | * @param query original query (hash) | ||
108 | * @param xquery extrended query data (can be NULL, depending on type) | ||
109 | * @param xquery_size number of bytes in @a xquery | ||
110 | * @param reply_block response to validate | ||
111 | * @param reply_block_size number of bytes in @a reply_block | ||
112 | * @return characterization of result | ||
113 | */ | ||
114 | static enum GNUNET_BLOCK_EvaluationResult | ||
115 | evaluate_block_regex (void *cls, | ||
116 | enum GNUNET_BLOCK_Type type, | ||
117 | struct GNUNET_BLOCK_Group *bg, | ||
118 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
119 | const struct GNUNET_HashCode *query, | ||
120 | const void *xquery, | ||
121 | size_t xquery_size, | ||
122 | const void *reply_block, | ||
123 | size_t reply_block_size) | ||
124 | { | ||
125 | struct GNUNET_HashCode chash; | ||
126 | |||
127 | if (NULL == reply_block) | ||
128 | { | ||
129 | if (0 != xquery_size) | ||
130 | { | ||
131 | const char *s; | ||
132 | |||
133 | s = (const char *) xquery; | ||
134 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
135 | { | ||
136 | GNUNET_break_op (0); | ||
137 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
138 | } | ||
139 | } | ||
140 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
141 | } | ||
142 | if (0 != xquery_size) | ||
143 | { | ||
144 | const char *s; | ||
145 | |||
146 | s = (const char *) xquery; | ||
147 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
148 | { | ||
149 | GNUNET_break_op (0); | ||
150 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
151 | } | ||
152 | } | ||
153 | else if (NULL != query) | ||
154 | { | ||
155 | /* xquery is required for regex GETs, at least an empty string */ | ||
156 | GNUNET_break_op (0); | ||
157 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "type %d, query %p, xquery %p\n", | ||
158 | type, query, xquery); | ||
159 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
160 | } | ||
161 | switch (REGEX_BLOCK_check (reply_block, | ||
162 | reply_block_size, | ||
163 | query, | ||
164 | xquery)) | ||
165 | { | ||
166 | case GNUNET_SYSERR: | ||
167 | GNUNET_break_op (0); | ||
168 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
169 | |||
170 | case GNUNET_NO: | ||
171 | /* xquery mismatch, can happen */ | ||
172 | return GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT; | ||
173 | |||
174 | default: | ||
175 | break; | ||
176 | } | ||
177 | GNUNET_CRYPTO_hash (reply_block, | ||
178 | reply_block_size, | ||
179 | &chash); | ||
180 | if (GNUNET_YES == | ||
181 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
182 | &chash)) | ||
183 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
184 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
185 | } | ||
186 | |||
187 | |||
188 | /** | ||
189 | * Function called to validate a reply or a request of type | ||
190 | * #GNUNET_BLOCK_TYPE_REGEX_ACCEPT. | ||
191 | * For request evaluation, pass "NULL" for the reply_block. | ||
192 | * Note that it is assumed that the reply has already been | ||
193 | * matched to the key (and signatures checked) as it would | ||
194 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
195 | * | ||
196 | * @param cls closure | ||
197 | * @param type block type | ||
198 | * @param bg block group to evaluate against | ||
199 | * @param eo control flags | ||
200 | * @param query original query (hash) | ||
201 | * @param xquery extrended query data (can be NULL, depending on type) | ||
202 | * @param xquery_size number of bytes in @a xquery | ||
203 | * @param reply_block response to validate | ||
204 | * @param reply_block_size number of bytes in @a reply_block | ||
205 | * @return characterization of result | ||
206 | */ | ||
207 | static enum GNUNET_BLOCK_EvaluationResult | ||
208 | evaluate_block_regex_accept (void *cls, | ||
209 | enum GNUNET_BLOCK_Type type, | ||
210 | struct GNUNET_BLOCK_Group *bg, | ||
211 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
212 | const struct GNUNET_HashCode *query, | ||
213 | const void *xquery, | ||
214 | size_t xquery_size, const void *reply_block, | ||
215 | size_t reply_block_size) | ||
216 | { | ||
217 | const struct RegexAcceptBlock *rba; | ||
218 | struct GNUNET_HashCode chash; | ||
219 | |||
220 | if (0 != xquery_size) | ||
221 | { | ||
222 | GNUNET_break_op (0); | ||
223 | return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; | ||
224 | } | ||
225 | if (NULL == reply_block) | ||
226 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
227 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | ||
228 | { | ||
229 | GNUNET_break_op (0); | ||
230 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
231 | } | ||
232 | rba = reply_block; | ||
233 | if (ntohl (rba->purpose.size) != | ||
234 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
235 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
236 | + sizeof(struct GNUNET_HashCode)) | ||
237 | { | ||
238 | GNUNET_break_op (0); | ||
239 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
240 | } | ||
241 | if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh ( | ||
242 | rba->expiration_time)). | ||
243 | rel_value_us) | ||
244 | { | ||
245 | /* technically invalid, but can happen without an error, so | ||
246 | we're nice by reporting it as a 'duplicate' */ | ||
247 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
248 | } | ||
249 | if (GNUNET_OK != | ||
250 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT, | ||
251 | &rba->purpose, | ||
252 | &rba->signature, | ||
253 | &rba->peer.public_key)) | ||
254 | { | ||
255 | GNUNET_break_op (0); | ||
256 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
257 | } | ||
258 | GNUNET_CRYPTO_hash (reply_block, | ||
259 | reply_block_size, | ||
260 | &chash); | ||
261 | if (GNUNET_YES == | ||
262 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
263 | &chash)) | ||
264 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
265 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
266 | } | ||
267 | |||
268 | |||
269 | /** | ||
270 | * Function called to validate a reply or a request. For | ||
271 | * request evaluation, simply pass "NULL" for the reply_block. | ||
272 | * Note that it is assumed that the reply has already been | ||
273 | * matched to the key (and signatures checked) as it would | ||
274 | * be done with the #GNUNET_BLOCK_get_key() function. | ||
275 | * | ||
276 | * @param cls closure | ||
277 | * @param ctx block context | ||
278 | * @param type block type | ||
279 | * @param bg group to evaluate against | ||
280 | * @param eo control flags | ||
281 | * @param query original query (hash) | ||
282 | * @param xquery extrended query data (can be NULL, depending on type) | ||
283 | * @param xquery_size number of bytes in xquery | ||
284 | * @param reply_block response to validate | ||
285 | * @param reply_block_size number of bytes in reply block | ||
286 | * @return characterization of result | ||
287 | */ | ||
288 | static enum GNUNET_BLOCK_EvaluationResult | ||
289 | block_plugin_regex_evaluate (void *cls, | ||
290 | struct GNUNET_BLOCK_Context *ctx, | ||
291 | enum GNUNET_BLOCK_Type type, | ||
292 | struct GNUNET_BLOCK_Group *bg, | ||
293 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
294 | const struct GNUNET_HashCode *query, | ||
295 | const void *xquery, | ||
296 | size_t xquery_size, | ||
297 | const void *reply_block, | ||
298 | size_t reply_block_size) | ||
299 | { | ||
300 | enum GNUNET_BLOCK_EvaluationResult result; | ||
301 | |||
302 | switch (type) | ||
303 | { | ||
304 | case GNUNET_BLOCK_TYPE_REGEX: | ||
305 | result = evaluate_block_regex (cls, | ||
306 | type, | ||
307 | bg, | ||
308 | eo, | ||
309 | query, | ||
310 | xquery, xquery_size, | ||
311 | reply_block, reply_block_size); | ||
312 | break; | ||
313 | |||
314 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
315 | result = evaluate_block_regex_accept (cls, | ||
316 | type, | ||
317 | bg, | ||
318 | eo, | ||
319 | query, | ||
320 | xquery, xquery_size, | ||
321 | reply_block, reply_block_size); | ||
322 | break; | ||
323 | |||
324 | default: | ||
325 | result = GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
326 | } | ||
327 | return result; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Function called to validate a query. | 96 | * Function called to validate a query. |
333 | * | 97 | * |
334 | * @param cls closure | 98 | * @param cls closure |
@@ -341,10 +105,10 @@ block_plugin_regex_evaluate (void *cls, | |||
341 | */ | 105 | */ |
342 | static enum GNUNET_GenericReturnValue | 106 | static enum GNUNET_GenericReturnValue |
343 | block_plugin_regex_check_query (void *cls, | 107 | block_plugin_regex_check_query (void *cls, |
344 | enum GNUNET_BLOCK_Type type, | 108 | enum GNUNET_BLOCK_Type type, |
345 | const struct GNUNET_HashCode *query, | 109 | const struct GNUNET_HashCode *query, |
346 | const void *xquery, | 110 | const void *xquery, |
347 | size_t xquery_size) | 111 | size_t xquery_size) |
348 | { | 112 | { |
349 | switch (type) | 113 | switch (type) |
350 | { | 114 | { |
@@ -380,7 +144,6 @@ block_plugin_regex_check_query (void *cls, | |||
380 | * | 144 | * |
381 | * @param cls closure | 145 | * @param cls closure |
382 | * @param type block type | 146 | * @param type block type |
383 | * @param query key for the block (hash), must match exactly | ||
384 | * @param block block data to validate | 147 | * @param block block data to validate |
385 | * @param block_size number of bytes in @a block | 148 | * @param block_size number of bytes in @a block |
386 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 149 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -388,7 +151,6 @@ block_plugin_regex_check_query (void *cls, | |||
388 | static enum GNUNET_GenericReturnValue | 151 | static enum GNUNET_GenericReturnValue |
389 | block_plugin_regex_check_block (void *cls, | 152 | block_plugin_regex_check_block (void *cls, |
390 | enum GNUNET_BLOCK_Type type, | 153 | enum GNUNET_BLOCK_Type type, |
391 | const struct GNUNET_HashCode *query, | ||
392 | const void *block, | 154 | const void *block, |
393 | size_t block_size) | 155 | size_t block_size) |
394 | { | 156 | { |
@@ -398,7 +160,7 @@ block_plugin_regex_check_block (void *cls, | |||
398 | if (GNUNET_SYSERR == | 160 | if (GNUNET_SYSERR == |
399 | REGEX_BLOCK_check (block, | 161 | REGEX_BLOCK_check (block, |
400 | block_size, | 162 | block_size, |
401 | query, | 163 | NULL, |
402 | NULL)) | 164 | NULL)) |
403 | return GNUNET_NO; | 165 | return GNUNET_NO; |
404 | return GNUNET_OK; | 166 | return GNUNET_OK; |
@@ -480,12 +242,7 @@ block_plugin_regex_check_reply ( | |||
480 | const char *s; | 242 | const char *s; |
481 | 243 | ||
482 | s = (const char *) xquery; | 244 | s = (const char *) xquery; |
483 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | 245 | GNUNET_assert ('\0' == s[xquery_size - 1]); |
484 | { | ||
485 | /* Technically, the query is invalid ... */ | ||
486 | GNUNET_break (0); | ||
487 | return GNUNET_BLOCK_REPLY_INVALID; | ||
488 | } | ||
489 | } | 246 | } |
490 | switch (REGEX_BLOCK_check (reply_block, | 247 | switch (REGEX_BLOCK_check (reply_block, |
491 | reply_block_size, | 248 | reply_block_size, |
@@ -493,8 +250,7 @@ block_plugin_regex_check_reply ( | |||
493 | xquery)) | 250 | xquery)) |
494 | { | 251 | { |
495 | case GNUNET_SYSERR: | 252 | case GNUNET_SYSERR: |
496 | GNUNET_break_op (0); | 253 | GNUNET_assert (0); |
497 | return GNUNET_BLOCK_REPLY_INVALID; | ||
498 | case GNUNET_NO: | 254 | case GNUNET_NO: |
499 | /* xquery mismatch, can happen */ | 255 | /* xquery mismatch, can happen */ |
500 | return GNUNET_BLOCK_REPLY_IRRELEVANT; | 256 | return GNUNET_BLOCK_REPLY_IRRELEVANT; |
@@ -513,20 +269,12 @@ block_plugin_regex_check_reply ( | |||
513 | { | 269 | { |
514 | const struct RegexAcceptBlock *rba; | 270 | const struct RegexAcceptBlock *rba; |
515 | 271 | ||
516 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | 272 | GNUNET_assert (sizeof(struct RegexAcceptBlock) == reply_block_size); |
517 | { | ||
518 | GNUNET_break_op (0); | ||
519 | return GNUNET_BLOCK_REPLY_INVALID; | ||
520 | } | ||
521 | rba = reply_block; | 273 | rba = reply_block; |
522 | if (ntohl (rba->purpose.size) != | 274 | GNUNET_assert (ntohl (rba->purpose.size) == |
523 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 275 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
524 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | 276 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) |
525 | + sizeof(struct GNUNET_HashCode)) | 277 | + sizeof(struct GNUNET_HashCode)); |
526 | { | ||
527 | GNUNET_break_op (0); | ||
528 | return GNUNET_BLOCK_REPLY_INVALID; | ||
529 | } | ||
530 | GNUNET_CRYPTO_hash (reply_block, | 278 | GNUNET_CRYPTO_hash (reply_block, |
531 | reply_block_size, | 279 | reply_block_size, |
532 | &chash); | 280 | &chash); |
@@ -552,8 +300,8 @@ block_plugin_regex_check_reply ( | |||
552 | * @param block block to get the key for | 300 | * @param block block to get the key for |
553 | * @param block_size number of bytes in @a block | 301 | * @param block_size number of bytes in @a block |
554 | * @param key set to the key (query) for the given block | 302 | * @param key set to the key (query) for the given block |
555 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 303 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported, |
556 | * (or if extracting a key from a block of this type does not work) | 304 | * #GNUNET_NO if extracting a key from a block of this type does not work |
557 | */ | 305 | */ |
558 | static enum GNUNET_GenericReturnValue | 306 | static enum GNUNET_GenericReturnValue |
559 | block_plugin_regex_get_key (void *cls, | 307 | block_plugin_regex_get_key (void *cls, |
@@ -571,14 +319,20 @@ block_plugin_regex_get_key (void *cls, | |||
571 | key)) | 319 | key)) |
572 | { | 320 | { |
573 | GNUNET_break_op (0); | 321 | GNUNET_break_op (0); |
574 | return GNUNET_NO; | 322 | memset (key, |
323 | 0, | ||
324 | sizeof (*key)); | ||
325 | return GNUNET_OK; | ||
575 | } | 326 | } |
576 | return GNUNET_OK; | 327 | return GNUNET_OK; |
577 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | 328 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: |
578 | if (sizeof(struct RegexAcceptBlock) != block_size) | 329 | if (sizeof(struct RegexAcceptBlock) != block_size) |
579 | { | 330 | { |
580 | GNUNET_break_op (0); | 331 | GNUNET_break_op (0); |
581 | return GNUNET_NO; | 332 | memset (key, |
333 | 0, | ||
334 | sizeof (*key)); | ||
335 | return GNUNET_OK; | ||
582 | } | 336 | } |
583 | *key = ((struct RegexAcceptBlock *) block)->key; | 337 | *key = ((struct RegexAcceptBlock *) block)->key; |
584 | return GNUNET_OK; | 338 | return GNUNET_OK; |
@@ -603,7 +357,6 @@ libgnunet_plugin_block_regex_init (void *cls) | |||
603 | struct GNUNET_BLOCK_PluginFunctions *api; | 357 | struct GNUNET_BLOCK_PluginFunctions *api; |
604 | 358 | ||
605 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 359 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
606 | api->evaluate = &block_plugin_regex_evaluate; | ||
607 | api->get_key = &block_plugin_regex_get_key; | 360 | api->get_key = &block_plugin_regex_get_key; |
608 | api->check_query = &block_plugin_regex_check_query; | 361 | api->check_query = &block_plugin_regex_check_query; |
609 | api->check_block = &block_plugin_regex_check_block; | 362 | api->check_block = &block_plugin_regex_check_block; |
diff --git a/src/revocation/gnunet-revocation-tvg.c b/src/revocation/gnunet-revocation-tvg.c index 3ba5b56fa..a34a6bc98 100644 --- a/src/revocation/gnunet-revocation-tvg.c +++ b/src/revocation/gnunet-revocation-tvg.c | |||
@@ -159,6 +159,7 @@ run (void *cls, | |||
159 | print_bytes (pow, | 159 | print_bytes (pow, |
160 | GNUNET_REVOCATION_proof_get_size (pow), | 160 | GNUNET_REVOCATION_proof_get_size (pow), |
161 | 8); | 161 | 8); |
162 | GNUNET_free (ph); | ||
162 | } | 163 | } |
163 | 164 | ||
164 | 165 | ||
diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c index 3beae60bb..12ec555e4 100644 --- a/src/revocation/plugin_block_revocation.c +++ b/src/revocation/plugin_block_revocation.c | |||
@@ -44,65 +44,6 @@ struct InternalContext | |||
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
47 | * Function called to validate a reply or a request. For | ||
48 | * request evaluation, simply pass "NULL" for the reply_block. | ||
49 | * | ||
50 | * @param cls our `struct InternalContext` | ||
51 | * @param ctx context | ||
52 | * @param type block type | ||
53 | * @param group block group to use | ||
54 | * @param eo control flags | ||
55 | * @param query original query (hash) | ||
56 | * @param xquery extrended query data (can be NULL, depending on type) | ||
57 | * @param xquery_size number of bytes in xquery | ||
58 | * @param reply_block response to validate | ||
59 | * @param reply_block_size number of bytes in reply block | ||
60 | * @return characterization of result | ||
61 | */ | ||
62 | static enum GNUNET_BLOCK_EvaluationResult | ||
63 | block_plugin_revocation_evaluate (void *cls, | ||
64 | struct GNUNET_BLOCK_Context *ctx, | ||
65 | enum GNUNET_BLOCK_Type type, | ||
66 | struct GNUNET_BLOCK_Group *group, | ||
67 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
68 | const struct GNUNET_HashCode *query, | ||
69 | const void *xquery, | ||
70 | size_t xquery_size, | ||
71 | const void *reply_block, | ||
72 | size_t reply_block_size) | ||
73 | { | ||
74 | struct InternalContext *ic = cls; | ||
75 | ssize_t pklen; | ||
76 | const struct RevokeMessage *rm = reply_block; | ||
77 | |||
78 | if (NULL == reply_block) | ||
79 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
80 | if (reply_block_size != sizeof(*rm)) | ||
81 | { | ||
82 | GNUNET_break_op (0); | ||
83 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
84 | } | ||
85 | struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; | ||
86 | const struct GNUNET_IDENTITY_PublicKey *pk; | ||
87 | pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; | ||
88 | if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow, | ||
89 | ic->matching_bits, | ||
90 | ic->epoch_duration)) | ||
91 | { | ||
92 | GNUNET_break_op (0); | ||
93 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
94 | } | ||
95 | pklen = GNUNET_IDENTITY_key_get_length (pk); | ||
96 | if (0 > pklen) | ||
97 | { | ||
98 | GNUNET_break_op (0); | ||
99 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
100 | } | ||
101 | return GNUNET_BLOCK_EVALUATION_OK_LAST; | ||
102 | } | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Function called to validate a query. | 47 | * Function called to validate a query. |
107 | * | 48 | * |
108 | * @param cls closure | 49 | * @param cls closure |
@@ -124,7 +65,10 @@ block_plugin_revocation_check_query (void *cls, | |||
124 | (void) query; | 65 | (void) query; |
125 | (void) xquery; | 66 | (void) xquery; |
126 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | 67 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) |
68 | { | ||
69 | GNUNET_break (0); | ||
127 | return GNUNET_SYSERR; | 70 | return GNUNET_SYSERR; |
71 | } | ||
128 | if (0 != xquery_size) | 72 | if (0 != xquery_size) |
129 | return GNUNET_NO; | 73 | return GNUNET_NO; |
130 | return GNUNET_OK; | 74 | return GNUNET_OK; |
@@ -136,7 +80,6 @@ block_plugin_revocation_check_query (void *cls, | |||
136 | * | 80 | * |
137 | * @param cls closure | 81 | * @param cls closure |
138 | * @param type block type | 82 | * @param type block type |
139 | * @param query key for the block (hash), must match exactly | ||
140 | * @param block block data to validate | 83 | * @param block block data to validate |
141 | * @param block_size number of bytes in @a block | 84 | * @param block_size number of bytes in @a block |
142 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 85 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -144,7 +87,6 @@ block_plugin_revocation_check_query (void *cls, | |||
144 | static enum GNUNET_GenericReturnValue | 87 | static enum GNUNET_GenericReturnValue |
145 | block_plugin_revocation_check_block (void *cls, | 88 | block_plugin_revocation_check_block (void *cls, |
146 | enum GNUNET_BLOCK_Type type, | 89 | enum GNUNET_BLOCK_Type type, |
147 | const struct GNUNET_HashCode *query, | ||
148 | const void *block, | 90 | const void *block, |
149 | size_t block_size) | 91 | size_t block_size) |
150 | { | 92 | { |
@@ -157,7 +99,10 @@ block_plugin_revocation_check_block (void *cls, | |||
157 | size_t left; | 99 | size_t left; |
158 | 100 | ||
159 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | 101 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) |
102 | { | ||
103 | GNUNET_break (0); | ||
160 | return GNUNET_SYSERR; | 104 | return GNUNET_SYSERR; |
105 | } | ||
161 | if (block_size < sizeof(*rm) + sizeof(*pow)) | 106 | if (block_size < sizeof(*rm) + sizeof(*pow)) |
162 | { | 107 | { |
163 | GNUNET_break_op (0); | 108 | GNUNET_break_op (0); |
@@ -224,7 +169,10 @@ block_plugin_revocation_check_reply ( | |||
224 | (void) reply_block; | 169 | (void) reply_block; |
225 | (void) reply_block_size; | 170 | (void) reply_block_size; |
226 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | 171 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) |
172 | { | ||
173 | GNUNET_break (0); | ||
227 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | 174 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
175 | } | ||
228 | return GNUNET_BLOCK_REPLY_OK_LAST; | 176 | return GNUNET_BLOCK_REPLY_OK_LAST; |
229 | } | 177 | } |
230 | 178 | ||
@@ -255,7 +203,10 @@ block_plugin_revocation_get_key (void *cls, | |||
255 | size_t left; | 203 | size_t left; |
256 | 204 | ||
257 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) | 205 | if (GNUNET_BLOCK_TYPE_REVOCATION != type) |
206 | { | ||
207 | GNUNET_break (0); | ||
258 | return GNUNET_SYSERR; | 208 | return GNUNET_SYSERR; |
209 | } | ||
259 | if (block_size < sizeof(*rm) + sizeof(*pow)) | 210 | if (block_size < sizeof(*rm) + sizeof(*pow)) |
260 | { | 211 | { |
261 | GNUNET_break_op (0); | 212 | GNUNET_break_op (0); |
@@ -314,7 +265,6 @@ libgnunet_plugin_block_revocation_init (void *cls) | |||
314 | return NULL; | 265 | return NULL; |
315 | 266 | ||
316 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 267 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
317 | api->evaluate = &block_plugin_revocation_evaluate; | ||
318 | api->get_key = &block_plugin_revocation_get_key; | 268 | api->get_key = &block_plugin_revocation_get_key; |
319 | api->check_query = &block_plugin_revocation_check_query; | 269 | api->check_query = &block_plugin_revocation_check_query; |
320 | api->check_block = &block_plugin_revocation_check_block; | 270 | api->check_block = &block_plugin_revocation_check_block; |
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index bc5dae021..9080ab862 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c | |||
@@ -758,13 +758,11 @@ GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow) | |||
758 | size_t size; | 758 | size_t size; |
759 | size_t ksize; | 759 | size_t ksize; |
760 | const struct GNUNET_IDENTITY_PublicKey *pk; | 760 | const struct GNUNET_IDENTITY_PublicKey *pk; |
761 | const struct GNUNET_IDENTITY_Signature *sig; | ||
762 | 761 | ||
763 | size = sizeof (struct GNUNET_REVOCATION_PowP); | 762 | size = sizeof (struct GNUNET_REVOCATION_PowP); |
764 | pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; | 763 | pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; |
765 | ksize = GNUNET_IDENTITY_key_get_length (pk); | 764 | ksize = GNUNET_IDENTITY_key_get_length (pk); |
766 | size += ksize; | 765 | size += ksize; |
767 | sig = (struct GNUNET_IDENTITY_Signature *) ((char*) &pow[1] + ksize); | ||
768 | size += GNUNET_IDENTITY_signature_get_raw_length_by_type (pk->type); | 766 | size += GNUNET_IDENTITY_signature_get_raw_length_by_type (pk->type); |
769 | return size; | 767 | return size; |
770 | } | 768 | } |
diff --git a/src/set/plugin_block_set_test.c b/src/set/plugin_block_set_test.c index 3d66831bb..cb5cef5ad 100644 --- a/src/set/plugin_block_set_test.c +++ b/src/set/plugin_block_set_test.c | |||
@@ -30,46 +30,9 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Function called to validate a reply or a request. For | ||
34 | * request evaluation, simply pass "NULL" for the reply_block. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param ctx block context | ||
38 | * @param type block type | ||
39 | * @param group block group to use | ||
40 | * @param eo control flags | ||
41 | * @param query original query (hash) | ||
42 | * @param xquery extrended query data (can be NULL, depending on type) | ||
43 | * @param xquery_size number of bytes in xquery | ||
44 | * @param reply_block response to validate | ||
45 | * @param reply_block_size number of bytes in reply block | ||
46 | * @return characterization of result | ||
47 | */ | ||
48 | static enum GNUNET_BLOCK_EvaluationResult | ||
49 | block_plugin_set_test_evaluate (void *cls, | ||
50 | struct GNUNET_BLOCK_Context *ctx, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | struct GNUNET_BLOCK_Group *group, | ||
53 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
54 | const struct GNUNET_HashCode *query, | ||
55 | const void *xquery, | ||
56 | size_t xquery_size, | ||
57 | const void *reply_block, | ||
58 | size_t reply_block_size) | ||
59 | { | ||
60 | if ((NULL == reply_block) || | ||
61 | (reply_block_size == 0) || | ||
62 | (0 != ((char *) reply_block)[0])) | ||
63 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
64 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Function called to validate a query. | 33 | * Function called to validate a query. |
70 | * | 34 | * |
71 | * @param cls closure | 35 | * @param cls closure |
72 | * @param ctx block context | ||
73 | * @param type block type | 36 | * @param type block type |
74 | * @param query original query (hash) | 37 | * @param query original query (hash) |
75 | * @param xquery extrended query data (can be NULL, depending on type) | 38 | * @param xquery extrended query data (can be NULL, depending on type) |
@@ -92,7 +55,6 @@ block_plugin_set_test_check_query (void *cls, | |||
92 | * | 55 | * |
93 | * @param cls closure | 56 | * @param cls closure |
94 | * @param type block type | 57 | * @param type block type |
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | 58 | * @param block block data to validate |
97 | * @param block_size number of bytes in @a block | 59 | * @param block_size number of bytes in @a block |
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 60 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -100,7 +62,6 @@ block_plugin_set_test_check_query (void *cls, | |||
100 | static enum GNUNET_GenericReturnValue | 62 | static enum GNUNET_GenericReturnValue |
101 | block_plugin_set_test_check_block (void *cls, | 63 | block_plugin_set_test_check_block (void *cls, |
102 | enum GNUNET_BLOCK_Type type, | 64 | enum GNUNET_BLOCK_Type type, |
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | 65 | const void *block, |
105 | size_t block_size) | 66 | size_t block_size) |
106 | { | 67 | { |
@@ -141,7 +102,7 @@ block_plugin_set_test_check_reply (void *cls, | |||
141 | if ((NULL == reply_block) || | 102 | if ((NULL == reply_block) || |
142 | (0 == reply_block_size) || | 103 | (0 == reply_block_size) || |
143 | (0 != ((char *) reply_block)[0])) | 104 | (0 != ((char *) reply_block)[0])) |
144 | return GNUNET_BLOCK_REPLY_INVALID; | 105 | GNUNET_assert (0); |
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | 106 | return GNUNET_BLOCK_REPLY_OK_MORE; |
146 | } | 107 | } |
147 | 108 | ||
@@ -164,7 +125,7 @@ block_plugin_set_test_get_key (void *cls, | |||
164 | size_t block_size, | 125 | size_t block_size, |
165 | struct GNUNET_HashCode *key) | 126 | struct GNUNET_HashCode *key) |
166 | { | 127 | { |
167 | return GNUNET_SYSERR; | 128 | return GNUNET_NO; |
168 | } | 129 | } |
169 | 130 | ||
170 | 131 | ||
@@ -181,7 +142,6 @@ libgnunet_plugin_block_set_test_init (void *cls) | |||
181 | struct GNUNET_BLOCK_PluginFunctions *api; | 142 | struct GNUNET_BLOCK_PluginFunctions *api; |
182 | 143 | ||
183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 144 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
184 | api->evaluate = &block_plugin_set_test_evaluate; | ||
185 | api->get_key = &block_plugin_set_test_get_key; | 145 | api->get_key = &block_plugin_set_test_get_key; |
186 | api->check_query = &block_plugin_set_test_check_query; | 146 | api->check_query = &block_plugin_set_test_check_query; |
187 | api->check_block = &block_plugin_set_test_check_block; | 147 | api->check_block = &block_plugin_set_test_check_block; |
diff --git a/src/seti/plugin_block_seti_test.c b/src/seti/plugin_block_seti_test.c index af86e1af6..5b9196cef 100644 --- a/src/seti/plugin_block_seti_test.c +++ b/src/seti/plugin_block_seti_test.c | |||
@@ -30,42 +30,6 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Function called to validate a reply or a request. For | ||
34 | * request evaluation, simply pass "NULL" for the reply_block. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param ctx block context | ||
38 | * @param type block type | ||
39 | * @param group block group to use | ||
40 | * @param eo control flags | ||
41 | * @param query original query (hash) | ||
42 | * @param xquery extrended query data (can be NULL, depending on type) | ||
43 | * @param xquery_size number of bytes in xquery | ||
44 | * @param reply_block response to validate | ||
45 | * @param reply_block_size number of bytes in reply block | ||
46 | * @return characterization of result | ||
47 | */ | ||
48 | static enum GNUNET_BLOCK_EvaluationResult | ||
49 | block_plugin_seti_test_evaluate (void *cls, | ||
50 | struct GNUNET_BLOCK_Context *ctx, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | struct GNUNET_BLOCK_Group *group, | ||
53 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
54 | const struct GNUNET_HashCode *query, | ||
55 | const void *xquery, | ||
56 | size_t xquery_size, | ||
57 | const void *reply_block, | ||
58 | size_t reply_block_size) | ||
59 | { | ||
60 | if ((NULL == reply_block) || | ||
61 | (reply_block_size == 0) || | ||
62 | (0 != ((char *) reply_block)[0])) | ||
63 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
64 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Function called to validate a query. | 33 | * Function called to validate a query. |
70 | * | 34 | * |
71 | * @param cls closure | 35 | * @param cls closure |
@@ -83,6 +47,16 @@ block_plugin_seti_test_check_query (void *cls, | |||
83 | const void *xquery, | 47 | const void *xquery, |
84 | size_t xquery_size) | 48 | size_t xquery_size) |
85 | { | 49 | { |
50 | if (GNUNET_BLOCK_TYPE_SETI_TEST != type) | ||
51 | { | ||
52 | GNUNET_break (0); | ||
53 | return GNUNET_SYSERR; | ||
54 | } | ||
55 | if (0 != xquery_size) | ||
56 | { | ||
57 | GNUNET_break_op (0); | ||
58 | return GNUNET_NO; | ||
59 | } | ||
86 | return GNUNET_OK; | 60 | return GNUNET_OK; |
87 | } | 61 | } |
88 | 62 | ||
@@ -92,7 +66,6 @@ block_plugin_seti_test_check_query (void *cls, | |||
92 | * | 66 | * |
93 | * @param cls closure | 67 | * @param cls closure |
94 | * @param type block type | 68 | * @param type block type |
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | 69 | * @param block block data to validate |
97 | * @param block_size number of bytes in @a block | 70 | * @param block_size number of bytes in @a block |
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 71 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -100,10 +73,15 @@ block_plugin_seti_test_check_query (void *cls, | |||
100 | static enum GNUNET_GenericReturnValue | 73 | static enum GNUNET_GenericReturnValue |
101 | block_plugin_seti_test_check_block (void *cls, | 74 | block_plugin_seti_test_check_block (void *cls, |
102 | enum GNUNET_BLOCK_Type type, | 75 | enum GNUNET_BLOCK_Type type, |
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | 76 | const void *block, |
105 | size_t block_size) | 77 | size_t block_size) |
106 | { | 78 | { |
79 | (void) cls; | ||
80 | if (GNUNET_BLOCK_TYPE_SETI_TEST != type) | ||
81 | { | ||
82 | GNUNET_break (0); | ||
83 | return GNUNET_SYSERR; | ||
84 | } | ||
107 | if ((NULL == block) || | 85 | if ((NULL == block) || |
108 | (0 == block_size) || | 86 | (0 == block_size) || |
109 | (0 != ((char *) block)[0])) | 87 | (0 != ((char *) block)[0])) |
@@ -138,10 +116,18 @@ block_plugin_seti_test_check_reply (void *cls, | |||
138 | const void *reply_block, | 116 | const void *reply_block, |
139 | size_t reply_block_size) | 117 | size_t reply_block_size) |
140 | { | 118 | { |
119 | (void) cls; | ||
120 | (void) xquery; | ||
121 | (void) xquery_size; | ||
122 | if (GNUNET_BLOCK_TYPE_SETI_TEST != type) | ||
123 | { | ||
124 | GNUNET_break (0); | ||
125 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
126 | } | ||
141 | if ( (NULL == reply_block) || | 127 | if ( (NULL == reply_block) || |
142 | (0 == reply_block_size) || | 128 | (0 == reply_block_size) || |
143 | (0 != ((char *) reply_block)[0]) ) | 129 | (0 != ((char *) reply_block)[0]) ) |
144 | return GNUNET_BLOCK_REPLY_INVALID; | 130 | GNUNET_assert (0); |
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | 131 | return GNUNET_BLOCK_REPLY_OK_MORE; |
146 | } | 132 | } |
147 | 133 | ||
@@ -164,7 +150,12 @@ block_plugin_seti_test_get_key (void *cls, | |||
164 | size_t block_size, | 150 | size_t block_size, |
165 | struct GNUNET_HashCode *key) | 151 | struct GNUNET_HashCode *key) |
166 | { | 152 | { |
167 | return GNUNET_SYSERR; | 153 | if (GNUNET_BLOCK_TYPE_SETI_TEST != type) |
154 | { | ||
155 | GNUNET_break (0); | ||
156 | return GNUNET_SYSERR; | ||
157 | } | ||
158 | return GNUNET_NO; | ||
168 | } | 159 | } |
169 | 160 | ||
170 | 161 | ||
@@ -181,7 +172,6 @@ libgnunet_plugin_block_seti_test_init (void *cls) | |||
181 | struct GNUNET_BLOCK_PluginFunctions *api; | 172 | struct GNUNET_BLOCK_PluginFunctions *api; |
182 | 173 | ||
183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 174 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
184 | api->evaluate = &block_plugin_seti_test_evaluate; | ||
185 | api->get_key = &block_plugin_seti_test_get_key; | 175 | api->get_key = &block_plugin_seti_test_get_key; |
186 | api->check_query = &block_plugin_seti_test_check_query; | 176 | api->check_query = &block_plugin_seti_test_check_query; |
187 | api->check_block = &block_plugin_seti_test_check_block; | 177 | api->check_block = &block_plugin_seti_test_check_block; |
diff --git a/src/setu/plugin_block_setu_test.c b/src/setu/plugin_block_setu_test.c index 9872bba39..178ad3314 100644 --- a/src/setu/plugin_block_setu_test.c +++ b/src/setu/plugin_block_setu_test.c | |||
@@ -23,49 +23,12 @@ | |||
23 | * @brief set test block, recognizes elements with non-zero first byte as invalid | 23 | * @brief set test block, recognizes elements with non-zero first byte as invalid |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
26 | |||
27 | #include "platform.h" | 26 | #include "platform.h" |
28 | #include "gnunet_block_plugin.h" | 27 | #include "gnunet_block_plugin.h" |
29 | #include "gnunet_block_group_lib.h" | 28 | #include "gnunet_block_group_lib.h" |
30 | 29 | ||
31 | 30 | ||
32 | /** | 31 | /** |
33 | * Function called to validate a reply or a request. For | ||
34 | * request evaluation, simply pass "NULL" for the reply_block. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param ctx block context | ||
38 | * @param type block type | ||
39 | * @param group block group to use | ||
40 | * @param eo control flags | ||
41 | * @param query original query (hash) | ||
42 | * @param xquery extrended query data (can be NULL, depending on type) | ||
43 | * @param xquery_size number of bytes in xquery | ||
44 | * @param reply_block response to validate | ||
45 | * @param reply_block_size number of bytes in reply block | ||
46 | * @return characterization of result | ||
47 | */ | ||
48 | static enum GNUNET_BLOCK_EvaluationResult | ||
49 | block_plugin_setu_test_evaluate (void *cls, | ||
50 | struct GNUNET_BLOCK_Context *ctx, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | struct GNUNET_BLOCK_Group *group, | ||
53 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
54 | const struct GNUNET_HashCode *query, | ||
55 | const void *xquery, | ||
56 | size_t xquery_size, | ||
57 | const void *reply_block, | ||
58 | size_t reply_block_size) | ||
59 | { | ||
60 | if ((NULL == reply_block) || | ||
61 | (reply_block_size == 0) || | ||
62 | (0 != ((char *) reply_block)[0])) | ||
63 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
64 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Function called to validate a query. | 32 | * Function called to validate a query. |
70 | * | 33 | * |
71 | * @param cls closure | 34 | * @param cls closure |
@@ -83,6 +46,16 @@ block_plugin_setu_test_check_query (void *cls, | |||
83 | const void *xquery, | 46 | const void *xquery, |
84 | size_t xquery_size) | 47 | size_t xquery_size) |
85 | { | 48 | { |
49 | if (GNUNET_BLOCK_TYPE_SETU_TEST != type) | ||
50 | { | ||
51 | GNUNET_break (0); | ||
52 | return GNUNET_SYSERR; | ||
53 | } | ||
54 | if (0 != xquery_size) | ||
55 | { | ||
56 | GNUNET_break_op (0); | ||
57 | return GNUNET_NO; | ||
58 | } | ||
86 | return GNUNET_OK; | 59 | return GNUNET_OK; |
87 | } | 60 | } |
88 | 61 | ||
@@ -92,7 +65,6 @@ block_plugin_setu_test_check_query (void *cls, | |||
92 | * | 65 | * |
93 | * @param cls closure | 66 | * @param cls closure |
94 | * @param type block type | 67 | * @param type block type |
95 | * @param query key for the block (hash), must match exactly | ||
96 | * @param block block data to validate | 68 | * @param block block data to validate |
97 | * @param block_size number of bytes in @a block | 69 | * @param block_size number of bytes in @a block |
98 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | 70 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not |
@@ -100,14 +72,18 @@ block_plugin_setu_test_check_query (void *cls, | |||
100 | static enum GNUNET_GenericReturnValue | 72 | static enum GNUNET_GenericReturnValue |
101 | block_plugin_setu_test_check_block (void *cls, | 73 | block_plugin_setu_test_check_block (void *cls, |
102 | enum GNUNET_BLOCK_Type type, | 74 | enum GNUNET_BLOCK_Type type, |
103 | const struct GNUNET_HashCode *query, | ||
104 | const void *block, | 75 | const void *block, |
105 | size_t block_size) | 76 | size_t block_size) |
106 | { | 77 | { |
78 | if (GNUNET_BLOCK_TYPE_SETU_TEST != type) | ||
79 | { | ||
80 | GNUNET_break (0); | ||
81 | return GNUNET_SYSERR; | ||
82 | } | ||
107 | if ( (NULL == block) || | 83 | if ( (NULL == block) || |
108 | (0 == block_size) || | 84 | (0 == block_size) || |
109 | (0 != ((char *) block)[0]) ) | 85 | (0 != ((char *) block)[0]) ) |
110 | return GNUNET_SYSERR; | 86 | return GNUNET_NO; |
111 | return GNUNET_OK; | 87 | return GNUNET_OK; |
112 | } | 88 | } |
113 | 89 | ||
@@ -138,10 +114,18 @@ block_plugin_setu_test_check_reply (void *cls, | |||
138 | const void *reply_block, | 114 | const void *reply_block, |
139 | size_t reply_block_size) | 115 | size_t reply_block_size) |
140 | { | 116 | { |
117 | (void) cls; | ||
118 | (void) xquery; | ||
119 | (void) xquery_size; | ||
120 | if (GNUNET_BLOCK_TYPE_SETU_TEST != type) | ||
121 | { | ||
122 | GNUNET_break (0); | ||
123 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
124 | } | ||
141 | if ( (NULL == reply_block) || | 125 | if ( (NULL == reply_block) || |
142 | (0 == reply_block_size) || | 126 | (0 == reply_block_size) || |
143 | (0 != ((char *) reply_block)[0]) ) | 127 | (0 != ((char *) reply_block)[0]) ) |
144 | return GNUNET_BLOCK_REPLY_INVALID; | 128 | GNUNET_assert (0); |
145 | return GNUNET_BLOCK_REPLY_OK_MORE; | 129 | return GNUNET_BLOCK_REPLY_OK_MORE; |
146 | } | 130 | } |
147 | 131 | ||
@@ -164,7 +148,12 @@ block_plugin_setu_test_get_key (void *cls, | |||
164 | size_t block_size, | 148 | size_t block_size, |
165 | struct GNUNET_HashCode *key) | 149 | struct GNUNET_HashCode *key) |
166 | { | 150 | { |
167 | return GNUNET_SYSERR; | 151 | if (GNUNET_BLOCK_TYPE_SETU_TEST != type) |
152 | { | ||
153 | GNUNET_break (0); | ||
154 | return GNUNET_SYSERR; | ||
155 | } | ||
156 | return GNUNET_NO; | ||
168 | } | 157 | } |
169 | 158 | ||
170 | 159 | ||
@@ -175,13 +164,12 @@ void * | |||
175 | libgnunet_plugin_block_setu_test_init (void *cls) | 164 | libgnunet_plugin_block_setu_test_init (void *cls) |
176 | { | 165 | { |
177 | static enum GNUNET_BLOCK_Type types[] = { | 166 | static enum GNUNET_BLOCK_Type types[] = { |
178 | GNUNET_BLOCK_TYPE_SETU_TEST, | 167 | GNUNET_BLOCK_TYPE_SETU_TEST, |
179 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 168 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
180 | }; | 169 | }; |
181 | struct GNUNET_BLOCK_PluginFunctions *api; | 170 | struct GNUNET_BLOCK_PluginFunctions *api; |
182 | 171 | ||
183 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 172 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
184 | api->evaluate = &block_plugin_setu_test_evaluate; | ||
185 | api->get_key = &block_plugin_setu_test_get_key; | 173 | api->get_key = &block_plugin_setu_test_get_key; |
186 | api->check_query = &block_plugin_setu_test_check_query; | 174 | api->check_query = &block_plugin_setu_test_check_query; |
187 | api->check_block = &block_plugin_setu_test_check_block; | 175 | api->check_block = &block_plugin_setu_test_check_block; |
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index ec00bc917..69b05fb13 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -773,6 +773,8 @@ TESTS += \ | |||
773 | endif | 773 | endif |
774 | endif | 774 | endif |
775 | 775 | ||
776 | # Only test TNG if we run experimental | ||
777 | if HAVE_EXPERIMENTAL | ||
776 | check_SCRIPTS= \ | 778 | check_SCRIPTS= \ |
777 | test_transport_simple_send_string.sh \ | 779 | test_transport_simple_send_string.sh \ |
778 | test_transport_simple_send.sh \ | 780 | test_transport_simple_send.sh \ |
@@ -780,6 +782,7 @@ check_SCRIPTS= \ | |||
780 | test_transport_udp_backchannel.sh \ | 782 | test_transport_udp_backchannel.sh \ |
781 | test_transport_simple_send_dv_circle.sh | 783 | test_transport_simple_send_dv_circle.sh |
782 | # test_transport_simple_send_dv_inverse.sh | 784 | # test_transport_simple_send_dv_inverse.sh |
785 | endif | ||
783 | 786 | ||
784 | test_transport_start_with_config_SOURCES = \ | 787 | test_transport_start_with_config_SOURCES = \ |
785 | test_transport_start_with_config.c | 788 | test_transport_start_with_config.c |
@@ -1521,7 +1524,10 @@ test_transport_api_slow_ats_LDADD = \ | |||
1521 | 1524 | ||
1522 | 1525 | ||
1523 | EXTRA_DIST = \ | 1526 | EXTRA_DIST = \ |
1524 | $(check_SCRIPTS) \ | 1527 | test_transport_simple_send_string.sh \ |
1528 | test_transport_simple_send.sh \ | ||
1529 | test_transport_simple_send_broadcast.sh \ | ||
1530 | test_transport_udp_backchannel.sh \ | ||
1525 | gnunet-transport-certificate-creation.in \ | 1531 | gnunet-transport-certificate-creation.in \ |
1526 | communicator-unix.conf \ | 1532 | communicator-unix.conf \ |
1527 | test_plugin_hostkey \ | 1533 | test_plugin_hostkey \ |
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index 3bfdeaa90..be75fa0e8 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -143,7 +143,7 @@ struct TcpHandshakeSignature | |||
143 | /** | 143 | /** |
144 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. | 144 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. |
145 | */ | 145 | */ |
146 | struct ChallengeNonceP challenge; | 146 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /** | 149 | /** |
@@ -176,7 +176,7 @@ struct TcpHandshakeAckSignature | |||
176 | /** | 176 | /** |
177 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. | 177 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. |
178 | */ | 178 | */ |
179 | struct ChallengeNonceP challenge; | 179 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
180 | }; | 180 | }; |
181 | 181 | ||
182 | /** | 182 | /** |
@@ -203,7 +203,7 @@ struct TCPConfirmation | |||
203 | /** | 203 | /** |
204 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. | 204 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. |
205 | */ | 205 | */ |
206 | struct ChallengeNonceP challenge; | 206 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
207 | 207 | ||
208 | }; | 208 | }; |
209 | 209 | ||
@@ -238,7 +238,7 @@ struct TCPConfirmationAck | |||
238 | /** | 238 | /** |
239 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. | 239 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. |
240 | */ | 240 | */ |
241 | struct ChallengeNonceP challenge; | 241 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
242 | 242 | ||
243 | }; | 243 | }; |
244 | 244 | ||
@@ -587,12 +587,12 @@ struct Queue | |||
587 | /** | 587 | /** |
588 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. | 588 | * Challenge value used to protect against replay attack, if there is no stored monotonic time value. |
589 | */ | 589 | */ |
590 | struct ChallengeNonceP challenge; | 590 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
591 | 591 | ||
592 | /** | 592 | /** |
593 | * Challenge value received. In case of inbound connection we have to remember the value, because we send the challenge back later after we received the GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK. | 593 | * Challenge value received. In case of inbound connection we have to remember the value, because we send the challenge back later after we received the GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK. |
594 | */ | 594 | */ |
595 | struct ChallengeNonceP challenge_received; | 595 | struct GNUNET_CRYPTO_ChallengeNonceP challenge_received; |
596 | 596 | ||
597 | /** | 597 | /** |
598 | * Iteration Context for retrieving the monotonic time send with key for rekeying. | 598 | * Iteration Context for retrieving the monotonic time send with key for rekeying. |
@@ -1447,7 +1447,7 @@ handshake_ack_monotime_cb (void *cls, | |||
1447 | * @param queue The queue context. | 1447 | * @param queue The queue context. |
1448 | */ | 1448 | */ |
1449 | static void | 1449 | static void |
1450 | send_challenge (struct ChallengeNonceP challenge, struct Queue *queue) | 1450 | send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct Queue *queue) |
1451 | { | 1451 | { |
1452 | struct TCPConfirmationAck tca; | 1452 | struct TCPConfirmationAck tca; |
1453 | struct TcpHandshakeAckSignature thas; | 1453 | struct TcpHandshakeAckSignature thas; |
@@ -1680,7 +1680,7 @@ try_handle_plaintext (struct Queue *queue) | |||
1680 | uint16_t type; | 1680 | uint16_t type; |
1681 | size_t size = 0; /* make compiler happy */ | 1681 | size_t size = 0; /* make compiler happy */ |
1682 | struct TcpHandshakeAckSignature thas; | 1682 | struct TcpHandshakeAckSignature thas; |
1683 | const struct ChallengeNonceP challenge = queue->challenge; | 1683 | const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge; |
1684 | 1684 | ||
1685 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1685 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1686 | "try handle plaintext!\n"); | 1686 | "try handle plaintext!\n"); |
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 0427bd229..21c9be05c 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -581,7 +581,7 @@ struct DvInitPS | |||
581 | /** | 581 | /** |
582 | * Challenge value used by the initiator to re-identify the path. | 582 | * Challenge value used by the initiator to re-identify the path. |
583 | */ | 583 | */ |
584 | struct ChallengeNonceP challenge; | 584 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
585 | }; | 585 | }; |
586 | 586 | ||
587 | 587 | ||
@@ -621,7 +621,7 @@ struct DvHopPS | |||
621 | /** | 621 | /** |
622 | * Challenge value used by the initiator to re-identify the path. | 622 | * Challenge value used by the initiator to re-identify the path. |
623 | */ | 623 | */ |
624 | struct ChallengeNonceP challenge; | 624 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
625 | }; | 625 | }; |
626 | 626 | ||
627 | 627 | ||
@@ -715,7 +715,7 @@ struct TransportDVLearnMessage | |||
715 | /** | 715 | /** |
716 | * Challenge value used by the initiator to re-identify the path. | 716 | * Challenge value used by the initiator to re-identify the path. |
717 | */ | 717 | */ |
718 | struct ChallengeNonceP challenge; | 718 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
719 | 719 | ||
720 | /* Followed by @e num_hops `struct DVPathEntryP` values, | 720 | /* Followed by @e num_hops `struct DVPathEntryP` values, |
721 | excluding the initiator of the DV trace; the last entry is the | 721 | excluding the initiator of the DV trace; the last entry is the |
@@ -834,7 +834,7 @@ struct TransportValidationChallengeMessage | |||
834 | /** | 834 | /** |
835 | * Challenge to be signed by the receiving peer. | 835 | * Challenge to be signed by the receiving peer. |
836 | */ | 836 | */ |
837 | struct ChallengeNonceP challenge; | 837 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
838 | 838 | ||
839 | /** | 839 | /** |
840 | * Timestamp of the sender, to be copied into the reply to allow | 840 | * Timestamp of the sender, to be copied into the reply to allow |
@@ -864,7 +864,7 @@ struct TransportValidationPS | |||
864 | /** | 864 | /** |
865 | * Challenge signed by the receiving peer. | 865 | * Challenge signed by the receiving peer. |
866 | */ | 866 | */ |
867 | struct ChallengeNonceP challenge; | 867 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
868 | }; | 868 | }; |
869 | 869 | ||
870 | 870 | ||
@@ -893,7 +893,7 @@ struct TransportValidationResponseMessage | |||
893 | /** | 893 | /** |
894 | * The challenge that was signed by the receiving peer. | 894 | * The challenge that was signed by the receiving peer. |
895 | */ | 895 | */ |
896 | struct ChallengeNonceP challenge; | 896 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
897 | 897 | ||
898 | /** | 898 | /** |
899 | * Original timestamp of the sender (was @code{sender_time}), | 899 | * Original timestamp of the sender (was @code{sender_time}), |
@@ -1056,7 +1056,7 @@ struct LearnLaunchEntry | |||
1056 | /** | 1056 | /** |
1057 | * Challenge that uniquely identifies this activity. | 1057 | * Challenge that uniquely identifies this activity. |
1058 | */ | 1058 | */ |
1059 | struct ChallengeNonceP challenge; | 1059 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
1060 | 1060 | ||
1061 | /** | 1061 | /** |
1062 | * When did we transmit the DV learn message (used to calculate RTT) and | 1062 | * When did we transmit the DV learn message (used to calculate RTT) and |
@@ -2569,7 +2569,7 @@ struct ValidationState | |||
2569 | * (We must not rotate more often as otherwise we may discard valid answers | 2569 | * (We must not rotate more often as otherwise we may discard valid answers |
2570 | * due to packet losses, latency and reorderings on the network). | 2570 | * due to packet losses, latency and reorderings on the network). |
2571 | */ | 2571 | */ |
2572 | struct ChallengeNonceP challenge; | 2572 | struct GNUNET_CRYPTO_ChallengeNonceP challenge; |
2573 | 2573 | ||
2574 | /** | 2574 | /** |
2575 | * Claimed address of the peer. | 2575 | * Claimed address of the peer. |
@@ -6886,7 +6886,7 @@ static int | |||
6886 | validate_dv_initiator_signature ( | 6886 | validate_dv_initiator_signature ( |
6887 | struct GNUNET_TIME_AbsoluteNBO sender_monotonic_time, | 6887 | struct GNUNET_TIME_AbsoluteNBO sender_monotonic_time, |
6888 | const struct GNUNET_PeerIdentity *init, | 6888 | const struct GNUNET_PeerIdentity *init, |
6889 | const struct ChallengeNonceP *challenge, | 6889 | const struct GNUNET_CRYPTO_ChallengeNonceP *challenge, |
6890 | const struct GNUNET_CRYPTO_EddsaSignature *init_sig) | 6890 | const struct GNUNET_CRYPTO_EddsaSignature *init_sig) |
6891 | { | 6891 | { |
6892 | struct DvInitPS ip = { .purpose.purpose = htonl ( | 6892 | struct DvInitPS ip = { .purpose.purpose = htonl ( |
@@ -8340,7 +8340,7 @@ struct CheckKnownChallengeContext | |||
8340 | /** | 8340 | /** |
8341 | * Set to the challenge we are looking for. | 8341 | * Set to the challenge we are looking for. |
8342 | */ | 8342 | */ |
8343 | const struct ChallengeNonceP *challenge; | 8343 | const struct GNUNET_CRYPTO_ChallengeNonceP *challenge; |
8344 | 8344 | ||
8345 | /** | 8345 | /** |
8346 | * Set to a matching validation state, if one was found. | 8346 | * Set to a matching validation state, if one was found. |
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 24cc6464a..fad2ca4a1 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -1628,8 +1628,8 @@ GST_receive_callback (void *cls, | |||
1628 | GST_neighbours_notify_data_recv (address, message); | 1628 | GST_neighbours_notify_data_recv (address, message); |
1629 | switch (type) | 1629 | switch (type) |
1630 | { | 1630 | { |
1631 | case GNUNET_MESSAGE_TYPE_HELLO_LEGACY: | 1631 | case GNUNET_MESSAGE_TYPE_HELLO_URI: |
1632 | /* Legacy HELLO message, discard */ | 1632 | /* Future HELLO message, discard */ |
1633 | return ret; | 1633 | return ret; |
1634 | 1634 | ||
1635 | case GNUNET_MESSAGE_TYPE_HELLO: | 1635 | case GNUNET_MESSAGE_TYPE_HELLO: |
diff --git a/src/transport/test_transport_simple_send.sh b/src/transport/test_transport_simple_send.sh index 3d5266622..0250070be 100755 --- a/src/transport/test_transport_simple_send.sh +++ b/src/transport/test_transport_simple_send.sh | |||
@@ -2,9 +2,10 @@ | |||
2 | if ! [ -d "/run/netns" ]; then | 2 | if ! [ -d "/run/netns" ]; then |
3 | echo You have to create the directory /run/netns. | 3 | echo You have to create the directory /run/netns. |
4 | fi | 4 | fi |
5 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 5 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
6 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_simple_send_topo.conf" | 6 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
7 | else | ||
8 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 7 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
9 | exit 78 | 8 | exit 78 |
9 | fi | ||
10 | fi | 10 | fi |
11 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_simple_send_topo.conf" | ||
diff --git a/src/transport/test_transport_simple_send_broadcast.sh b/src/transport/test_transport_simple_send_broadcast.sh index f264b1203..a4801bf70 100755 --- a/src/transport/test_transport_simple_send_broadcast.sh +++ b/src/transport/test_transport_simple_send_broadcast.sh | |||
@@ -2,10 +2,10 @@ | |||
2 | if ! [ -d "/run/netns" ]; then | 2 | if ! [ -d "/run/netns" ]; then |
3 | echo You have to create the directory /run/netns. | 3 | echo You have to create the directory /run/netns. |
4 | fi | 4 | fi |
5 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 5 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
6 | # exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes --trace-children=yes --trace-children-skip=/usr/bin/awk,/usr/bin/cut,/usr/bin/seq,/sbin/ip/sed/bash ./test_transport_start_with_config test_transport_simple_send_broadcast_topo.conf" | 6 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
7 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_simple_send_broadcast_topo.conf" | ||
8 | else | ||
9 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 7 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
10 | exit 78 | 8 | exit 78 |
9 | fi | ||
11 | fi | 10 | fi |
11 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_simple_send_broadcast_topo.conf" | ||
diff --git a/src/transport/test_transport_simple_send_dv.sh b/src/transport/test_transport_simple_send_dv.sh index fa127cfa4..b57ee0629 100755 --- a/src/transport/test_transport_simple_send_dv.sh +++ b/src/transport/test_transport_simple_send_dv.sh | |||
@@ -2,10 +2,10 @@ | |||
2 | if ! [ -d "/run/netns" ]; then | 2 | if ! [ -d "/run/netns" ]; then |
3 | echo You have to create the directory /run/netns. | 3 | echo You have to create the directory /run/netns. |
4 | fi | 4 | fi |
5 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 5 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
6 | # exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes --trace-children=yes --trace-children-skip=/usr/bin/awk,/usr/bin/cut,/usr/bin/seq,/sbin/ip/sed/bash ./test_transport_start_with_config test_transport_distance_vector_topo.conf" | 6 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
7 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_distance_vector_topo.conf" | ||
8 | else | ||
9 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 7 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
10 | exit 78 | 8 | exit 78 |
9 | fi | ||
11 | fi | 10 | fi |
11 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_distance_vector_topo.conf" | ||
diff --git a/src/transport/test_transport_simple_send_dv_circle.sh b/src/transport/test_transport_simple_send_dv_circle.sh index de16df356..bd5f00abe 100755 --- a/src/transport/test_transport_simple_send_dv_circle.sh +++ b/src/transport/test_transport_simple_send_dv_circle.sh | |||
@@ -2,11 +2,10 @@ | |||
2 | if ! [ -d "/run/netns" ]; then | 2 | if ! [ -d "/run/netns" ]; then |
3 | echo You have to create the directory /run/netns. | 3 | echo You have to create the directory /run/netns. |
4 | fi | 4 | fi |
5 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 5 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
6 | # exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes --trace-children=yes --trace-children-skip=/usr/bin/awk,/usr/bin/cut,/usr/bin/seq,/sbin/ip/sed/bash ./test_transport_start_with_config test_transport_distance_vector_topo.conf" | 6 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
7 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_distance_vector_circle_topo.conf" | ||
8 | #./test_transport_start_with_config test_transport_distance_vector_circle_topo.conf | ||
9 | else | ||
10 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 7 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
11 | exit 78 | 8 | exit 78 |
9 | fi | ||
12 | fi | 10 | fi |
11 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config test_transport_distance_vector_circle_topo.conf" | ||
diff --git a/src/transport/test_transport_simple_send_string.sh b/src/transport/test_transport_simple_send_string.sh index b2bd05d5f..211abb494 100755 --- a/src/transport/test_transport_simple_send_string.sh +++ b/src/transport/test_transport_simple_send_string.sh | |||
@@ -11,9 +11,11 @@ EOF | |||
11 | if ! [ -d "/run/netns" ]; then | 11 | if ! [ -d "/run/netns" ]; then |
12 | echo You have to create the directory /run/netns. | 12 | echo You have to create the directory /run/netns. |
13 | fi | 13 | fi |
14 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 14 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
15 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config -s '$string'" | 15 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
16 | else | ||
17 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 16 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
18 | exit 78 | 17 | exit 78 |
18 | fi | ||
19 | fi | 19 | fi |
20 | |||
21 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; ./test_transport_start_with_config -s '$string'" | ||
diff --git a/src/transport/test_transport_udp_backchannel.sh b/src/transport/test_transport_udp_backchannel.sh index c52734a55..1a7c83385 100755 --- a/src/transport/test_transport_udp_backchannel.sh +++ b/src/transport/test_transport_udp_backchannel.sh | |||
@@ -5,11 +5,10 @@ fi | |||
5 | if ! [ -d "/run/netns" ]; then | 5 | if ! [ -d "/run/netns" ]; then |
6 | echo You have to create the directory /run/netns. | 6 | echo You have to create the directory /run/netns. |
7 | fi | 7 | fi |
8 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" == 1 ]; then | 8 | if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then |
9 | #exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes --trace-children=yes --trace-children-skip=/usr/bin/awk,/usr/bin/cut,/usr/bin/seq,/sbin/ip ./test_transport_start_with_config test_transport_udp_backchannel_topo.conf" | 9 | if [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" != 1 ]; then |
10 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; GNUNET_FORCE_LOG=';;;;DEBUG' GNUNET_FORCE_LOGFILE='test.out' ./test_transport_start_with_config test_transport_udp_backchannel_topo.conf" | ||
11 | # exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; valgrind --leak-check=full --track-origins=yes ./test_transport_start_with_config test_transport_udp_backchannel_topo.conf" | ||
12 | else | ||
13 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" | 10 | echo -e "Error during test setup: The kernel parameter kernel.unprivileged_userns_clone has to be set to 1! One has to execute\n\n sysctl kernel.unprivileged_userns_clone=1\n" |
14 | exit 78 | 11 | exit 78 |
12 | fi | ||
15 | fi | 13 | fi |
14 | exec unshare -r -nmU bash -c "mount -t tmpfs --make-rshared tmpfs /run/netns; GNUNET_FORCE_LOG=';;;;DEBUG' GNUNET_FORCE_LOGFILE='test.out' ./test_transport_start_with_config test_transport_udp_backchannel_topo.conf" | ||
diff --git a/src/util/common_logging.c b/src/util/common_logging.c index cba37cd2f..b07f3fc0b 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c | |||
@@ -321,6 +321,28 @@ log_rotate (const char *new_name) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | 323 | ||
324 | const char * | ||
325 | GNUNET_b2s (const void *buf, | ||
326 | size_t buf_size) | ||
327 | { | ||
328 | static GNUNET_THREAD_LOCAL char ret[9]; | ||
329 | struct GNUNET_HashCode hc; | ||
330 | char *tmp; | ||
331 | |||
332 | GNUNET_CRYPTO_hash (buf, | ||
333 | buf_size, | ||
334 | &hc); | ||
335 | tmp = GNUNET_STRINGS_data_to_string_alloc (&hc, | ||
336 | sizeof (hc)); | ||
337 | memcpy (ret, | ||
338 | tmp, | ||
339 | 8); | ||
340 | GNUNET_free (tmp); | ||
341 | ret[8] = '\0'; | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | |||
324 | /** | 346 | /** |
325 | * Setup the log file. | 347 | * Setup the log file. |
326 | * | 348 | * |
@@ -1015,7 +1037,8 @@ mylog (enum GNUNET_ErrorType kind, | |||
1015 | else | 1037 | else |
1016 | { | 1038 | { |
1017 | /* RFC 3339 timestamp, with snprintf placeholder for microseconds */ | 1039 | /* RFC 3339 timestamp, with snprintf placeholder for microseconds */ |
1018 | if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z", tmptr)) | 1040 | if (0 == strftime (date2, DATE_STR_SIZE, "%Y-%m-%dT%H:%M:%S.%%06u%z", |
1041 | tmptr)) | ||
1019 | abort (); | 1042 | abort (); |
1020 | /* Fill in microseconds */ | 1043 | /* Fill in microseconds */ |
1021 | if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec)) | 1044 | if (0 > snprintf (date, sizeof(date), date2, timeofday.tv_usec)) |
diff --git a/src/util/crypto_cs.c b/src/util/crypto_cs.c index c89ba5d83..4c6648229 100644 --- a/src/util/crypto_cs.c +++ b/src/util/crypto_cs.c | |||
@@ -40,11 +40,6 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | 42 | ||
43 | /** | ||
44 | * Create a new random private key. | ||
45 | * | ||
46 | * @param[out] priv where to write the fresh private key | ||
47 | */ | ||
48 | void | 43 | void |
49 | GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv) | 44 | GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv) |
50 | { | 45 | { |
@@ -52,16 +47,10 @@ GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv) | |||
52 | } | 47 | } |
53 | 48 | ||
54 | 49 | ||
55 | /** | ||
56 | * Extract the public key of the given private key. | ||
57 | * | ||
58 | * @param priv the private key | ||
59 | * @param[out] pub where to write the public key | ||
60 | */ | ||
61 | void | 50 | void |
62 | GNUNET_CRYPTO_cs_private_key_get_public (const struct | 51 | GNUNET_CRYPTO_cs_private_key_get_public ( |
63 | GNUNET_CRYPTO_CsPrivateKey *priv, | 52 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
64 | struct GNUNET_CRYPTO_CsPublicKey *pub) | 53 | struct GNUNET_CRYPTO_CsPublicKey *pub) |
65 | { | 54 | { |
66 | GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (pub->point.y, | 55 | GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (pub->point.y, |
67 | priv->scalar.d)); | 56 | priv->scalar.d)); |
@@ -69,63 +58,40 @@ GNUNET_CRYPTO_cs_private_key_get_public (const struct | |||
69 | 58 | ||
70 | 59 | ||
71 | /** | 60 | /** |
72 | * maps 32 random bytes to a scalar | 61 | * Maps 32 random bytes to a scalar. This is necessary because libsodium |
73 | * this is necessary because libsodium expects scalar to be in the prime order subgroup | 62 | * expects scalar to be in the prime order subgroup. |
74 | * @param[out] scalar containing 32 byte char array, is modified to be in prime order subgroup | 63 | * |
64 | * @param[in,out] scalar containing 32 byte char array, is modified to be in prime order subgroup | ||
75 | */ | 65 | */ |
76 | static void | 66 | static void |
77 | map_to_scalar_subgroup (struct GNUNET_CRYPTO_Cs25519Scalar *scalar) | 67 | map_to_scalar_subgroup (struct GNUNET_CRYPTO_Cs25519Scalar *scalar) |
78 | { | 68 | { |
79 | // perform clamping as described in RFC7748 | 69 | /* perform clamping as described in RFC7748 */ |
80 | scalar->d[0] &= 248; | 70 | scalar->d[0] &= 248; |
81 | scalar->d[31] &= 127; | 71 | scalar->d[31] &= 127; |
82 | scalar->d[31] |= 64; | 72 | scalar->d[31] |= 64; |
83 | } | 73 | } |
84 | 74 | ||
85 | 75 | ||
86 | /** | ||
87 | * Derive a new secret r pair r0 and r1. | ||
88 | * In original papers r is generated randomly | ||
89 | * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE | ||
90 | * To ensure unpredictability a new nonce should be used when a new r needs to be derived. | ||
91 | * Uses HKDF internally. | ||
92 | * Comment: Can be done in one HKDF shot and split output. | ||
93 | * | ||
94 | * @param nonce is a random nonce | ||
95 | * @param lts is a long-term-secret in form of a private key | ||
96 | * @param[out] r array containing derived secrets r0 and r1 | ||
97 | */ | ||
98 | void | 76 | void |
99 | GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, | 77 | GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, |
78 | const char *seed, | ||
100 | const struct GNUNET_CRYPTO_CsPrivateKey *lts, | 79 | const struct GNUNET_CRYPTO_CsPrivateKey *lts, |
101 | struct GNUNET_CRYPTO_CsRSecret r[2]) | 80 | struct GNUNET_CRYPTO_CsRSecret r[2]) |
102 | { | 81 | { |
103 | GNUNET_assert (GNUNET_YES == | 82 | GNUNET_assert ( |
104 | GNUNET_CRYPTO_hkdf (r, | 83 | GNUNET_YES == |
105 | sizeof (struct GNUNET_CRYPTO_CsRSecret) | 84 | GNUNET_CRYPTO_kdf ( |
106 | * 2, | 85 | r, sizeof (struct GNUNET_CRYPTO_CsRSecret) * 2, |
107 | GCRY_MD_SHA512, | 86 | seed, strlen (seed), |
108 | GCRY_MD_SHA256, | 87 | lts, sizeof (*lts), |
109 | "r", | 88 | nonce, sizeof (*nonce), |
110 | strlen ("r"), | 89 | NULL, 0)); |
111 | lts, | ||
112 | sizeof (*lts), | ||
113 | nonce, | ||
114 | sizeof (*nonce), | ||
115 | NULL, | ||
116 | 0)); | ||
117 | |||
118 | map_to_scalar_subgroup (&r[0].scalar); | 90 | map_to_scalar_subgroup (&r[0].scalar); |
119 | map_to_scalar_subgroup (&r[1].scalar); | 91 | map_to_scalar_subgroup (&r[1].scalar); |
120 | } | 92 | } |
121 | 93 | ||
122 | 94 | ||
123 | /** | ||
124 | * Extract the public R of the given secret r. | ||
125 | * | ||
126 | * @param r_priv the private key | ||
127 | * @param[out] r_pub where to write the public key | ||
128 | */ | ||
129 | void | 95 | void |
130 | GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | 96 | GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, |
131 | struct GNUNET_CRYPTO_CsRPublic *r_pub) | 97 | struct GNUNET_CRYPTO_CsRPublic *r_pub) |
@@ -135,36 +101,23 @@ GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | |||
135 | } | 101 | } |
136 | 102 | ||
137 | 103 | ||
138 | /** | ||
139 | * Derives new random blinding factors. | ||
140 | * In original papers blinding factors are generated randomly | ||
141 | * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE | ||
142 | * To ensure unpredictability a new nonce has to be used. | ||
143 | * Uses HKDF internally | ||
144 | * | ||
145 | * @param secret is secret to derive blinding factors | ||
146 | * @param secret_len secret length | ||
147 | * @param[out] bs array containing the two derived blinding secrets | ||
148 | */ | ||
149 | void | 104 | void |
150 | GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct | 105 | GNUNET_CRYPTO_cs_blinding_secrets_derive ( |
151 | GNUNET_CRYPTO_CsNonce *blind_seed, | 106 | const struct GNUNET_CRYPTO_CsNonce *blind_seed, |
152 | struct GNUNET_CRYPTO_CsBlindingSecret | 107 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]) |
153 | bs[2]) | ||
154 | { | 108 | { |
155 | GNUNET_assert (GNUNET_YES == | 109 | GNUNET_assert ( |
156 | GNUNET_CRYPTO_hkdf (bs, | 110 | GNUNET_YES == |
157 | sizeof (struct | 111 | GNUNET_CRYPTO_hkdf (bs, |
158 | GNUNET_CRYPTO_CsBlindingSecret) | 112 | sizeof (struct GNUNET_CRYPTO_CsBlindingSecret) * 2, |
159 | * 2, | 113 | GCRY_MD_SHA512, |
160 | GCRY_MD_SHA512, | 114 | GCRY_MD_SHA256, |
161 | GCRY_MD_SHA256, | 115 | "alphabeta", |
162 | "alphabeta", | 116 | strlen ("alphabeta"), |
163 | strlen ("alphabeta"), | 117 | blind_seed, |
164 | blind_seed, | 118 | sizeof(*blind_seed), |
165 | sizeof(*blind_seed), | 119 | NULL, |
166 | NULL, | 120 | 0)); |
167 | 0)); | ||
168 | map_to_scalar_subgroup (&bs[0].alpha); | 121 | map_to_scalar_subgroup (&bs[0].alpha); |
169 | map_to_scalar_subgroup (&bs[0].beta); | 122 | map_to_scalar_subgroup (&bs[0].beta); |
170 | map_to_scalar_subgroup (&bs[1].alpha); | 123 | map_to_scalar_subgroup (&bs[1].alpha); |
@@ -205,11 +158,16 @@ cs_full_domain_hash (const struct GNUNET_CRYPTO_CsRPublic *r_dash, | |||
205 | memcpy (r_m_concat, r_dash, sizeof(struct GNUNET_CRYPTO_CsRPublic)); | 158 | memcpy (r_m_concat, r_dash, sizeof(struct GNUNET_CRYPTO_CsRPublic)); |
206 | memcpy (r_m_concat + sizeof(struct GNUNET_CRYPTO_CsRPublic), msg, msg_len); | 159 | memcpy (r_m_concat + sizeof(struct GNUNET_CRYPTO_CsRPublic), msg, msg_len); |
207 | struct GNUNET_HashCode prehash; | 160 | struct GNUNET_HashCode prehash; |
208 | GNUNET_CRYPTO_hash (r_m_concat, r_m_concat_len, &prehash); | 161 | |
162 | GNUNET_CRYPTO_hash (r_m_concat, | ||
163 | r_m_concat_len, | ||
164 | &prehash); | ||
209 | 165 | ||
210 | // modulus converted to MPI representation | 166 | // modulus converted to MPI representation |
211 | gcry_mpi_t l_mpi; | 167 | gcry_mpi_t l_mpi; |
212 | GNUNET_CRYPTO_mpi_scan_unsigned (&l_mpi, L_BIG_ENDIAN, sizeof(L_BIG_ENDIAN)); | 168 | GNUNET_CRYPTO_mpi_scan_unsigned (&l_mpi, |
169 | L_BIG_ENDIAN, | ||
170 | sizeof(L_BIG_ENDIAN)); | ||
213 | 171 | ||
214 | // calculate full domain hash | 172 | // calculate full domain hash |
215 | gcry_mpi_t c_mpi; | 173 | gcry_mpi_t c_mpi; |
@@ -224,7 +182,9 @@ cs_full_domain_hash (const struct GNUNET_CRYPTO_CsRPublic *r_dash, | |||
224 | 182 | ||
225 | // convert c from mpi | 183 | // convert c from mpi |
226 | unsigned char c_big_endian[256 / 8]; | 184 | unsigned char c_big_endian[256 / 8]; |
227 | GNUNET_CRYPTO_mpi_print_unsigned (c_big_endian, sizeof(c_big_endian), c_mpi); | 185 | GNUNET_CRYPTO_mpi_print_unsigned (c_big_endian, |
186 | sizeof(c_big_endian), | ||
187 | c_mpi); | ||
228 | gcry_mpi_release (c_mpi); | 188 | gcry_mpi_release (c_mpi); |
229 | for (size_t i = 0; i<32; i++) | 189 | for (size_t i = 0; i<32; i++) |
230 | c->scalar.d[i] = c_big_endian[31 - i]; | 190 | c->scalar.d[i] = c_big_endian[31 - i]; |
@@ -266,28 +226,15 @@ calc_r_dash (const struct GNUNET_CRYPTO_CsBlindingSecret *bs, | |||
266 | } | 226 | } |
267 | 227 | ||
268 | 228 | ||
269 | /** | ||
270 | * Calculate two blinded c's | ||
271 | * Comment: One would be insecure due to Wagner's algorithm solving ROS | ||
272 | * | ||
273 | * @param bs array of the two blinding factor structs each containing alpha and beta | ||
274 | * @param r_pub array of the two signer's nonce R | ||
275 | * @param pub the public key of the signer | ||
276 | * @param msg the message to blind in preparation for signing | ||
277 | * @param msg_len length of message msg | ||
278 | * @param[out] blinded_c array of the two blinded c's | ||
279 | * @param[out] blinded_r_pub array of the two blinded R | ||
280 | */ | ||
281 | void | 229 | void |
282 | GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret | 230 | GNUNET_CRYPTO_cs_calc_blinded_c ( |
283 | bs[2], | 231 | const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], |
284 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], | 232 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], |
285 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 233 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
286 | const void *msg, | 234 | const void *msg, |
287 | size_t msg_len, | 235 | size_t msg_len, |
288 | struct GNUNET_CRYPTO_CsC blinded_c[2], | 236 | struct GNUNET_CRYPTO_CsC blinded_c[2], |
289 | struct GNUNET_CRYPTO_CsRPublic | 237 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2]) |
290 | blinded_r_pub[2]) | ||
291 | { | 238 | { |
292 | // for i 0/1: R'i = Ri + alpha i*G + beta i*pub | 239 | // for i 0/1: R'i = Ri + alpha i*G + beta i*pub |
293 | calc_r_dash (&bs[0], &r_pub[0], pub, &blinded_r_pub[0]); | 240 | calc_r_dash (&bs[0], &r_pub[0], pub, &blinded_r_pub[0]); |
@@ -309,30 +256,13 @@ GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret | |||
309 | } | 256 | } |
310 | 257 | ||
311 | 258 | ||
312 | /** | ||
313 | * Sign a blinded c | ||
314 | * This function derives b from a nonce and a longterm secret | ||
315 | * In original papers b is generated randomly | ||
316 | * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE. | ||
317 | * To ensure unpredictability a new nonce has to be used for every signature | ||
318 | * HKDF is used internally for derivation | ||
319 | * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive | ||
320 | * | ||
321 | * @param priv private key to use for the signing and as LTS in HKDF | ||
322 | * @param r array of the two secret nonce from the signer | ||
323 | * @param c array of the two blinded c to sign c_b | ||
324 | * @param nonce is a random nonce | ||
325 | * @param[out] blinded_signature_scalar where to write the signature | ||
326 | * @return 0 or 1 for b (see Clause Blind Signature Scheme) | ||
327 | */ | ||
328 | unsigned int | 259 | unsigned int |
329 | GNUNET_CRYPTO_cs_sign_derive (const struct GNUNET_CRYPTO_CsPrivateKey *priv, | 260 | GNUNET_CRYPTO_cs_sign_derive ( |
330 | const struct GNUNET_CRYPTO_CsRSecret r[2], | 261 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
331 | const struct GNUNET_CRYPTO_CsC c[2], | 262 | const struct GNUNET_CRYPTO_CsRSecret r[2], |
332 | const struct GNUNET_CRYPTO_CsNonce *nonce, | 263 | const struct GNUNET_CRYPTO_CsC c[2], |
333 | struct GNUNET_CRYPTO_CsBlindS * | 264 | const struct GNUNET_CRYPTO_CsNonce *nonce, |
334 | blinded_signature_scalar | 265 | struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar) |
335 | ) | ||
336 | { | 266 | { |
337 | uint32_t hkdf_out; | 267 | uint32_t hkdf_out; |
338 | 268 | ||
@@ -365,18 +295,11 @@ GNUNET_CRYPTO_cs_sign_derive (const struct GNUNET_CRYPTO_CsPrivateKey *priv, | |||
365 | } | 295 | } |
366 | 296 | ||
367 | 297 | ||
368 | /** | ||
369 | * Unblind a blind-signed signature using a c that was blinded | ||
370 | * | ||
371 | * @param blinded_signature_scalar the signature made on the blinded c | ||
372 | * @param bs the blinding factors used in the blinding | ||
373 | * @param[out] signature_scalar where to write the unblinded signature | ||
374 | */ | ||
375 | void | 298 | void |
376 | GNUNET_CRYPTO_cs_unblind (const struct | 299 | GNUNET_CRYPTO_cs_unblind ( |
377 | GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, | 300 | const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, |
378 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, | 301 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, |
379 | struct GNUNET_CRYPTO_CsS *signature_scalar) | 302 | struct GNUNET_CRYPTO_CsS *signature_scalar) |
380 | { | 303 | { |
381 | crypto_core_ed25519_scalar_add (signature_scalar->scalar.d, | 304 | crypto_core_ed25519_scalar_add (signature_scalar->scalar.d, |
382 | blinded_signature_scalar->scalar.d, | 305 | blinded_signature_scalar->scalar.d, |
@@ -384,16 +307,6 @@ GNUNET_CRYPTO_cs_unblind (const struct | |||
384 | } | 307 | } |
385 | 308 | ||
386 | 309 | ||
387 | /** | ||
388 | * Verify whether the given message corresponds to the given signature and the | ||
389 | * signature is valid with respect to the given public key. | ||
390 | * | ||
391 | * @param sig signature that is being validated | ||
392 | * @param pub public key of the signer | ||
393 | * @param msg is the message that should be signed by @a sig (message is used to calculate c) | ||
394 | * @param msg_len is the message length | ||
395 | * @returns #GNUNET_YES on success, #GNUNET_SYSERR if signature invalid | ||
396 | */ | ||
397 | enum GNUNET_GenericReturnValue | 310 | enum GNUNET_GenericReturnValue |
398 | GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, | 311 | GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, |
399 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 312 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
@@ -402,7 +315,12 @@ GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, | |||
402 | { | 315 | { |
403 | // calculate c' = H(R, m) | 316 | // calculate c' = H(R, m) |
404 | struct GNUNET_CRYPTO_CsC c_dash; | 317 | struct GNUNET_CRYPTO_CsC c_dash; |
405 | cs_full_domain_hash (&sig->r_point, msg, msg_len, pub, &c_dash); | 318 | |
319 | cs_full_domain_hash (&sig->r_point, | ||
320 | msg, | ||
321 | msg_len, | ||
322 | pub, | ||
323 | &c_dash); | ||
406 | 324 | ||
407 | // s'G ?= R' + c' pub | 325 | // s'G ?= R' + c' pub |
408 | struct GNUNET_CRYPTO_Cs25519Point sig_scal_mul_base; | 326 | struct GNUNET_CRYPTO_Cs25519Point sig_scal_mul_base; |
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index dcd46e5f9..f516f5474 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c | |||
@@ -76,7 +76,8 @@ GNUNET_CRYPTO_hash_from_string2 (const char *enc, | |||
76 | char upper_enc[enclen]; | 76 | char upper_enc[enclen]; |
77 | char *up_ptr = upper_enc; | 77 | char *up_ptr = upper_enc; |
78 | 78 | ||
79 | GNUNET_STRINGS_utf8_toupper (enc, up_ptr); | 79 | if (GNUNET_OK != GNUNET_STRINGS_utf8_toupper (enc, up_ptr)) |
80 | return GNUNET_SYSERR; | ||
80 | 81 | ||
81 | return GNUNET_STRINGS_string_to_data (upper_enc, enclen, | 82 | return GNUNET_STRINGS_string_to_data (upper_enc, enclen, |
82 | (unsigned char *) result, | 83 | (unsigned char *) result, |
diff --git a/src/util/dnsstub.c b/src/util/dnsstub.c index 1ac274c92..c2f2a441f 100644 --- a/src/util/dnsstub.c +++ b/src/util/dnsstub.c | |||
@@ -324,24 +324,50 @@ do_dns_read (struct GNUNET_DNSSTUB_RequestSocket *rs, | |||
324 | found = GNUNET_NO; | 324 | found = GNUNET_NO; |
325 | for (struct DnsServer *ds = ctx->dns_head; NULL != ds; ds = ds->next) | 325 | for (struct DnsServer *ds = ctx->dns_head; NULL != ds; ds = ds->next) |
326 | { | 326 | { |
327 | if (0 == memcmp (&addr, | 327 | if (ds->ss.ss_family != addr.ss_family) |
328 | &ds->ss, | 328 | continue; |
329 | GNUNET_MIN (sizeof(struct sockaddr_storage), addrlen))) | 329 | if (addr.ss_family == AF_INET) |
330 | { | 330 | { |
331 | found = GNUNET_YES; | 331 | struct sockaddr_in *v4 = (struct sockaddr_in *) &addr; |
332 | break; | 332 | struct sockaddr_in *ds_v4 = (struct sockaddr_in *) &ds->ss; |
333 | |||
334 | |||
335 | if ((0 == memcmp (&v4->sin_addr, | ||
336 | &ds_v4->sin_addr, | ||
337 | sizeof(struct sockaddr_in))) && | ||
338 | (v4->sin_port == ds_v4->sin_port)) | ||
339 | { | ||
340 | found = GNUNET_YES; | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | else | ||
345 | { | ||
346 | struct sockaddr_in6 *v6 = (struct sockaddr_in6 *) &addr; | ||
347 | struct sockaddr_in6 *ds_v6 = (struct sockaddr_in6 *) &ds->ss; | ||
348 | |||
349 | if (0 == memcmp (&v6->sin6_addr, | ||
350 | &ds_v6->sin6_addr, | ||
351 | sizeof (v6->sin6_addr)) && | ||
352 | (v6->sin6_port == ds_v6->sin6_port)) | ||
353 | { | ||
354 | found = GNUNET_YES; | ||
355 | break; | ||
356 | } | ||
357 | |||
333 | } | 358 | } |
334 | } | 359 | } |
335 | if (GNUNET_NO == found) | 360 | if (GNUNET_NO == found) |
336 | { | 361 | { |
337 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 362 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
338 | "Received DNS response from server we never asked (ignored)"); | 363 | "Received DNS response from server we never asked (ignored)\n"); |
364 | |||
339 | return GNUNET_NO; | 365 | return GNUNET_NO; |
340 | } | 366 | } |
341 | if (sizeof(struct GNUNET_TUN_DnsHeader) > (size_t) r) | 367 | if (sizeof(struct GNUNET_TUN_DnsHeader) > (size_t) r) |
342 | { | 368 | { |
343 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 369 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
344 | _ ("Received DNS response that is too small (%u bytes)"), | 370 | _ ("Received DNS response that is too small (%u bytes)\n"), |
345 | (unsigned int) r); | 371 | (unsigned int) r); |
346 | return GNUNET_NO; | 372 | return GNUNET_NO; |
347 | } | 373 | } |
@@ -648,7 +674,7 @@ GNUNET_DNSSTUB_add_dns_sa (struct GNUNET_DNSSTUB_Context *ctx, | |||
648 | ds = GNUNET_new (struct DnsServer); | 674 | ds = GNUNET_new (struct DnsServer); |
649 | switch (sa->sa_family) | 675 | switch (sa->sa_family) |
650 | { | 676 | { |
651 | case AF_INET: | 677 | case AF_INET : |
652 | GNUNET_memcpy (&ds->ss, sa, sizeof(struct sockaddr_in)); | 678 | GNUNET_memcpy (&ds->ss, sa, sizeof(struct sockaddr_in)); |
653 | break; | 679 | break; |
654 | 680 | ||
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c index 917aa440b..96aee40e3 100644 --- a/src/util/getopt_helpers.c +++ b/src/util/getopt_helpers.c | |||
@@ -174,7 +174,8 @@ OUTER: | |||
174 | i++; | 174 | i++; |
175 | } | 175 | } |
176 | pd = GNUNET_OS_project_data_get (); | 176 | pd = GNUNET_OS_project_data_get (); |
177 | printf ("Report bugs to %s.\n" | 177 | printf ("\n" |
178 | "Report bugs to %s.\n" | ||
178 | "Home page: %s\n", | 179 | "Home page: %s\n", |
179 | pd->bug_email, | 180 | pd->bug_email, |
180 | pd->homepage); | 181 | pd->homepage); |
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c index 6b2a7f472..0071f3e90 100644 --- a/src/util/gnunet-crypto-tvg.c +++ b/src/util/gnunet-crypto-tvg.c | |||
@@ -852,7 +852,7 @@ checkvec (const char *operation, | |||
852 | return GNUNET_SYSERR; | 852 | return GNUNET_SYSERR; |
853 | } | 853 | } |
854 | 854 | ||
855 | if ((b != 1)&& (b != 0)) | 855 | if ((b != 1) && (b != 0)) |
856 | { | 856 | { |
857 | GNUNET_break (0); | 857 | GNUNET_break (0); |
858 | return GNUNET_SYSERR; | 858 | return GNUNET_SYSERR; |
@@ -869,9 +869,14 @@ checkvec (const char *operation, | |||
869 | unsigned int b_comp; | 869 | unsigned int b_comp; |
870 | 870 | ||
871 | 871 | ||
872 | GNUNET_CRYPTO_cs_r_derive (&nonce, &priv, r_priv_comp); | 872 | GNUNET_CRYPTO_cs_r_derive (&nonce, |
873 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[0], &r_pub_comp[0]); | 873 | "rw", |
874 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[1], &r_pub_comp[1]); | 874 | &priv, |
875 | r_priv_comp); | ||
876 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[0], | ||
877 | &r_pub_comp[0]); | ||
878 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[1], | ||
879 | &r_pub_comp[1]); | ||
875 | GNUNET_assert (0 == memcmp (&r_priv_comp, | 880 | GNUNET_assert (0 == memcmp (&r_priv_comp, |
876 | &r_priv, | 881 | &r_priv, |
877 | sizeof(struct GNUNET_CRYPTO_CsRSecret) * 2)); | 882 | sizeof(struct GNUNET_CRYPTO_CsRSecret) * 2)); |
@@ -1316,9 +1321,14 @@ output_vectors () | |||
1316 | strlen ("nonce_secret"), | 1321 | strlen ("nonce_secret"), |
1317 | NULL, | 1322 | NULL, |
1318 | 0)); | 1323 | 0)); |
1319 | GNUNET_CRYPTO_cs_r_derive (&nonce, &priv, r_priv); | 1324 | GNUNET_CRYPTO_cs_r_derive (&nonce, |
1320 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[0], &r_pub[0]); | 1325 | "rw", |
1321 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[1], &r_pub[1]); | 1326 | &priv, |
1327 | r_priv); | ||
1328 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[0], | ||
1329 | &r_pub[0]); | ||
1330 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[1], | ||
1331 | &r_pub[1]); | ||
1322 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce, | 1332 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce, |
1323 | bs); | 1333 | bs); |
1324 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, | 1334 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, |
diff --git a/src/util/network.c b/src/util/network.c index 688c37665..2f77bc54e 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -350,7 +350,8 @@ initialize_network_handle (struct GNUNET_NETWORK_Handle *h, | |||
350 | 350 | ||
351 | if (h->fd >= FD_SETSIZE) | 351 | if (h->fd >= FD_SETSIZE) |
352 | { | 352 | { |
353 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (h)); | 353 | GNUNET_break (GNUNET_OK == |
354 | GNUNET_NETWORK_socket_close (h)); | ||
354 | errno = EMFILE; | 355 | errno = EMFILE; |
355 | return GNUNET_SYSERR; | 356 | return GNUNET_SYSERR; |
356 | } | 357 | } |
diff --git a/src/util/plugin.c b/src/util/plugin.c index 39874a588..6ee41eec9 100644 --- a/src/util/plugin.c +++ b/src/util/plugin.c | |||
@@ -289,12 +289,12 @@ GNUNET_PLUGIN_unload (const char *library_name, | |||
289 | done = resolve_function (pos, | 289 | done = resolve_function (pos, |
290 | "done"); | 290 | "done"); |
291 | ret = NULL; | 291 | ret = NULL; |
292 | if (NULL != done) | ||
293 | ret = done (arg); | ||
294 | if (NULL == prev) | 292 | if (NULL == prev) |
295 | plugins = pos->next; | 293 | plugins = pos->next; |
296 | else | 294 | else |
297 | prev->next = pos->next; | 295 | prev->next = pos->next; |
296 | if (NULL != done) | ||
297 | ret = done (arg); | ||
298 | lt_dlclose (pos->handle); | 298 | lt_dlclose (pos->handle); |
299 | GNUNET_free (pos->name); | 299 | GNUNET_free (pos->name); |
300 | GNUNET_free (pos); | 300 | GNUNET_free (pos); |
diff --git a/src/util/strings.c b/src/util/strings.c index ece096f72..7e218cc59 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -390,7 +390,7 @@ GNUNET_STRINGS_conv (const char *input, | |||
390 | ret[encoded_string_length] = '\0'; | 390 | ret[encoded_string_length] = '\0'; |
391 | free (encoded_string); | 391 | free (encoded_string); |
392 | return ret; | 392 | return ret; |
393 | fail: | 393 | fail: |
394 | LOG (GNUNET_ERROR_TYPE_WARNING, | 394 | LOG (GNUNET_ERROR_TYPE_WARNING, |
395 | _ ("Character sets requested were `%s'->`%s'\n"), | 395 | _ ("Character sets requested were `%s'->`%s'\n"), |
396 | "UTF-8", | 396 | "UTF-8", |
@@ -426,24 +426,27 @@ GNUNET_STRINGS_from_utf8 (const char *input, | |||
426 | } | 426 | } |
427 | 427 | ||
428 | 428 | ||
429 | void | 429 | char * |
430 | GNUNET_STRINGS_utf8_normalize (const char *input, | 430 | GNUNET_STRINGS_utf8_normalize (const char *input) |
431 | char *output) | ||
432 | { | 431 | { |
433 | uint8_t *tmp; | 432 | uint8_t *tmp; |
434 | size_t len; | 433 | size_t len; |
435 | 434 | char *output; | |
436 | tmp = u8_normalize (UNINORM_NFC, | 435 | tmp = u8_normalize (UNINORM_NFC, |
437 | (uint8_t *) input, | 436 | (uint8_t *) input, |
438 | strlen ((char*) input), | 437 | strlen ((char*) input), |
439 | NULL, | 438 | NULL, |
440 | &len); | 439 | &len); |
440 | if (NULL == tmp) | ||
441 | return NULL; | ||
442 | output = GNUNET_malloc (len + 1); | ||
441 | GNUNET_memcpy (output, tmp, len); | 443 | GNUNET_memcpy (output, tmp, len); |
442 | output[len] = '\0'; | 444 | output[len] = '\0'; |
443 | free (tmp); | 445 | free (tmp); |
446 | return output; | ||
444 | } | 447 | } |
445 | 448 | ||
446 | void | 449 | enum GNUNET_GenericReturnValue |
447 | GNUNET_STRINGS_utf8_tolower (const char *input, | 450 | GNUNET_STRINGS_utf8_tolower (const char *input, |
448 | char *output) | 451 | char *output) |
449 | { | 452 | { |
@@ -456,13 +459,16 @@ GNUNET_STRINGS_utf8_tolower (const char *input, | |||
456 | UNINORM_NFD, | 459 | UNINORM_NFD, |
457 | NULL, | 460 | NULL, |
458 | &len); | 461 | &len); |
462 | if (NULL == tmp_in) | ||
463 | return GNUNET_SYSERR; | ||
459 | GNUNET_memcpy (output, tmp_in, len); | 464 | GNUNET_memcpy (output, tmp_in, len); |
460 | output[len] = '\0'; | 465 | output[len] = '\0'; |
461 | free (tmp_in); | 466 | GNUNET_free (tmp_in); |
467 | return GNUNET_OK; | ||
462 | } | 468 | } |
463 | 469 | ||
464 | 470 | ||
465 | void | 471 | enum GNUNET_GenericReturnValue |
466 | GNUNET_STRINGS_utf8_toupper (const char *input, | 472 | GNUNET_STRINGS_utf8_toupper (const char *input, |
467 | char *output) | 473 | char *output) |
468 | { | 474 | { |
@@ -475,9 +481,13 @@ GNUNET_STRINGS_utf8_toupper (const char *input, | |||
475 | UNINORM_NFD, | 481 | UNINORM_NFD, |
476 | NULL, | 482 | NULL, |
477 | &len); | 483 | &len); |
484 | if (NULL == tmp_in) | ||
485 | return GNUNET_SYSERR; | ||
486 | /* 0-terminator does not fit */ | ||
478 | GNUNET_memcpy (output, tmp_in, len); | 487 | GNUNET_memcpy (output, tmp_in, len); |
479 | output[len] = '\0'; | 488 | output[len] = '\0'; |
480 | free (tmp_in); | 489 | GNUNET_free (tmp_in); |
490 | return GNUNET_OK; | ||
481 | } | 491 | } |
482 | 492 | ||
483 | 493 | ||
@@ -1604,7 +1614,7 @@ GNUNET_STRINGS_base64_encode (const void *in, | |||
1604 | char *opt; | 1614 | char *opt; |
1605 | 1615 | ||
1606 | ret = 0; | 1616 | ret = 0; |
1607 | GNUNET_assert (len < SIZE_MAX / 4 * 3 ); | 1617 | GNUNET_assert (len < SIZE_MAX / 4 * 3); |
1608 | opt = GNUNET_malloc (2 + (len * 4 / 3) + 8); | 1618 | opt = GNUNET_malloc (2 + (len * 4 / 3) + 8); |
1609 | for (size_t i = 0; i < len; ++i) | 1619 | for (size_t i = 0; i < len; ++i) |
1610 | { | 1620 | { |
@@ -1741,7 +1751,7 @@ GNUNET_STRINGS_base64_decode (const char *data, | |||
1741 | output[ret++] = c; | 1751 | output[ret++] = c; |
1742 | } | 1752 | } |
1743 | } | 1753 | } |
1744 | END: | 1754 | END: |
1745 | *out = output; | 1755 | *out = output; |
1746 | return ret; | 1756 | return ret; |
1747 | } | 1757 | } |
@@ -1803,12 +1813,19 @@ GNUNET_STRINGS_urldecode (const char *data, | |||
1803 | char *wpos = *out; | 1813 | char *wpos = *out; |
1804 | size_t resl = 0; | 1814 | size_t resl = 0; |
1805 | 1815 | ||
1806 | while ('\0' != *rpos) | 1816 | while ( ('\0' != *rpos) && |
1817 | (data + len != rpos) ) | ||
1807 | { | 1818 | { |
1808 | unsigned int num; | 1819 | unsigned int num; |
1809 | switch (*rpos) | 1820 | switch (*rpos) |
1810 | { | 1821 | { |
1811 | case '%': | 1822 | case '%': |
1823 | if (rpos + 3 > data + len) | ||
1824 | { | ||
1825 | GNUNET_break_op (0); | ||
1826 | GNUNET_free (*out); | ||
1827 | return 0; | ||
1828 | } | ||
1812 | if (1 != sscanf (rpos + 1, "%2x", &num)) | 1829 | if (1 != sscanf (rpos + 1, "%2x", &num)) |
1813 | break; | 1830 | break; |
1814 | *wpos = (char) ((unsigned char) num); | 1831 | *wpos = (char) ((unsigned char) num); |
diff --git a/src/util/test_crypto_cs.c b/src/util/test_crypto_cs.c index d3406516e..914ded9bc 100644 --- a/src/util/test_crypto_cs.c +++ b/src/util/test_crypto_cs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2014,2015 GNUnet e.V. | 3 | Copyright (C) 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 |
@@ -30,148 +30,168 @@ | |||
30 | 30 | ||
31 | #define ITER 25 | 31 | #define ITER 25 |
32 | 32 | ||
33 | void | 33 | static void |
34 | test_create_priv (struct GNUNET_CRYPTO_CsPrivateKey *priv) | 34 | test_create_priv (struct GNUNET_CRYPTO_CsPrivateKey *priv) |
35 | { | 35 | { |
36 | /* TEST 1 | 36 | /* TEST 1 |
37 | * Check that privkey is set | 37 | * Check that privkey is set |
38 | */ | 38 | */ |
39 | struct GNUNET_CRYPTO_CsPrivateKey other_priv; | 39 | struct GNUNET_CRYPTO_CsPrivateKey other_priv; |
40 | memcpy (&other_priv.scalar, &priv->scalar, sizeof(other_priv.scalar)); | ||
41 | 40 | ||
41 | other_priv = *priv; | ||
42 | GNUNET_CRYPTO_cs_private_key_generate (priv); | 42 | GNUNET_CRYPTO_cs_private_key_generate (priv); |
43 | 43 | GNUNET_assert (0 != | |
44 | GNUNET_assert (0 != memcmp (&other_priv.scalar, | 44 | GNUNET_memcmp (&other_priv.scalar, |
45 | &priv->scalar, | 45 | &priv->scalar)); |
46 | sizeof(other_priv.scalar))); | ||
47 | } | 46 | } |
48 | 47 | ||
49 | 48 | ||
50 | void | 49 | static void |
51 | test_generate_pub (const struct GNUNET_CRYPTO_CsPrivateKey *priv, | 50 | test_generate_pub (const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
52 | struct GNUNET_CRYPTO_CsPublicKey *pub) | 51 | struct GNUNET_CRYPTO_CsPublicKey *pub) |
53 | { | 52 | { |
54 | /* TEST 1 | 53 | /* TEST 1 |
55 | * Check that pubkey is set | 54 | * Check that pubkey is set |
56 | */ | 55 | */ |
57 | struct GNUNET_CRYPTO_CsPublicKey other_pub; | 56 | struct GNUNET_CRYPTO_CsPublicKey other_pub; |
58 | memcpy (&other_pub.point, &pub->point, sizeof(other_pub.point)); | ||
59 | |||
60 | GNUNET_CRYPTO_cs_private_key_get_public (priv, pub); | ||
61 | 57 | ||
62 | GNUNET_assert (0 != memcmp (&other_pub.point, | 58 | other_pub = *pub; |
63 | &pub->point, | 59 | GNUNET_CRYPTO_cs_private_key_get_public (priv, |
64 | sizeof(other_pub.point))); | 60 | pub); |
61 | GNUNET_assert (0 != | ||
62 | GNUNET_memcmp (&other_pub.point, | ||
63 | &pub->point)); | ||
65 | 64 | ||
66 | /* TEST 2 | 65 | /* TEST 2 |
67 | * Check that pubkey is a valid point | 66 | * Check that pubkey is a valid point |
68 | */ | 67 | */ |
69 | GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (pub->point.y)); | 68 | GNUNET_assert (1 == |
69 | crypto_core_ed25519_is_valid_point (pub->point.y)); | ||
70 | 70 | ||
71 | /* TEST 3 | 71 | /* TEST 3 |
72 | * Check if function gives the same result for the same output | 72 | * Check if function gives the same result for the same output |
73 | */ | 73 | */ |
74 | memcpy (&other_pub.point, &pub->point, sizeof(other_pub.point)); | 74 | other_pub = *pub; |
75 | 75 | for (unsigned int i = 0; i<ITER; i++) | |
76 | for (int i = 0; i<ITER; i++) { | 76 | { |
77 | GNUNET_CRYPTO_cs_private_key_get_public (priv, pub); | 77 | GNUNET_CRYPTO_cs_private_key_get_public (priv, |
78 | GNUNET_assert (0 == memcmp (&other_pub.point, | 78 | pub); |
79 | &pub->point, | 79 | GNUNET_assert (0 == |
80 | sizeof(other_pub.point))); | 80 | GNUNET_memcmp (&other_pub.point, |
81 | &pub->point)); | ||
81 | } | 82 | } |
82 | } | 83 | } |
83 | 84 | ||
84 | 85 | ||
85 | void | 86 | static void |
86 | test_derive_rsecret (const struct GNUNET_CRYPTO_CsNonce *nonce, | 87 | test_derive_rsecret (const struct GNUNET_CRYPTO_CsNonce *nonce, |
87 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, | 88 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
88 | struct GNUNET_CRYPTO_CsRSecret r[2]) | 89 | struct GNUNET_CRYPTO_CsRSecret r[2]) |
89 | { | 90 | { |
90 | /* TEST 1 | 91 | /* TEST 1 |
91 | * Check that r are set | 92 | * Check that r are set |
92 | */ | 93 | */ |
93 | struct GNUNET_CRYPTO_CsPrivateKey other_r[2]; | 94 | struct GNUNET_CRYPTO_CsPrivateKey other_r[2]; |
94 | memcpy (&other_r[0], &r[0], sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2); | ||
95 | 95 | ||
96 | GNUNET_CRYPTO_cs_r_derive (nonce, priv, r); | 96 | memcpy (other_r, |
97 | 97 | r, | |
98 | GNUNET_assert (0 != memcmp (&other_r[0], | 98 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2); |
99 | &r[0], | 99 | GNUNET_CRYPTO_cs_r_derive (nonce, |
100 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2)); | 100 | "nw", |
101 | priv, | ||
102 | r); | ||
103 | GNUNET_assert (0 != | ||
104 | memcmp (&other_r[0], | ||
105 | &r[0], | ||
106 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2)); | ||
101 | 107 | ||
102 | /* TEST 2 | 108 | /* TEST 2 |
103 | * Check if function gives the same result for the same input. | 109 | * Check if function gives the same result for the same input. |
104 | * This test ensures that the derivation is deterministic. | 110 | * This test ensures that the derivation is deterministic. |
105 | */ | 111 | */ |
106 | memcpy (&other_r[0], &r[0], sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2); | 112 | memcpy (other_r, |
107 | for (int i = 0; i<ITER; i++) { | 113 | r, |
108 | GNUNET_CRYPTO_cs_r_derive (nonce, priv, r); | 114 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2); |
109 | GNUNET_assert (0 == memcmp (&other_r[0], | 115 | for (unsigned int i = 0; i<ITER; i++) |
110 | &r[0], | 116 | { |
111 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2)); | 117 | GNUNET_CRYPTO_cs_r_derive (nonce, |
118 | "nw", | ||
119 | priv, | ||
120 | r); | ||
121 | GNUNET_assert (0 == | ||
122 | memcmp (other_r, | ||
123 | r, | ||
124 | sizeof(struct GNUNET_CRYPTO_CsPrivateKey) * 2)); | ||
112 | } | 125 | } |
113 | } | 126 | } |
114 | 127 | ||
115 | 128 | ||
116 | void | 129 | static void |
117 | test_generate_rpublic (const struct GNUNET_CRYPTO_CsRSecret *r_priv, | 130 | test_generate_rpublic (const struct GNUNET_CRYPTO_CsRSecret *r_priv, |
118 | struct GNUNET_CRYPTO_CsRPublic *r_pub) | 131 | struct GNUNET_CRYPTO_CsRPublic *r_pub) |
119 | { | 132 | { |
120 | /* TEST 1 | 133 | /* TEST 1 |
121 | * Check that r_pub is set | 134 | * Check that r_pub is set |
122 | */ | 135 | */ |
123 | struct GNUNET_CRYPTO_CsRPublic other_r_pub; | 136 | struct GNUNET_CRYPTO_CsRPublic other_r_pub; |
124 | memcpy (&other_r_pub.point, &r_pub->point, sizeof(other_r_pub.point)); | ||
125 | |||
126 | GNUNET_CRYPTO_cs_r_get_public (r_priv, r_pub); | ||
127 | |||
128 | GNUNET_assert (0 != memcmp (&other_r_pub.point, | ||
129 | &r_pub->point, | ||
130 | sizeof(other_r_pub.point))); | ||
131 | 137 | ||
138 | other_r_pub = *r_pub; | ||
139 | GNUNET_CRYPTO_cs_r_get_public (r_priv, | ||
140 | r_pub); | ||
141 | GNUNET_assert (0 != | ||
142 | GNUNET_memcmp (&other_r_pub.point, | ||
143 | &r_pub->point)); | ||
132 | /* TEST 2 | 144 | /* TEST 2 |
133 | * Check that r_pub is a valid point | 145 | * Check that r_pub is a valid point |
134 | */ | 146 | */ |
135 | GNUNET_assert (1 == crypto_core_ed25519_is_valid_point (r_pub->point.y)); | 147 | GNUNET_assert (1 == |
148 | crypto_core_ed25519_is_valid_point (r_pub->point.y)); | ||
136 | 149 | ||
137 | /* TEST 3 | 150 | /* TEST 3 |
138 | * Check if function gives the same result for the same output | 151 | * Check if function gives the same result for the same output |
139 | */ | 152 | */ |
140 | memcpy (&other_r_pub.point, &r_pub->point, sizeof(other_r_pub.point)); | 153 | other_r_pub.point = r_pub->point; |
141 | for (int i = 0; i<ITER; i++) { | 154 | for (int i = 0; i<ITER; i++) |
142 | GNUNET_CRYPTO_cs_r_get_public (r_priv, r_pub); | 155 | { |
143 | GNUNET_assert (0 == memcmp (&other_r_pub.point, | 156 | GNUNET_CRYPTO_cs_r_get_public (r_priv, |
144 | &r_pub->point, | 157 | r_pub); |
145 | sizeof(other_r_pub.point))); | 158 | GNUNET_assert (0 == |
159 | GNUNET_memcmp (&other_r_pub.point, | ||
160 | &r_pub->point)); | ||
146 | } | 161 | } |
147 | } | 162 | } |
148 | 163 | ||
149 | 164 | ||
150 | void | 165 | static void |
151 | test_derive_blindingsecrets (const struct GNUNET_CRYPTO_CsNonce *blind_seed, | 166 | test_derive_blindingsecrets (const struct GNUNET_CRYPTO_CsNonce *blind_seed, |
152 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]) | 167 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]) |
153 | { | 168 | { |
154 | /* TEST 1 | 169 | /* TEST 1 |
155 | * Check that blinding secrets are set | 170 | * Check that blinding secrets are set |
156 | */ | 171 | */ |
157 | struct GNUNET_CRYPTO_CsBlindingSecret other_bs[2]; | 172 | struct GNUNET_CRYPTO_CsBlindingSecret other_bs[2]; |
158 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 173 | |
159 | * 2); | 174 | memcpy (other_bs, |
175 | bs, | ||
176 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) * 2); | ||
160 | 177 | ||
161 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); | 178 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); |
162 | 179 | ||
163 | GNUNET_assert (0 != memcmp (&other_bs[0], | 180 | GNUNET_assert (0 != |
164 | &bs[0], | 181 | memcmp (other_bs, |
165 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 182 | bs, |
166 | * 2)); | 183 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) |
184 | * 2)); | ||
167 | 185 | ||
168 | /* TEST 2 | 186 | /* TEST 2 |
169 | * Check if function gives the same result for the same input. | 187 | * Check if function gives the same result for the same input. |
170 | * This test ensures that the derivation is deterministic. | 188 | * This test ensures that the derivation is deterministic. |
171 | */ | 189 | */ |
172 | memcpy (&other_bs[0], &bs[0], sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | 190 | memcpy (other_bs, |
173 | * 2); | 191 | bs, |
174 | for (int i = 0; i<ITER; i++) { | 192 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) * 2); |
193 | for (unsigned int i = 0; i<ITER; i++) | ||
194 | { | ||
175 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); | 195 | GNUNET_CRYPTO_cs_blinding_secrets_derive (blind_seed, bs); |
176 | GNUNET_assert (0 == memcmp (&other_bs[0], | 196 | GNUNET_assert (0 == memcmp (&other_bs[0], |
177 | &bs[0], | 197 | &bs[0], |
@@ -181,19 +201,20 @@ test_derive_blindingsecrets (const struct GNUNET_CRYPTO_CsNonce *blind_seed, | |||
181 | } | 201 | } |
182 | 202 | ||
183 | 203 | ||
184 | void | 204 | static void |
185 | test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], | 205 | test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], |
186 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], | 206 | const struct GNUNET_CRYPTO_CsRPublic r_pub[2], |
187 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 207 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
188 | const void *msg, | 208 | const void *msg, |
189 | size_t msg_len, | 209 | size_t msg_len, |
190 | struct GNUNET_CRYPTO_CsC blinded_cs[2], | 210 | struct GNUNET_CRYPTO_CsC blinded_cs[2], |
191 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2]) | 211 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pub[2]) |
192 | { | 212 | { |
193 | /* TEST 1 | 213 | /* TEST 1 |
194 | * Check that the blinded c's and blinded r's | 214 | * Check that the blinded c's and blinded r's |
195 | */ | 215 | */ |
196 | struct GNUNET_CRYPTO_CsC other_blinded_c[2]; | 216 | struct GNUNET_CRYPTO_CsC other_blinded_c[2]; |
217 | |||
197 | memcpy (&other_blinded_c[0], | 218 | memcpy (&other_blinded_c[0], |
198 | &blinded_cs[0], | 219 | &blinded_cs[0], |
199 | sizeof(struct GNUNET_CRYPTO_CsC) * 2); | 220 | sizeof(struct GNUNET_CRYPTO_CsC) * 2); |
@@ -222,7 +243,8 @@ test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], | |||
222 | * Check if R' - aG -bX = R for b = 0 | 243 | * Check if R' - aG -bX = R for b = 0 |
223 | * This test does the opposite operations and checks wether the equation is still correct. | 244 | * This test does the opposite operations and checks wether the equation is still correct. |
224 | */ | 245 | */ |
225 | for (unsigned int b = 0; b <= 1; b++) { | 246 | for (unsigned int b = 0; b <= 1; b++) |
247 | { | ||
226 | struct GNUNET_CRYPTO_Cs25519Point aG; | 248 | struct GNUNET_CRYPTO_Cs25519Point aG; |
227 | struct GNUNET_CRYPTO_Cs25519Point bX; | 249 | struct GNUNET_CRYPTO_Cs25519Point bX; |
228 | struct GNUNET_CRYPTO_Cs25519Point r_min_aG; | 250 | struct GNUNET_CRYPTO_Cs25519Point r_min_aG; |
@@ -252,7 +274,6 @@ test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], | |||
252 | } | 274 | } |
253 | 275 | ||
254 | 276 | ||
255 | |||
256 | /* TEST 3 | 277 | /* TEST 3 |
257 | * Check that the blinded r_pubs' are valid points | 278 | * Check that the blinded r_pubs' are valid points |
258 | */ | 279 | */ |
@@ -271,7 +292,8 @@ test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], | |||
271 | &blinded_r_pub[0], | 292 | &blinded_r_pub[0], |
272 | sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2); | 293 | sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2); |
273 | 294 | ||
274 | for (int i = 0; i<ITER; i++) { | 295 | for (unsigned int i = 0; i<ITER; i++) |
296 | { | ||
275 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, | 297 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, |
276 | r_pub, | 298 | r_pub, |
277 | pub, | 299 | pub, |
@@ -289,13 +311,13 @@ test_calc_blindedc (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], | |||
289 | } | 311 | } |
290 | 312 | ||
291 | 313 | ||
292 | void | 314 | static void |
293 | test_blind_sign (unsigned int *b, | 315 | test_blind_sign (unsigned int *b, |
294 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, | 316 | const struct GNUNET_CRYPTO_CsPrivateKey *priv, |
295 | const struct GNUNET_CRYPTO_CsRSecret r[2], | 317 | const struct GNUNET_CRYPTO_CsRSecret r[2], |
296 | const struct GNUNET_CRYPTO_CsC c[2], | 318 | const struct GNUNET_CRYPTO_CsC c[2], |
297 | const struct GNUNET_CRYPTO_CsNonce *nonce, | 319 | const struct GNUNET_CRYPTO_CsNonce *nonce, |
298 | struct GNUNET_CRYPTO_CsBlindS *blinded_s) | 320 | struct GNUNET_CRYPTO_CsBlindS *blinded_s) |
299 | { | 321 | { |
300 | /* TEST 1 | 322 | /* TEST 1 |
301 | * Check that blinded_s is set | 323 | * Check that blinded_s is set |
@@ -336,8 +358,10 @@ test_blind_sign (unsigned int *b, | |||
336 | * Check if function gives the same result for the same input. | 358 | * Check if function gives the same result for the same input. |
337 | */ | 359 | */ |
338 | memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS)); | 360 | memcpy (&other_blinded_s, blinded_s, sizeof(struct GNUNET_CRYPTO_CsBlindS)); |
339 | unsigned int other_b; | 361 | for (unsigned int i = 0; i<ITER; i++) |
340 | for (int i = 0; i<ITER; i++) { | 362 | { |
363 | unsigned int other_b; | ||
364 | |||
341 | other_b = GNUNET_CRYPTO_cs_sign_derive (priv, r, c, nonce, blinded_s); | 365 | other_b = GNUNET_CRYPTO_cs_sign_derive (priv, r, c, nonce, blinded_s); |
342 | 366 | ||
343 | GNUNET_assert (other_b == *b); | 367 | GNUNET_assert (other_b == *b); |
@@ -348,10 +372,10 @@ test_blind_sign (unsigned int *b, | |||
348 | } | 372 | } |
349 | 373 | ||
350 | 374 | ||
351 | void | 375 | static void |
352 | test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, | 376 | test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, |
353 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, | 377 | const struct GNUNET_CRYPTO_CsBlindingSecret *bs, |
354 | struct GNUNET_CRYPTO_CsS *signature_scalar) | 378 | struct GNUNET_CRYPTO_CsS *signature_scalar) |
355 | { | 379 | { |
356 | /* TEST 1 | 380 | /* TEST 1 |
357 | * Check that signature_scalar is set | 381 | * Check that signature_scalar is set |
@@ -387,7 +411,8 @@ test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, | |||
387 | memcpy (&other_signature_scalar, signature_scalar, | 411 | memcpy (&other_signature_scalar, signature_scalar, |
388 | sizeof(struct GNUNET_CRYPTO_CsS)); | 412 | sizeof(struct GNUNET_CRYPTO_CsS)); |
389 | 413 | ||
390 | for (int i = 0; i<ITER; i++) { | 414 | for (unsigned int i = 0; i<ITER; i++) |
415 | { | ||
391 | GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar); | 416 | GNUNET_CRYPTO_cs_unblind (blinded_signature_scalar, bs, signature_scalar); |
392 | GNUNET_assert (0 == memcmp (&other_signature_scalar, | 417 | GNUNET_assert (0 == memcmp (&other_signature_scalar, |
393 | signature_scalar, | 418 | signature_scalar, |
@@ -396,10 +421,10 @@ test_unblinds (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, | |||
396 | } | 421 | } |
397 | 422 | ||
398 | 423 | ||
399 | void | 424 | static void |
400 | test_blind_verify (const struct GNUNET_CRYPTO_CsSignature *sig, | 425 | test_blind_verify (const struct GNUNET_CRYPTO_CsSignature *sig, |
401 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 426 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
402 | const struct GNUNET_CRYPTO_CsC *c) | 427 | const struct GNUNET_CRYPTO_CsC *c) |
403 | { | 428 | { |
404 | /* TEST 1 | 429 | /* TEST 1 |
405 | * Test verifies the blinded signature sG == Rb + cbX | 430 | * Test verifies the blinded signature sG == Rb + cbX |
@@ -425,28 +450,30 @@ test_blind_verify (const struct GNUNET_CRYPTO_CsSignature *sig, | |||
425 | } | 450 | } |
426 | 451 | ||
427 | 452 | ||
428 | void | 453 | static void |
429 | test_verify (const struct GNUNET_CRYPTO_CsSignature *sig, | 454 | test_verify (const struct GNUNET_CRYPTO_CsSignature *sig, |
430 | const struct GNUNET_CRYPTO_CsPublicKey *pub, | 455 | const struct GNUNET_CRYPTO_CsPublicKey *pub, |
431 | const void *msg, | 456 | const void *msg, |
432 | size_t msg_len) | 457 | size_t msg_len) |
433 | { | 458 | { |
434 | /* TEST 1 | 459 | /* TEST 1 |
435 | * Test simple verification | 460 | * Test simple verification |
436 | */ | 461 | */ |
437 | GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_cs_verify (sig, | 462 | GNUNET_assert (GNUNET_YES == |
438 | pub, | 463 | GNUNET_CRYPTO_cs_verify (sig, |
439 | msg, | 464 | pub, |
440 | msg_len)); | 465 | msg, |
466 | msg_len)); | ||
441 | /* TEST 2 | 467 | /* TEST 2 |
442 | * Test verification of "wrong" message | 468 | * Test verification of "wrong" message |
443 | */ | 469 | */ |
444 | char other_msg[] = "test massege"; | 470 | char other_msg[] = "test massege"; |
445 | size_t other_msg_len = strlen ("test massege"); | 471 | size_t other_msg_len = strlen ("test massege"); |
446 | GNUNET_assert (GNUNET_SYSERR == GNUNET_CRYPTO_cs_verify (sig, | 472 | GNUNET_assert (GNUNET_SYSERR == |
447 | pub, | 473 | GNUNET_CRYPTO_cs_verify (sig, |
448 | other_msg, | 474 | pub, |
449 | other_msg_len)); | 475 | other_msg, |
476 | other_msg_len)); | ||
450 | } | 477 | } |
451 | 478 | ||
452 | 479 | ||
@@ -461,71 +488,122 @@ main (int argc, | |||
461 | size_t message_len = strlen ("test message"); | 488 | size_t message_len = strlen ("test message"); |
462 | 489 | ||
463 | struct GNUNET_CRYPTO_CsPrivateKey priv; | 490 | struct GNUNET_CRYPTO_CsPrivateKey priv; |
491 | |||
492 | memset (&priv, | ||
493 | 42, | ||
494 | sizeof (priv)); | ||
464 | test_create_priv (&priv); | 495 | test_create_priv (&priv); |
465 | 496 | ||
466 | struct GNUNET_CRYPTO_CsPublicKey pub; | 497 | struct GNUNET_CRYPTO_CsPublicKey pub; |
467 | test_generate_pub (&priv, &pub); | 498 | |
499 | memset (&pub, | ||
500 | 42, | ||
501 | sizeof (pub)); | ||
502 | test_generate_pub (&priv, | ||
503 | &pub); | ||
468 | 504 | ||
469 | // derive nonce | 505 | // derive nonce |
470 | struct GNUNET_CRYPTO_CsNonce nonce; | 506 | struct GNUNET_CRYPTO_CsNonce nonce; |
471 | GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_hkdf (nonce.nonce, | 507 | GNUNET_assert (GNUNET_YES == |
472 | sizeof(nonce.nonce), | 508 | GNUNET_CRYPTO_kdf (nonce.nonce, |
473 | GCRY_MD_SHA512, | 509 | sizeof(nonce.nonce), |
474 | GCRY_MD_SHA256, | 510 | "nonce", |
475 | "nonce", | 511 | strlen ("nonce"), |
476 | strlen ("nonce"), | 512 | "nonce_secret", |
477 | "nonce_secret", | 513 | strlen ("nonce_secret"), |
478 | strlen ("nonce_secret"), | 514 | NULL, |
479 | NULL, | 515 | 0)); |
480 | 0)); | ||
481 | 516 | ||
482 | // generate r, R | 517 | // generate r, R |
483 | struct GNUNET_CRYPTO_CsRSecret r_secrets[2]; | 518 | struct GNUNET_CRYPTO_CsRSecret r_secrets[2]; |
484 | test_derive_rsecret (&nonce, &priv, r_secrets); | 519 | |
520 | memset (r_secrets, | ||
521 | 42, | ||
522 | sizeof (r_secrets)); | ||
523 | test_derive_rsecret (&nonce, | ||
524 | &priv, | ||
525 | r_secrets); | ||
485 | 526 | ||
486 | struct GNUNET_CRYPTO_CsRPublic r_publics[2]; | 527 | struct GNUNET_CRYPTO_CsRPublic r_publics[2]; |
487 | test_generate_rpublic (&r_secrets[0], &r_publics[0]); | 528 | |
488 | test_generate_rpublic (&r_secrets[1], &r_publics[1]); | 529 | memset (r_publics, |
530 | 42, | ||
531 | sizeof (r_publics)); | ||
532 | test_generate_rpublic (&r_secrets[0], | ||
533 | &r_publics[0]); | ||
534 | test_generate_rpublic (&r_secrets[1], | ||
535 | &r_publics[1]); | ||
489 | 536 | ||
490 | // ---------- actions performed by user | 537 | // ---------- actions performed by user |
491 | 538 | ||
492 | // generate blinding secrets | 539 | // generate blinding secrets |
493 | struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2]; | 540 | struct GNUNET_CRYPTO_CsBlindingSecret blindingsecrets[2]; |
541 | |||
542 | memset (blindingsecrets, | ||
543 | 42, | ||
544 | sizeof (blindingsecrets)); | ||
494 | test_derive_blindingsecrets (&nonce, | 545 | test_derive_blindingsecrets (&nonce, |
495 | blindingsecrets); | 546 | blindingsecrets); |
496 | 547 | ||
497 | // calculate blinded c's | 548 | // calculate blinded c's |
498 | struct GNUNET_CRYPTO_CsC blinded_cs[2]; | 549 | struct GNUNET_CRYPTO_CsC blinded_cs[2]; |
499 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pubs[2]; | 550 | struct GNUNET_CRYPTO_CsRPublic blinded_r_pubs[2]; |
551 | |||
552 | memset (blinded_cs, | ||
553 | 42, | ||
554 | sizeof (blinded_cs)); | ||
555 | memset (blinded_r_pubs, | ||
556 | 42, | ||
557 | sizeof (blinded_r_pubs)); | ||
500 | test_calc_blindedc (blindingsecrets, | 558 | test_calc_blindedc (blindingsecrets, |
501 | r_publics, | 559 | r_publics, |
502 | &pub, | 560 | &pub, |
503 | message, | 561 | message, |
504 | message_len, | 562 | message_len, |
505 | blinded_cs, | 563 | blinded_cs, |
506 | blinded_r_pubs); | 564 | blinded_r_pubs); |
507 | 565 | ||
508 | // ---------- actions performed by signer | 566 | // ---------- actions performed by signer |
509 | // sign blinded c's and get b and s in return | 567 | // sign blinded c's and get b and s in return |
510 | unsigned int b; | 568 | unsigned int b; |
511 | struct GNUNET_CRYPTO_CsBlindS blinded_s; | 569 | struct GNUNET_CRYPTO_CsBlindS blinded_s; |
512 | test_blind_sign (&b, &priv, r_secrets, blinded_cs, &nonce, &blinded_s); | 570 | |
571 | memset (&blinded_s, | ||
572 | 42, | ||
573 | sizeof (blinded_s)); | ||
574 | test_blind_sign (&b, | ||
575 | &priv, | ||
576 | r_secrets, | ||
577 | blinded_cs, | ||
578 | &nonce, | ||
579 | &blinded_s); | ||
513 | 580 | ||
514 | // verify blinded signature | 581 | // verify blinded signature |
515 | struct GNUNET_CRYPTO_CsSignature blinded_signature; | 582 | struct GNUNET_CRYPTO_CsSignature blinded_signature; |
583 | |||
516 | blinded_signature.r_point = r_publics[b]; | 584 | blinded_signature.r_point = r_publics[b]; |
517 | blinded_signature.s_scalar.scalar = blinded_s.scalar; | 585 | blinded_signature.s_scalar.scalar = blinded_s.scalar; |
518 | test_blind_verify (&blinded_signature, &pub, &blinded_cs[b]); | 586 | test_blind_verify (&blinded_signature, |
587 | &pub, | ||
588 | &blinded_cs[b]); | ||
519 | 589 | ||
520 | // ---------- actions performed by user | 590 | // ---------- actions performed by user |
521 | struct GNUNET_CRYPTO_CsS sig_scalar; | 591 | struct GNUNET_CRYPTO_CsS sig_scalar; |
522 | test_unblinds (&blinded_s, &blindingsecrets[b], &sig_scalar); | 592 | |
593 | memset (&sig_scalar, | ||
594 | 42, | ||
595 | sizeof (sig_scalar)); | ||
596 | test_unblinds (&blinded_s, | ||
597 | &blindingsecrets[b], | ||
598 | &sig_scalar); | ||
523 | 599 | ||
524 | // verify unblinded signature | 600 | // verify unblinded signature |
525 | struct GNUNET_CRYPTO_CsSignature signature; | 601 | struct GNUNET_CRYPTO_CsSignature signature; |
526 | signature.r_point = blinded_r_pubs[b]; | 602 | signature.r_point = blinded_r_pubs[b]; |
527 | signature.s_scalar = sig_scalar; | 603 | signature.s_scalar = sig_scalar; |
528 | test_verify (&signature, &pub, message, message_len); | 604 | test_verify (&signature, |
529 | 605 | &pub, | |
606 | message, | ||
607 | message_len); | ||
530 | return 0; | 608 | return 0; |
531 | } | 609 | } |
diff --git a/src/util/test_strings.c b/src/util/test_strings.c index 1ecd31464..cccffcaf5 100644 --- a/src/util/test_strings.c +++ b/src/util/test_strings.c | |||
@@ -114,10 +114,9 @@ main (int argc, char *argv[]) | |||
114 | /* Normalization */ | 114 | /* Normalization */ |
115 | r = "q\u0307\u0323"; /* Non-canonical order */ | 115 | r = "q\u0307\u0323"; /* Non-canonical order */ |
116 | 116 | ||
117 | GNUNET_STRINGS_utf8_normalize (r, | 117 | b = GNUNET_STRINGS_utf8_normalize (r); |
118 | buf); | 118 | GNUNET_assert (0 == strcmp ("q\u0323\u0307", b)); |
119 | GNUNET_assert (0 == strcmp ("q\u0323\u0307", buf)); | 119 | GNUNET_free (b); |
120 | |||
121 | b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII"); | 120 | b = GNUNET_STRINGS_to_utf8 ("TEST", 4, "ASCII"); |
122 | WANT ("TEST", b); | 121 | WANT ("TEST", b); |
123 | 122 | ||
diff --git a/src/util/time.c b/src/util/time.c index 83b39b4e8..68a6937a0 100644 --- a/src/util/time.c +++ b/src/util/time.c | |||
@@ -695,6 +695,13 @@ GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch) | |||
695 | } | 695 | } |
696 | 696 | ||
697 | 697 | ||
698 | uint64_t | ||
699 | GNUNET_TIME_timestamp_to_s (struct GNUNET_TIME_Timestamp ts) | ||
700 | { | ||
701 | return ts.abs_time.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us; | ||
702 | } | ||
703 | |||
704 | |||
698 | struct GNUNET_TIME_Absolute | 705 | struct GNUNET_TIME_Absolute |
699 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) | 706 | GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a) |
700 | { | 707 | { |
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c index 3392a19d7..748a0f342 100644 --- a/src/zonemaster/gnunet-service-zonemaster-monitor.c +++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include "gnunet_namestore_service.h" | 29 | #include "gnunet_namestore_service.h" |
30 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
31 | 31 | ||
32 | |||
33 | #define LOG_STRERROR_FILE(kind, syscall, \ | 32 | #define LOG_STRERROR_FILE(kind, syscall, \ |
34 | filename) GNUNET_log_from_strerror_file (kind, "util", \ | 33 | filename) GNUNET_log_from_strerror_file (kind, "util", \ |
35 | syscall, \ | 34 | syscall, \ |
@@ -58,7 +57,6 @@ | |||
58 | */ | 57 | */ |
59 | #define DHT_GNS_REPLICATION_LEVEL 5 | 58 | #define DHT_GNS_REPLICATION_LEVEL 5 |
60 | 59 | ||
61 | |||
62 | /** | 60 | /** |
63 | * Handle for DHT PUT activity triggered from the namestore monitor. | 61 | * Handle for DHT PUT activity triggered from the namestore monitor. |
64 | */ | 62 | */ |
@@ -197,39 +195,6 @@ dht_put_monitor_continuation (void *cls) | |||
197 | 195 | ||
198 | 196 | ||
199 | /** | 197 | /** |
200 | * Convert namestore records from the internal format to that | ||
201 | * suitable for publication (removes private records, converts | ||
202 | * to absolute expiration time). | ||
203 | * | ||
204 | * @param rd input records | ||
205 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
206 | * @param rd_public where to write the converted records | ||
207 | * @return number of records written to @a rd_public | ||
208 | */ | ||
209 | static unsigned int | ||
210 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | ||
211 | unsigned int rd_count, | ||
212 | struct GNUNET_GNSRECORD_Data *rd_public) | ||
213 | { | ||
214 | struct GNUNET_TIME_Absolute now; | ||
215 | unsigned int rd_public_count; | ||
216 | |||
217 | rd_public_count = 0; | ||
218 | now = GNUNET_TIME_absolute_get (); | ||
219 | for (unsigned int i = 0; i < rd_count; i++) | ||
220 | { | ||
221 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) | ||
222 | continue; | ||
223 | if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && | ||
224 | (rd[i].expiration_time < now.abs_value_us)) | ||
225 | continue; /* record already expired, skip it */ | ||
226 | rd_public[rd_public_count++] = rd[i]; | ||
227 | } | ||
228 | return rd_public_count; | ||
229 | } | ||
230 | |||
231 | |||
232 | /** | ||
233 | * Store GNS records in the DHT. | 198 | * Store GNS records in the DHT. |
234 | * | 199 | * |
235 | * @param key key of the zone | 200 | * @param key key of the zone |
@@ -244,16 +209,14 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
244 | const char *label, | 209 | const char *label, |
245 | const struct GNUNET_GNSRECORD_Data *rd_public, | 210 | const struct GNUNET_GNSRECORD_Data *rd_public, |
246 | unsigned int rd_public_count, | 211 | unsigned int rd_public_count, |
212 | struct GNUNET_TIME_Absolute expire, | ||
247 | struct DhtPutActivity *ma) | 213 | struct DhtPutActivity *ma) |
248 | { | 214 | { |
249 | struct GNUNET_GNSRECORD_Block *block; | 215 | struct GNUNET_GNSRECORD_Block *block; |
250 | struct GNUNET_HashCode query; | 216 | struct GNUNET_HashCode query; |
251 | struct GNUNET_TIME_Absolute expire; | ||
252 | size_t block_size; | 217 | size_t block_size; |
253 | struct GNUNET_DHT_PutHandle *ret; | 218 | struct GNUNET_DHT_PutHandle *ret; |
254 | 219 | ||
255 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | ||
256 | rd_public); | ||
257 | if (cache_keys) | 220 | if (cache_keys) |
258 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, | 221 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, |
259 | expire, | 222 | expire, |
@@ -301,7 +264,6 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
301 | return ret; | 264 | return ret; |
302 | } | 265 | } |
303 | 266 | ||
304 | |||
305 | /** | 267 | /** |
306 | * Process a record that was stored in the namestore | 268 | * Process a record that was stored in the namestore |
307 | * (invoked by the monitor). | 269 | * (invoked by the monitor). |
@@ -322,6 +284,8 @@ handle_monitor_event (void *cls, | |||
322 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | 284 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; |
323 | unsigned int rd_public_count; | 285 | unsigned int rd_public_count; |
324 | struct DhtPutActivity *ma; | 286 | struct DhtPutActivity *ma; |
287 | struct GNUNET_TIME_Absolute expire; | ||
288 | char *emsg; | ||
325 | 289 | ||
326 | (void) cls; | 290 | (void) cls; |
327 | GNUNET_STATISTICS_update (statistics, | 291 | GNUNET_STATISTICS_update (statistics, |
@@ -334,9 +298,21 @@ handle_monitor_event (void *cls, | |||
334 | label); | 298 | label); |
335 | /* filter out records that are not public, and convert to | 299 | /* filter out records that are not public, and convert to |
336 | absolute expiration time. */ | 300 | absolute expiration time. */ |
337 | rd_public_count = convert_records_for_export (rd, | 301 | if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label, |
338 | rd_count, | 302 | rd, |
339 | rd_public); | 303 | rd_count, |
304 | rd_public, | ||
305 | &rd_public_count, | ||
306 | &expire, | ||
307 | &emsg)) | ||
308 | { | ||
309 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
310 | "Zonemaster-monitor failed: %s\n", emsg); | ||
311 | GNUNET_free (emsg); | ||
312 | GNUNET_NAMESTORE_zone_monitor_next (zmon, | ||
313 | 1); | ||
314 | return; /* nothing to do */ | ||
315 | } | ||
340 | if (0 == rd_public_count) | 316 | if (0 == rd_public_count) |
341 | { | 317 | { |
342 | GNUNET_NAMESTORE_zone_monitor_next (zmon, | 318 | GNUNET_NAMESTORE_zone_monitor_next (zmon, |
@@ -347,8 +323,9 @@ handle_monitor_event (void *cls, | |||
347 | ma->start_date = GNUNET_TIME_absolute_get (); | 323 | ma->start_date = GNUNET_TIME_absolute_get (); |
348 | ma->ph = perform_dht_put (zone, | 324 | ma->ph = perform_dht_put (zone, |
349 | label, | 325 | label, |
350 | rd, | 326 | rd_public, |
351 | rd_count, | 327 | rd_public_count, |
328 | expire, | ||
352 | ma); | 329 | ma); |
353 | if (NULL == ma->ph) | 330 | if (NULL == ma->ph) |
354 | { | 331 | { |
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c index bacafb97c..c6b86bf71 100644 --- a/src/zonemaster/gnunet-service-zonemaster.c +++ b/src/zonemaster/gnunet-service-zonemaster.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "gnunet_namestore_service.h" | 30 | #include "gnunet_namestore_service.h" |
31 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
32 | 32 | ||
33 | |||
34 | #define LOG_STRERROR_FILE(kind, syscall, \ | 33 | #define LOG_STRERROR_FILE(kind, syscall, \ |
35 | filename) GNUNET_log_from_strerror_file (kind, "util", \ | 34 | filename) GNUNET_log_from_strerror_file (kind, "util", \ |
36 | syscall, \ | 35 | syscall, \ |
@@ -90,7 +89,6 @@ | |||
90 | */ | 89 | */ |
91 | #define DHT_GNS_REPLICATION_LEVEL 5 | 90 | #define DHT_GNS_REPLICATION_LEVEL 5 |
92 | 91 | ||
93 | |||
94 | /** | 92 | /** |
95 | * Handle for DHT PUT activity triggered from the namestore monitor. | 93 | * Handle for DHT PUT activity triggered from the namestore monitor. |
96 | */ | 94 | */ |
@@ -527,46 +525,6 @@ dht_put_continuation (void *cls) | |||
527 | } | 525 | } |
528 | 526 | ||
529 | 527 | ||
530 | /** | ||
531 | * Convert namestore records from the internal format to that | ||
532 | * suitable for publication (removes private records, converts | ||
533 | * to absolute expiration time). | ||
534 | * | ||
535 | * @param rd input records | ||
536 | * @param rd_count size of the @a rd and @a rd_public arrays | ||
537 | * @param rd_public where to write the converted records | ||
538 | * @return number of records written to @a rd_public | ||
539 | */ | ||
540 | static unsigned int | ||
541 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | ||
542 | unsigned int rd_count, | ||
543 | struct GNUNET_GNSRECORD_Data *rd_public) | ||
544 | { | ||
545 | struct GNUNET_TIME_Absolute now; | ||
546 | unsigned int rd_public_count; | ||
547 | |||
548 | rd_public_count = 0; | ||
549 | now = GNUNET_TIME_absolute_get (); | ||
550 | for (unsigned int i = 0; i < rd_count; i++) | ||
551 | { | ||
552 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) | ||
553 | continue; | ||
554 | if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && | ||
555 | (rd[i].expiration_time < now.abs_value_us)) | ||
556 | continue; /* record already expired, skip it */ | ||
557 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
558 | { | ||
559 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
560 | we just need to adjust our iteration frequency */ | ||
561 | min_relative_record_time.rel_value_us = | ||
562 | GNUNET_MIN (rd[i].expiration_time, | ||
563 | min_relative_record_time.rel_value_us); | ||
564 | } | ||
565 | rd_public[rd_public_count++] = rd[i]; | ||
566 | } | ||
567 | return rd_public_count; | ||
568 | } | ||
569 | |||
570 | 528 | ||
571 | /** | 529 | /** |
572 | * Store GNS records in the DHT. | 530 | * Store GNS records in the DHT. |
@@ -583,30 +541,28 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
583 | const char *label, | 541 | const char *label, |
584 | const struct GNUNET_GNSRECORD_Data *rd_public, | 542 | const struct GNUNET_GNSRECORD_Data *rd_public, |
585 | unsigned int rd_public_count, | 543 | unsigned int rd_public_count, |
544 | const struct GNUNET_TIME_Absolute expire, | ||
586 | struct DhtPutActivity *ma) | 545 | struct DhtPutActivity *ma) |
587 | { | 546 | { |
588 | struct GNUNET_GNSRECORD_Block *block; | 547 | struct GNUNET_GNSRECORD_Block *block; |
589 | struct GNUNET_HashCode query; | 548 | struct GNUNET_HashCode query; |
590 | struct GNUNET_TIME_Absolute expire; | ||
591 | size_t block_size; | 549 | size_t block_size; |
592 | struct GNUNET_DHT_PutHandle *ret; | 550 | struct GNUNET_DHT_PutHandle *ret; |
593 | 551 | ||
594 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | ||
595 | rd_public); | ||
596 | if (cache_keys) | 552 | if (cache_keys) |
597 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, | 553 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, |
598 | expire, | 554 | expire, |
599 | label, | 555 | label, |
600 | rd_public, | 556 | rd_public, |
601 | rd_public_count, | 557 | rd_public_count, |
602 | &block)); | 558 | &block)); |
603 | else | 559 | else |
604 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, | 560 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, |
605 | expire, | 561 | expire, |
606 | label, | 562 | label, |
607 | rd_public, | 563 | rd_public, |
608 | rd_public_count, | 564 | rd_public_count, |
609 | &block)); | 565 | &block)); |
610 | if (NULL == block) | 566 | if (NULL == block) |
611 | { | 567 | { |
612 | GNUNET_break (0); | 568 | GNUNET_break (0); |
@@ -713,7 +669,6 @@ zone_iteration_finished (void *cls) | |||
713 | } | 669 | } |
714 | } | 670 | } |
715 | 671 | ||
716 | |||
717 | /** | 672 | /** |
718 | * Function used to put all records successively into the DHT. | 673 | * Function used to put all records successively into the DHT. |
719 | * | 674 | * |
@@ -733,12 +688,26 @@ put_gns_record (void *cls, | |||
733 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | 688 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; |
734 | unsigned int rd_public_count; | 689 | unsigned int rd_public_count; |
735 | struct DhtPutActivity *ma; | 690 | struct DhtPutActivity *ma; |
691 | struct GNUNET_TIME_Absolute expire; | ||
692 | char *emsg; | ||
736 | 693 | ||
737 | (void) cls; | 694 | (void) cls; |
738 | ns_iteration_left--; | 695 | ns_iteration_left--; |
739 | rd_public_count = convert_records_for_export (rd, | 696 | if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label, |
740 | rd_count, | 697 | rd, |
741 | rd_public); | 698 | rd_count, |
699 | rd_public, | ||
700 | &rd_public_count, | ||
701 | &expire, | ||
702 | &emsg)) | ||
703 | { | ||
704 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
705 | "Record set inconsistent, moving to next record set: %s\n", | ||
706 | emsg); | ||
707 | GNUNET_free (emsg); | ||
708 | check_zone_namestore_next (); | ||
709 | return; | ||
710 | } | ||
742 | if (0 == rd_public_count) | 711 | if (0 == rd_public_count) |
743 | { | 712 | { |
744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 713 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -746,15 +715,30 @@ put_gns_record (void *cls, | |||
746 | check_zone_namestore_next (); | 715 | check_zone_namestore_next (); |
747 | return; | 716 | return; |
748 | } | 717 | } |
718 | for (unsigned int i = 0; i < rd_public_count; i++) | ||
719 | { | ||
720 | if (0 != (rd_public[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
721 | { | ||
722 | /* GNUNET_GNSRECORD_block_create will convert to absolute time; | ||
723 | we just need to adjust our iteration frequency */ | ||
724 | min_relative_record_time.rel_value_us = | ||
725 | GNUNET_MIN (rd_public[i].expiration_time, | ||
726 | min_relative_record_time.rel_value_us); | ||
727 | } | ||
728 | } | ||
729 | |||
730 | |||
749 | /* We got a set of records to publish */ | 731 | /* We got a set of records to publish */ |
750 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 732 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
751 | "Starting DHT PUT\n"); | 733 | "Starting DHT PUT\n"); |
734 | |||
752 | ma = GNUNET_new (struct DhtPutActivity); | 735 | ma = GNUNET_new (struct DhtPutActivity); |
753 | ma->start_date = GNUNET_TIME_absolute_get (); | 736 | ma->start_date = GNUNET_TIME_absolute_get (); |
754 | ma->ph = perform_dht_put (key, | 737 | ma->ph = perform_dht_put (key, |
755 | label, | 738 | label, |
756 | rd_public, | 739 | rd_public, |
757 | rd_public_count, | 740 | rd_public_count, |
741 | expire, | ||
758 | ma); | 742 | ma); |
759 | put_cnt++; | 743 | put_cnt++; |
760 | if (0 == put_cnt % DELTA_INTERVAL) | 744 | if (0 == put_cnt % DELTA_INTERVAL) |
@@ -788,7 +772,6 @@ put_gns_record (void *cls, | |||
788 | } | 772 | } |
789 | } | 773 | } |
790 | 774 | ||
791 | |||
792 | /** | 775 | /** |
793 | * Periodically iterate over all zones and store everything in DHT | 776 | * Periodically iterate over all zones and store everything in DHT |
794 | * | 777 | * |