diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-09-26 21:24:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-09-26 21:24:03 +0000 |
commit | 7b00dd51218edbd9182caa664cfce185edc2cc45 (patch) | |
tree | 2cea8a9d7085aa6e3d16256f18f7c77f3320bb75 /src/dht | |
parent | 60ff113fe4e7bb71d5696063b9a9b81eba60a108 (diff) | |
download | gnunet-7b00dd51218edbd9182caa664cfce185edc2cc45.tar.gz gnunet-7b00dd51218edbd9182caa664cfce185edc2cc45.zip |
porting xdht to new service API, major code de-duplication effort
Diffstat (limited to 'src/dht')
28 files changed, 642 insertions, 3334 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index f7dc5df6d..10aeae175 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -82,10 +82,9 @@ gnunet_service_dht_LDADD = \ | |||
82 | -lm | 82 | -lm |
83 | 83 | ||
84 | gnunet_service_dht_xvine_SOURCES = \ | 84 | gnunet_service_dht_xvine_SOURCES = \ |
85 | gnunet-service-xdht.c gnunet-service-xdht.h \ | 85 | gnunet-service-xdht.c gnunet-service-dht.h \ |
86 | gnunet-service-xdht_clients.c gnunet-service-xdht_clients.h \ | 86 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ |
87 | gnunet-service-xdht_datacache.c gnunet-service-xdht_datacache.h \ | 87 | gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ |
88 | gnunet-service-xdht_nse.c gnunet-service-xdht_nse.h \ | ||
89 | gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \ | 88 | gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \ |
90 | gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h | 89 | gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h |
91 | 90 | ||
@@ -105,8 +104,8 @@ gnunet_service_dht_xvine_LDADD = \ | |||
105 | gnunet_service_dht_whanau_SOURCES = \ | 104 | gnunet_service_dht_whanau_SOURCES = \ |
106 | gnunet-service-wdht.c gnunet-service-wdht.h \ | 105 | gnunet-service-wdht.c gnunet-service-wdht.h \ |
107 | gnunet-service-wdht_clients.c gnunet-service-wdht_clients.h \ | 106 | gnunet-service-wdht_clients.c gnunet-service-wdht_clients.h \ |
108 | gnunet-service-wdht_datacache.c gnunet-service-wdht_datacache.h \ | 107 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ |
109 | gnunet-service-wdht_nse.c gnunet-service-wdht_nse.h \ | 108 | gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ |
110 | gnunet-service-wdht_neighbours.c gnunet-service-wdht_neighbours.h | 109 | gnunet-service-wdht_neighbours.c gnunet-service-wdht_neighbours.h |
111 | gnunet_service_dht_whanau_LDADD = \ | 110 | gnunet_service_dht_whanau_LDADD = \ |
112 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 111 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index a2ba2e8b0..f2b922dc4 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c | |||
@@ -39,27 +39,6 @@ | |||
39 | #include "gnunet-service-dht_nse.h" | 39 | #include "gnunet-service-dht_nse.h" |
40 | #include "gnunet-service-dht_routing.h" | 40 | #include "gnunet-service-dht_routing.h" |
41 | 41 | ||
42 | |||
43 | /** | ||
44 | * Handle for the statistics service. | ||
45 | */ | ||
46 | struct GNUNET_STATISTICS_Handle *GDS_stats; | ||
47 | |||
48 | /** | ||
49 | * Handle for the service. | ||
50 | */ | ||
51 | struct GNUNET_SERVICE_Handle *GDS_service; | ||
52 | |||
53 | /** | ||
54 | * Our handle to the BLOCK library. | ||
55 | */ | ||
56 | struct GNUNET_BLOCK_Context *GDS_block_context; | ||
57 | |||
58 | /** | ||
59 | * The configuration the DHT service is running with | ||
60 | */ | ||
61 | const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | ||
62 | |||
63 | /** | 42 | /** |
64 | * Our HELLO | 43 | * Our HELLO |
65 | */ | 44 | */ |
@@ -180,7 +159,7 @@ run (void *cls, | |||
180 | 159 | ||
181 | 160 | ||
182 | /* Finally, define the main method */ | 161 | /* Finally, define the main method */ |
183 | GDS_DHT_SERVICE_INIT(&run); | 162 | GDS_DHT_SERVICE_INIT("dht", &run); |
184 | 163 | ||
185 | 164 | ||
186 | 165 | ||
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index bc7a48b5a..493c3b961 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h | |||
@@ -82,7 +82,8 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | |||
82 | const struct GNUNET_PeerIdentity *get_path, | 82 | const struct GNUNET_PeerIdentity *get_path, |
83 | unsigned int put_path_length, | 83 | unsigned int put_path_length, |
84 | const struct GNUNET_PeerIdentity *put_path, | 84 | const struct GNUNET_PeerIdentity *put_path, |
85 | enum GNUNET_BLOCK_Type type, size_t data_size, | 85 | enum GNUNET_BLOCK_Type type, |
86 | size_t data_size, | ||
86 | const void *data); | 87 | const void *data); |
87 | 88 | ||
88 | 89 | ||
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index 0e344b566..df56c010a 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -213,6 +213,25 @@ struct ClientHandle | |||
213 | 213 | ||
214 | }; | 214 | }; |
215 | 215 | ||
216 | /** | ||
217 | * Our handle to the BLOCK library. | ||
218 | */ | ||
219 | struct GNUNET_BLOCK_Context *GDS_block_context; | ||
220 | |||
221 | /** | ||
222 | * Handle for the statistics service. | ||
223 | */ | ||
224 | struct GNUNET_STATISTICS_Handle *GDS_stats; | ||
225 | |||
226 | /** | ||
227 | * Handle for the service. | ||
228 | */ | ||
229 | struct GNUNET_SERVICE_Handle *GDS_service; | ||
230 | |||
231 | /** | ||
232 | * The configuration the DHT service is running with | ||
233 | */ | ||
234 | const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | ||
216 | 235 | ||
217 | /** | 236 | /** |
218 | * List of active monitoring requests. | 237 | * List of active monitoring requests. |
@@ -496,7 +515,7 @@ handle_dht_local_put (void *cls, | |||
496 | ntohl (dht_msg->options), | 515 | ntohl (dht_msg->options), |
497 | ntohl (dht_msg->desired_replication_level), | 516 | ntohl (dht_msg->desired_replication_level), |
498 | GNUNET_TIME_absolute_ntoh (dht_msg->expiration), | 517 | GNUNET_TIME_absolute_ntoh (dht_msg->expiration), |
499 | 0 /* hop count */ , | 518 | 0 /* hop count */, |
500 | peer_bf, | 519 | peer_bf, |
501 | &dht_msg->key, | 520 | &dht_msg->key, |
502 | 0, | 521 | 0, |
@@ -541,6 +560,43 @@ check_dht_local_get (void *cls, | |||
541 | 560 | ||
542 | 561 | ||
543 | /** | 562 | /** |
563 | * Handle a result from local datacache for a GET operation. | ||
564 | * | ||
565 | * @param cls the `struct ClientHandle` of the client doing the query | ||
566 | * @param type type of the block | ||
567 | * @param expiration_time when does the content expire | ||
568 | * @param key key for the content | ||
569 | * @param put_path_length number of entries in @a put_path | ||
570 | * @param put_path peers the original PUT traversed (if tracked) | ||
571 | * @param get_path_length number of entries in @a get_path | ||
572 | * @param get_path peers this reply has traversed so far (if tracked) | ||
573 | * @param data payload of the reply | ||
574 | * @param data_size number of bytes in @a data | ||
575 | */ | ||
576 | static void | ||
577 | handle_local_result (void *cls, | ||
578 | enum GNUNET_BLOCK_Type type, | ||
579 | struct GNUNET_TIME_Absolute expiration_time, | ||
580 | const struct GNUNET_HashCode *key, | ||
581 | unsigned int put_path_length, | ||
582 | const struct GNUNET_PeerIdentity *put_path, | ||
583 | unsigned int get_path_length, | ||
584 | const struct GNUNET_PeerIdentity *get_path, | ||
585 | const void *data, | ||
586 | size_t data_size) | ||
587 | { | ||
588 | // FIXME: this needs some clean up: inline the function, | ||
589 | // possibly avoid even looking up the client! | ||
590 | GDS_CLIENTS_handle_reply (expiration_time, | ||
591 | key, | ||
592 | 0, NULL, | ||
593 | put_path_length, put_path, | ||
594 | type, | ||
595 | data_size, data); | ||
596 | } | ||
597 | |||
598 | |||
599 | /** | ||
544 | * Handler for DHT GET messages from the client. | 600 | * Handler for DHT GET messages from the client. |
545 | * | 601 | * |
546 | * @param cls the client we received this message from | 602 | * @param cls the client we received this message from |
@@ -611,7 +667,9 @@ handle_dht_local_get (void *cls, | |||
611 | cqr->xquery, | 667 | cqr->xquery, |
612 | xquery_size, | 668 | xquery_size, |
613 | NULL, | 669 | NULL, |
614 | 0); | 670 | 0, |
671 | &handle_local_result, | ||
672 | ch); | ||
615 | GNUNET_SERVICE_client_continue (ch->client); | 673 | GNUNET_SERVICE_client_continue (ch->client); |
616 | } | 674 | } |
617 | 675 | ||
@@ -1413,11 +1471,12 @@ GDS_CLIENTS_stop () | |||
1413 | /** | 1471 | /** |
1414 | * Define "main" method using service macro. | 1472 | * Define "main" method using service macro. |
1415 | * | 1473 | * |
1474 | * @param name name of the service, i.e. "dht" or "xdht" | ||
1416 | * @param run name of the initializaton method for the service | 1475 | * @param run name of the initializaton method for the service |
1417 | */ | 1476 | */ |
1418 | #define GDS_DHT_SERVICE_INIT(run) \ | 1477 | #define GDS_DHT_SERVICE_INIT(name,run) \ |
1419 | GNUNET_SERVICE_MAIN \ | 1478 | GNUNET_SERVICE_MAIN \ |
1420 | ("dht", \ | 1479 | (name, \ |
1421 | GNUNET_SERVICE_OPTION_NONE, \ | 1480 | GNUNET_SERVICE_OPTION_NONE, \ |
1422 | run, \ | 1481 | run, \ |
1423 | &client_connect_cb, \ | 1482 | &client_connect_cb, \ |
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 12c79764d..9b4dace67 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c | |||
@@ -31,6 +31,11 @@ | |||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-dhtcache",__VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-dhtcache",__VA_ARGS__) |
33 | 33 | ||
34 | /** | ||
35 | * How many "closest" results to we return for migration when | ||
36 | * asked (at most)? | ||
37 | */ | ||
38 | #define NUM_CLOSEST 42 | ||
34 | 39 | ||
35 | /** | 40 | /** |
36 | * Handle to the datacache service (for inserting/retrieving data) | 41 | * Handle to the datacache service (for inserting/retrieving data) |
@@ -127,6 +132,17 @@ struct GetRequestContext | |||
127 | * Return value to give back. | 132 | * Return value to give back. |
128 | */ | 133 | */ |
129 | enum GNUNET_BLOCK_EvaluationResult eval; | 134 | enum GNUNET_BLOCK_EvaluationResult eval; |
135 | |||
136 | /** | ||
137 | * Function to call on results. | ||
138 | */ | ||
139 | GDS_DATACACHE_GetCallback gc; | ||
140 | |||
141 | /** | ||
142 | * Closure for @e gc. | ||
143 | */ | ||
144 | void *gc_cls; | ||
145 | |||
130 | }; | 146 | }; |
131 | 147 | ||
132 | 148 | ||
@@ -136,7 +152,7 @@ struct GetRequestContext | |||
136 | * @param cls closure for iterator, a `struct GetRequestContext` | 152 | * @param cls closure for iterator, a `struct GetRequestContext` |
137 | * @param exp when does this value expire? | 153 | * @param exp when does this value expire? |
138 | * @param key the key this data is stored under | 154 | * @param key the key this data is stored under |
139 | * @param size the size of the data identified by key | 155 | * @param data_size the size of the data identified by key |
140 | * @param data the actual data | 156 | * @param data the actual data |
141 | * @param type the type of the @a data | 157 | * @param type the type of the @a data |
142 | * @param put_path_length number of peers in @a put_path | 158 | * @param put_path_length number of peers in @a put_path |
@@ -147,7 +163,7 @@ struct GetRequestContext | |||
147 | static int | 163 | static int |
148 | datacache_get_iterator (void *cls, | 164 | datacache_get_iterator (void *cls, |
149 | const struct GNUNET_HashCode *key, | 165 | const struct GNUNET_HashCode *key, |
150 | size_t size, | 166 | size_t data_size, |
151 | const char *data, | 167 | const char *data, |
152 | enum GNUNET_BLOCK_Type type, | 168 | enum GNUNET_BLOCK_Type type, |
153 | struct GNUNET_TIME_Absolute exp, | 169 | struct GNUNET_TIME_Absolute exp, |
@@ -157,8 +173,8 @@ datacache_get_iterator (void *cls, | |||
157 | struct GetRequestContext *ctx = cls; | 173 | struct GetRequestContext *ctx = cls; |
158 | enum GNUNET_BLOCK_EvaluationResult eval; | 174 | enum GNUNET_BLOCK_EvaluationResult eval; |
159 | 175 | ||
160 | eval = | 176 | eval |
161 | GNUNET_BLOCK_evaluate (GDS_block_context, | 177 | = GNUNET_BLOCK_evaluate (GDS_block_context, |
162 | type, | 178 | type, |
163 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | 179 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, |
164 | key, | 180 | key, |
@@ -167,7 +183,7 @@ datacache_get_iterator (void *cls, | |||
167 | ctx->xquery, | 183 | ctx->xquery, |
168 | ctx->xquery_size, | 184 | ctx->xquery_size, |
169 | data, | 185 | data, |
170 | size); | 186 | data_size); |
171 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 187 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
172 | "Found reply for query %s in datacache, evaluation result is %d\n", | 188 | "Found reply for query %s in datacache, evaluation result is %d\n", |
173 | GNUNET_h2s (key), | 189 | GNUNET_h2s (key), |
@@ -182,18 +198,13 @@ datacache_get_iterator (void *cls, | |||
182 | gettext_noop | 198 | gettext_noop |
183 | ("# Good RESULTS found in datacache"), 1, | 199 | ("# Good RESULTS found in datacache"), 1, |
184 | GNUNET_NO); | 200 | GNUNET_NO); |
185 | GDS_CLIENTS_handle_reply (exp, key, | 201 | ctx->gc (ctx->gc_cls, |
186 | 0, NULL, | 202 | type, |
187 | put_path_length, put_path, | 203 | exp, |
188 | type, | 204 | key, |
189 | size, data); | 205 | put_path_length, put_path, |
190 | /* forward to other peers */ | 206 | 0, NULL, |
191 | GDS_ROUTING_process (type, | 207 | data, data_size); |
192 | exp, | ||
193 | key, | ||
194 | put_path_length, put_path, | ||
195 | 0, NULL, | ||
196 | data, size); | ||
197 | break; | 208 | break; |
198 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | 209 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: |
199 | GNUNET_STATISTICS_update (GDS_stats, | 210 | GNUNET_STATISTICS_update (GDS_stats, |
@@ -242,6 +253,8 @@ datacache_get_iterator (void *cls, | |||
242 | * @param xquery_size number of bytes in @a xquery | 253 | * @param xquery_size number of bytes in @a xquery |
243 | * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL | 254 | * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL |
244 | * @param reply_bf_mutator mutation value for @a reply_bf | 255 | * @param reply_bf_mutator mutation value for @a reply_bf |
256 | * @param gc function to call on the results | ||
257 | * @param gc_cls closure for @a gc | ||
245 | * @return evaluation result for the local replies | 258 | * @return evaluation result for the local replies |
246 | */ | 259 | */ |
247 | enum GNUNET_BLOCK_EvaluationResult | 260 | enum GNUNET_BLOCK_EvaluationResult |
@@ -250,7 +263,9 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
250 | const void *xquery, | 263 | const void *xquery, |
251 | size_t xquery_size, | 264 | size_t xquery_size, |
252 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | 265 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, |
253 | uint32_t reply_bf_mutator) | 266 | uint32_t reply_bf_mutator, |
267 | GDS_DATACACHE_GetCallback gc, | ||
268 | void *gc_cls) | ||
254 | { | 269 | { |
255 | struct GetRequestContext ctx; | 270 | struct GetRequestContext ctx; |
256 | unsigned int r; | 271 | unsigned int r; |
@@ -267,6 +282,8 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
267 | ctx.xquery_size = xquery_size; | 282 | ctx.xquery_size = xquery_size; |
268 | ctx.reply_bf = reply_bf; | 283 | ctx.reply_bf = reply_bf; |
269 | ctx.reply_bf_mutator = reply_bf_mutator; | 284 | ctx.reply_bf_mutator = reply_bf_mutator; |
285 | ctx.gc = gc; | ||
286 | ctx.gc_cls = gc_cls; | ||
270 | r = GNUNET_DATACACHE_get (datacache, | 287 | r = GNUNET_DATACACHE_get (datacache, |
271 | key, | 288 | key, |
272 | type, | 289 | type, |
@@ -282,6 +299,146 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | |||
282 | 299 | ||
283 | 300 | ||
284 | /** | 301 | /** |
302 | * Function called with a random element from the datacache. | ||
303 | * Stores the key in the closure. | ||
304 | * | ||
305 | * @param cls a `struct GNUNET_HashCode *`, where to store the @a key | ||
306 | * @param key key for the content | ||
307 | * @param data_size number of bytes in @a data | ||
308 | * @param data content stored | ||
309 | * @param type type of the content | ||
310 | * @param exp when will the content expire? | ||
311 | * @param path_info_len number of entries in @a path_info | ||
312 | * @param path_info a path through the network | ||
313 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort | ||
314 | */ | ||
315 | static int | ||
316 | datacache_random_iterator (void *cls, | ||
317 | const struct GNUNET_HashCode *key, | ||
318 | size_t data_size, | ||
319 | const char *data, | ||
320 | enum GNUNET_BLOCK_Type type, | ||
321 | struct GNUNET_TIME_Absolute exp, | ||
322 | unsigned int path_info_len, | ||
323 | const struct GNUNET_PeerIdentity *path_info) | ||
324 | { | ||
325 | struct GNUNET_HashCode *dest = cls; | ||
326 | |||
327 | *dest = *key; | ||
328 | return GNUNET_OK; /* should actually not matter which we return */ | ||
329 | } | ||
330 | |||
331 | |||
332 | /** | ||
333 | * Obtain a random key from the datacache. | ||
334 | * Used by Whanau for load-balancing. | ||
335 | * | ||
336 | * @param[out] key where to store the key of a random element, | ||
337 | * randomized by PRNG if datacache is empty | ||
338 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
339 | */ | ||
340 | int | ||
341 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) | ||
342 | { | ||
343 | if (0 == | ||
344 | GNUNET_DATACACHE_get_random (datacache, | ||
345 | &datacache_random_iterator, | ||
346 | key)) | ||
347 | { | ||
348 | /* randomize key in this case */ | ||
349 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
350 | key); | ||
351 | return GNUNET_SYSERR; | ||
352 | } | ||
353 | return GNUNET_OK; | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
358 | * Closure for #datacache_get_successors_iterator(). | ||
359 | */ | ||
360 | struct SuccContext | ||
361 | { | ||
362 | /** | ||
363 | * Function to call on the result | ||
364 | */ | ||
365 | GDS_DATACACHE_SuccessorCallback cb; | ||
366 | |||
367 | /** | ||
368 | * Closure for @e cb. | ||
369 | */ | ||
370 | void *cb_cls; | ||
371 | }; | ||
372 | |||
373 | |||
374 | /** | ||
375 | * Iterator for local get request results, | ||
376 | * | ||
377 | * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID | ||
378 | * @param key the key this data is stored under | ||
379 | * @param size the size of the data identified by key | ||
380 | * @param data the actual data | ||
381 | * @param type the type of the data | ||
382 | * @param exp when does this value expire? | ||
383 | * @param put_path_length number of peers in @a put_path | ||
384 | * @param put_path path the reply took on put | ||
385 | * @return #GNUNET_OK to continue iteration, anything else | ||
386 | * to stop iteration. | ||
387 | */ | ||
388 | static int | ||
389 | datacache_get_successors_iterator (void *cls, | ||
390 | const struct GNUNET_HashCode *key, | ||
391 | size_t size, | ||
392 | const char *data, | ||
393 | enum GNUNET_BLOCK_Type type, | ||
394 | struct GNUNET_TIME_Absolute exp, | ||
395 | unsigned int put_path_length, | ||
396 | const struct GNUNET_PeerIdentity *put_path) | ||
397 | { | ||
398 | const struct SuccContext *sc = cls; | ||
399 | |||
400 | /* NOTE: The datacache currently does not store the RO from | ||
401 | the original 'put', so we don't know the 'correct' option | ||
402 | at this point anymore. Thus, we conservatively assume | ||
403 | that recording is desired (for now). */ | ||
404 | sc->cb (sc->cb_cls, | ||
405 | GNUNET_DHT_RO_RECORD_ROUTE, | ||
406 | key, | ||
407 | type, | ||
408 | put_path_length, put_path, | ||
409 | exp, | ||
410 | data, | ||
411 | size); | ||
412 | return GNUNET_OK; | ||
413 | } | ||
414 | |||
415 | |||
416 | /** | ||
417 | * Handle a request for data close to a key that we have received from | ||
418 | * another peer. | ||
419 | * | ||
420 | * @param key the location at which the peer is looking for data that is close | ||
421 | * @param cb function to call with the result | ||
422 | * @param cb_cls closure for @a cb | ||
423 | */ | ||
424 | void | ||
425 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | ||
426 | GDS_DATACACHE_SuccessorCallback cb, | ||
427 | void *cb_cls) | ||
428 | { | ||
429 | struct SuccContext sc; | ||
430 | |||
431 | sc.cb = cb; | ||
432 | sc.cb_cls = cb_cls; | ||
433 | (void) GNUNET_DATACACHE_get_closest (datacache, | ||
434 | key, | ||
435 | NUM_CLOSEST, | ||
436 | &datacache_get_successors_iterator, | ||
437 | &sc); | ||
438 | } | ||
439 | |||
440 | |||
441 | /** | ||
285 | * Initialize datacache subsystem. | 442 | * Initialize datacache subsystem. |
286 | */ | 443 | */ |
287 | void | 444 | void |
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 66bfc3bbf..5069883c7 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
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 | 33 | ||
33 | /** | 34 | /** |
34 | * Handle a datum we've received from another peer. Cache if | 35 | * Handle a datum we've received from another peer. Cache if |
@@ -44,14 +45,42 @@ | |||
44 | */ | 45 | */ |
45 | void | 46 | void |
46 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | 47 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, |
47 | const struct GNUNET_HashCode * key, | 48 | const struct GNUNET_HashCode *key, |
48 | unsigned int put_path_length, | 49 | unsigned int put_path_length, |
49 | const struct GNUNET_PeerIdentity *put_path, | 50 | const struct GNUNET_PeerIdentity *put_path, |
50 | enum GNUNET_BLOCK_Type type, size_t data_size, | 51 | enum GNUNET_BLOCK_Type type, |
52 | size_t data_size, | ||
51 | const void *data); | 53 | const void *data); |
52 | 54 | ||
53 | 55 | ||
54 | /** | 56 | /** |
57 | * Handle a result for a GET operation. | ||
58 | * | ||
59 | * @param cls closure | ||
60 | * @param type type of the block | ||
61 | * @param expiration_time when does the content expire | ||
62 | * @param key key for the content | ||
63 | * @param put_path_length number of entries in @a put_path | ||
64 | * @param put_path peers the original PUT traversed (if tracked) | ||
65 | * @param get_path_length number of entries in @a get_path | ||
66 | * @param get_path peers this reply has traversed so far (if tracked) | ||
67 | * @param data payload of the reply | ||
68 | * @param data_size number of bytes in @a data | ||
69 | */ | ||
70 | typedef void | ||
71 | (*GDS_DATACACHE_GetCallback)(void *cls, | ||
72 | enum GNUNET_BLOCK_Type type, | ||
73 | struct GNUNET_TIME_Absolute expiration_time, | ||
74 | const struct GNUNET_HashCode *key, | ||
75 | unsigned int put_path_length, | ||
76 | const struct GNUNET_PeerIdentity *put_path, | ||
77 | unsigned int get_path_length, | ||
78 | const struct GNUNET_PeerIdentity *get_path, | ||
79 | const void *data, | ||
80 | size_t data_size); | ||
81 | |||
82 | |||
83 | /** | ||
55 | * Handle a GET request we've received from another peer. | 84 | * Handle a GET request we've received from another peer. |
56 | * | 85 | * |
57 | * @param key the query | 86 | * @param key the query |
@@ -60,14 +89,70 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | |||
60 | * @param xquery_size number of bytes in xquery | 89 | * @param xquery_size number of bytes in xquery |
61 | * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL | 90 | * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL |
62 | * @param reply_bf_mutator mutation value for reply_bf | 91 | * @param reply_bf_mutator mutation value for reply_bf |
92 | * @param gc function to call on the results | ||
93 | * @param gc_cls closure for @a gc | ||
63 | * @return evaluation result for the local replies | 94 | * @return evaluation result for the local replies |
64 | */ | 95 | */ |
65 | enum GNUNET_BLOCK_EvaluationResult | 96 | enum GNUNET_BLOCK_EvaluationResult |
66 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, | 97 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, |
67 | enum GNUNET_BLOCK_Type type, const void *xquery, | 98 | enum GNUNET_BLOCK_Type type, |
99 | const void *xquery, | ||
68 | size_t xquery_size, | 100 | size_t xquery_size, |
69 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | 101 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, |
70 | uint32_t reply_bf_mutator); | 102 | uint32_t reply_bf_mutator, |
103 | GDS_DATACACHE_GetCallback gc, | ||
104 | void *gc_cls); | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Obtain a random key from the datacache. | ||
109 | * Used by Whanau for load-balancing. | ||
110 | * | ||
111 | * @param[out] key where to store the key of a random element, | ||
112 | * randomized by PRNG if datacache is empty | ||
113 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
114 | */ | ||
115 | int | ||
116 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Send the get result to requesting client. | ||
121 | * | ||
122 | * @param cls closure | ||
123 | * @param options routing options (from GET request) | ||
124 | * @param key key of the requested data. | ||
125 | * @param type block type | ||
126 | * @param put_path_length number of peers in @a put_path | ||
127 | * @param put_path path taken to put the data at its stored location. | ||
128 | * @param expiration when will this result expire? | ||
129 | * @param data payload to store | ||
130 | * @param data_size size of the @a data | ||
131 | */ | ||
132 | typedef void | ||
133 | (*GDS_DATACACHE_SuccessorCallback)(void *cls, | ||
134 | enum GNUNET_DHT_RouteOption options, | ||
135 | const struct GNUNET_HashCode *key, | ||
136 | enum GNUNET_BLOCK_Type type, | ||
137 | unsigned int put_path_length, | ||
138 | const struct GNUNET_PeerIdentity *put_path, | ||
139 | struct GNUNET_TIME_Absolute expiration, | ||
140 | const void *data, | ||
141 | size_t data_size); | ||
142 | |||
143 | |||
144 | /** | ||
145 | * Handle a request for data close to a key that we have received from | ||
146 | * another peer. | ||
147 | * | ||
148 | * @param key the location at which the peer is looking for data that is close | ||
149 | * @param cb function to call with the result | ||
150 | * @param cb_cls closure for @a cb | ||
151 | */ | ||
152 | void | ||
153 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, | ||
154 | GDS_DATACACHE_SuccessorCallback cb, | ||
155 | void *cb_cls); | ||
71 | 156 | ||
72 | 157 | ||
73 | /** | 158 | /** |
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 39fb43495..574ed9ad0 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -1255,8 +1255,8 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1255 | gettext_noop ("# PUT requests routed"), | 1255 | gettext_noop ("# PUT requests routed"), |
1256 | 1, | 1256 | 1, |
1257 | GNUNET_NO); | 1257 | GNUNET_NO); |
1258 | target_count = | 1258 | target_count |
1259 | get_target_peers (key, | 1259 | = get_target_peers (key, |
1260 | bf, | 1260 | bf, |
1261 | hop_count, | 1261 | hop_count, |
1262 | desired_replication_level, | 1262 | desired_replication_level, |
@@ -1768,9 +1768,13 @@ handle_dht_p2p_put (void *cls, | |||
1768 | /* store locally */ | 1768 | /* store locally */ |
1769 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || | 1769 | if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || |
1770 | (am_closest_peer (&put->key, bf))) | 1770 | (am_closest_peer (&put->key, bf))) |
1771 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh | 1771 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time), |
1772 | (put->expiration_time), &put->key, putlen, pp, | 1772 | &put->key, |
1773 | ntohl (put->type), payload_size, payload); | 1773 | putlen, |
1774 | pp, | ||
1775 | ntohl (put->type), | ||
1776 | payload_size, | ||
1777 | payload); | ||
1774 | /* route to other peers */ | 1778 | /* route to other peers */ |
1775 | forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), | 1779 | forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), |
1776 | options, | 1780 | options, |
@@ -1913,6 +1917,44 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1913 | 1917 | ||
1914 | 1918 | ||
1915 | /** | 1919 | /** |
1920 | * Handle a result from local datacache for a GET operation. | ||
1921 | * | ||
1922 | * @param cls the `struct ClientHandle` of the client doing the query | ||
1923 | * @param type type of the block | ||
1924 | * @param expiration_time when does the content expire | ||
1925 | * @param key key for the content | ||
1926 | * @param put_path_length number of entries in @a put_path | ||
1927 | * @param put_path peers the original PUT traversed (if tracked) | ||
1928 | * @param get_path_length number of entries in @a get_path | ||
1929 | * @param get_path peers this reply has traversed so far (if tracked) | ||
1930 | * @param data payload of the reply | ||
1931 | * @param data_size number of bytes in @a data | ||
1932 | */ | ||
1933 | static void | ||
1934 | handle_local_result (void *cls, | ||
1935 | enum GNUNET_BLOCK_Type type, | ||
1936 | struct GNUNET_TIME_Absolute expiration_time, | ||
1937 | const struct GNUNET_HashCode *key, | ||
1938 | unsigned int put_path_length, | ||
1939 | const struct GNUNET_PeerIdentity *put_path, | ||
1940 | unsigned int get_path_length, | ||
1941 | const struct GNUNET_PeerIdentity *get_path, | ||
1942 | const void *data, | ||
1943 | size_t data_size) | ||
1944 | { | ||
1945 | // FIXME: we can probably do better here by | ||
1946 | // passing the peer that did the query in the closure... | ||
1947 | GDS_ROUTING_process (NULL, | ||
1948 | type, | ||
1949 | expiration_time, | ||
1950 | key, | ||
1951 | put_path_length, put_path, | ||
1952 | 0, NULL, | ||
1953 | data, data_size); | ||
1954 | } | ||
1955 | |||
1956 | |||
1957 | /** | ||
1916 | * Check validity of p2p get request. | 1958 | * Check validity of p2p get request. |
1917 | * | 1959 | * |
1918 | * @param cls closure with the `struct PeerInfo` of the sender | 1960 | * @param cls closure with the `struct PeerInfo` of the sender |
@@ -2067,7 +2109,9 @@ handle_dht_p2p_get (void *cls, | |||
2067 | xquery, | 2109 | xquery, |
2068 | xquery_size, | 2110 | xquery_size, |
2069 | &reply_bf, | 2111 | &reply_bf, |
2070 | get->bf_mutator); | 2112 | get->bf_mutator, |
2113 | &handle_local_result, | ||
2114 | NULL); | ||
2071 | } | 2115 | } |
2072 | } | 2116 | } |
2073 | else | 2117 | else |
@@ -2276,7 +2320,8 @@ handle_dht_p2p_result (void *cls, | |||
2276 | data); | 2320 | data); |
2277 | } | 2321 | } |
2278 | /* forward to other peers */ | 2322 | /* forward to other peers */ |
2279 | GDS_ROUTING_process (type, | 2323 | GDS_ROUTING_process (NULL, |
2324 | type, | ||
2280 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | 2325 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2281 | &prm->key, | 2326 | &prm->key, |
2282 | put_path_length, | 2327 | put_path_length, |
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 856f1faae..d89e5c54f 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h | |||
@@ -58,7 +58,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
58 | struct GNUNET_TIME_Absolute expiration_time, | 58 | struct GNUNET_TIME_Absolute expiration_time, |
59 | uint32_t hop_count, | 59 | uint32_t hop_count, |
60 | struct GNUNET_CONTAINER_BloomFilter *bf, | 60 | struct GNUNET_CONTAINER_BloomFilter *bf, |
61 | const struct GNUNET_HashCode * key, | 61 | const struct GNUNET_HashCode *key, |
62 | unsigned int put_path_length, | 62 | unsigned int put_path_length, |
63 | struct GNUNET_PeerIdentity *put_path, | 63 | struct GNUNET_PeerIdentity *put_path, |
64 | const void *data, size_t data_size); | 64 | const void *data, size_t data_size); |
@@ -125,7 +125,7 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, | |||
125 | /** | 125 | /** |
126 | * Initialize neighbours subsystem. | 126 | * Initialize neighbours subsystem. |
127 | * | 127 | * |
128 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 128 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
129 | */ | 129 | */ |
130 | int | 130 | int |
131 | GDS_NEIGHBOURS_init (void); | 131 | GDS_NEIGHBOURS_init (void); |
@@ -144,7 +144,7 @@ GDS_NEIGHBOURS_done (void); | |||
144 | * @return identity of the local node | 144 | * @return identity of the local node |
145 | */ | 145 | */ |
146 | struct GNUNET_PeerIdentity * | 146 | struct GNUNET_PeerIdentity * |
147 | GDS_NEIGHBOURS_get_id (); | 147 | GDS_NEIGHBOURS_get_id (void); |
148 | 148 | ||
149 | 149 | ||
150 | #endif | 150 | #endif |
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index d078c865d..48bece35e 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -277,13 +277,16 @@ process (void *cls, const struct GNUNET_HashCode * key, void *value) | |||
277 | * @param data_size number of bytes in data | 277 | * @param data_size number of bytes in data |
278 | */ | 278 | */ |
279 | void | 279 | void |
280 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 280 | GDS_ROUTING_process (void *cls, |
281 | enum GNUNET_BLOCK_Type type, | ||
281 | struct GNUNET_TIME_Absolute expiration_time, | 282 | struct GNUNET_TIME_Absolute expiration_time, |
282 | const struct GNUNET_HashCode * key, unsigned int put_path_length, | 283 | const struct GNUNET_HashCode *key, |
284 | unsigned int put_path_length, | ||
283 | const struct GNUNET_PeerIdentity *put_path, | 285 | const struct GNUNET_PeerIdentity *put_path, |
284 | unsigned int get_path_length, | 286 | unsigned int get_path_length, |
285 | const struct GNUNET_PeerIdentity *get_path, | 287 | const struct GNUNET_PeerIdentity *get_path, |
286 | const void *data, size_t data_size) | 288 | const void *data, |
289 | size_t data_size) | ||
287 | { | 290 | { |
288 | struct ProcessContext pc; | 291 | struct ProcessContext pc; |
289 | 292 | ||
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 1b163c25b..7c57361dc 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h | |||
@@ -38,6 +38,7 @@ | |||
38 | * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching | 38 | * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching |
39 | * request recently. | 39 | * request recently. |
40 | * | 40 | * |
41 | * @param cls closure | ||
41 | * @param type type of the block | 42 | * @param type type of the block |
42 | * @param expiration_time when does the content expire | 43 | * @param expiration_time when does the content expire |
43 | * @param key key for the content | 44 | * @param key key for the content |
@@ -49,13 +50,16 @@ | |||
49 | * @param data_size number of bytes in @a data | 50 | * @param data_size number of bytes in @a data |
50 | */ | 51 | */ |
51 | void | 52 | void |
52 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 53 | GDS_ROUTING_process (void *cls, |
54 | enum GNUNET_BLOCK_Type type, | ||
53 | struct GNUNET_TIME_Absolute expiration_time, | 55 | struct GNUNET_TIME_Absolute expiration_time, |
54 | const struct GNUNET_HashCode * key, unsigned int put_path_length, | 56 | const struct GNUNET_HashCode *key, |
57 | unsigned int put_path_length, | ||
55 | const struct GNUNET_PeerIdentity *put_path, | 58 | const struct GNUNET_PeerIdentity *put_path, |
56 | unsigned int get_path_length, | 59 | unsigned int get_path_length, |
57 | const struct GNUNET_PeerIdentity *get_path, | 60 | const struct GNUNET_PeerIdentity *get_path, |
58 | const void *data, size_t data_size); | 61 | const void *data, |
62 | size_t data_size); | ||
59 | 63 | ||
60 | 64 | ||
61 | /** | 65 | /** |
diff --git a/src/dht/gnunet-service-wdht.c b/src/dht/gnunet-service-wdht.c index b58bb729d..8be25ad5e 100644 --- a/src/dht/gnunet-service-wdht.c +++ b/src/dht/gnunet-service-wdht.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file dht/gnunet-service-xdht.c | 22 | * @file dht/gnunet-service-wdht.c |
23 | * @brief GNUnet DHT service | 23 | * @brief GNUnet DHT service |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
@@ -34,9 +34,9 @@ | |||
34 | #include "gnunet_statistics_service.h" | 34 | #include "gnunet_statistics_service.h" |
35 | #include "gnunet-service-wdht.h" | 35 | #include "gnunet-service-wdht.h" |
36 | #include "gnunet-service-wdht_clients.h" | 36 | #include "gnunet-service-wdht_clients.h" |
37 | #include "gnunet-service-wdht_datacache.h" | 37 | #include "gnunet-service-dht_datacache.h" |
38 | #include "gnunet-service-wdht_neighbours.h" | 38 | #include "gnunet-service-wdht_neighbours.h" |
39 | #include "gnunet-service-wdht_nse.h" | 39 | #include "gnunet-service-dht_nse.h" |
40 | 40 | ||
41 | 41 | ||
42 | 42 | ||
diff --git a/src/dht/gnunet-service-wdht_clients.c b/src/dht/gnunet-service-wdht_clients.c index 2abeea661..7ad0d2904 100644 --- a/src/dht/gnunet-service-wdht_clients.c +++ b/src/dht/gnunet-service-wdht_clients.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
32 | #include "gnunet-service-wdht.h" | 32 | #include "gnunet-service-wdht.h" |
33 | #include "gnunet-service-wdht_clients.h" | 33 | #include "gnunet-service-wdht_clients.h" |
34 | #include "gnunet-service-wdht_datacache.h" | 34 | #include "gnunet-service-dht_datacache.h" |
35 | #include "gnunet-service-wdht_neighbours.h" | 35 | #include "gnunet-service-wdht_neighbours.h" |
36 | #include "dht.h" | 36 | #include "dht.h" |
37 | 37 | ||
diff --git a/src/dht/gnunet-service-wdht_datacache.c b/src/dht/gnunet-service-wdht_datacache.c deleted file mode 100644 index 40d54bf5a..000000000 --- a/src/dht/gnunet-service-wdht_datacache.c +++ /dev/null | |||
@@ -1,459 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-wdht_datacache.c | ||
23 | * @brief GNUnet DHT service's datacache integration | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_datacache_lib.h" | ||
29 | #include "gnunet-service-wdht_clients.h" | ||
30 | #include "gnunet-service-wdht_datacache.h" | ||
31 | #include "gnunet-service-wdht_neighbours.h" | ||
32 | #include "gnunet-service-dht.h" | ||
33 | |||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__) | ||
35 | |||
36 | #define DEBUG(...) \ | ||
37 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
38 | |||
39 | /** | ||
40 | * How many "closest" results to we return for migration when | ||
41 | * asked (at most)? | ||
42 | */ | ||
43 | #define NUM_CLOSEST 42 | ||
44 | |||
45 | /** | ||
46 | * Handle to the datacache service (for inserting/retrieving data) | ||
47 | */ | ||
48 | static struct GNUNET_DATACACHE_Handle *datacache; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Handle a datum we've received from another peer. Cache if | ||
53 | * possible. | ||
54 | * | ||
55 | * @param expiration when will the reply expire | ||
56 | * @param key the query this reply is for | ||
57 | * @param put_path_length number of peers in @a put_path | ||
58 | * @param put_path path the reply took on put | ||
59 | * @param get_path_length number of peers in @a get_path | ||
60 | * @param get_path path the reply took on get | ||
61 | * @param type type of the reply | ||
62 | * @param data_size number of bytes in @a data | ||
63 | * @param data application payload data | ||
64 | */ | ||
65 | void | ||
66 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | ||
67 | const struct GNUNET_HashCode *key, | ||
68 | unsigned int put_path_length, | ||
69 | const struct GNUNET_PeerIdentity *put_path, | ||
70 | unsigned int get_path_length, | ||
71 | const struct GNUNET_PeerIdentity *get_path, | ||
72 | enum GNUNET_BLOCK_Type type, | ||
73 | size_t data_size, | ||
74 | const void *data) | ||
75 | { | ||
76 | int r; | ||
77 | struct GNUNET_PeerIdentity path[get_path_length + put_path_length]; | ||
78 | |||
79 | if (NULL == datacache) | ||
80 | { | ||
81 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
82 | _("PUT request received, but have no datacache!\n")); | ||
83 | return; | ||
84 | } | ||
85 | if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
86 | { | ||
87 | GNUNET_break (0); | ||
88 | return; | ||
89 | } | ||
90 | GNUNET_memcpy (path, | ||
91 | put_path, | ||
92 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
93 | GNUNET_memcpy (&path[put_path_length], | ||
94 | get_path, | ||
95 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
96 | /* Put size is actual data size plus struct overhead plus path length (if any) */ | ||
97 | r = GNUNET_DATACACHE_put (datacache, | ||
98 | key, | ||
99 | data_size, | ||
100 | data, | ||
101 | type, | ||
102 | expiration, | ||
103 | get_path_length + put_path_length, | ||
104 | path); | ||
105 | if (GNUNET_OK == r) | ||
106 | GNUNET_STATISTICS_update (GDS_stats, | ||
107 | gettext_noop ("# ITEMS stored in datacache"), 1, | ||
108 | GNUNET_NO); | ||
109 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
110 | "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", | ||
111 | GNUNET_h2s (key), | ||
112 | data_size, | ||
113 | r, | ||
114 | put_path_length + get_path_length); | ||
115 | } | ||
116 | |||
117 | |||
118 | /** | ||
119 | * Context containing information about a GET request. | ||
120 | */ | ||
121 | struct GetRequestContext | ||
122 | { | ||
123 | /** | ||
124 | * extended query (see gnunet_block_lib.h). | ||
125 | */ | ||
126 | const void *xquery; | ||
127 | |||
128 | /** | ||
129 | * Bloomfilter to filter out duplicate replies (updated) | ||
130 | */ | ||
131 | struct GNUNET_CONTAINER_BloomFilter **reply_bf; | ||
132 | |||
133 | /** | ||
134 | * The key this request was about | ||
135 | */ | ||
136 | struct GNUNET_HashCode key; | ||
137 | |||
138 | /** | ||
139 | * The trail this request was for | ||
140 | */ | ||
141 | const struct GNUNET_HashCode *trail_id; | ||
142 | |||
143 | /** | ||
144 | * Number of bytes in @e xquery. | ||
145 | */ | ||
146 | size_t xquery_size; | ||
147 | |||
148 | /** | ||
149 | * Mutator value for the @e reply_bf, see gnunet_block_lib.h | ||
150 | */ | ||
151 | uint32_t reply_bf_mutator; | ||
152 | |||
153 | /** | ||
154 | * Return value to give back. | ||
155 | */ | ||
156 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
157 | |||
158 | /** | ||
159 | * Routing options of the GET. | ||
160 | */ | ||
161 | enum GNUNET_DHT_RouteOption options; | ||
162 | |||
163 | }; | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Iterator for local get request results, | ||
168 | * | ||
169 | * @param cls closure for iterator, a `struct GetRequestContext` | ||
170 | * @param key the key this data is stored under | ||
171 | * @param size the size of the data identified by key | ||
172 | * @param data the actual data | ||
173 | * @param type the type of the data | ||
174 | * @param exp when does this value expire? | ||
175 | * @param put_path_length number of peers in @a put_path | ||
176 | * @param put_path path the reply took on put | ||
177 | * @return #GNUNET_OK to continue iteration, anything else | ||
178 | * to stop iteration. | ||
179 | */ | ||
180 | static int | ||
181 | datacache_get_iterator (void *cls, | ||
182 | const struct GNUNET_HashCode *key, | ||
183 | size_t size, | ||
184 | const char *data, | ||
185 | enum GNUNET_BLOCK_Type type, | ||
186 | struct GNUNET_TIME_Absolute exp, | ||
187 | unsigned int put_path_length, | ||
188 | const struct GNUNET_PeerIdentity *put_path) | ||
189 | { | ||
190 | struct GetRequestContext *ctx = cls; | ||
191 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
192 | |||
193 | eval = | ||
194 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
195 | type, | ||
196 | GNUNET_BLOCK_EO_NONE, | ||
197 | key, | ||
198 | ctx->reply_bf, | ||
199 | ctx->reply_bf_mutator, | ||
200 | ctx->xquery, | ||
201 | ctx->xquery_size, | ||
202 | data, | ||
203 | size); | ||
204 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
205 | "Found reply for query %s in datacache, evaluation result is %d\n", | ||
206 | GNUNET_h2s (key), (int) eval); | ||
207 | ctx->eval = eval; | ||
208 | |||
209 | switch (eval) | ||
210 | { | ||
211 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
212 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
213 | /* forward to local clients */ | ||
214 | GNUNET_STATISTICS_update (GDS_stats, | ||
215 | gettext_noop | ||
216 | ("# Good RESULTS found in datacache"), 1, | ||
217 | GNUNET_NO); | ||
218 | GDS_NEIGHBOURS_send_get_result (ctx->trail_id, | ||
219 | ctx->options, | ||
220 | key, | ||
221 | type, | ||
222 | put_path_length, | ||
223 | put_path, | ||
224 | exp, | ||
225 | data, | ||
226 | size); | ||
227 | break; | ||
228 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
229 | GNUNET_STATISTICS_update (GDS_stats, | ||
230 | gettext_noop | ||
231 | ("# Duplicate RESULTS found in datacache"), 1, | ||
232 | GNUNET_NO); | ||
233 | break; | ||
234 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
235 | GNUNET_STATISTICS_update (GDS_stats, | ||
236 | gettext_noop | ||
237 | ("# Invalid RESULTS found in datacache"), 1, | ||
238 | GNUNET_NO); | ||
239 | break; | ||
240 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
241 | GNUNET_STATISTICS_update (GDS_stats, | ||
242 | gettext_noop | ||
243 | ("# Irrelevant RESULTS found in datacache"), 1, | ||
244 | GNUNET_NO); | ||
245 | break; | ||
246 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
247 | GNUNET_break (0); | ||
248 | break; | ||
249 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
250 | GNUNET_break_op (0); | ||
251 | return GNUNET_SYSERR; | ||
252 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
253 | GNUNET_STATISTICS_update (GDS_stats, | ||
254 | gettext_noop | ||
255 | ("# Unsupported RESULTS found in datacache"), 1, | ||
256 | GNUNET_NO); | ||
257 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
258 | _("Unsupported block type (%u) in local response!\n"), type); | ||
259 | break; | ||
260 | } | ||
261 | |||
262 | return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; | ||
263 | } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * Handle a GET request we've received from another peer. | ||
268 | * | ||
269 | * @param trail_id trail identifying where to send the result to, NULL for us | ||
270 | * @param options routing options (to be passed along) | ||
271 | * @param key the query | ||
272 | * @param type requested data type | ||
273 | * @param xquery extended query | ||
274 | * @param xquery_size number of bytes in @a xquery | ||
275 | * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL | ||
276 | * @param reply_bf_mutator mutation value for @a reply_bf | ||
277 | * @return evaluation result for the local replies | ||
278 | */ | ||
279 | enum GNUNET_BLOCK_EvaluationResult | ||
280 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id, | ||
281 | enum GNUNET_DHT_RouteOption options, | ||
282 | const struct GNUNET_HashCode *key, | ||
283 | enum GNUNET_BLOCK_Type type, | ||
284 | const void *xquery, | ||
285 | size_t xquery_size, | ||
286 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | ||
287 | uint32_t reply_bf_mutator) | ||
288 | { | ||
289 | struct GetRequestContext ctx; | ||
290 | unsigned int r; | ||
291 | |||
292 | if (NULL == datacache) | ||
293 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
294 | GNUNET_STATISTICS_update (GDS_stats, | ||
295 | gettext_noop ("# GET requests given to datacache"), | ||
296 | 1, GNUNET_NO); | ||
297 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
298 | ctx.trail_id = trail_id; | ||
299 | ctx.options = options; | ||
300 | ctx.key = *key; | ||
301 | ctx.xquery = xquery; | ||
302 | ctx.xquery_size = xquery_size; | ||
303 | ctx.reply_bf = reply_bf; | ||
304 | ctx.reply_bf_mutator = reply_bf_mutator; | ||
305 | r = GNUNET_DATACACHE_get (datacache, | ||
306 | key, | ||
307 | type, | ||
308 | &datacache_get_iterator, | ||
309 | &ctx); | ||
310 | DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n", | ||
311 | GNUNET_h2s (key), | ||
312 | ctx.eval, | ||
313 | r); | ||
314 | return ctx.eval; | ||
315 | } | ||
316 | |||
317 | |||
318 | /** | ||
319 | * Function called with a random element from the datacache. | ||
320 | * Stores the key in the closure. | ||
321 | * | ||
322 | * @param cls a `struct GNUNET_HashCode *`, where to store the @a key | ||
323 | * @param key key for the content | ||
324 | * @param data_size number of bytes in @a data | ||
325 | * @param data content stored | ||
326 | * @param type type of the content | ||
327 | * @param exp when will the content expire? | ||
328 | * @param path_info_len number of entries in @a path_info | ||
329 | * @param path_info a path through the network | ||
330 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort | ||
331 | */ | ||
332 | static int | ||
333 | datacache_random_iterator (void *cls, | ||
334 | const struct GNUNET_HashCode *key, | ||
335 | size_t data_size, | ||
336 | const char *data, | ||
337 | enum GNUNET_BLOCK_Type type, | ||
338 | struct GNUNET_TIME_Absolute exp, | ||
339 | unsigned int path_info_len, | ||
340 | const struct GNUNET_PeerIdentity *path_info) | ||
341 | { | ||
342 | struct GNUNET_HashCode *dest = cls; | ||
343 | |||
344 | *dest = *key; | ||
345 | return GNUNET_OK; /* should actually not matter which we return */ | ||
346 | } | ||
347 | |||
348 | |||
349 | /** | ||
350 | * Obtain a random key from the datacache. | ||
351 | * Used by Whanau for load-balancing. | ||
352 | * | ||
353 | * @param[out] key where to store the key of a random element, | ||
354 | * randomized by PRNG if datacache is empty | ||
355 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
356 | */ | ||
357 | int | ||
358 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) | ||
359 | { | ||
360 | if (0 == | ||
361 | GNUNET_DATACACHE_get_random (datacache, | ||
362 | &datacache_random_iterator, | ||
363 | key)) | ||
364 | { | ||
365 | /* randomize key in this case */ | ||
366 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
367 | key); | ||
368 | return GNUNET_SYSERR; | ||
369 | } | ||
370 | return GNUNET_OK; | ||
371 | } | ||
372 | |||
373 | |||
374 | /** | ||
375 | * Iterator for local get request results, | ||
376 | * | ||
377 | * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID | ||
378 | * @param key the key this data is stored under | ||
379 | * @param size the size of the data identified by key | ||
380 | * @param data the actual data | ||
381 | * @param type the type of the data | ||
382 | * @param exp when does this value expire? | ||
383 | * @param put_path_length number of peers in @a put_path | ||
384 | * @param put_path path the reply took on put | ||
385 | * @return #GNUNET_OK to continue iteration, anything else | ||
386 | * to stop iteration. | ||
387 | */ | ||
388 | static int | ||
389 | datacache_get_successors_iterator (void *cls, | ||
390 | const struct GNUNET_HashCode *key, | ||
391 | size_t size, | ||
392 | const char *data, | ||
393 | enum GNUNET_BLOCK_Type type, | ||
394 | struct GNUNET_TIME_Absolute exp, | ||
395 | unsigned int put_path_length, | ||
396 | const struct GNUNET_PeerIdentity *put_path) | ||
397 | { | ||
398 | const struct GNUNET_HashCode *trail_id = cls; | ||
399 | |||
400 | /* NOTE: The datacache currently does not store the RO from | ||
401 | the original 'put', so we don't know the 'correct' option | ||
402 | at this point anymore. Thus, we conservatively assume | ||
403 | that recording is desired (for now). */ | ||
404 | GDS_NEIGHBOURS_send_get_result (trail_id, | ||
405 | GNUNET_DHT_RO_RECORD_ROUTE, | ||
406 | key, | ||
407 | type, | ||
408 | put_path_length, put_path, | ||
409 | exp, | ||
410 | data, | ||
411 | size); | ||
412 | return GNUNET_OK; | ||
413 | } | ||
414 | |||
415 | |||
416 | /** | ||
417 | * Handle a request for data close to a key that we have received from | ||
418 | * another peer. | ||
419 | * | ||
420 | * @param trail_id trail where the reply needs to be send to | ||
421 | * @param key the location at which the peer is looking for data that is close | ||
422 | */ | ||
423 | void | ||
424 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id, | ||
425 | const struct GNUNET_HashCode *key) | ||
426 | { | ||
427 | (void) GNUNET_DATACACHE_get_closest (datacache, | ||
428 | key, | ||
429 | NUM_CLOSEST, | ||
430 | &datacache_get_successors_iterator, | ||
431 | (void *) trail_id); | ||
432 | } | ||
433 | |||
434 | |||
435 | /** | ||
436 | * Initialize datacache subsystem. | ||
437 | */ | ||
438 | void | ||
439 | GDS_DATACACHE_init () | ||
440 | { | ||
441 | datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); | ||
442 | } | ||
443 | |||
444 | |||
445 | /** | ||
446 | * Shutdown datacache subsystem. | ||
447 | */ | ||
448 | void | ||
449 | GDS_DATACACHE_done () | ||
450 | { | ||
451 | if (NULL != datacache) | ||
452 | { | ||
453 | GNUNET_DATACACHE_destroy (datacache); | ||
454 | datacache = NULL; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | |||
459 | /* end of gnunet-service-wdht_datacache.c */ | ||
diff --git a/src/dht/gnunet-service-wdht_datacache.h b/src/dht/gnunet-service-wdht_datacache.h deleted file mode 100644 index ba9b55a0c..000000000 --- a/src/dht/gnunet-service-wdht_datacache.h +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-dht_datacache.h | ||
23 | * @brief GNUnet DHT service's datacache integration | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | #ifndef GNUNET_SERVICE_DHT_DATACACHE_H | ||
28 | #define GNUNET_SERVICE_DHT_DATACACHE_H | ||
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_block_lib.h" | ||
32 | #include "gnunet_dht_service.h" | ||
33 | |||
34 | /** | ||
35 | * Handle a datum we've received from another peer. Cache if | ||
36 | * possible. | ||
37 | * | ||
38 | * @param expiration when will the reply expire | ||
39 | * @param key the query this reply is for | ||
40 | * @param put_path_length number of peers in @a put_path | ||
41 | * @param put_path path the reply took on put | ||
42 | * @param get_path_length number of peers in @a get_path | ||
43 | * @param get_path path the reply took on get | ||
44 | * @param type type of the reply | ||
45 | * @param data_size number of bytes in @a data | ||
46 | * @param data application payload data | ||
47 | */ | ||
48 | void | ||
49 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | ||
50 | const struct GNUNET_HashCode *key, | ||
51 | unsigned int put_path_length, | ||
52 | const struct GNUNET_PeerIdentity *put_path, | ||
53 | unsigned int get_path_length, | ||
54 | const struct GNUNET_PeerIdentity *get_path, | ||
55 | enum GNUNET_BLOCK_Type type, | ||
56 | size_t data_size, | ||
57 | const void *data); | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Handle a GET request we've received from another peer. | ||
62 | * | ||
63 | * @param trail_id trail where the reply needs to be send to | ||
64 | * @param options routing options (to be passed along) | ||
65 | * @param key the query | ||
66 | * @param type requested data type | ||
67 | * @param xquery extended query | ||
68 | * @param xquery_size number of bytes in @a xquery | ||
69 | * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL | ||
70 | * @param reply_bf_mutator mutation value for @a reply_bf | ||
71 | * @return evaluation result for the local replies | ||
72 | * | ||
73 | * FIXME: also pass options, so we know to record paths or not... | ||
74 | */ | ||
75 | enum GNUNET_BLOCK_EvaluationResult | ||
76 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id, | ||
77 | enum GNUNET_DHT_RouteOption options, | ||
78 | const struct GNUNET_HashCode *key, | ||
79 | enum GNUNET_BLOCK_Type type, | ||
80 | const void *xquery, | ||
81 | size_t xquery_size, | ||
82 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | ||
83 | uint32_t reply_bf_mutator); | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Obtain a random key from the datacache. | ||
88 | * Used by Whanau for load-balancing. | ||
89 | * | ||
90 | * @param[out] key where to store the key of a random element, | ||
91 | * randomized by PRNG if datacache is empty | ||
92 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty | ||
93 | */ | ||
94 | int | ||
95 | GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Handle a request for data close to a key that we have received from | ||
100 | * another peer. | ||
101 | * | ||
102 | * @param trail_id trail where the reply needs to be send to | ||
103 | * @param key the location at which the peer is looking for data that is close | ||
104 | */ | ||
105 | void | ||
106 | GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id, | ||
107 | const struct GNUNET_HashCode *key); | ||
108 | |||
109 | |||
110 | /** | ||
111 | * Initialize datacache subsystem. | ||
112 | */ | ||
113 | void | ||
114 | GDS_DATACACHE_init (void); | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Shutdown datacache subsystem. | ||
119 | */ | ||
120 | void | ||
121 | GDS_DATACACHE_done (void); | ||
122 | |||
123 | #endif | ||
diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c index a6ebdb033..2a88ffa09 100644 --- a/src/dht/gnunet-service-wdht_neighbours.c +++ b/src/dht/gnunet-service-wdht_neighbours.c | |||
@@ -41,9 +41,9 @@ | |||
41 | #include "gnunet_statistics_service.h" | 41 | #include "gnunet_statistics_service.h" |
42 | #include "gnunet-service-wdht.h" | 42 | #include "gnunet-service-wdht.h" |
43 | #include "gnunet-service-wdht_clients.h" | 43 | #include "gnunet-service-wdht_clients.h" |
44 | #include "gnunet-service-wdht_datacache.h" | 44 | #include "gnunet-service-dht_datacache.h" |
45 | #include "gnunet-service-wdht_neighbours.h" | 45 | #include "gnunet-service-wdht_neighbours.h" |
46 | #include "gnunet-service-wdht_nse.h" | 46 | #include "gnunet-service-dht_nse.h" |
47 | #include "dht.h" | 47 | #include "dht.h" |
48 | 48 | ||
49 | #define DEBUG(...) \ | 49 | #define DEBUG(...) \ |
@@ -605,7 +605,6 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, | |||
605 | GDS_DATACACHE_handle_put (expiration_time, | 605 | GDS_DATACACHE_handle_put (expiration_time, |
606 | key, | 606 | key, |
607 | 0, NULL, | 607 | 0, NULL, |
608 | 0, NULL, | ||
609 | block_type, | 608 | block_type, |
610 | data_size, | 609 | data_size, |
611 | data); | 610 | data); |
@@ -777,7 +776,7 @@ forward_message_on_trail (struct FriendInfo *next_target, | |||
777 | /** | 776 | /** |
778 | * Send the get result to requesting client. | 777 | * Send the get result to requesting client. |
779 | * | 778 | * |
780 | * @param trail_id trail identifying where to send the result to, NULL for us | 779 | * @param cls trail identifying where to send the result to, NULL for us |
781 | * @param options routing options (from GET request) | 780 | * @param options routing options (from GET request) |
782 | * @param key Key of the requested data. | 781 | * @param key Key of the requested data. |
783 | * @param type Block type | 782 | * @param type Block type |
@@ -788,7 +787,7 @@ forward_message_on_trail (struct FriendInfo *next_target, | |||
788 | * @param data_size Size of the @a data | 787 | * @param data_size Size of the @a data |
789 | */ | 788 | */ |
790 | void | 789 | void |
791 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, | 790 | GDS_NEIGHBOURS_send_get_result (void *cls, |
792 | enum GNUNET_DHT_RouteOption options, | 791 | enum GNUNET_DHT_RouteOption options, |
793 | const struct GNUNET_HashCode *key, | 792 | const struct GNUNET_HashCode *key, |
794 | enum GNUNET_BLOCK_Type type, | 793 | enum GNUNET_BLOCK_Type type, |
@@ -798,6 +797,7 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, | |||
798 | const void *data, | 797 | const void *data, |
799 | size_t data_size) | 798 | size_t data_size) |
800 | { | 799 | { |
800 | const struct GNUNET_HashCode *trail_id = cls; | ||
801 | struct GNUNET_MessageHeader *payload; | 801 | struct GNUNET_MessageHeader *payload; |
802 | struct Trail *trail; | 802 | struct Trail *trail; |
803 | 803 | ||
@@ -1221,13 +1221,13 @@ handle_dht_p2p_random_walk (void *cls, | |||
1221 | /** | 1221 | /** |
1222 | * Handle a `struct RandomWalkResponseMessage`. | 1222 | * Handle a `struct RandomWalkResponseMessage`. |
1223 | * | 1223 | * |
1224 | * @param cls closure | 1224 | * @param cls closure |
1225 | * @param rwrm the setup response message | 1225 | * @param rwrm the setup response message |
1226 | */ | 1226 | */ |
1227 | static void | 1227 | static void |
1228 | handle_dht_p2p_random_walk_response (void *cls, | 1228 | handle_dht_p2p_random_walk_response (void *cls, |
1229 | const struct RandomWalkResponseMessage *rwrm) | 1229 | const struct RandomWalkResponseMessage *rwrm) |
1230 | { | 1230 | { |
1231 | struct Trail *trail; | 1231 | struct Trail *trail; |
1232 | struct FriendInfo *pred; | 1232 | struct FriendInfo *pred; |
1233 | struct FingerTable *ft; | 1233 | struct FingerTable *ft; |
@@ -1298,7 +1298,7 @@ handle_dht_p2p_random_walk_response (void *cls, | |||
1298 | static void | 1298 | static void |
1299 | handle_dht_p2p_trail_destroy (void *cls, | 1299 | handle_dht_p2p_trail_destroy (void *cls, |
1300 | const struct TrailDestroyMessage *tdm) | 1300 | const struct TrailDestroyMessage *tdm) |
1301 | { | 1301 | { |
1302 | struct FriendInfo *sender = cls; | 1302 | struct FriendInfo *sender = cls; |
1303 | struct Trail *trail; | 1303 | struct Trail *trail; |
1304 | 1304 | ||
@@ -1340,8 +1340,9 @@ handle_dht_p2p_successor_find (void *cls, | |||
1340 | of successor finding... */ | 1340 | of successor finding... */ |
1341 | GNUNET_break_op (0 == trail_path_length); | 1341 | GNUNET_break_op (0 == trail_path_length); |
1342 | fsm = (const struct FindSuccessorMessage *) message; | 1342 | fsm = (const struct FindSuccessorMessage *) message; |
1343 | GDS_DATACACHE_get_successors (trail_id, | 1343 | GDS_DATACACHE_get_successors (&fsm->key, |
1344 | &fsm->key); | 1344 | &GDS_NEIGHBOURS_send_get_result, |
1345 | (void *) trail_id); | ||
1345 | return GNUNET_OK; | 1346 | return GNUNET_OK; |
1346 | } | 1347 | } |
1347 | 1348 | ||
@@ -1522,7 +1523,7 @@ struct TrailHandler | |||
1522 | /** | 1523 | /** |
1523 | * Check that a `struct TrailRouteMessage` is well-formed. | 1524 | * Check that a `struct TrailRouteMessage` is well-formed. |
1524 | * | 1525 | * |
1525 | * @param cls closure | 1526 | * @param cls closure |
1526 | * @param trm the finger destroy message | 1527 | * @param trm the finger destroy message |
1527 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1528 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1528 | */ | 1529 | */ |
@@ -1534,7 +1535,7 @@ check_dht_p2p_trail_route (void *cls, | |||
1534 | uint16_t path_length; | 1535 | uint16_t path_length; |
1535 | const struct GNUNET_MessageHeader *payload; | 1536 | const struct GNUNET_MessageHeader *payload; |
1536 | size_t msize; | 1537 | size_t msize; |
1537 | 1538 | ||
1538 | msize = ntohs (trm->header.size); | 1539 | msize = ntohs (trm->header.size); |
1539 | path_length = ntohs (trm->path_length); | 1540 | path_length = ntohs (trm->path_length); |
1540 | if (msize < sizeof (struct TrailRouteMessage) + | 1541 | if (msize < sizeof (struct TrailRouteMessage) + |
@@ -1561,7 +1562,7 @@ check_dht_p2p_trail_route (void *cls, | |||
1561 | /** | 1562 | /** |
1562 | * Handle a `struct TrailRouteMessage`. | 1563 | * Handle a `struct TrailRouteMessage`. |
1563 | * | 1564 | * |
1564 | * @param cls closure | 1565 | * @param cls closure |
1565 | * @param trm the finger destroy message | 1566 | * @param trm the finger destroy message |
1566 | */ | 1567 | */ |
1567 | static void | 1568 | static void |
diff --git a/src/dht/gnunet-service-wdht_neighbours.h b/src/dht/gnunet-service-wdht_neighbours.h index f080258bb..8461d16e8 100644 --- a/src/dht/gnunet-service-wdht_neighbours.h +++ b/src/dht/gnunet-service-wdht_neighbours.h | |||
@@ -71,7 +71,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, | |||
71 | /** | 71 | /** |
72 | * Send the get result to requesting client. | 72 | * Send the get result to requesting client. |
73 | * | 73 | * |
74 | * @param trail_id trail identifying where to send the result to, NULL for us | 74 | * @param cls a `const struct GNUNET_HashCode *` trail identifying where to send the result to, NULL for us |
75 | * @param options routing options (from GET request) | 75 | * @param options routing options (from GET request) |
76 | * @param key key of the requested data. | 76 | * @param key key of the requested data. |
77 | * @param type block type | 77 | * @param type block type |
@@ -82,14 +82,15 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, | |||
82 | * @param data_size size of the @a data | 82 | * @param data_size size of the @a data |
83 | */ | 83 | */ |
84 | void | 84 | void |
85 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, | 85 | GDS_NEIGHBOURS_send_get_result (void *cls, |
86 | enum GNUNET_DHT_RouteOption options, | 86 | enum GNUNET_DHT_RouteOption options, |
87 | const struct GNUNET_HashCode *key, | 87 | const struct GNUNET_HashCode *key, |
88 | enum GNUNET_BLOCK_Type type, | 88 | enum GNUNET_BLOCK_Type type, |
89 | unsigned int put_path_length, | 89 | unsigned int put_path_length, |
90 | const struct GNUNET_PeerIdentity *put_path, | 90 | const struct GNUNET_PeerIdentity *put_path, |
91 | struct GNUNET_TIME_Absolute expiration, | 91 | struct GNUNET_TIME_Absolute expiration, |
92 | const void *data, size_t data_size); | 92 | const void *data, |
93 | size_t data_size); | ||
93 | 94 | ||
94 | 95 | ||
95 | /** | 96 | /** |
diff --git a/src/dht/gnunet-service-wdht_nse.c b/src/dht/gnunet-service-wdht_nse.c deleted file mode 100644 index 400c8242e..000000000 --- a/src/dht/gnunet-service-wdht_nse.c +++ /dev/null | |||
@@ -1,116 +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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_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-wdht.h" | ||
29 | #include "gnunet-service-wdht_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, struct GNUNET_TIME_Absolute timestamp, | ||
56 | double logestimate, double std_dev) | ||
57 | { | ||
58 | GNUNET_STATISTICS_update (GDS_stats, | ||
59 | gettext_noop ("# Network size estimates received"), | ||
60 | 1, GNUNET_NO); | ||
61 | /* do not allow estimates < 0.5 */ | ||
62 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); | ||
63 | } | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Return the log of the current network size estimate. | ||
68 | * | ||
69 | * @return log of NSE | ||
70 | */ | ||
71 | double | ||
72 | GDS_NSE_get () | ||
73 | { | ||
74 | return log_of_network_size_estimate; | ||
75 | } | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Initialize NSE subsystem. | ||
80 | */ | ||
81 | void | ||
82 | GDS_NSE_init () | ||
83 | { | ||
84 | unsigned long long hops; | ||
85 | |||
86 | if ( (GNUNET_YES == | ||
87 | GNUNET_CONFIGURATION_have_value (GDS_cfg, | ||
88 | "dht", | ||
89 | "FORCE_NSE")) && | ||
90 | (GNUNET_OK == | ||
91 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, | ||
92 | "dht", | ||
93 | "FORCE_NSE", | ||
94 | &hops)) ) | ||
95 | { | ||
96 | log_of_network_size_estimate = (double) hops; | ||
97 | return; | ||
98 | } | ||
99 | nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Shutdown NSE subsystem. | ||
105 | */ | ||
106 | void | ||
107 | GDS_NSE_done () | ||
108 | { | ||
109 | if (NULL != nse) | ||
110 | { | ||
111 | GNUNET_NSE_disconnect (nse); | ||
112 | nse = NULL; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /* end of gnunet-service-dht_nse.c */ | ||
diff --git a/src/dht/gnunet-service-wdht_nse.h b/src/dht/gnunet-service-wdht_nse.h deleted file mode 100644 index 358c0c4bd..000000000 --- a/src/dht/gnunet-service-wdht_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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_nse.h | ||
23 | * @brief GNUnet DHT integration with NSE | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_NSE_H | ||
27 | #define GNUNET_SERVICE_XDHT_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-xdht.c b/src/dht/gnunet-service-xdht.c index e7b2c50c4..382a3b7c3 100644 --- a/src/dht/gnunet-service-xdht.c +++ b/src/dht/gnunet-service-xdht.c | |||
@@ -30,36 +30,23 @@ | |||
30 | #include "gnunet_hello_lib.h" | 30 | #include "gnunet_hello_lib.h" |
31 | #include "gnunet_dht_service.h" | 31 | #include "gnunet_dht_service.h" |
32 | #include "gnunet_statistics_service.h" | 32 | #include "gnunet_statistics_service.h" |
33 | #include "gnunet-service-xdht.h" | 33 | #include "gnunet-service-dht.h" |
34 | #include "gnunet-service-xdht_clients.h" | 34 | #include "gnunet-service-dht_datacache.h" |
35 | #include "gnunet-service-xdht_datacache.h" | 35 | #include "gnunet-service-dht_neighbours.h" |
36 | #include "gnunet-service-xdht_neighbours.h" | 36 | #include "gnunet-service-dht_nse.h" |
37 | #include "gnunet-service-xdht_nse.h" | ||
38 | #include "gnunet-service-xdht_routing.h" | 37 | #include "gnunet-service-xdht_routing.h" |
39 | 38 | ||
40 | 39 | ||
41 | |||
42 | /** | ||
43 | * Handle for the statistics service. | ||
44 | */ | ||
45 | struct GNUNET_STATISTICS_Handle *GDS_stats; | ||
46 | |||
47 | /** | ||
48 | * Our handle to the BLOCK library. | ||
49 | */ | ||
50 | struct GNUNET_BLOCK_Context *GDS_block_context; | ||
51 | |||
52 | /** | ||
53 | * The configuration the DHT service is running with | ||
54 | */ | ||
55 | const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | ||
56 | |||
57 | /** | 40 | /** |
58 | * Should we store our topology predecessor and successor IDs into statistics? | 41 | * Should we store our topology predecessor and successor IDs into statistics? |
59 | */ | 42 | */ |
60 | extern unsigned int track_topology; | 43 | extern unsigned int track_topology; |
61 | 44 | ||
62 | 45 | ||
46 | /* Code shared between different DHT implementations */ | ||
47 | #include "gnunet-service-dht_clients.c" | ||
48 | |||
49 | |||
63 | /** | 50 | /** |
64 | * Task run during shutdown. | 51 | * Task run during shutdown. |
65 | * | 52 | * |
@@ -72,16 +59,17 @@ shutdown_task (void *cls) | |||
72 | GDS_DATACACHE_done (); | 59 | GDS_DATACACHE_done (); |
73 | GDS_ROUTING_done (); | 60 | GDS_ROUTING_done (); |
74 | GDS_NSE_done (); | 61 | GDS_NSE_done (); |
75 | if (GDS_block_context != NULL) | 62 | if (NULL != GDS_block_context) |
76 | { | 63 | { |
77 | GNUNET_BLOCK_context_destroy (GDS_block_context); | 64 | GNUNET_BLOCK_context_destroy (GDS_block_context); |
78 | GDS_block_context = NULL; | 65 | GDS_block_context = NULL; |
79 | } | 66 | } |
80 | if (GDS_stats != NULL) | 67 | if (NULL != GDS_stats) |
81 | { | 68 | { |
82 | GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); | 69 | GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); |
83 | GDS_stats = NULL; | 70 | GDS_stats = NULL; |
84 | } | 71 | } |
72 | GDS_CLIENTS_stop (); | ||
85 | } | 73 | } |
86 | 74 | ||
87 | 75 | ||
@@ -89,24 +77,29 @@ shutdown_task (void *cls) | |||
89 | * Process dht requests. | 77 | * Process dht requests. |
90 | * | 78 | * |
91 | * @param cls closure | 79 | * @param cls closure |
92 | * @param server the initialized server | ||
93 | * @param c configuration to use | 80 | * @param c configuration to use |
81 | * @param service the initialized service | ||
94 | */ | 82 | */ |
95 | static void | 83 | static void |
96 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 84 | run (void *cls, |
97 | const struct GNUNET_CONFIGURATION_Handle *c) | 85 | const struct GNUNET_CONFIGURATION_Handle *c, |
86 | struct GNUNET_SERVICE_Handle *service) | ||
98 | { | 87 | { |
99 | unsigned long long _track_topology; | 88 | unsigned long long _track_topology; |
100 | 89 | ||
101 | GDS_cfg = c; | 90 | GDS_cfg = c; |
91 | GDS_service = service; | ||
102 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); | 92 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); |
103 | GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg); | 93 | GDS_stats = GNUNET_STATISTICS_create ("dht", |
94 | GDS_cfg); | ||
104 | GDS_ROUTING_init (); | 95 | GDS_ROUTING_init (); |
105 | GDS_NSE_init (); | 96 | GDS_NSE_init (); |
106 | GDS_DATACACHE_init (); | 97 | GDS_DATACACHE_init (); |
107 | GDS_CLIENTS_init (server); | 98 | GDS_CLIENTS_init (); |
108 | if (GNUNET_OK == | 99 | if (GNUNET_OK == |
109 | GNUNET_CONFIGURATION_get_value_number (c, "xdht", "track_toplogy", | 100 | GNUNET_CONFIGURATION_get_value_number (c, |
101 | "xdht", | ||
102 | "track_toplogy", | ||
110 | &_track_topology)) | 103 | &_track_topology)) |
111 | { | 104 | { |
112 | track_topology = (unsigned int) _track_topology; | 105 | track_topology = (unsigned int) _track_topology; |
@@ -121,26 +114,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
121 | } | 114 | } |
122 | 115 | ||
123 | 116 | ||
124 | /** | 117 | /* Finally, define the main method */ |
125 | * The main function for the dht service. | 118 | GDS_DHT_SERVICE_INIT("xdht", &run); |
126 | * | 119 | |
127 | * @param argc number of arguments from the command line | ||
128 | * @param argv command line arguments | ||
129 | * @return 0 ok, 1 on error | ||
130 | */ | ||
131 | int | ||
132 | main (int argc, char *const *argv) | ||
133 | { | ||
134 | int ret; | ||
135 | |||
136 | ret = | ||
137 | (GNUNET_OK == | ||
138 | GNUNET_SERVICE_run (argc, argv, | ||
139 | "xdht", | ||
140 | GNUNET_SERVICE_OPTION_NONE, &run, | ||
141 | NULL)) ? 0 : 1; | ||
142 | GDS_CLIENTS_done (); | ||
143 | return ret; | ||
144 | } | ||
145 | 120 | ||
146 | /* end of gnunet-service-xdht.c */ | 121 | /* end of gnunet-service-xdht.c */ |
diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c deleted file mode 100644 index 3185243b7..000000000 --- a/src/dht/gnunet-service-xdht_clients.c +++ /dev/null | |||
@@ -1,1417 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-dht_clients.c | ||
23 | * @brief GNUnet DHT service's client management code | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_constants.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | #include "gnunet-service-xdht.h" | ||
33 | #include "gnunet-service-xdht_clients.h" | ||
34 | #include "gnunet-service-xdht_datacache.h" | ||
35 | #include "gnunet-service-xdht_neighbours.h" | ||
36 | #include "dht.h" | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Should routing details be logged to stderr (for debugging)? | ||
41 | */ | ||
42 | #define LOG_TRAFFIC(kind,...) GNUNET_log_from (kind, "dht-traffic",__VA_ARGS__) | ||
43 | |||
44 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__) | ||
45 | |||
46 | #define DEBUG(...) \ | ||
47 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
48 | |||
49 | /** | ||
50 | * Linked list of messages to send to clients. | ||
51 | */ | ||
52 | struct PendingMessage | ||
53 | { | ||
54 | /** | ||
55 | * Pointer to next item in the list | ||
56 | */ | ||
57 | struct PendingMessage *next; | ||
58 | |||
59 | /** | ||
60 | * Pointer to previous item in the list | ||
61 | */ | ||
62 | struct PendingMessage *prev; | ||
63 | |||
64 | /** | ||
65 | * Actual message to be sent, allocated at the end of the struct: | ||
66 | * // msg = (cast) &pm[1]; | ||
67 | * // GNUNET_memcpy (&pm[1], data, len); | ||
68 | */ | ||
69 | const struct GNUNET_MessageHeader *msg; | ||
70 | |||
71 | }; | ||
72 | |||
73 | |||
74 | /** | ||
75 | * Struct containing information about a client, | ||
76 | * handle to connect to it, and any pending messages | ||
77 | * that need to be sent to it. | ||
78 | */ | ||
79 | struct ClientList | ||
80 | { | ||
81 | /** | ||
82 | * Linked list of active clients | ||
83 | */ | ||
84 | struct ClientList *next; | ||
85 | |||
86 | /** | ||
87 | * Linked list of active clients | ||
88 | */ | ||
89 | struct ClientList *prev; | ||
90 | |||
91 | /** | ||
92 | * The handle to this client | ||
93 | */ | ||
94 | struct GNUNET_SERVER_Client *client_handle; | ||
95 | |||
96 | /** | ||
97 | * Handle to the current transmission request, NULL | ||
98 | * if none pending. | ||
99 | */ | ||
100 | struct GNUNET_SERVER_TransmitHandle *transmit_handle; | ||
101 | |||
102 | /** | ||
103 | * Linked list of pending messages for this client | ||
104 | */ | ||
105 | struct PendingMessage *pending_head; | ||
106 | |||
107 | /** | ||
108 | * Tail of linked list of pending messages for this client | ||
109 | */ | ||
110 | struct PendingMessage *pending_tail; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Entry in the local forwarding map for a client's GET request. | ||
117 | */ | ||
118 | struct ClientQueryRecord | ||
119 | { | ||
120 | |||
121 | /** | ||
122 | * The key this request was about | ||
123 | */ | ||
124 | struct GNUNET_HashCode key; | ||
125 | |||
126 | /** | ||
127 | * Client responsible for the request. | ||
128 | */ | ||
129 | struct ClientList *client; | ||
130 | |||
131 | /** | ||
132 | * Extended query (see gnunet_block_lib.h), allocated at the end of this struct. | ||
133 | */ | ||
134 | const void *xquery; | ||
135 | |||
136 | /** | ||
137 | * Replies we have already seen for this request. | ||
138 | */ | ||
139 | struct GNUNET_HashCode *seen_replies; | ||
140 | |||
141 | /** | ||
142 | * Pointer to this nodes heap location in the retry-heap (for fast removal) | ||
143 | */ | ||
144 | struct GNUNET_CONTAINER_HeapNode *hnode; | ||
145 | |||
146 | /** | ||
147 | * What's the delay between re-try operations that we currently use for this | ||
148 | * request? | ||
149 | */ | ||
150 | struct GNUNET_TIME_Relative retry_frequency; | ||
151 | |||
152 | /** | ||
153 | * What's the next time we should re-try this request? | ||
154 | */ | ||
155 | struct GNUNET_TIME_Absolute retry_time; | ||
156 | |||
157 | /** | ||
158 | * The unique identifier of this request | ||
159 | */ | ||
160 | uint64_t unique_id; | ||
161 | |||
162 | /** | ||
163 | * Number of bytes in xquery. | ||
164 | */ | ||
165 | size_t xquery_size; | ||
166 | |||
167 | /** | ||
168 | * Number of entries in 'seen_replies'. | ||
169 | */ | ||
170 | unsigned int seen_replies_count; | ||
171 | |||
172 | /** | ||
173 | * Desired replication level | ||
174 | */ | ||
175 | uint32_t replication; | ||
176 | |||
177 | /** | ||
178 | * Any message options for this request | ||
179 | */ | ||
180 | uint32_t msg_options; | ||
181 | |||
182 | /** | ||
183 | * The type for the data for the GET request. | ||
184 | */ | ||
185 | enum GNUNET_BLOCK_Type type; | ||
186 | |||
187 | }; | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Struct containing paremeters of monitoring requests. | ||
192 | */ | ||
193 | struct ClientMonitorRecord | ||
194 | { | ||
195 | |||
196 | /** | ||
197 | * Next element in DLL. | ||
198 | */ | ||
199 | struct ClientMonitorRecord *next; | ||
200 | |||
201 | /** | ||
202 | * Previous element in DLL. | ||
203 | */ | ||
204 | struct ClientMonitorRecord *prev; | ||
205 | |||
206 | /** | ||
207 | * Type of blocks that are of interest | ||
208 | */ | ||
209 | enum GNUNET_BLOCK_Type type; | ||
210 | |||
211 | /** | ||
212 | * Key of data of interest, NULL for all. | ||
213 | */ | ||
214 | struct GNUNET_HashCode *key; | ||
215 | |||
216 | /** | ||
217 | * Flag whether to notify about GET messages. | ||
218 | */ | ||
219 | int16_t get; | ||
220 | |||
221 | /** | ||
222 | * Flag whether to notify about GET_REPONSE messages. | ||
223 | */ | ||
224 | int16_t get_resp; | ||
225 | |||
226 | /** | ||
227 | * Flag whether to notify about PUT messages. | ||
228 | */ | ||
229 | uint16_t put; | ||
230 | |||
231 | /** | ||
232 | * Client to notify of these requests. | ||
233 | */ | ||
234 | struct ClientList *client; | ||
235 | }; | ||
236 | |||
237 | |||
238 | /** | ||
239 | * List of active clients. | ||
240 | */ | ||
241 | static struct ClientList *client_head; | ||
242 | |||
243 | /** | ||
244 | * List of active clients. | ||
245 | */ | ||
246 | static struct ClientList *client_tail; | ||
247 | |||
248 | /** | ||
249 | * List of active monitoring requests. | ||
250 | */ | ||
251 | static struct ClientMonitorRecord *monitor_head; | ||
252 | |||
253 | /** | ||
254 | * List of active monitoring requests. | ||
255 | */ | ||
256 | static struct ClientMonitorRecord *monitor_tail; | ||
257 | |||
258 | /** | ||
259 | * Hashmap for fast key based lookup, maps keys to `struct ClientQueryRecord` entries. | ||
260 | */ | ||
261 | static struct GNUNET_CONTAINER_MultiHashMap *forward_map; | ||
262 | |||
263 | /** | ||
264 | * Heap with all of our client's request, sorted by retry time (earliest on top). | ||
265 | */ | ||
266 | static struct GNUNET_CONTAINER_Heap *retry_heap; | ||
267 | |||
268 | /** | ||
269 | * Task that re-transmits requests (using retry_heap). | ||
270 | */ | ||
271 | static struct GNUNET_SCHEDULER_Task * retry_task; | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Task run to check for messages that need to be sent to a client. | ||
276 | * | ||
277 | * @param client a ClientList, containing the client and any messages to be sent to it | ||
278 | */ | ||
279 | static void | ||
280 | process_pending_messages (struct ClientList *client); | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready | ||
285 | * request. A ClientList is passed as closure, take the head of the list | ||
286 | * and copy it into buf, which has the result of sending the message to the | ||
287 | * client. | ||
288 | * | ||
289 | * @param cls closure to this call | ||
290 | * @param size maximum number of bytes available to send | ||
291 | * @param buf where to copy the actual message to | ||
292 | * | ||
293 | * @return the number of bytes actually copied, 0 indicates failure | ||
294 | */ | ||
295 | static size_t | ||
296 | send_reply_to_client (void *cls, size_t size, void *buf) | ||
297 | { | ||
298 | struct ClientList *client = cls; | ||
299 | char *cbuf = buf; | ||
300 | struct PendingMessage *reply; | ||
301 | size_t off; | ||
302 | size_t msize; | ||
303 | |||
304 | client->transmit_handle = NULL; | ||
305 | if (buf == NULL) | ||
306 | { | ||
307 | /* client disconnected */ | ||
308 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
309 | "Client %p disconnected, pending messages will be discarded\n", | ||
310 | client->client_handle); | ||
311 | return 0; | ||
312 | } | ||
313 | off = 0; | ||
314 | while ((NULL != (reply = client->pending_head)) && | ||
315 | (size >= off + (msize = ntohs (reply->msg->size)))) | ||
316 | { | ||
317 | GNUNET_CONTAINER_DLL_remove (client->pending_head, client->pending_tail, | ||
318 | reply); | ||
319 | GNUNET_memcpy (&cbuf[off], reply->msg, msize); | ||
320 | GNUNET_free (reply); | ||
321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
322 | "Transmitting %u bytes to client %p\n", | ||
323 | (unsigned int) msize, | ||
324 | client->client_handle); | ||
325 | off += msize; | ||
326 | } | ||
327 | process_pending_messages (client); | ||
328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
329 | "Transmitted %u/%u bytes to client %p\n", | ||
330 | (unsigned int) off, | ||
331 | (unsigned int) size, | ||
332 | client->client_handle); | ||
333 | return off; | ||
334 | } | ||
335 | |||
336 | |||
337 | /** | ||
338 | * Task run to check for messages that need to be sent to a client. | ||
339 | * | ||
340 | * @param client a ClientList, containing the client and any messages to be sent to it | ||
341 | */ | ||
342 | static void | ||
343 | process_pending_messages (struct ClientList *client) | ||
344 | { | ||
345 | if ((client->pending_head == NULL) || (client->transmit_handle != NULL)) | ||
346 | { | ||
347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
348 | "Not asking for transmission to %p now: %s\n", | ||
349 | client->client_handle, | ||
350 | client->pending_head == | ||
351 | NULL ? "no more messages" : "request already pending"); | ||
352 | return; | ||
353 | } | ||
354 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
355 | "Asking for transmission of %u bytes to client %p\n", | ||
356 | ntohs (client->pending_head->msg->size), client->client_handle); | ||
357 | client->transmit_handle = | ||
358 | GNUNET_SERVER_notify_transmit_ready (client->client_handle, | ||
359 | ntohs (client->pending_head-> | ||
360 | msg->size), | ||
361 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
362 | &send_reply_to_client, client); | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * Add a PendingMessage to the clients list of messages to be sent | ||
368 | * | ||
369 | * @param client the active client to send the message to | ||
370 | * @param pending_message the actual message to send | ||
371 | */ | ||
372 | static void | ||
373 | add_pending_message (struct ClientList *client, | ||
374 | struct PendingMessage *pending_message) | ||
375 | { | ||
376 | GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, | ||
377 | pending_message); | ||
378 | process_pending_messages (client); | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * Closure for 'forward_reply' | ||
384 | */ | ||
385 | struct ForwardReplyContext | ||
386 | { | ||
387 | |||
388 | /** | ||
389 | * Actual message to send to matching clients. | ||
390 | */ | ||
391 | struct PendingMessage *pm; | ||
392 | |||
393 | /** | ||
394 | * Embedded payload. | ||
395 | */ | ||
396 | const void *data; | ||
397 | |||
398 | /** | ||
399 | * Type of the data. | ||
400 | */ | ||
401 | enum GNUNET_BLOCK_Type type; | ||
402 | |||
403 | /** | ||
404 | * Number of bytes in data. | ||
405 | */ | ||
406 | size_t data_size; | ||
407 | |||
408 | /** | ||
409 | * Do we need to copy 'pm' because it was already used? | ||
410 | */ | ||
411 | int do_copy; | ||
412 | |||
413 | }; | ||
414 | |||
415 | |||
416 | /** | ||
417 | * Find a client if it exists, add it otherwise. | ||
418 | * | ||
419 | * @param client the server handle to the client | ||
420 | * | ||
421 | * @return the client if found, a new client otherwise | ||
422 | */ | ||
423 | static struct ClientList * | ||
424 | find_active_client (struct GNUNET_SERVER_Client *client) | ||
425 | { | ||
426 | struct ClientList *pos = client_head; | ||
427 | struct ClientList *ret; | ||
428 | |||
429 | while (pos != NULL) | ||
430 | { | ||
431 | if (pos->client_handle == client) | ||
432 | return pos; | ||
433 | pos = pos->next; | ||
434 | } | ||
435 | ret = GNUNET_new (struct ClientList); | ||
436 | ret->client_handle = client; | ||
437 | GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ret); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Iterator over hash map entries that frees all entries | ||
444 | * associated with the given client. | ||
445 | * | ||
446 | * @param cls client to search for in source routes | ||
447 | * @param key current key code (ignored) | ||
448 | * @param value value in the hash map, a ClientQueryRecord | ||
449 | * @return #GNUNET_YES (we should continue to iterate) | ||
450 | */ | ||
451 | static int | ||
452 | remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
453 | { | ||
454 | struct ClientList *client = cls; | ||
455 | struct ClientQueryRecord *record = value; | ||
456 | |||
457 | if (record->client != client) | ||
458 | return GNUNET_YES; | ||
459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
460 | "Removing client %p's record for key %s\n", client, | ||
461 | GNUNET_h2s (key)); | ||
462 | GNUNET_assert (GNUNET_YES == | ||
463 | GNUNET_CONTAINER_multihashmap_remove (forward_map, key, | ||
464 | record)); | ||
465 | if (NULL != record->hnode) | ||
466 | GNUNET_CONTAINER_heap_remove_node (record->hnode); | ||
467 | GNUNET_array_grow (record->seen_replies, record->seen_replies_count, 0); | ||
468 | GNUNET_free (record); | ||
469 | return GNUNET_YES; | ||
470 | } | ||
471 | |||
472 | |||
473 | /** | ||
474 | * Iterator over hash map entries that send a given reply to | ||
475 | * each of the matching clients. With some tricky recycling | ||
476 | * of the buffer. | ||
477 | * | ||
478 | * @param cls the 'struct ForwardReplyContext' | ||
479 | * @param key current key | ||
480 | * @param value value in the hash map, a ClientQueryRecord | ||
481 | * @return GNUNET_YES (we should continue to iterate), | ||
482 | * if the result is mal-formed, GNUNET_NO | ||
483 | */ | ||
484 | static int | ||
485 | forward_reply (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
486 | { | ||
487 | struct ForwardReplyContext *frc = cls; | ||
488 | struct ClientQueryRecord *record = value; | ||
489 | struct PendingMessage *pm; | ||
490 | struct GNUNET_DHT_ClientResultMessage *reply; | ||
491 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
492 | int do_free; | ||
493 | struct GNUNET_HashCode ch; | ||
494 | unsigned int i; | ||
495 | |||
496 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | ||
497 | "XVINE CLIENT-RESULT %s\n", | ||
498 | GNUNET_h2s_full (key)); | ||
499 | #if 0 | ||
500 | if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) | ||
501 | { | ||
502 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
503 | "Record type missmatch, not passing request for key %s to local client\n", | ||
504 | GNUNET_h2s (key)); | ||
505 | |||
506 | GNUNET_STATISTICS_update (GDS_stats, | ||
507 | gettext_noop | ||
508 | ("# Key match, type mismatches in REPLY to CLIENT"), | ||
509 | 1, GNUNET_NO); | ||
510 | return GNUNET_YES; /* type mismatch */ | ||
511 | } | ||
512 | #endif | ||
513 | GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); | ||
514 | for (i = 0; i < record->seen_replies_count; i++) | ||
515 | if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode))) | ||
516 | { | ||
517 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
518 | "Duplicate reply, not passing request for key %s to local client\n", | ||
519 | GNUNET_h2s (key)); | ||
520 | GNUNET_STATISTICS_update (GDS_stats, | ||
521 | gettext_noop | ||
522 | ("# Duplicate REPLIES to CLIENT request dropped"), | ||
523 | 1, GNUNET_NO); | ||
524 | return GNUNET_YES; /* duplicate */ | ||
525 | } | ||
526 | eval = | ||
527 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
528 | record->type, | ||
529 | GNUNET_BLOCK_EO_NONE, | ||
530 | key, NULL, 0, | ||
531 | record->xquery, | ||
532 | record->xquery_size, | ||
533 | frc->data, | ||
534 | frc->data_size); | ||
535 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
536 | "Evaluation result is %d for key %s for local client's query\n", | ||
537 | (int) eval, GNUNET_h2s (key)); | ||
538 | switch (eval) | ||
539 | { | ||
540 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
541 | do_free = GNUNET_YES; | ||
542 | break; | ||
543 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
544 | GNUNET_array_append (record->seen_replies, record->seen_replies_count, ch); | ||
545 | do_free = GNUNET_NO; | ||
546 | break; | ||
547 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
548 | /* should be impossible to encounter here */ | ||
549 | GNUNET_break (0); | ||
550 | return GNUNET_YES; | ||
551 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
552 | GNUNET_break_op (0); | ||
553 | return GNUNET_NO; | ||
554 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
555 | GNUNET_break (0); | ||
556 | return GNUNET_NO; | ||
557 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
558 | GNUNET_break (0); | ||
559 | return GNUNET_NO; | ||
560 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
561 | return GNUNET_YES; | ||
562 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
563 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
564 | _("Unsupported block type (%u) in request!\n"), record->type); | ||
565 | return GNUNET_NO; | ||
566 | default: | ||
567 | GNUNET_break (0); | ||
568 | return GNUNET_NO; | ||
569 | } | ||
570 | if (GNUNET_NO == frc->do_copy) | ||
571 | { | ||
572 | /* first time, we can use the original data */ | ||
573 | pm = frc->pm; | ||
574 | frc->do_copy = GNUNET_YES; | ||
575 | } | ||
576 | else | ||
577 | { | ||
578 | /* two clients waiting for same reply, must copy for queueing */ | ||
579 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
580 | ntohs (frc->pm->msg->size)); | ||
581 | GNUNET_memcpy (pm, frc->pm, | ||
582 | sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size)); | ||
583 | pm->next = pm->prev = NULL; | ||
584 | pm->msg = (struct GNUNET_MessageHeader *) &pm[1]; | ||
585 | } | ||
586 | GNUNET_STATISTICS_update (GDS_stats, | ||
587 | gettext_noop ("# RESULTS queued for clients"), 1, | ||
588 | GNUNET_NO); | ||
589 | reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; | ||
590 | reply->unique_id = record->unique_id; | ||
591 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
592 | "Queueing reply to query %s for client %p\n", | ||
593 | GNUNET_h2s (key), | ||
594 | record->client->client_handle); | ||
595 | add_pending_message (record->client, pm); | ||
596 | if (GNUNET_YES == do_free) | ||
597 | remove_client_records (record->client, key, record); | ||
598 | return GNUNET_YES; | ||
599 | } | ||
600 | |||
601 | |||
602 | /** | ||
603 | * Handle a reply we've received from another peer. If the reply | ||
604 | * matches any of our pending queries, forward it to the respective | ||
605 | * client(s). | ||
606 | * | ||
607 | * @param expiration when will the reply expire | ||
608 | * @param key the query this reply is for | ||
609 | * @param get_path_length number of peers in @a get_path | ||
610 | * @param get_path path the reply took on get | ||
611 | * @param put_path_length number of peers in @a put_path | ||
612 | * @param put_path path the reply took on put | ||
613 | * @param type type of the reply | ||
614 | * @param data_size number of bytes in @a data | ||
615 | * @param data application payload data | ||
616 | */ | ||
617 | void | ||
618 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | ||
619 | const struct GNUNET_HashCode *key, | ||
620 | unsigned int get_path_length, | ||
621 | const struct GNUNET_PeerIdentity *get_path, | ||
622 | unsigned int put_path_length, | ||
623 | const struct GNUNET_PeerIdentity *put_path, | ||
624 | enum GNUNET_BLOCK_Type type, size_t data_size, | ||
625 | const void *data) | ||
626 | { | ||
627 | struct ForwardReplyContext frc; | ||
628 | struct PendingMessage *pm; | ||
629 | struct GNUNET_DHT_ClientResultMessage *reply; | ||
630 | struct GNUNET_PeerIdentity *paths; | ||
631 | size_t msize; | ||
632 | |||
633 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
634 | "reply for key %s\n", | ||
635 | GNUNET_h2s (key)); | ||
636 | |||
637 | if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, key)) | ||
638 | { | ||
639 | GNUNET_STATISTICS_update (GDS_stats, | ||
640 | gettext_noop | ||
641 | ("# REPLIES ignored for CLIENTS (no match)"), 1, | ||
642 | GNUNET_NO); | ||
643 | return; /* no matching request, fast exit! */ | ||
644 | } | ||
645 | msize = | ||
646 | sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size + | ||
647 | (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity); | ||
648 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
649 | { | ||
650 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
651 | _("Could not pass reply to client, message too big!\n")); | ||
652 | return; | ||
653 | } | ||
654 | DEBUG ("reply FOR DATA_SIZE = %u\n", | ||
655 | (unsigned int) msize); | ||
656 | pm = GNUNET_malloc (msize + sizeof (struct PendingMessage)); | ||
657 | reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; | ||
658 | pm->msg = &reply->header; | ||
659 | reply->header.size = htons ((uint16_t) msize); | ||
660 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); | ||
661 | reply->type = htonl (type); | ||
662 | reply->get_path_length = htonl (get_path_length); | ||
663 | reply->put_path_length = htonl (put_path_length); | ||
664 | reply->unique_id = 0; /* filled in later */ | ||
665 | reply->expiration = GNUNET_TIME_absolute_hton (expiration); | ||
666 | reply->key = *key; | ||
667 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; | ||
668 | GNUNET_memcpy (paths, | ||
669 | put_path, | ||
670 | sizeof (struct GNUNET_PeerIdentity) * put_path_length); | ||
671 | GNUNET_memcpy (&paths[put_path_length], | ||
672 | get_path, | ||
673 | sizeof (struct GNUNET_PeerIdentity) * get_path_length); | ||
674 | GNUNET_memcpy (&paths[get_path_length + put_path_length], | ||
675 | data, | ||
676 | data_size); | ||
677 | frc.do_copy = GNUNET_NO; | ||
678 | frc.pm = pm; | ||
679 | frc.data = data; | ||
680 | frc.data_size = data_size; | ||
681 | frc.type = type; | ||
682 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
683 | key, | ||
684 | &forward_reply, | ||
685 | &frc); | ||
686 | if (GNUNET_NO == frc.do_copy) | ||
687 | { | ||
688 | /* did not match any of the requests, free! */ | ||
689 | GNUNET_STATISTICS_update (GDS_stats, | ||
690 | gettext_noop | ||
691 | ("# REPLIES ignored for CLIENTS (no match)"), 1, | ||
692 | GNUNET_NO); | ||
693 | GNUNET_free (pm); | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * Check if some client is monitoring GET messages and notify | ||
699 | * them in that case. | ||
700 | * | ||
701 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
702 | * @param type The type of data in the request. | ||
703 | * @param hop_count Hop count so far. | ||
704 | * @param path_length number of entries in path (or 0 if not recorded). | ||
705 | * @param path peers on the GET path (or NULL if not recorded). | ||
706 | * @param desired_replication_level Desired replication level. | ||
707 | * @param key Key of the requested data. | ||
708 | */ | ||
709 | void | ||
710 | GDS_CLIENTS_process_get (uint32_t options, | ||
711 | enum GNUNET_BLOCK_Type type, | ||
712 | uint32_t hop_count, | ||
713 | uint32_t desired_replication_level, | ||
714 | unsigned int path_length, | ||
715 | const struct GNUNET_PeerIdentity *path, | ||
716 | const struct GNUNET_HashCode * key) | ||
717 | { | ||
718 | struct ClientMonitorRecord *m; | ||
719 | struct ClientList **cl; | ||
720 | unsigned int cl_size; | ||
721 | |||
722 | cl = NULL; | ||
723 | cl_size = 0; | ||
724 | for (m = monitor_head; NULL != m; m = m->next) | ||
725 | { | ||
726 | if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && | ||
727 | (NULL == m->key || | ||
728 | memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) | ||
729 | { | ||
730 | struct PendingMessage *pm; | ||
731 | struct GNUNET_DHT_MonitorGetMessage *mmsg; | ||
732 | struct GNUNET_PeerIdentity *msg_path; | ||
733 | size_t msize; | ||
734 | unsigned int i; | ||
735 | |||
736 | /* Don't send duplicates */ | ||
737 | for (i = 0; i < cl_size; i++) | ||
738 | if (cl[i] == m->client) | ||
739 | break; | ||
740 | if (i < cl_size) | ||
741 | continue; | ||
742 | GNUNET_array_append (cl, cl_size, m->client); | ||
743 | |||
744 | msize = path_length * sizeof (struct GNUNET_PeerIdentity); | ||
745 | msize += sizeof (struct GNUNET_DHT_MonitorGetMessage); | ||
746 | msize += sizeof (struct PendingMessage); | ||
747 | pm = GNUNET_malloc (msize); | ||
748 | mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1]; | ||
749 | pm->msg = &mmsg->header; | ||
750 | mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); | ||
751 | mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); | ||
752 | mmsg->options = htonl(options); | ||
753 | mmsg->type = htonl(type); | ||
754 | mmsg->hop_count = htonl(hop_count); | ||
755 | mmsg->desired_replication_level = htonl(desired_replication_level); | ||
756 | mmsg->get_path_length = htonl(path_length); | ||
757 | GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); | ||
758 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
759 | if (path_length > 0) | ||
760 | GNUNET_memcpy (msg_path, path, | ||
761 | path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
762 | add_pending_message (m->client, pm); | ||
763 | } | ||
764 | } | ||
765 | GNUNET_free_non_null (cl); | ||
766 | } | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Check if some client is monitoring PUT messages and notify | ||
771 | * them in that case. | ||
772 | * | ||
773 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
774 | * @param type The type of data in the request. | ||
775 | * @param hop_count Hop count so far. | ||
776 | * @param path_length number of entries in path (or 0 if not recorded). | ||
777 | * @param path peers on the PUT path (or NULL if not recorded). | ||
778 | * @param desired_replication_level Desired replication level. | ||
779 | * @param exp Expiration time of the data. | ||
780 | * @param key Key under which data is to be stored. | ||
781 | * @param data Pointer to the data carried. | ||
782 | * @param size Number of bytes in data. | ||
783 | */ | ||
784 | void | ||
785 | GDS_CLIENTS_process_put (uint32_t options, | ||
786 | enum GNUNET_BLOCK_Type type, | ||
787 | uint32_t hop_count, | ||
788 | uint32_t desired_replication_level, | ||
789 | unsigned int path_length, | ||
790 | const struct GNUNET_PeerIdentity *path, | ||
791 | struct GNUNET_TIME_Absolute exp, | ||
792 | const struct GNUNET_HashCode * key, | ||
793 | const void *data, | ||
794 | size_t size) | ||
795 | { | ||
796 | struct ClientMonitorRecord *m; | ||
797 | struct ClientList **cl; | ||
798 | unsigned int cl_size; | ||
799 | |||
800 | cl = NULL; | ||
801 | cl_size = 0; | ||
802 | for (m = monitor_head; NULL != m; m = m->next) | ||
803 | { | ||
804 | if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && | ||
805 | (NULL == m->key || | ||
806 | memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) | ||
807 | { | ||
808 | struct PendingMessage *pm; | ||
809 | struct GNUNET_DHT_MonitorPutMessage *mmsg; | ||
810 | struct GNUNET_PeerIdentity *msg_path; | ||
811 | size_t msize; | ||
812 | unsigned int i; | ||
813 | |||
814 | /* Don't send duplicates */ | ||
815 | for (i = 0; i < cl_size; i++) | ||
816 | if (cl[i] == m->client) | ||
817 | break; | ||
818 | if (i < cl_size) | ||
819 | continue; | ||
820 | GNUNET_array_append (cl, cl_size, m->client); | ||
821 | |||
822 | msize = size; | ||
823 | msize += path_length * sizeof (struct GNUNET_PeerIdentity); | ||
824 | msize += sizeof (struct GNUNET_DHT_MonitorPutMessage); | ||
825 | msize += sizeof (struct PendingMessage); | ||
826 | pm = GNUNET_malloc (msize); | ||
827 | mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1]; | ||
828 | pm->msg = (struct GNUNET_MessageHeader *) mmsg; | ||
829 | mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); | ||
830 | mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); | ||
831 | mmsg->options = htonl(options); | ||
832 | mmsg->type = htonl(type); | ||
833 | mmsg->hop_count = htonl(hop_count); | ||
834 | mmsg->desired_replication_level = htonl(desired_replication_level); | ||
835 | mmsg->put_path_length = htonl(path_length); | ||
836 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
837 | if (path_length > 0) | ||
838 | { | ||
839 | GNUNET_memcpy (msg_path, path, | ||
840 | path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
841 | } | ||
842 | mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); | ||
843 | GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); | ||
844 | if (size > 0) | ||
845 | GNUNET_memcpy (&msg_path[path_length], data, size); | ||
846 | add_pending_message (m->client, pm); | ||
847 | } | ||
848 | } | ||
849 | GNUNET_free_non_null (cl); | ||
850 | } | ||
851 | |||
852 | |||
853 | /** | ||
854 | * Route the given request via the DHT. | ||
855 | */ | ||
856 | static void | ||
857 | transmit_request (struct ClientQueryRecord *cqr) | ||
858 | { | ||
859 | GNUNET_STATISTICS_update (GDS_stats, | ||
860 | gettext_noop | ||
861 | ("# GET requests from clients injected"), 1, | ||
862 | GNUNET_NO); | ||
863 | |||
864 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
865 | "Initiating GET for %s, replication %u, already have %u replies\n", | ||
866 | GNUNET_h2s (&cqr->key), | ||
867 | cqr->replication, | ||
868 | cqr->seen_replies_count); | ||
869 | |||
870 | GDS_NEIGHBOURS_handle_get (&cqr->key, cqr->type, cqr->msg_options, | ||
871 | cqr->replication); | ||
872 | |||
873 | /* exponential back-off for retries. | ||
874 | * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ | ||
875 | cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); | ||
876 | cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); | ||
877 | } | ||
878 | |||
879 | |||
880 | /** | ||
881 | * Task that looks at the 'retry_heap' and transmits all of the requests | ||
882 | * on the heap that are ready for transmission. Then re-schedules | ||
883 | * itself (unless the heap is empty). | ||
884 | * | ||
885 | * @param cls unused | ||
886 | */ | ||
887 | static void | ||
888 | transmit_next_request_task (void *cls) | ||
889 | { | ||
890 | struct ClientQueryRecord *cqr; | ||
891 | struct GNUNET_TIME_Relative delay; | ||
892 | |||
893 | retry_task = NULL; | ||
894 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) | ||
895 | { | ||
896 | cqr->hnode = NULL; | ||
897 | delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); | ||
898 | if (delay.rel_value_us > 0) | ||
899 | { | ||
900 | cqr->hnode = | ||
901 | GNUNET_CONTAINER_heap_insert (retry_heap, cqr, | ||
902 | cqr->retry_time.abs_value_us); | ||
903 | retry_task = | ||
904 | GNUNET_SCHEDULER_add_delayed (delay, &transmit_next_request_task, | ||
905 | NULL); | ||
906 | return; | ||
907 | } | ||
908 | transmit_request (cqr); | ||
909 | cqr->hnode = | ||
910 | GNUNET_CONTAINER_heap_insert (retry_heap, cqr, | ||
911 | cqr->retry_time.abs_value_us); | ||
912 | } | ||
913 | } | ||
914 | |||
915 | |||
916 | /** | ||
917 | * Handler for PUT messages. | ||
918 | * | ||
919 | * @param cls closure for the service | ||
920 | * @param client the client we received this message from | ||
921 | * @param message the actual message received | ||
922 | */ | ||
923 | static void | ||
924 | handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, | ||
925 | const struct GNUNET_MessageHeader *message) | ||
926 | { | ||
927 | const struct GNUNET_DHT_ClientPutMessage *put_msg; | ||
928 | struct PendingMessage *pm; | ||
929 | struct GNUNET_DHT_ClientPutConfirmationMessage *conf; | ||
930 | uint16_t size; | ||
931 | |||
932 | size = ntohs (message->size); | ||
933 | if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) | ||
934 | { | ||
935 | GNUNET_break (0); | ||
936 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
937 | return; | ||
938 | } | ||
939 | GNUNET_STATISTICS_update (GDS_stats, | ||
940 | gettext_noop | ||
941 | ("# PUT requests received from clients"), 1, | ||
942 | GNUNET_NO); | ||
943 | put_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; | ||
944 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE DHT CLIENT-PUT %s\n", | ||
945 | GNUNET_h2s_full (&put_msg->key)); | ||
946 | /* give to local clients */ | ||
947 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
948 | "Handling local PUT of %u-bytes for query %s\n", | ||
949 | size - sizeof (struct GNUNET_DHT_ClientPutMessage), | ||
950 | GNUNET_h2s (&put_msg->key)); | ||
951 | DEBUG("PUT doing put i = %s\n",GNUNET_h2s(&(put_msg->key))); | ||
952 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (put_msg->expiration), | ||
953 | &put_msg->key, 0, NULL, 0, NULL, | ||
954 | ntohl (put_msg->type), | ||
955 | size - sizeof (struct GNUNET_DHT_ClientPutMessage), | ||
956 | &put_msg[1]); | ||
957 | |||
958 | GDS_NEIGHBOURS_handle_put (&put_msg->key, | ||
959 | ntohl (put_msg->type), ntohl (put_msg->options), | ||
960 | ntohl (put_msg->desired_replication_level), | ||
961 | GNUNET_TIME_absolute_ntoh (put_msg->expiration), | ||
962 | &put_msg[1], | ||
963 | size - sizeof (struct GNUNET_DHT_ClientPutMessage)); | ||
964 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
965 | sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); | ||
966 | conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; | ||
967 | conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); | ||
968 | conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK); | ||
969 | conf->reserved = htonl (0); | ||
970 | conf->unique_id = put_msg->unique_id; | ||
971 | pm->msg = &conf->header; | ||
972 | add_pending_message (find_active_client (client), pm); | ||
973 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
974 | } | ||
975 | |||
976 | |||
977 | /** | ||
978 | * Handler for DHT GET messages from the client. | ||
979 | * | ||
980 | * @param cls closure for the service | ||
981 | * @param client the client we received this message from | ||
982 | * @param message the actual message received | ||
983 | */ | ||
984 | static void | ||
985 | handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, | ||
986 | const struct GNUNET_MessageHeader *message) | ||
987 | { | ||
988 | const struct GNUNET_DHT_ClientGetMessage *get; | ||
989 | struct ClientQueryRecord *cqr; | ||
990 | size_t xquery_size; | ||
991 | const char *xquery; | ||
992 | uint16_t size; | ||
993 | |||
994 | size = ntohs (message->size); | ||
995 | if (size < sizeof (struct GNUNET_DHT_ClientGetMessage)) | ||
996 | { | ||
997 | GNUNET_break (0); | ||
998 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
999 | return; | ||
1000 | } | ||
1001 | xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage); | ||
1002 | get = (const struct GNUNET_DHT_ClientGetMessage *) message; | ||
1003 | xquery = (const char *) &get[1]; | ||
1004 | GNUNET_STATISTICS_update (GDS_stats, | ||
1005 | gettext_noop | ||
1006 | ("# GET requests received from clients"), 1, | ||
1007 | GNUNET_NO); | ||
1008 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1009 | "Received GET request for %s from local client %p, xq: %.*s\n", | ||
1010 | GNUNET_h2s (&get->key), client, xquery_size, xquery); | ||
1011 | |||
1012 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE CLIENT-GET %s\n", | ||
1013 | GNUNET_h2s_full (&get->key)); | ||
1014 | |||
1015 | |||
1016 | cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); | ||
1017 | cqr->key = get->key; | ||
1018 | cqr->client = find_active_client (client); | ||
1019 | cqr->xquery = (void *) &cqr[1]; | ||
1020 | GNUNET_memcpy (&cqr[1], xquery, xquery_size); | ||
1021 | cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); | ||
1022 | cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; | ||
1023 | cqr->retry_time = GNUNET_TIME_absolute_get (); | ||
1024 | cqr->unique_id = get->unique_id; | ||
1025 | cqr->xquery_size = xquery_size; | ||
1026 | cqr->replication = ntohl (get->desired_replication_level); | ||
1027 | cqr->msg_options = ntohl (get->options); | ||
1028 | cqr->type = ntohl (get->type); | ||
1029 | |||
1030 | // FIXME use cqr->key, set multihashmap create to GNUNET_YES | ||
1031 | GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, | ||
1032 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1033 | |||
1034 | struct GNUNET_PeerIdentity my_identity; | ||
1035 | my_identity = GDS_NEIGHBOURS_get_my_id(); | ||
1036 | GDS_CLIENTS_process_get (ntohl (get->options), | ||
1037 | ntohl (get->type), | ||
1038 | 0, | ||
1039 | ntohl (get->desired_replication_level), | ||
1040 | 1, | ||
1041 | &my_identity, | ||
1042 | &get->key); | ||
1043 | /* start remote requests */ | ||
1044 | if (NULL != retry_task) | ||
1045 | GNUNET_SCHEDULER_cancel (retry_task); | ||
1046 | retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); | ||
1047 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1048 | } | ||
1049 | |||
1050 | |||
1051 | /** | ||
1052 | * Closure for 'find_by_unique_id'. | ||
1053 | */ | ||
1054 | struct FindByUniqueIdContext | ||
1055 | { | ||
1056 | /** | ||
1057 | * Where to store the result, if found. | ||
1058 | */ | ||
1059 | struct ClientQueryRecord *cqr; | ||
1060 | |||
1061 | uint64_t unique_id; | ||
1062 | }; | ||
1063 | |||
1064 | |||
1065 | /** | ||
1066 | * Function called for each existing DHT record for the given | ||
1067 | * query. Checks if it matches the UID given in the closure | ||
1068 | * and if so returns the entry as a result. | ||
1069 | * | ||
1070 | * @param cls the search context | ||
1071 | * @param key query for the lookup (not used) | ||
1072 | * @param value the 'struct ClientQueryRecord' | ||
1073 | * @return GNUNET_YES to continue iteration (result not yet found) | ||
1074 | */ | ||
1075 | static int | ||
1076 | find_by_unique_id (void *cls, | ||
1077 | const struct GNUNET_HashCode *key, | ||
1078 | void *value) | ||
1079 | { | ||
1080 | struct FindByUniqueIdContext *fui_ctx = cls; | ||
1081 | struct ClientQueryRecord *cqr = value; | ||
1082 | |||
1083 | if (cqr->unique_id != fui_ctx->unique_id) | ||
1084 | return GNUNET_YES; | ||
1085 | fui_ctx->cqr = cqr; | ||
1086 | return GNUNET_NO; | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | /** | ||
1091 | * Handler for "GET result seen" messages from the client. | ||
1092 | * | ||
1093 | * @param cls closure for the service | ||
1094 | * @param client the client we received this message from | ||
1095 | * @param message the actual message received | ||
1096 | */ | ||
1097 | static void | ||
1098 | handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client, | ||
1099 | const struct GNUNET_MessageHeader *message) | ||
1100 | { | ||
1101 | const struct GNUNET_DHT_ClientGetResultSeenMessage *seen; | ||
1102 | uint16_t size; | ||
1103 | unsigned int hash_count; | ||
1104 | unsigned int old_count; | ||
1105 | const struct GNUNET_HashCode *hc; | ||
1106 | struct FindByUniqueIdContext fui_ctx; | ||
1107 | struct ClientQueryRecord *cqr; | ||
1108 | |||
1109 | size = ntohs (message->size); | ||
1110 | if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) | ||
1111 | { | ||
1112 | GNUNET_break (0); | ||
1113 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1114 | return; | ||
1115 | } | ||
1116 | seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message; | ||
1117 | hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode); | ||
1118 | if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode)) | ||
1119 | { | ||
1120 | GNUNET_break (0); | ||
1121 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1122 | return; | ||
1123 | } | ||
1124 | hc = (const struct GNUNET_HashCode*) &seen[1]; | ||
1125 | fui_ctx.unique_id = seen->unique_id; | ||
1126 | fui_ctx.cqr = NULL; | ||
1127 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
1128 | &seen->key, | ||
1129 | &find_by_unique_id, | ||
1130 | &fui_ctx); | ||
1131 | if (NULL == (cqr = fui_ctx.cqr)) | ||
1132 | { | ||
1133 | GNUNET_break (0); | ||
1134 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1135 | return; | ||
1136 | } | ||
1137 | /* finally, update 'seen' list */ | ||
1138 | old_count = cqr->seen_replies_count; | ||
1139 | GNUNET_array_grow (cqr->seen_replies, | ||
1140 | cqr->seen_replies_count, | ||
1141 | cqr->seen_replies_count + hash_count); | ||
1142 | GNUNET_memcpy (&cqr->seen_replies[old_count], | ||
1143 | hc, | ||
1144 | sizeof (struct GNUNET_HashCode) * hash_count); | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | /** | ||
1149 | * Closure for 'remove_by_unique_id'. | ||
1150 | */ | ||
1151 | struct RemoveByUniqueIdContext | ||
1152 | { | ||
1153 | /** | ||
1154 | * Client that issued the removal request. | ||
1155 | */ | ||
1156 | struct ClientList *client; | ||
1157 | |||
1158 | /** | ||
1159 | * Unique ID of the request. | ||
1160 | */ | ||
1161 | uint64_t unique_id; | ||
1162 | }; | ||
1163 | |||
1164 | |||
1165 | /** | ||
1166 | * Iterator over hash map entries that frees all entries | ||
1167 | * that match the given client and unique ID. | ||
1168 | * | ||
1169 | * @param cls unique ID and client to search for in source routes | ||
1170 | * @param key current key code | ||
1171 | * @param value value in the hash map, a ClientQueryRecord | ||
1172 | * @return GNUNET_YES (we should continue to iterate) | ||
1173 | */ | ||
1174 | static int | ||
1175 | remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
1176 | { | ||
1177 | const struct RemoveByUniqueIdContext *ctx = cls; | ||
1178 | struct ClientQueryRecord *record = value; | ||
1179 | |||
1180 | if (record->unique_id != ctx->unique_id) | ||
1181 | return GNUNET_YES; | ||
1182 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1183 | "Removing client %p's record for key %s (by unique id)\n", | ||
1184 | ctx->client->client_handle, GNUNET_h2s (key)); | ||
1185 | return remove_client_records (ctx->client, key, record); | ||
1186 | } | ||
1187 | |||
1188 | |||
1189 | /** | ||
1190 | * Handler for any generic DHT stop messages, calls the appropriate handler | ||
1191 | * depending on message type (if processed locally) | ||
1192 | * | ||
1193 | * @param cls closure for the service | ||
1194 | * @param client the client we received this message from | ||
1195 | * @param message the actual message received | ||
1196 | * | ||
1197 | */ | ||
1198 | static void | ||
1199 | handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, | ||
1200 | const struct GNUNET_MessageHeader *message) | ||
1201 | { | ||
1202 | const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg = | ||
1203 | (const struct GNUNET_DHT_ClientGetStopMessage *) message; | ||
1204 | struct RemoveByUniqueIdContext ctx; | ||
1205 | |||
1206 | GNUNET_STATISTICS_update (GDS_stats, | ||
1207 | gettext_noop | ||
1208 | ("# GET STOP requests received from clients"), 1, | ||
1209 | GNUNET_NO); | ||
1210 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1211 | "Received GET STOP request for %s from local client %p\n", | ||
1212 | GNUNET_h2s (&dht_stop_msg->key), | ||
1213 | client); | ||
1214 | ctx.client = find_active_client (client); | ||
1215 | ctx.unique_id = dht_stop_msg->unique_id; | ||
1216 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key, | ||
1217 | &remove_by_unique_id, &ctx); | ||
1218 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1219 | } | ||
1220 | |||
1221 | |||
1222 | /** | ||
1223 | * Handler for monitor start messages | ||
1224 | * | ||
1225 | * @param cls closure for the service | ||
1226 | * @param client the client we received this message from | ||
1227 | * @param message the actual message received | ||
1228 | * | ||
1229 | */ | ||
1230 | static void | ||
1231 | handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, | ||
1232 | const struct GNUNET_MessageHeader *message) | ||
1233 | { | ||
1234 | struct ClientMonitorRecord *r; | ||
1235 | const struct GNUNET_DHT_MonitorStartStopMessage *msg; | ||
1236 | |||
1237 | msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; | ||
1238 | r = GNUNET_new (struct ClientMonitorRecord); | ||
1239 | |||
1240 | r->client = find_active_client(client); | ||
1241 | r->type = ntohl(msg->type); | ||
1242 | r->get = ntohs(msg->get); | ||
1243 | r->get_resp = ntohs(msg->get_resp); | ||
1244 | r->put = ntohs(msg->put); | ||
1245 | if (0 == ntohs(msg->filter_key)) | ||
1246 | r->key = NULL; | ||
1247 | else | ||
1248 | { | ||
1249 | r->key = GNUNET_new (struct GNUNET_HashCode); | ||
1250 | GNUNET_memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode)); | ||
1251 | } | ||
1252 | GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r); | ||
1253 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1254 | } | ||
1255 | |||
1256 | |||
1257 | /** | ||
1258 | * Handler for monitor stop messages | ||
1259 | * | ||
1260 | * @param cls closure for the service | ||
1261 | * @param client the client we received this message from | ||
1262 | * @param message the actual message received | ||
1263 | * | ||
1264 | */ | ||
1265 | static void | ||
1266 | handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, | ||
1267 | const struct GNUNET_MessageHeader *message) | ||
1268 | { | ||
1269 | struct ClientMonitorRecord *r; | ||
1270 | const struct GNUNET_DHT_MonitorStartStopMessage *msg; | ||
1271 | int keys_match; | ||
1272 | |||
1273 | msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; | ||
1274 | r = monitor_head; | ||
1275 | |||
1276 | while (NULL != r) | ||
1277 | { | ||
1278 | if (NULL == r->key) | ||
1279 | keys_match = (0 == ntohs(msg->filter_key)); | ||
1280 | else | ||
1281 | { | ||
1282 | keys_match = (0 != ntohs(msg->filter_key) | ||
1283 | && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode))); | ||
1284 | } | ||
1285 | if (find_active_client(client) == r->client | ||
1286 | && ntohl(msg->type) == r->type | ||
1287 | && r->get == msg->get | ||
1288 | && r->get_resp == msg->get_resp | ||
1289 | && r->put == msg->put | ||
1290 | && keys_match | ||
1291 | ) | ||
1292 | { | ||
1293 | GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r); | ||
1294 | GNUNET_free_non_null (r->key); | ||
1295 | GNUNET_free (r); | ||
1296 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1297 | return; /* Delete only ONE entry */ | ||
1298 | } | ||
1299 | r = r->next; | ||
1300 | } | ||
1301 | |||
1302 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1303 | } | ||
1304 | |||
1305 | |||
1306 | /** | ||
1307 | * Functions with this signature are called whenever a client | ||
1308 | * is disconnected on the network level. | ||
1309 | * | ||
1310 | * @param cls closure (NULL for dht) | ||
1311 | * @param client identification of the client; NULL | ||
1312 | * for the last call when the server is destroyed | ||
1313 | */ | ||
1314 | static void | ||
1315 | handle_client_disconnect (void *cls, | ||
1316 | struct GNUNET_SERVER_Client *client) | ||
1317 | { | ||
1318 | struct ClientList *pos; | ||
1319 | struct PendingMessage *reply; | ||
1320 | struct ClientMonitorRecord *monitor; | ||
1321 | |||
1322 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1323 | "Local client %p disconnects\n", | ||
1324 | client); | ||
1325 | pos = find_active_client (client); | ||
1326 | GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); | ||
1327 | if (pos->transmit_handle != NULL) | ||
1328 | GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); | ||
1329 | while (NULL != (reply = pos->pending_head)) | ||
1330 | { | ||
1331 | GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); | ||
1332 | GNUNET_free (reply); | ||
1333 | } | ||
1334 | monitor = monitor_head; | ||
1335 | while (NULL != monitor) | ||
1336 | { | ||
1337 | if (monitor->client == pos) | ||
1338 | { | ||
1339 | struct ClientMonitorRecord *next; | ||
1340 | |||
1341 | GNUNET_free_non_null (monitor->key); | ||
1342 | next = monitor->next; | ||
1343 | GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); | ||
1344 | GNUNET_free (monitor); | ||
1345 | monitor = next; | ||
1346 | } | ||
1347 | else | ||
1348 | monitor = monitor->next; | ||
1349 | } | ||
1350 | GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, | ||
1351 | pos); | ||
1352 | GNUNET_free (pos); | ||
1353 | } | ||
1354 | |||
1355 | |||
1356 | |||
1357 | /** | ||
1358 | * Initialize client subsystem. | ||
1359 | * | ||
1360 | * @param server the initialized server | ||
1361 | */ | ||
1362 | void | ||
1363 | GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) | ||
1364 | { | ||
1365 | static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { | ||
1366 | {&handle_dht_local_put, NULL, | ||
1367 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, 0}, | ||
1368 | {&handle_dht_local_get, NULL, | ||
1369 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0}, | ||
1370 | {&handle_dht_local_get_stop, NULL, | ||
1371 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, | ||
1372 | sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, | ||
1373 | {&handle_dht_local_monitor, NULL, | ||
1374 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, | ||
1375 | sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, | ||
1376 | {&handle_dht_local_monitor_stop, NULL, | ||
1377 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, | ||
1378 | sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, | ||
1379 | {&handle_dht_local_get_result_seen, NULL, | ||
1380 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0}, | ||
1381 | {NULL, NULL, 0, 0} | ||
1382 | }; | ||
1383 | forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); | ||
1384 | retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1385 | GNUNET_SERVER_add_handlers (server, plugin_handlers); | ||
1386 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | ||
1387 | } | ||
1388 | |||
1389 | |||
1390 | /** | ||
1391 | * Shutdown client subsystem. | ||
1392 | */ | ||
1393 | void | ||
1394 | GDS_CLIENTS_done () | ||
1395 | { | ||
1396 | GNUNET_assert (client_head == NULL); | ||
1397 | GNUNET_assert (client_tail == NULL); | ||
1398 | if (NULL != retry_task) | ||
1399 | { | ||
1400 | GNUNET_SCHEDULER_cancel (retry_task); | ||
1401 | retry_task = NULL; | ||
1402 | } | ||
1403 | if (NULL != retry_heap) | ||
1404 | { | ||
1405 | GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap)); | ||
1406 | GNUNET_CONTAINER_heap_destroy (retry_heap); | ||
1407 | retry_heap = NULL; | ||
1408 | } | ||
1409 | if (NULL != forward_map) | ||
1410 | { | ||
1411 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map)); | ||
1412 | GNUNET_CONTAINER_multihashmap_destroy (forward_map); | ||
1413 | forward_map = NULL; | ||
1414 | } | ||
1415 | } | ||
1416 | |||
1417 | /* end of gnunet-service-dht_clients.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_clients.h b/src/dht/gnunet-service-xdht_clients.h deleted file mode 100644 index f51564136..000000000 --- a/src/dht/gnunet-service-xdht_clients.h +++ /dev/null | |||
@@ -1,149 +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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_clients.h | ||
23 | * @brief GNUnet DHT service's client management code | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | #ifndef GNUNET_SERVICE_DHT_CLIENT_H | ||
28 | #define GNUNET_SERVICE_DHT_CLIENT_H | ||
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_block_lib.h" | ||
32 | |||
33 | /** | ||
34 | * Handle a reply we've received from another peer. If the reply | ||
35 | * matches any of our pending queries, forward it to the respective | ||
36 | * client(s). | ||
37 | * | ||
38 | * @param expiration when will the reply expire | ||
39 | * @param key the query this reply is for | ||
40 | * @param get_path_length number of peers in @a get_path | ||
41 | * @param get_path path the reply took on get | ||
42 | * @param put_path_length number of peers in @a put_path | ||
43 | * @param put_path path the reply took on put | ||
44 | * @param type type of the reply | ||
45 | * @param data_size number of bytes in @a data | ||
46 | * @param data application payload data | ||
47 | */ | ||
48 | void | ||
49 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | ||
50 | const struct GNUNET_HashCode *key, | ||
51 | unsigned int get_path_length, | ||
52 | const struct GNUNET_PeerIdentity *get_path, | ||
53 | unsigned int put_path_length, | ||
54 | const struct GNUNET_PeerIdentity *put_path, | ||
55 | enum GNUNET_BLOCK_Type type, size_t data_size, | ||
56 | const void *data); | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Check if some client is monitoring GET messages and notify | ||
61 | * them in that case. | ||
62 | * | ||
63 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
64 | * @param type The type of data in the request. | ||
65 | * @param hop_count Hop count so far. | ||
66 | * @param path_length number of entries in path (or 0 if not recorded). | ||
67 | * @param path peers on the GET path (or NULL if not recorded). | ||
68 | * @param desired_replication_level Desired replication level. | ||
69 | * @param key Key of the requested data. | ||
70 | */ | ||
71 | void | ||
72 | GDS_CLIENTS_process_get (uint32_t options, | ||
73 | enum GNUNET_BLOCK_Type type, | ||
74 | uint32_t hop_count, | ||
75 | uint32_t desired_replication_level, | ||
76 | unsigned int path_length, | ||
77 | const struct GNUNET_PeerIdentity *path, | ||
78 | const struct GNUNET_HashCode *key); | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Check if some client is monitoring GET RESP messages and notify | ||
83 | * them in that case. | ||
84 | * | ||
85 | * @param type The type of data in the result. | ||
86 | * @param get_path Peers on GET path (or NULL if not recorded). | ||
87 | * @param get_path_length number of entries in @a get_path. | ||
88 | * @param put_path peers on the PUT path (or NULL if not recorded). | ||
89 | * @param put_path_length number of entries in @a get_path. | ||
90 | * @param exp Expiration time of the data. | ||
91 | * @param key Key of the @a data. | ||
92 | * @param data Pointer to the result data. | ||
93 | * @param size Number of bytes in @a data. | ||
94 | */ | ||
95 | void | ||
96 | GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, | ||
97 | const struct GNUNET_PeerIdentity *get_path, | ||
98 | unsigned int get_path_length, | ||
99 | const struct GNUNET_PeerIdentity *put_path, | ||
100 | unsigned int put_path_length, | ||
101 | struct GNUNET_TIME_Absolute exp, | ||
102 | const struct GNUNET_HashCode * key, | ||
103 | const void *data, | ||
104 | size_t size); | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Check if some client is monitoring PUT messages and notify | ||
109 | * them in that case. | ||
110 | * | ||
111 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
112 | * @param type The type of data in the request. | ||
113 | * @param hop_count Hop count so far. | ||
114 | * @param path_length number of entries in path (or 0 if not recorded). | ||
115 | * @param path peers on the PUT path (or NULL if not recorded). | ||
116 | * @param desired_replication_level Desired replication level. | ||
117 | * @param exp Expiration time of the data. | ||
118 | * @param key Key under which data is to be stored. | ||
119 | * @param data Pointer to the data carried. | ||
120 | * @param size Number of bytes in data. | ||
121 | */ | ||
122 | void | ||
123 | GDS_CLIENTS_process_put (uint32_t options, | ||
124 | enum GNUNET_BLOCK_Type type, | ||
125 | uint32_t hop_count, | ||
126 | uint32_t desired_replication_level, | ||
127 | unsigned int path_length, | ||
128 | const struct GNUNET_PeerIdentity *path, | ||
129 | struct GNUNET_TIME_Absolute exp, | ||
130 | const struct GNUNET_HashCode * key, | ||
131 | const void *data, | ||
132 | size_t size); | ||
133 | |||
134 | /** | ||
135 | * Initialize client subsystem. | ||
136 | * | ||
137 | * @param server the initialized server | ||
138 | */ | ||
139 | void | ||
140 | GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server); | ||
141 | |||
142 | |||
143 | /** | ||
144 | * Shutdown client subsystem. | ||
145 | */ | ||
146 | void | ||
147 | GDS_CLIENTS_done (void); | ||
148 | |||
149 | #endif | ||
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c deleted file mode 100644 index 10ae0068e..000000000 --- a/src/dht/gnunet-service-xdht_datacache.c +++ /dev/null | |||
@@ -1,401 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file dht/gnunet-service-xdht_datacache.c | ||
22 | * @brief GNUnet DHT service's datacache integration | ||
23 | * @author Christian Grothoff | ||
24 | * @author Nathan Evans | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_datacache_lib.h" | ||
28 | #include "gnunet-service-xdht_clients.h" | ||
29 | #include "gnunet-service-xdht_datacache.h" | ||
30 | #include "gnunet-service-xdht_routing.h" | ||
31 | #include "gnunet-service-xdht_neighbours.h" | ||
32 | #include "gnunet-service-dht.h" | ||
33 | |||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__) | ||
35 | |||
36 | #define DEBUG(...) \ | ||
37 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
38 | |||
39 | /** | ||
40 | * Handle to the datacache service (for inserting/retrieving data) | ||
41 | */ | ||
42 | static struct GNUNET_DATACACHE_Handle *datacache; | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Handle a datum we've received from another peer. Cache if | ||
47 | * possible. | ||
48 | * | ||
49 | * @param expiration when will the reply expire | ||
50 | * @param key the query this reply is for | ||
51 | * @param put_path_length number of peers in @a put_path | ||
52 | * @param put_path path the reply took on put | ||
53 | * @param type type of the reply | ||
54 | * @param data_size number of bytes in @a data | ||
55 | * @param data application payload data | ||
56 | */ | ||
57 | void | ||
58 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | ||
59 | const struct GNUNET_HashCode *key, | ||
60 | unsigned int put_path_length, | ||
61 | const struct GNUNET_PeerIdentity *put_path, | ||
62 | enum GNUNET_BLOCK_Type type, | ||
63 | size_t data_size, | ||
64 | const void *data) | ||
65 | { | ||
66 | int r; | ||
67 | |||
68 | if (NULL == datacache) | ||
69 | { | ||
70 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
71 | "PUT request received, but have no datacache!\n"); | ||
72 | return; | ||
73 | } | ||
74 | if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
75 | { | ||
76 | GNUNET_break (0); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | /* Put size is actual data size plus struct overhead plus path length (if any) */ | ||
81 | r = GNUNET_DATACACHE_put (datacache, | ||
82 | key, | ||
83 | data_size, | ||
84 | data, | ||
85 | type, | ||
86 | expiration, | ||
87 | put_path_length, | ||
88 | put_path); | ||
89 | if (GNUNET_OK == r) | ||
90 | GNUNET_STATISTICS_update (GDS_stats, | ||
91 | gettext_noop ("# ITEMS stored in datacache"), 1, | ||
92 | GNUNET_NO); | ||
93 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
94 | "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", | ||
95 | GNUNET_h2s (key), | ||
96 | data_size, | ||
97 | r, | ||
98 | put_path_length); | ||
99 | } | ||
100 | |||
101 | |||
102 | /** | ||
103 | * List of peers in the get path. | ||
104 | */ | ||
105 | struct GetPath | ||
106 | { | ||
107 | /** | ||
108 | * Pointer to next item in the list | ||
109 | */ | ||
110 | struct GetPath *next; | ||
111 | |||
112 | /** | ||
113 | * Pointer to previous item in the list | ||
114 | */ | ||
115 | struct GetPath *prev; | ||
116 | |||
117 | /** | ||
118 | * An element in the get path. | ||
119 | */ | ||
120 | struct GNUNET_PeerIdentity peer; | ||
121 | }; | ||
122 | |||
123 | |||
124 | /** | ||
125 | * Context containing information about a GET request. | ||
126 | */ | ||
127 | struct GetRequestContext | ||
128 | { | ||
129 | /** | ||
130 | * extended query (see gnunet_block_lib.h). | ||
131 | */ | ||
132 | const void *xquery; | ||
133 | |||
134 | /** | ||
135 | * Bloomfilter to filter out duplicate replies (updated) | ||
136 | */ | ||
137 | struct GNUNET_CONTAINER_BloomFilter **reply_bf; | ||
138 | |||
139 | /** | ||
140 | * The key this request was about | ||
141 | */ | ||
142 | struct GNUNET_HashCode key; | ||
143 | |||
144 | /** | ||
145 | * Number of bytes in xquery. | ||
146 | */ | ||
147 | size_t xquery_size; | ||
148 | |||
149 | /** | ||
150 | * Mutator value for the @e reply_bf, see gnunet_block_lib.h | ||
151 | */ | ||
152 | uint32_t reply_bf_mutator; | ||
153 | |||
154 | /** | ||
155 | * Total number of peers in get path. | ||
156 | */ | ||
157 | unsigned int get_path_length; | ||
158 | |||
159 | /** | ||
160 | * Return value to give back. | ||
161 | */ | ||
162 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
163 | |||
164 | /** | ||
165 | * Peeer which has the data for the key. | ||
166 | */ | ||
167 | struct GNUNET_PeerIdentity source_peer; | ||
168 | |||
169 | /** | ||
170 | * Next hop to forward the get result to. | ||
171 | */ | ||
172 | struct GNUNET_PeerIdentity next_hop; | ||
173 | |||
174 | /** | ||
175 | * Head of get path. | ||
176 | */ | ||
177 | struct GetPath *head; | ||
178 | |||
179 | /** | ||
180 | * Tail of get path. | ||
181 | */ | ||
182 | struct GetPath *tail; | ||
183 | |||
184 | /* get_path */ | ||
185 | }; | ||
186 | |||
187 | |||
188 | /** | ||
189 | * Iterator for local get request results, | ||
190 | * | ||
191 | * @param cls closure for iterator, a `struct GetRequestContext` | ||
192 | * @param key the key this @a data is stored under | ||
193 | * @param size the size of the data identified by key | ||
194 | * @param data the actual data | ||
195 | * @param type the type of the @a data | ||
196 | * @param exp when does this value expire? | ||
197 | * @param put_path_length number of peers in @a put_path | ||
198 | * @param put_path path the reply took on put | ||
199 | * @return #GNUNET_OK to continue iteration, anything else | ||
200 | * to stop iteration. | ||
201 | */ | ||
202 | static int | ||
203 | datacache_get_iterator (void *cls, | ||
204 | const struct GNUNET_HashCode *key, | ||
205 | size_t size, | ||
206 | const char *data, | ||
207 | enum GNUNET_BLOCK_Type type, | ||
208 | struct GNUNET_TIME_Absolute exp, | ||
209 | unsigned int put_path_length, | ||
210 | const struct GNUNET_PeerIdentity *put_path) | ||
211 | { | ||
212 | struct GetRequestContext *ctx = cls; | ||
213 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
214 | |||
215 | eval = | ||
216 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
217 | type, | ||
218 | GNUNET_BLOCK_EO_NONE, | ||
219 | key, | ||
220 | ctx->reply_bf, | ||
221 | ctx->reply_bf_mutator, | ||
222 | ctx->xquery, | ||
223 | ctx->xquery_size, | ||
224 | data, | ||
225 | size); | ||
226 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
227 | "Found reply for query %s in datacache, evaluation result is %d\n", | ||
228 | GNUNET_h2s (key), (int) eval); | ||
229 | ctx->eval = eval; | ||
230 | |||
231 | switch (eval) | ||
232 | { | ||
233 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
234 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
235 | /* forward to local clients */ | ||
236 | GNUNET_STATISTICS_update (GDS_stats, | ||
237 | gettext_noop | ||
238 | ("# Good RESULTS found in datacache"), 1, | ||
239 | GNUNET_NO); | ||
240 | struct GNUNET_PeerIdentity *get_path; | ||
241 | get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * | ||
242 | ctx->get_path_length); | ||
243 | struct GetPath *iterator; | ||
244 | iterator = ctx->head; | ||
245 | int i = 0; | ||
246 | while (i < ctx->get_path_length) | ||
247 | { | ||
248 | get_path[i] = iterator->peer; | ||
249 | i++; | ||
250 | iterator = iterator->next; | ||
251 | } | ||
252 | GDS_NEIGHBOURS_send_get_result (key,type, | ||
253 | &ctx->next_hop, | ||
254 | &ctx->source_peer, | ||
255 | put_path_length, | ||
256 | put_path, | ||
257 | ctx->get_path_length, | ||
258 | get_path, | ||
259 | exp, | ||
260 | data, | ||
261 | size); | ||
262 | GNUNET_free_non_null (get_path); | ||
263 | break; | ||
264 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
265 | GNUNET_STATISTICS_update (GDS_stats, | ||
266 | gettext_noop | ||
267 | ("# Duplicate RESULTS found in datacache"), 1, | ||
268 | GNUNET_NO); | ||
269 | break; | ||
270 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
271 | GNUNET_STATISTICS_update (GDS_stats, | ||
272 | gettext_noop | ||
273 | ("# Invalid RESULTS found in datacache"), 1, | ||
274 | GNUNET_NO); | ||
275 | break; | ||
276 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
277 | GNUNET_STATISTICS_update (GDS_stats, | ||
278 | gettext_noop | ||
279 | ("# Irrelevant RESULTS found in datacache"), 1, | ||
280 | GNUNET_NO); | ||
281 | break; | ||
282 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
283 | GNUNET_break (0); | ||
284 | break; | ||
285 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
286 | GNUNET_break_op (0); | ||
287 | return GNUNET_SYSERR; | ||
288 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
289 | GNUNET_STATISTICS_update (GDS_stats, | ||
290 | gettext_noop | ||
291 | ("# Unsupported RESULTS found in datacache"), 1, | ||
292 | GNUNET_NO); | ||
293 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
294 | _("Unsupported block type (%u) in local response!\n"), | ||
295 | type); | ||
296 | break; | ||
297 | } | ||
298 | |||
299 | return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; | ||
300 | } | ||
301 | |||
302 | |||
303 | /** | ||
304 | * Handle a GET request we've received from another peer. | ||
305 | * | ||
306 | * @param key the query | ||
307 | * @param type requested data type | ||
308 | * @param xquery extended query | ||
309 | * @param xquery_size number of bytes in @a xquery | ||
310 | * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL | ||
311 | * @param reply_bf_mutator mutation value for @a reply_bf | ||
312 | * @return evaluation result for the local replies | ||
313 | * @get_path_length Total number of peers in get path | ||
314 | * @get_path Peers in get path. | ||
315 | */ | ||
316 | enum GNUNET_BLOCK_EvaluationResult | ||
317 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, | ||
318 | enum GNUNET_BLOCK_Type type, | ||
319 | const void *xquery, | ||
320 | size_t xquery_size, | ||
321 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | ||
322 | uint32_t reply_bf_mutator, | ||
323 | uint32_t get_path_length, | ||
324 | struct GNUNET_PeerIdentity *get_path, | ||
325 | struct GNUNET_PeerIdentity *next_hop, | ||
326 | struct GNUNET_PeerIdentity *source_peer) | ||
327 | { | ||
328 | struct GetRequestContext ctx; | ||
329 | unsigned int r; | ||
330 | |||
331 | if (datacache == NULL) | ||
332 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
333 | GNUNET_STATISTICS_update (GDS_stats, | ||
334 | gettext_noop ("# GET requests given to datacache"), | ||
335 | 1, GNUNET_NO); | ||
336 | ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
337 | ctx.key = *key; | ||
338 | ctx.xquery = xquery; | ||
339 | ctx.xquery_size = xquery_size; | ||
340 | ctx.reply_bf = reply_bf; | ||
341 | ctx.reply_bf_mutator = reply_bf_mutator; | ||
342 | ctx.get_path_length = get_path_length; | ||
343 | |||
344 | if (NULL != next_hop) | ||
345 | ctx.next_hop = *next_hop; | ||
346 | unsigned int i = 0; | ||
347 | |||
348 | ctx.head = NULL; | ||
349 | ctx.tail = NULL; | ||
350 | if (NULL != get_path) | ||
351 | { | ||
352 | while (i < get_path_length) | ||
353 | { | ||
354 | struct GetPath *element; | ||
355 | element = GNUNET_new (struct GetPath); | ||
356 | element->next = NULL; | ||
357 | element->prev = NULL; | ||
358 | element->peer = get_path[i]; | ||
359 | GNUNET_CONTAINER_DLL_insert_tail (ctx.head, ctx.tail, element); | ||
360 | i++; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | r = GNUNET_DATACACHE_get (datacache, | ||
365 | key, | ||
366 | type, | ||
367 | &datacache_get_iterator, | ||
368 | &ctx); | ||
369 | DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n", | ||
370 | GNUNET_h2s (key), | ||
371 | ctx.eval, | ||
372 | r); | ||
373 | return ctx.eval; | ||
374 | } | ||
375 | |||
376 | |||
377 | /** | ||
378 | * Initialize datacache subsystem. | ||
379 | */ | ||
380 | void | ||
381 | GDS_DATACACHE_init () | ||
382 | { | ||
383 | datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); | ||
384 | } | ||
385 | |||
386 | |||
387 | /** | ||
388 | * Shutdown datacache subsystem. | ||
389 | */ | ||
390 | void | ||
391 | GDS_DATACACHE_done () | ||
392 | { | ||
393 | if (NULL != datacache) | ||
394 | { | ||
395 | GNUNET_DATACACHE_destroy (datacache); | ||
396 | datacache = NULL; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | |||
401 | /* end of gnunet-service-xdht_datacache.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_datacache.h b/src/dht/gnunet-service-xdht_datacache.h deleted file mode 100644 index f160d03bc..000000000 --- a/src/dht/gnunet-service-xdht_datacache.h +++ /dev/null | |||
@@ -1,90 +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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-dht_datacache.h | ||
23 | * @brief GNUnet DHT service's datacache integration | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | #ifndef GNUNET_SERVICE_DHT_DATACACHE_H | ||
28 | #define GNUNET_SERVICE_DHT_DATACACHE_H | ||
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_block_lib.h" | ||
32 | |||
33 | /** | ||
34 | * Handle a datum we've received from another peer. Cache if | ||
35 | * possible. | ||
36 | * | ||
37 | * @param expiration when will the reply expire | ||
38 | * @param key the query this reply is for | ||
39 | * @param put_path_length number of peers in 'put_path' | ||
40 | * @param put_path path the reply took on put | ||
41 | * @param type type of the reply | ||
42 | * @param data_size number of bytes in 'data' | ||
43 | * @param data application payload data | ||
44 | */ | ||
45 | void | ||
46 | GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, | ||
47 | const struct GNUNET_HashCode * key, | ||
48 | unsigned int put_path_length, | ||
49 | const struct GNUNET_PeerIdentity *put_path, | ||
50 | enum GNUNET_BLOCK_Type type, size_t data_size, | ||
51 | const void *data); | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Handle a GET request we've received from another peer. | ||
56 | * | ||
57 | * @param key the query | ||
58 | * @param type requested data type | ||
59 | * @param xquery extended query | ||
60 | * @param xquery_size number of bytes in xquery | ||
61 | * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL | ||
62 | * @param reply_bf_mutator mutation value for reply_bf | ||
63 | * @return evaluation result for the local replies | ||
64 | */ | ||
65 | enum GNUNET_BLOCK_EvaluationResult | ||
66 | GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, | ||
67 | enum GNUNET_BLOCK_Type type, const void *xquery, | ||
68 | size_t xquery_size, | ||
69 | struct GNUNET_CONTAINER_BloomFilter **reply_bf, | ||
70 | uint32_t reply_bf_mutator, | ||
71 | uint32_t get_path_length, | ||
72 | struct GNUNET_PeerIdentity *get_path, | ||
73 | struct GNUNET_PeerIdentity *next_hop, | ||
74 | struct GNUNET_PeerIdentity *source_peer); | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Initialize datacache subsystem. | ||
79 | */ | ||
80 | void | ||
81 | GDS_DATACACHE_init (void); | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Shutdown datacache subsystem. | ||
86 | */ | ||
87 | void | ||
88 | GDS_DATACACHE_done (void); | ||
89 | |||
90 | #endif | ||
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c index 7ab462a58..e3462f618 100644 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ b/src/dht/gnunet-service-xdht_neighbours.c | |||
@@ -37,10 +37,9 @@ | |||
37 | #include "gnunet_transport_service.h" | 37 | #include "gnunet_transport_service.h" |
38 | #include "gnunet_dht_service.h" | 38 | #include "gnunet_dht_service.h" |
39 | #include "gnunet_statistics_service.h" | 39 | #include "gnunet_statistics_service.h" |
40 | #include "gnunet-service-xdht.h" | 40 | #include "gnunet-service-dht.h" |
41 | #include "gnunet-service-xdht_clients.h" | 41 | #include "gnunet-service-dht_datacache.h" |
42 | #include "gnunet-service-xdht_datacache.h" | 42 | #include "gnunet-service-dht_neighbours.h" |
43 | #include "gnunet-service-xdht_neighbours.h" | ||
44 | #include "gnunet-service-xdht_routing.h" | 43 | #include "gnunet-service-xdht_routing.h" |
45 | #include "dht.h" | 44 | #include "dht.h" |
46 | 45 | ||
@@ -1017,7 +1016,7 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *queryi | |||
1017 | tsrm->finger_identity = *finger; | 1016 | tsrm->finger_identity = *finger; |
1018 | tsrm->is_predecessor = htonl (is_predecessor); | 1017 | tsrm->is_predecessor = htonl (is_predecessor); |
1019 | tsrm->trail_id = *trail_id; | 1018 | tsrm->trail_id = *trail_id; |
1020 | tsrm->ultimate_destination_finger_value | 1019 | tsrm->ultimate_destination_finger_value |
1021 | = GNUNET_htonll (ultimate_destination_finger_value); | 1020 | = GNUNET_htonll (ultimate_destination_finger_value); |
1022 | GNUNET_memcpy (&tsrm[1], | 1021 | GNUNET_memcpy (&tsrm[1], |
1023 | trail_peer_list, | 1022 | trail_peer_list, |
@@ -1114,7 +1113,7 @@ GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_pe | |||
1114 | trm->congestion_time = congestion_timeout; | 1113 | trm->congestion_time = congestion_timeout; |
1115 | trm->is_predecessor = htonl (is_predecessor); | 1114 | trm->is_predecessor = htonl (is_predecessor); |
1116 | trm->trail_id = *trail_id; | 1115 | trm->trail_id = *trail_id; |
1117 | trm->ultimate_destination_finger_value | 1116 | trm->ultimate_destination_finger_value |
1118 | = GNUNET_htonll (ultimate_destination_finger_value); | 1117 | = GNUNET_htonll (ultimate_destination_finger_value); |
1119 | GNUNET_memcpy (&trm[1], | 1118 | GNUNET_memcpy (&trm[1], |
1120 | trail_peer_list, | 1119 | trail_peer_list, |
@@ -1957,7 +1956,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | |||
1957 | GNUNET_break (0); | 1956 | GNUNET_break (0); |
1958 | return; | 1957 | return; |
1959 | } | 1958 | } |
1960 | 1959 | ||
1961 | GNUNET_assert (NULL != | 1960 | GNUNET_assert (NULL != |
1962 | (target_friend = | 1961 | (target_friend = |
1963 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | 1962 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
@@ -1989,20 +1988,29 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | |||
1989 | /** | 1988 | /** |
1990 | * Handle the put request from the client. | 1989 | * Handle the put request from the client. |
1991 | * | 1990 | * |
1992 | * @param key Key for the content | ||
1993 | * @param block_type Type of the block | 1991 | * @param block_type Type of the block |
1994 | * @param options Routing options | 1992 | * @param options Routing options |
1995 | * @param desired_replication_level Desired replication count | 1993 | * @param desired_replication_level Desired replication count |
1996 | * @param expiration_time When does the content expire | 1994 | * @param expiration_time When does the content expire |
1995 | * @param hop_count how many hops has this message traversed so far | ||
1996 | * @param bf Bloom filter of peers this PUT has already traversed | ||
1997 | * @param key Key for the content | ||
1998 | * @param put_path_length number of entries in put_path | ||
1999 | * @param put_path peers this request has traversed so far (if tracked) | ||
1997 | * @param data Content to store | 2000 | * @param data Content to store |
1998 | * @param data_size Size of content @a data in bytes | 2001 | * @param data_size Size of content @a data in bytes |
2002 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
1999 | */ | 2003 | */ |
2000 | void | 2004 | int |
2001 | GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, | 2005 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type, |
2002 | enum GNUNET_BLOCK_Type block_type, | ||
2003 | enum GNUNET_DHT_RouteOption options, | 2006 | enum GNUNET_DHT_RouteOption options, |
2004 | uint32_t desired_replication_level, | 2007 | uint32_t desired_replication_level, |
2005 | struct GNUNET_TIME_Absolute expiration_time, | 2008 | struct GNUNET_TIME_Absolute expiration_time, |
2009 | uint32_t hop_count, | ||
2010 | struct GNUNET_CONTAINER_BloomFilter *bf, | ||
2011 | const struct GNUNET_HashCode *key, | ||
2012 | unsigned int put_path_length, | ||
2013 | struct GNUNET_PeerIdentity *put_path, | ||
2006 | const void *data, | 2014 | const void *data, |
2007 | size_t data_size) | 2015 | size_t data_size) |
2008 | { | 2016 | { |
@@ -2045,7 +2053,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, | |||
2045 | key, | 2053 | key, |
2046 | data, | 2054 | data, |
2047 | data_size); | 2055 | data_size); |
2048 | return; | 2056 | return GNUNET_NO; |
2049 | } | 2057 | } |
2050 | /* In case we are sending the request to a finger, then send across all of its | 2058 | /* In case we are sending the request to a finger, then send across all of its |
2051 | trail.*/ | 2059 | trail.*/ |
@@ -2062,6 +2070,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, | |||
2062 | expiration_time, | 2070 | expiration_time, |
2063 | data, | 2071 | data, |
2064 | data_size); | 2072 | data_size); |
2073 | return GNUNET_OK; | ||
2065 | } | 2074 | } |
2066 | 2075 | ||
2067 | 2076 | ||
@@ -2099,7 +2108,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | |||
2099 | struct GNUNET_MQ_Envelope *env; | 2108 | struct GNUNET_MQ_Envelope *env; |
2100 | struct FriendInfo *target_friend; | 2109 | struct FriendInfo *target_friend; |
2101 | size_t msize; | 2110 | size_t msize; |
2102 | 2111 | ||
2103 | msize = get_path_length * sizeof (struct GNUNET_PeerIdentity); | 2112 | msize = get_path_length * sizeof (struct GNUNET_PeerIdentity); |
2104 | if (msize + sizeof (struct PeerGetMessage) | 2113 | if (msize + sizeof (struct PeerGetMessage) |
2105 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 2114 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
@@ -2129,70 +2138,10 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | |||
2129 | 2138 | ||
2130 | 2139 | ||
2131 | /** | 2140 | /** |
2132 | * Handle the get request from the client file. If I am destination do | ||
2133 | * datacache put and return. Else find the target friend and forward message | ||
2134 | * to it. | ||
2135 | * | ||
2136 | * @param key Key for the content | ||
2137 | * @param block_type Type of the block | ||
2138 | * @param options Routing options | ||
2139 | * @param desired_replication_level Desired replication count | ||
2140 | */ | ||
2141 | void | ||
2142 | GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, | ||
2143 | enum GNUNET_BLOCK_Type block_type, | ||
2144 | enum GNUNET_DHT_RouteOption options, | ||
2145 | uint32_t desired_replication_level) | ||
2146 | { | ||
2147 | struct Closest_Peer successor; | ||
2148 | struct GNUNET_PeerIdentity best_known_dest; | ||
2149 | struct GNUNET_HashCode intermediate_trail_id; | ||
2150 | uint64_t key_value; | ||
2151 | |||
2152 | GNUNET_memcpy (&key_value, | ||
2153 | key, | ||
2154 | sizeof (uint64_t)); | ||
2155 | key_value = GNUNET_ntohll (key_value); | ||
2156 | successor = find_local_best_known_next_hop (key_value, | ||
2157 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
2158 | best_known_dest = successor.best_known_destination; | ||
2159 | intermediate_trail_id = successor.trail_id; | ||
2160 | |||
2161 | /* I am the destination. I have the data. */ | ||
2162 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
2163 | &best_known_dest)) | ||
2164 | { | ||
2165 | GDS_DATACACHE_handle_get (key, | ||
2166 | block_type, | ||
2167 | NULL, | ||
2168 | 0, | ||
2169 | NULL, | ||
2170 | 0, | ||
2171 | 1, | ||
2172 | &my_identity, | ||
2173 | NULL, | ||
2174 | &my_identity); | ||
2175 | return; | ||
2176 | } | ||
2177 | |||
2178 | GDS_NEIGHBOURS_send_get (key, | ||
2179 | block_type, | ||
2180 | options, | ||
2181 | desired_replication_level, | ||
2182 | &best_known_dest, | ||
2183 | &intermediate_trail_id, | ||
2184 | &successor.next_hop, | ||
2185 | 0, | ||
2186 | 1, | ||
2187 | &my_identity); | ||
2188 | } | ||
2189 | |||
2190 | |||
2191 | /** | ||
2192 | * Send the get result to requesting client. | 2141 | * Send the get result to requesting client. |
2193 | * | 2142 | * |
2194 | * @param key Key of the requested data. | 2143 | * @param key Key of the requested data. |
2195 | * @param type Block type | 2144 | * @param block_type Block type |
2196 | * @param target_peer Next peer to forward the message to. | 2145 | * @param target_peer Next peer to forward the message to. |
2197 | * @param source_peer Peer which has the data for the key. | 2146 | * @param source_peer Peer which has the data for the key. |
2198 | * @param put_path_length Number of peers in @a put_path | 2147 | * @param put_path_length Number of peers in @a put_path |
@@ -2205,7 +2154,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, | |||
2205 | */ | 2154 | */ |
2206 | void | 2155 | void |
2207 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, | 2156 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, |
2208 | enum GNUNET_BLOCK_Type type, | 2157 | enum GNUNET_BLOCK_Type block_type, |
2209 | const struct GNUNET_PeerIdentity *target_peer, | 2158 | const struct GNUNET_PeerIdentity *target_peer, |
2210 | const struct GNUNET_PeerIdentity *source_peer, | 2159 | const struct GNUNET_PeerIdentity *source_peer, |
2211 | unsigned int put_path_length, | 2160 | unsigned int put_path_length, |
@@ -2256,15 +2205,15 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, | |||
2256 | if (0 == current_path_index) | 2205 | if (0 == current_path_index) |
2257 | { | 2206 | { |
2258 | DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s", | 2207 | DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s", |
2259 | GNUNET_h2s(key), | 2208 | GNUNET_h2s (key), |
2260 | GNUNET_i2s(&my_identity)); | 2209 | GNUNET_i2s (&my_identity)); |
2261 | GDS_CLIENTS_handle_reply (expiration, | 2210 | GDS_CLIENTS_handle_reply (expiration, |
2262 | key, | 2211 | key, |
2263 | get_path_length, | 2212 | get_path_length, |
2264 | get_path, | 2213 | get_path, |
2265 | put_path_length, | 2214 | put_path_length, |
2266 | put_path, | 2215 | put_path, |
2267 | type, | 2216 | block_type, |
2268 | data_size, | 2217 | data_size, |
2269 | data); | 2218 | data); |
2270 | return; | 2219 | return; |
@@ -2298,6 +2247,120 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, | |||
2298 | 2247 | ||
2299 | 2248 | ||
2300 | /** | 2249 | /** |
2250 | * Handle a result for a GET operation. | ||
2251 | * | ||
2252 | * @param cls closure | ||
2253 | * @param type type of the block | ||
2254 | * @param expiration_time when does the content expire | ||
2255 | * @param key key for the content | ||
2256 | * @param put_path_length number of entries in @a put_path | ||
2257 | * @param put_path peers the original PUT traversed (if tracked) | ||
2258 | * @param get_path_length number of entries in @a get_path | ||
2259 | * @param get_path peers this reply has traversed so far (if tracked) | ||
2260 | * @param data payload of the reply | ||
2261 | * @param data_size number of bytes in @a data | ||
2262 | */ | ||
2263 | static void | ||
2264 | get_cb (void *cls, | ||
2265 | enum GNUNET_BLOCK_Type type, | ||
2266 | struct GNUNET_TIME_Absolute expiration_time, | ||
2267 | const struct GNUNET_HashCode *key, | ||
2268 | unsigned int put_path_length, | ||
2269 | const struct GNUNET_PeerIdentity *put_path, | ||
2270 | unsigned int get_path_length, | ||
2271 | const struct GNUNET_PeerIdentity *get_path, | ||
2272 | const void *data, | ||
2273 | size_t data_size) | ||
2274 | { | ||
2275 | struct GNUNET_PeerIdentity *target_peer = cls; | ||
2276 | // FIXME: inline? | ||
2277 | GDS_NEIGHBOURS_send_get_result (key, | ||
2278 | type, | ||
2279 | target_peer, | ||
2280 | &my_identity, | ||
2281 | put_path_length, | ||
2282 | put_path, | ||
2283 | 1, | ||
2284 | &my_identity, | ||
2285 | expiration_time, | ||
2286 | data, | ||
2287 | data_size); | ||
2288 | } | ||
2289 | |||
2290 | |||
2291 | /** | ||
2292 | * Perform a GET operation. Forwards the given request to other | ||
2293 | * peers. Does not lookup the key locally. May do nothing if this is | ||
2294 | * the only peer in the network (or if we are the closest peer in the | ||
2295 | * network). | ||
2296 | * | ||
2297 | * @param block_type type of the block | ||
2298 | * @param options routing options | ||
2299 | * @param desired_replication_level desired replication count | ||
2300 | * @param hop_count how many hops did this request traverse so far? | ||
2301 | * @param key key for the content | ||
2302 | * @param xquery extended query | ||
2303 | * @param xquery_size number of bytes in @a xquery | ||
2304 | * @param reply_bf bloomfilter to filter duplicates | ||
2305 | * @param reply_bf_mutator mutator for @a reply_bf | ||
2306 | * @param peer_bf filter for peers not to select (again, updated) | ||
2307 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
2308 | */ | ||
2309 | int | ||
2310 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type, | ||
2311 | enum GNUNET_DHT_RouteOption options, | ||
2312 | uint32_t desired_replication_level, | ||
2313 | uint32_t hop_count, | ||
2314 | const struct GNUNET_HashCode *key, | ||
2315 | const void *xquery, size_t xquery_size, | ||
2316 | const struct GNUNET_CONTAINER_BloomFilter *reply_bf, | ||
2317 | uint32_t reply_bf_mutator, | ||
2318 | struct GNUNET_CONTAINER_BloomFilter *peer_bf) | ||
2319 | { | ||
2320 | struct Closest_Peer successor; | ||
2321 | struct GNUNET_PeerIdentity best_known_dest; | ||
2322 | struct GNUNET_HashCode intermediate_trail_id; | ||
2323 | uint64_t key_value; | ||
2324 | |||
2325 | GNUNET_memcpy (&key_value, | ||
2326 | key, | ||
2327 | sizeof (uint64_t)); | ||
2328 | key_value = GNUNET_ntohll (key_value); | ||
2329 | successor = find_local_best_known_next_hop (key_value, | ||
2330 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
2331 | best_known_dest = successor.best_known_destination; | ||
2332 | intermediate_trail_id = successor.trail_id; | ||
2333 | |||
2334 | /* I am the destination. I have the data. */ | ||
2335 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
2336 | &best_known_dest)) | ||
2337 | { | ||
2338 | GDS_DATACACHE_handle_get (key, | ||
2339 | block_type, | ||
2340 | NULL, | ||
2341 | 0, | ||
2342 | NULL, | ||
2343 | 0, | ||
2344 | &get_cb, | ||
2345 | NULL); | ||
2346 | return GNUNET_NO; | ||
2347 | } | ||
2348 | |||
2349 | GDS_NEIGHBOURS_send_get (key, | ||
2350 | block_type, | ||
2351 | options, | ||
2352 | desired_replication_level, | ||
2353 | &best_known_dest, | ||
2354 | &intermediate_trail_id, | ||
2355 | &successor.next_hop, | ||
2356 | 0, | ||
2357 | 1, | ||
2358 | &my_identity); | ||
2359 | return GNUNET_OK; | ||
2360 | } | ||
2361 | |||
2362 | |||
2363 | /** | ||
2301 | * Randomly choose one of your friends (which is not congested and have not crossed | 2364 | * Randomly choose one of your friends (which is not congested and have not crossed |
2302 | * trail threshold) from the friend_peermap | 2365 | * trail threshold) from the friend_peermap |
2303 | * @return Friend Randomly chosen friend. | 2366 | * @return Friend Randomly chosen friend. |
@@ -3121,7 +3184,7 @@ update_current_search_finger_index (unsigned int finger_table_index) | |||
3121 | { | 3184 | { |
3122 | if (NULL == send_verify_successor_task) | 3185 | if (NULL == send_verify_successor_task) |
3123 | { | 3186 | { |
3124 | send_verify_successor_task | 3187 | send_verify_successor_task |
3125 | = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, | 3188 | = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, |
3126 | NULL); | 3189 | NULL); |
3127 | } | 3190 | } |
@@ -3389,7 +3452,7 @@ finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | |||
3389 | else | 3452 | else |
3390 | select_and_replace_trail (existing_finger, | 3453 | select_and_replace_trail (existing_finger, |
3391 | finger_trail, | 3454 | finger_trail, |
3392 | finger_trail_length, | 3455 | finger_trail_length, |
3393 | finger_trail_id); | 3456 | finger_trail_id); |
3394 | } | 3457 | } |
3395 | update_current_search_finger_index (finger_table_index); | 3458 | update_current_search_finger_index (finger_table_index); |
@@ -3425,7 +3488,7 @@ check_dht_p2p_put (void *cls, | |||
3425 | return GNUNET_OK; | 3488 | return GNUNET_OK; |
3426 | } | 3489 | } |
3427 | 3490 | ||
3428 | 3491 | ||
3429 | /** | 3492 | /** |
3430 | * Core handler for P2P put messages. | 3493 | * Core handler for P2P put messages. |
3431 | * | 3494 | * |
@@ -3435,7 +3498,7 @@ check_dht_p2p_put (void *cls, | |||
3435 | static void | 3498 | static void |
3436 | handle_dht_p2p_put (void *cls, | 3499 | handle_dht_p2p_put (void *cls, |
3437 | const struct PeerPutMessage *put) | 3500 | const struct PeerPutMessage *put) |
3438 | { | 3501 | { |
3439 | struct GNUNET_PeerIdentity *put_path; | 3502 | struct GNUNET_PeerIdentity *put_path; |
3440 | struct GNUNET_PeerIdentity current_best_known_dest; | 3503 | struct GNUNET_PeerIdentity current_best_known_dest; |
3441 | struct GNUNET_PeerIdentity best_known_dest; | 3504 | struct GNUNET_PeerIdentity best_known_dest; |
@@ -3623,7 +3686,7 @@ handle_dht_p2p_put (void *cls, | |||
3623 | * @return #GNUNET_OK if @a get is well-formed | 3686 | * @return #GNUNET_OK if @a get is well-formed |
3624 | */ | 3687 | */ |
3625 | static int | 3688 | static int |
3626 | check_dht_p2p_get (void *cls, | 3689 | check_dht_p2p_get (void *cls, |
3627 | const struct PeerGetMessage *get) | 3690 | const struct PeerGetMessage *get) |
3628 | { | 3691 | { |
3629 | uint32_t get_length; | 3692 | uint32_t get_length; |
@@ -3653,7 +3716,7 @@ check_dht_p2p_get (void *cls, | |||
3653 | * @param get the message | 3716 | * @param get the message |
3654 | */ | 3717 | */ |
3655 | static void | 3718 | static void |
3656 | handle_dht_p2p_get (void *cls, | 3719 | handle_dht_p2p_get (void *cls, |
3657 | const struct PeerGetMessage *get) | 3720 | const struct PeerGetMessage *get) |
3658 | { | 3721 | { |
3659 | const struct GNUNET_PeerIdentity *get_path; | 3722 | const struct GNUNET_PeerIdentity *get_path; |
@@ -3744,10 +3807,8 @@ handle_dht_p2p_get (void *cls, | |||
3744 | 0, | 3807 | 0, |
3745 | NULL, | 3808 | NULL, |
3746 | 0, | 3809 | 0, |
3747 | 1, | 3810 | &get_cb, |
3748 | &my_identity, | 3811 | NULL); |
3749 | NULL, | ||
3750 | &my_identity); | ||
3751 | } | 3812 | } |
3752 | else | 3813 | else |
3753 | { | 3814 | { |
@@ -3757,10 +3818,8 @@ handle_dht_p2p_get (void *cls, | |||
3757 | 0, | 3818 | 0, |
3758 | NULL, | 3819 | NULL, |
3759 | 0, | 3820 | 0, |
3760 | get_length, | 3821 | &get_cb, |
3761 | gp, | 3822 | &gp[get_length - 2]); |
3762 | &gp[get_length - 2], | ||
3763 | &my_identity); | ||
3764 | } | 3823 | } |
3765 | } | 3824 | } |
3766 | else | 3825 | else |
@@ -3822,7 +3881,7 @@ check_dht_p2p_get_result (void *cls, | |||
3822 | static void | 3881 | static void |
3823 | handle_dht_p2p_get_result (void *cls, | 3882 | handle_dht_p2p_get_result (void *cls, |
3824 | const struct PeerGetResultMessage *get_result) | 3883 | const struct PeerGetResultMessage *get_result) |
3825 | { | 3884 | { |
3826 | const struct GNUNET_PeerIdentity *get_path; | 3885 | const struct GNUNET_PeerIdentity *get_path; |
3827 | const struct GNUNET_PeerIdentity *put_path; | 3886 | const struct GNUNET_PeerIdentity *put_path; |
3828 | const void *payload; | 3887 | const void *payload; |
@@ -3965,7 +4024,7 @@ get_local_best_known_next_hop (uint64_t final_dest_finger_val, | |||
3965 | * @return #GNUNET_OK if @a trail_setup is well-formed | 4024 | * @return #GNUNET_OK if @a trail_setup is well-formed |
3966 | */ | 4025 | */ |
3967 | static int | 4026 | static int |
3968 | check_dht_p2p_trail_setup (void *cls, | 4027 | check_dht_p2p_trail_setup (void *cls, |
3969 | const struct PeerTrailSetupMessage *trail_setup) | 4028 | const struct PeerTrailSetupMessage *trail_setup) |
3970 | { | 4029 | { |
3971 | size_t msize; | 4030 | size_t msize; |
@@ -3988,7 +4047,7 @@ check_dht_p2p_trail_setup (void *cls, | |||
3988 | * @param trail_setup the message | 4047 | * @param trail_setup the message |
3989 | */ | 4048 | */ |
3990 | static void | 4049 | static void |
3991 | handle_dht_p2p_trail_setup (void *cls, | 4050 | handle_dht_p2p_trail_setup (void *cls, |
3992 | const struct PeerTrailSetupMessage *trail_setup) | 4051 | const struct PeerTrailSetupMessage *trail_setup) |
3993 | { | 4052 | { |
3994 | struct FriendInfo *friend = cls; | 4053 | struct FriendInfo *friend = cls; |
@@ -4014,7 +4073,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4014 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1]; | 4073 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1]; |
4015 | current_dest = trail_setup->best_known_destination; | 4074 | current_dest = trail_setup->best_known_destination; |
4016 | trail_id = trail_setup->trail_id; | 4075 | trail_id = trail_setup->trail_id; |
4017 | final_dest_finger_val | 4076 | final_dest_finger_val |
4018 | = GNUNET_ntohll (trail_setup->final_destination_finger_value); | 4077 | = GNUNET_ntohll (trail_setup->final_destination_finger_value); |
4019 | source = trail_setup->source_peer; | 4078 | source = trail_setup->source_peer; |
4020 | is_predecessor = ntohl (trail_setup->is_predecessor); | 4079 | is_predecessor = ntohl (trail_setup->is_predecessor); |
@@ -4024,7 +4083,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4024 | if ( (trail_length > 0) && | 4083 | if ( (trail_length > 0) && |
4025 | (0 != memcmp (&trail_peer_list[trail_length-1], | 4084 | (0 != memcmp (&trail_peer_list[trail_length-1], |
4026 | friend->id, | 4085 | friend->id, |
4027 | sizeof (struct GNUNET_PeerIdentity))) ) | 4086 | sizeof (struct GNUNET_PeerIdentity))) ) |
4028 | { | 4087 | { |
4029 | GNUNET_break_op (0); | 4088 | GNUNET_break_op (0); |
4030 | return; | 4089 | return; |
@@ -4052,7 +4111,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4052 | /* Is my routing table full? */ | 4111 | /* Is my routing table full? */ |
4053 | if (GNUNET_YES == GDS_ROUTING_threshold_reached ()) | 4112 | if (GNUNET_YES == GDS_ROUTING_threshold_reached ()) |
4054 | { | 4113 | { |
4055 | target_friend | 4114 | target_friend |
4056 | = (trail_length > 0) | 4115 | = (trail_length > 0) |
4057 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, | 4116 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
4058 | &trail_peer_list[trail_length - 1]) | 4117 | &trail_peer_list[trail_length - 1]) |
@@ -4077,7 +4136,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4077 | } | 4136 | } |
4078 | 4137 | ||
4079 | /* Get the next hop to forward the trail setup request. */ | 4138 | /* Get the next hop to forward the trail setup request. */ |
4080 | struct Closest_Peer next_peer | 4139 | struct Closest_Peer next_peer |
4081 | = get_local_best_known_next_hop (final_dest_finger_val, | 4140 | = get_local_best_known_next_hop (final_dest_finger_val, |
4082 | &intermediate_trail_id, | 4141 | &intermediate_trail_id, |
4083 | is_predecessor, | 4142 | is_predecessor, |
@@ -4100,7 +4159,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4100 | return; | 4159 | return; |
4101 | } | 4160 | } |
4102 | 4161 | ||
4103 | target_friend | 4162 | target_friend |
4104 | = (trail_length > 0) | 4163 | = (trail_length > 0) |
4105 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, | 4164 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
4106 | &trail_peer_list[trail_length-1]) | 4165 | &trail_peer_list[trail_length-1]) |
@@ -4139,7 +4198,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4139 | { | 4198 | { |
4140 | /* Add yourself to list of peers. */ | 4199 | /* Add yourself to list of peers. */ |
4141 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | 4200 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; |
4142 | 4201 | ||
4143 | GNUNET_memcpy (peer_list, | 4202 | GNUNET_memcpy (peer_list, |
4144 | trail_peer_list, | 4203 | trail_peer_list, |
4145 | trail_length * sizeof (struct GNUNET_PeerIdentity)); | 4204 | trail_length * sizeof (struct GNUNET_PeerIdentity)); |
@@ -4175,7 +4234,7 @@ handle_dht_p2p_trail_setup (void *cls, | |||
4175 | * @return #GNUNET_OK if @a trail_result is well-formed | 4234 | * @return #GNUNET_OK if @a trail_result is well-formed |
4176 | */ | 4235 | */ |
4177 | static int | 4236 | static int |
4178 | check_dht_p2p_trail_setup_result (void *cls, | 4237 | check_dht_p2p_trail_setup_result (void *cls, |
4179 | const struct PeerTrailSetupResultMessage *trail_result) | 4238 | const struct PeerTrailSetupResultMessage *trail_result) |
4180 | { | 4239 | { |
4181 | size_t msize; | 4240 | size_t msize; |
@@ -4189,7 +4248,7 @@ check_dht_p2p_trail_setup_result (void *cls, | |||
4189 | } | 4248 | } |
4190 | return GNUNET_OK; | 4249 | return GNUNET_OK; |
4191 | } | 4250 | } |
4192 | 4251 | ||
4193 | 4252 | ||
4194 | /** | 4253 | /** |
4195 | * Core handle for p2p trail setup result messages. | 4254 | * Core handle for p2p trail setup result messages. |
@@ -4198,7 +4257,7 @@ check_dht_p2p_trail_setup_result (void *cls, | |||
4198 | * @param trail_result the message | 4257 | * @param trail_result the message |
4199 | */ | 4258 | */ |
4200 | static void | 4259 | static void |
4201 | handle_dht_p2p_trail_setup_result (void *cls, | 4260 | handle_dht_p2p_trail_setup_result (void *cls, |
4202 | const struct PeerTrailSetupResultMessage *trail_result) | 4261 | const struct PeerTrailSetupResultMessage *trail_result) |
4203 | { | 4262 | { |
4204 | struct FriendInfo *friend = cls; | 4263 | struct FriendInfo *friend = cls; |
@@ -4228,7 +4287,7 @@ handle_dht_p2p_trail_setup_result (void *cls, | |||
4228 | finger_identity = trail_result->finger_identity; | 4287 | finger_identity = trail_result->finger_identity; |
4229 | trail_id = trail_result->trail_id; | 4288 | trail_id = trail_result->trail_id; |
4230 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; | 4289 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; |
4231 | ultimate_destination_finger_value | 4290 | ultimate_destination_finger_value |
4232 | = GNUNET_ntohll (trail_result->ultimate_destination_finger_value); | 4291 | = GNUNET_ntohll (trail_result->ultimate_destination_finger_value); |
4233 | 4292 | ||
4234 | /* Am I the one who initiated the query? */ | 4293 | /* Am I the one who initiated the query? */ |
@@ -4314,7 +4373,7 @@ handle_dht_p2p_trail_setup_result (void *cls, | |||
4314 | GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer, | 4373 | GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer, |
4315 | &finger_identity, | 4374 | &finger_identity, |
4316 | target_friend, | 4375 | target_friend, |
4317 | trail_length, | 4376 | trail_length, |
4318 | trail_peer_list, | 4377 | trail_peer_list, |
4319 | is_predecessor, | 4378 | is_predecessor, |
4320 | ultimate_destination_finger_value, | 4379 | ultimate_destination_finger_value, |
@@ -4569,7 +4628,7 @@ get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer, | |||
4569 | *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i; | 4628 | *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i; |
4570 | trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, | 4629 | trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, |
4571 | struct GNUNET_PeerIdentity); | 4630 | struct GNUNET_PeerIdentity); |
4572 | 4631 | ||
4573 | 4632 | ||
4574 | for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++) | 4633 | for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++) |
4575 | trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i]; | 4634 | trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i]; |
@@ -4821,7 +4880,7 @@ handle_dht_p2p_verify_successor (void *cls, | |||
4821 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_predecessor.finger_identity, | 4880 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_predecessor.finger_identity, |
4822 | &source_peer))) | 4881 | &source_peer))) |
4823 | { | 4882 | { |
4824 | trail_src_to_curr_pred | 4883 | trail_src_to_curr_pred |
4825 | = get_trail_src_to_curr_pred (source_peer, | 4884 | = get_trail_src_to_curr_pred (source_peer, |
4826 | trail, | 4885 | trail, |
4827 | trail_length, | 4886 | trail_length, |
@@ -4832,7 +4891,7 @@ handle_dht_p2p_verify_successor (void *cls, | |||
4832 | trail_src_to_curr_pred_len = trail_length; | 4891 | trail_src_to_curr_pred_len = trail_length; |
4833 | trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len, | 4892 | trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len, |
4834 | struct GNUNET_PeerIdentity); | 4893 | struct GNUNET_PeerIdentity); |
4835 | 4894 | ||
4836 | for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++) | 4895 | for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++) |
4837 | { | 4896 | { |
4838 | trail_src_to_curr_pred[i] = trail[i]; | 4897 | trail_src_to_curr_pred[i] = trail[i]; |
@@ -5175,7 +5234,7 @@ check_dht_p2p_verify_successor_result (void *cls, | |||
5175 | static void | 5234 | static void |
5176 | handle_dht_p2p_verify_successor_result (void *cls, | 5235 | handle_dht_p2p_verify_successor_result (void *cls, |
5177 | const struct PeerVerifySuccessorResultMessage *vsrm) | 5236 | const struct PeerVerifySuccessorResultMessage *vsrm) |
5178 | { | 5237 | { |
5179 | enum GDS_ROUTING_trail_direction trail_direction; | 5238 | enum GDS_ROUTING_trail_direction trail_direction; |
5180 | struct GNUNET_PeerIdentity querying_peer; | 5239 | struct GNUNET_PeerIdentity querying_peer; |
5181 | struct GNUNET_HashCode trail_id; | 5240 | struct GNUNET_HashCode trail_id; |
@@ -5211,7 +5270,7 @@ handle_dht_p2p_verify_successor_result (void *cls, | |||
5211 | if (NULL != send_verify_successor_retry_task) | 5270 | if (NULL != send_verify_successor_retry_task) |
5212 | { | 5271 | { |
5213 | struct VerifySuccessorContext *ctx; | 5272 | struct VerifySuccessorContext *ctx; |
5214 | 5273 | ||
5215 | ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); | 5274 | ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); |
5216 | GNUNET_free (ctx); | 5275 | GNUNET_free (ctx); |
5217 | send_verify_successor_retry_task = NULL; | 5276 | send_verify_successor_retry_task = NULL; |
@@ -5277,7 +5336,7 @@ check_dht_p2p_notify_new_successor (void *cls, | |||
5277 | return GNUNET_OK; | 5336 | return GNUNET_OK; |
5278 | } | 5337 | } |
5279 | 5338 | ||
5280 | 5339 | ||
5281 | /** | 5340 | /** |
5282 | * Core handle for p2p notify new successor messages. | 5341 | * Core handle for p2p notify new successor messages. |
5283 | * | 5342 | * |
@@ -5387,7 +5446,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls, | |||
5387 | struct GNUNET_HashCode trail_id; | 5446 | struct GNUNET_HashCode trail_id; |
5388 | struct FriendInfo *target_friend; | 5447 | struct FriendInfo *target_friend; |
5389 | const struct GNUNET_PeerIdentity *next_hop; | 5448 | const struct GNUNET_PeerIdentity *next_hop; |
5390 | 5449 | ||
5391 | GNUNET_STATISTICS_update (GDS_stats, | 5450 | GNUNET_STATISTICS_update (GDS_stats, |
5392 | gettext_noop ("# Bytes received from other peers"), | 5451 | gettext_noop ("# Bytes received from other peers"), |
5393 | ntohs (notify_confirmation->header.size), | 5452 | ntohs (notify_confirmation->header.size), |
@@ -5431,7 +5490,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls, | |||
5431 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + | 5490 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + |
5432 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 5491 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, |
5433 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); | 5492 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); |
5434 | send_verify_successor_task | 5493 | send_verify_successor_task |
5435 | = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, | 5494 | = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, |
5436 | &send_verify_successor_message, | 5495 | &send_verify_successor_message, |
5437 | NULL); | 5496 | NULL); |
@@ -5476,7 +5535,7 @@ check_dht_p2p_trail_setup_rejection (void *cls, | |||
5476 | } | 5535 | } |
5477 | return GNUNET_OK; | 5536 | return GNUNET_OK; |
5478 | } | 5537 | } |
5479 | 5538 | ||
5480 | 5539 | ||
5481 | /** | 5540 | /** |
5482 | * Core handler for P2P trail rejection message | 5541 | * Core handler for P2P trail rejection message |
@@ -5487,7 +5546,7 @@ check_dht_p2p_trail_setup_rejection (void *cls, | |||
5487 | static void | 5546 | static void |
5488 | handle_dht_p2p_trail_setup_rejection (void *cls, | 5547 | handle_dht_p2p_trail_setup_rejection (void *cls, |
5489 | const struct PeerTrailRejectionMessage *trail_rejection) | 5548 | const struct PeerTrailRejectionMessage *trail_rejection) |
5490 | { | 5549 | { |
5491 | struct FriendInfo *friend = cls; | 5550 | struct FriendInfo *friend = cls; |
5492 | unsigned int trail_length; | 5551 | unsigned int trail_length; |
5493 | const struct GNUNET_PeerIdentity *trail_peer_list; | 5552 | const struct GNUNET_PeerIdentity *trail_peer_list; |
@@ -5514,7 +5573,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, | |||
5514 | congestion_timeout = trail_rejection->congestion_time; | 5573 | congestion_timeout = trail_rejection->congestion_time; |
5515 | source = trail_rejection->source_peer; | 5574 | source = trail_rejection->source_peer; |
5516 | trail_id = trail_rejection->trail_id; | 5575 | trail_id = trail_rejection->trail_id; |
5517 | ultimate_destination_finger_value | 5576 | ultimate_destination_finger_value |
5518 | = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value); | 5577 | = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value); |
5519 | /* First set the congestion time of the friend that sent you this message. */ | 5578 | /* First set the congestion time of the friend that sent you this message. */ |
5520 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | 5579 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
@@ -5525,7 +5584,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, | |||
5525 | GNUNET_break(0); | 5584 | GNUNET_break(0); |
5526 | return; | 5585 | return; |
5527 | } | 5586 | } |
5528 | target_friend->congestion_timestamp | 5587 | target_friend->congestion_timestamp |
5529 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), | 5588 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), |
5530 | congestion_timeout); | 5589 | congestion_timeout); |
5531 | 5590 | ||
@@ -5549,7 +5608,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, | |||
5549 | else | 5608 | else |
5550 | next_peer = trail[new_trail_length-1]; | 5609 | next_peer = trail[new_trail_length-1]; |
5551 | 5610 | ||
5552 | target_friend | 5611 | target_friend |
5553 | = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | 5612 | = GNUNET_CONTAINER_multipeermap_get (friend_peermap, |
5554 | &next_peer); | 5613 | &next_peer); |
5555 | if (NULL == target_friend) | 5614 | if (NULL == target_friend) |
@@ -5640,7 +5699,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, | |||
5640 | * @param trail_teardown the message | 5699 | * @param trail_teardown the message |
5641 | */ | 5700 | */ |
5642 | static void | 5701 | static void |
5643 | handle_dht_p2p_trail_teardown (void *cls, | 5702 | handle_dht_p2p_trail_teardown (void *cls, |
5644 | const struct PeerTrailTearDownMessage *trail_teardown) | 5703 | const struct PeerTrailTearDownMessage *trail_teardown) |
5645 | { | 5704 | { |
5646 | enum GDS_ROUTING_trail_direction trail_direction; | 5705 | enum GDS_ROUTING_trail_direction trail_direction; |
@@ -5707,7 +5766,7 @@ handle_dht_p2p_trail_teardown (void *cls, | |||
5707 | * @return #GNUNET_OK if @a add_trail is well-formed | 5766 | * @return #GNUNET_OK if @a add_trail is well-formed |
5708 | */ | 5767 | */ |
5709 | static int | 5768 | static int |
5710 | check_dht_p2p_add_trail (void *cls, | 5769 | check_dht_p2p_add_trail (void *cls, |
5711 | const struct PeerAddTrailMessage *add_trail) | 5770 | const struct PeerAddTrailMessage *add_trail) |
5712 | { | 5771 | { |
5713 | size_t msize; | 5772 | size_t msize; |
@@ -5730,9 +5789,9 @@ check_dht_p2p_add_trail (void *cls, | |||
5730 | * @param add_trail the message | 5789 | * @param add_trail the message |
5731 | */ | 5790 | */ |
5732 | static void | 5791 | static void |
5733 | handle_dht_p2p_add_trail (void *cls, | 5792 | handle_dht_p2p_add_trail (void *cls, |
5734 | const struct PeerAddTrailMessage *add_trail) | 5793 | const struct PeerAddTrailMessage *add_trail) |
5735 | { | 5794 | { |
5736 | struct FriendInfo *friend = cls; | 5795 | struct FriendInfo *friend = cls; |
5737 | const struct GNUNET_PeerIdentity *trail; | 5796 | const struct GNUNET_PeerIdentity *trail; |
5738 | struct GNUNET_HashCode trail_id; | 5797 | struct GNUNET_HashCode trail_id; |
@@ -6183,7 +6242,7 @@ GDS_NEIGHBOURS_done (void) | |||
6183 | if (NULL != send_notify_new_successor_retry_task) | 6242 | if (NULL != send_notify_new_successor_retry_task) |
6184 | { | 6243 | { |
6185 | struct SendNotifyContext *notify_ctx; | 6244 | struct SendNotifyContext *notify_ctx; |
6186 | 6245 | ||
6187 | notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task); | 6246 | notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task); |
6188 | GNUNET_free (notify_ctx->successor_trail); | 6247 | GNUNET_free (notify_ctx->successor_trail); |
6189 | GNUNET_free (notify_ctx); | 6248 | GNUNET_free (notify_ctx); |
@@ -6197,10 +6256,10 @@ GDS_NEIGHBOURS_done (void) | |||
6197 | * | 6256 | * |
6198 | * @return my identity | 6257 | * @return my identity |
6199 | */ | 6258 | */ |
6200 | struct GNUNET_PeerIdentity | 6259 | struct GNUNET_PeerIdentity * |
6201 | GDS_NEIGHBOURS_get_my_id (void) | 6260 | GDS_NEIGHBOURS_get_id (void) |
6202 | { | 6261 | { |
6203 | return my_identity; | 6262 | return &my_identity; |
6204 | } | 6263 | } |
6205 | 6264 | ||
6206 | /* end of gnunet-service-xdht_neighbours.c */ | 6265 | /* end of gnunet-service-xdht_neighbours.c */ |
diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h index 1df45031d..2fb118448 100644 --- a/src/dht/gnunet-service-xdht_neighbours.h +++ b/src/dht/gnunet-service-xdht_neighbours.h | |||
@@ -33,67 +33,6 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Handle the put request from the client. | ||
37 | * @param key Key for the content | ||
38 | * @param block_type Type of the block | ||
39 | * @param options Routing options | ||
40 | * @param desired_replication_level Desired replication count | ||
41 | * @param expiration_time When does the content expire | ||
42 | * @param data Content to store | ||
43 | * @param data_size Size of content @a data in bytes | ||
44 | */ | ||
45 | void | ||
46 | GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, | ||
47 | enum GNUNET_BLOCK_Type block_type, | ||
48 | enum GNUNET_DHT_RouteOption options, | ||
49 | uint32_t desired_replication_level, | ||
50 | struct GNUNET_TIME_Absolute expiration_time, | ||
51 | const void *data, size_t data_size); | ||
52 | |||
53 | /** | ||
54 | * Handle the get request from the client file. If I am destination do | ||
55 | * datacache put and return. Else find the target friend and forward message | ||
56 | * to it. | ||
57 | * @param key Key for the content | ||
58 | * @param block_type Type of the block | ||
59 | * @param options Routing options | ||
60 | * @param desired_replication_level Desired replication count | ||
61 | */ | ||
62 | void | ||
63 | GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, | ||
64 | enum GNUNET_BLOCK_Type block_type, | ||
65 | enum GNUNET_DHT_RouteOption options, | ||
66 | uint32_t desired_replication_level); | ||
67 | |||
68 | /** | ||
69 | * Send the get result to requesting client. | ||
70 | * @param key Key of the requested data. | ||
71 | * @param type Block type | ||
72 | * @param target_peer Next peer to forward the message to. | ||
73 | * @param source_peer Peer which has the data for the key. | ||
74 | * @param put_path_length Number of peers in @a put_path | ||
75 | * @param put_path Path taken to put the data at its stored location. | ||
76 | * @param get_path_length Number of peers in @a get_path | ||
77 | * @param get_path Path taken to reach to the location of the key. | ||
78 | * @param expiration When will this result expire? | ||
79 | * @param data Payload to store | ||
80 | * @param data_size Size of the @a data | ||
81 | */ | ||
82 | void | ||
83 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, | ||
84 | enum GNUNET_BLOCK_Type type, | ||
85 | const struct GNUNET_PeerIdentity *target_peer, | ||
86 | const struct GNUNET_PeerIdentity *source_peer, | ||
87 | unsigned int put_path_length, | ||
88 | const struct GNUNET_PeerIdentity *put_path, | ||
89 | unsigned int get_path_length, | ||
90 | const struct GNUNET_PeerIdentity *get_path, | ||
91 | struct GNUNET_TIME_Absolute expiration, | ||
92 | const void *data, | ||
93 | size_t data_size); | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Construct a trail teardown message and forward it to target friend. | 36 | * Construct a trail teardown message and forward it to target friend. |
98 | * @param trail_id Unique identifier of the trail. | 37 | * @param trail_id Unique identifier of the trail. |
99 | * @param trail_direction Direction of trail. | 38 | * @param trail_direction Direction of trail. |
@@ -105,29 +44,4 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id, | |||
105 | const struct GNUNET_PeerIdentity *peer); | 44 | const struct GNUNET_PeerIdentity *peer); |
106 | 45 | ||
107 | 46 | ||
108 | /** | ||
109 | * Initialize neighbours subsystem. | ||
110 | * | ||
111 | * @return #GNUNET_OK on success, | ||
112 | * #GNUNET_SYSERR on error | ||
113 | */ | ||
114 | int | ||
115 | GDS_NEIGHBOURS_init (void); | ||
116 | |||
117 | |||
118 | /** | ||
119 | * Shutdown neighbours subsystem. | ||
120 | */ | ||
121 | void | ||
122 | GDS_NEIGHBOURS_done (void); | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Get my identity | ||
127 | * | ||
128 | * @return my identity | ||
129 | */ | ||
130 | struct GNUNET_PeerIdentity | ||
131 | GDS_NEIGHBOURS_get_my_id (void); | ||
132 | |||
133 | #endif | 47 | #endif |
diff --git a/src/dht/gnunet-service-xdht_nse.c b/src/dht/gnunet-service-xdht_nse.c deleted file mode 100644 index b7d60013a..000000000 --- a/src/dht/gnunet-service-xdht_nse.c +++ /dev/null | |||
@@ -1,116 +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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_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-xdht.h" | ||
29 | #include "gnunet-service-xdht_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, struct GNUNET_TIME_Absolute timestamp, | ||
56 | double logestimate, double std_dev) | ||
57 | { | ||
58 | GNUNET_STATISTICS_update (GDS_stats, | ||
59 | gettext_noop ("# Network size estimates received"), | ||
60 | 1, GNUNET_NO); | ||
61 | /* do not allow estimates < 0.5 */ | ||
62 | log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); | ||
63 | } | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Return the log of the current network size estimate. | ||
68 | * | ||
69 | * @return log of NSE | ||
70 | */ | ||
71 | double | ||
72 | GDS_NSE_get () | ||
73 | { | ||
74 | return log_of_network_size_estimate; | ||
75 | } | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Initialize NSE subsystem. | ||
80 | */ | ||
81 | void | ||
82 | GDS_NSE_init () | ||
83 | { | ||
84 | unsigned long long hops; | ||
85 | |||
86 | if ( (GNUNET_YES == | ||
87 | GNUNET_CONFIGURATION_have_value (GDS_cfg, | ||
88 | "dht", | ||
89 | "FORCE_NSE")) && | ||
90 | (GNUNET_OK == | ||
91 | GNUNET_CONFIGURATION_get_value_number (GDS_cfg, | ||
92 | "dht", | ||
93 | "FORCE_NSE", | ||
94 | &hops)) ) | ||
95 | { | ||
96 | log_of_network_size_estimate = (double) hops; | ||
97 | return; | ||
98 | } | ||
99 | nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Shutdown NSE subsystem. | ||
105 | */ | ||
106 | void | ||
107 | GDS_NSE_done () | ||
108 | { | ||
109 | if (NULL != nse) | ||
110 | { | ||
111 | GNUNET_NSE_disconnect (nse); | ||
112 | nse = NULL; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /* end of gnunet-service-dht_nse.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_nse.h b/src/dht/gnunet-service-xdht_nse.h deleted file mode 100644 index 358c0c4bd..000000000 --- a/src/dht/gnunet-service-xdht_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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_nse.h | ||
23 | * @brief GNUnet DHT integration with NSE | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_NSE_H | ||
27 | #define GNUNET_SERVICE_XDHT_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-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c index 12b85eb7f..ec7361579 100644 --- a/src/dht/gnunet-service-xdht_routing.c +++ b/src/dht/gnunet-service-xdht_routing.c | |||
@@ -24,9 +24,10 @@ | |||
24 | * @author Supriti Singh | 24 | * @author Supriti Singh |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet-service-dht_neighbours.h" | ||
27 | #include "gnunet-service-xdht_neighbours.h" | 28 | #include "gnunet-service-xdht_neighbours.h" |
28 | #include "gnunet-service-xdht_routing.h" | 29 | #include "gnunet-service-xdht_routing.h" |
29 | #include "gnunet-service-xdht.h" | 30 | #include "gnunet-service-dht.h" |
30 | 31 | ||
31 | 32 | ||
32 | /** | 33 | /** |
@@ -207,7 +208,7 @@ remove_matching_trails (void *cls, | |||
207 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, | 208 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, |
208 | disconnected_peer)) | 209 | disconnected_peer)) |
209 | { | 210 | { |
210 | my_identity = GDS_NEIGHBOURS_get_my_id (); | 211 | my_identity = *GDS_NEIGHBOURS_get_id (); |
211 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | 212 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, |
212 | &remove_trail->prev_hop)) | 213 | &remove_trail->prev_hop)) |
213 | { | 214 | { |
@@ -222,7 +223,7 @@ remove_matching_trails (void *cls, | |||
222 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, | 223 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, |
223 | disconnected_peer)) | 224 | disconnected_peer)) |
224 | { | 225 | { |
225 | my_identity = GDS_NEIGHBOURS_get_my_id (); | 226 | my_identity = *GDS_NEIGHBOURS_get_id (); |
226 | 227 | ||
227 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | 228 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, |
228 | &remove_trail->next_hop)) | 229 | &remove_trail->next_hop)) |
@@ -255,7 +256,7 @@ GDS_ROUTING_test_print (void) | |||
255 | struct GNUNET_HashCode key_ret; | 256 | struct GNUNET_HashCode key_ret; |
256 | int i; | 257 | int i; |
257 | 258 | ||
258 | struct GNUNET_PeerIdentity my_identity = GDS_NEIGHBOURS_get_my_id(); | 259 | struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id(); |
259 | print_peer = my_identity; | 260 | print_peer = my_identity; |
260 | FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); | 261 | FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); |
261 | iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); | 262 | iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); |