aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-09-27 08:58:06 +0000
committerChristian Grothoff <christian@grothoff.org>2011-09-27 08:58:06 +0000
commit4f3f80d05ac7101b8049c352d70abe97bc81ab23 (patch)
treec06793649eddaff22e7363bd97ea70ed2b069950 /src/dht
parente83f3d39b93b4a1aa721c6de33a9c1f04c82896d (diff)
downloadgnunet-4f3f80d05ac7101b8049c352d70abe97bc81ab23.tar.gz
gnunet-4f3f80d05ac7101b8049c352d70abe97bc81ab23.zip
making some files compile
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-dht-new.c664
-rw-r--r--src/dht/gnunet-service-dht.h18
-rw-r--r--src/dht/gnunet-service-dht_clients.c124
-rw-r--r--src/dht/gnunet-service-dht_clients.h2
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c92
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h14
-rw-r--r--src/dht/gnunet-service-dht_nse.c2
-rw-r--r--src/dht/gnunet-service-dht_routing.h11
8 files changed, 238 insertions, 689 deletions
diff --git a/src/dht/gnunet-service-dht-new.c b/src/dht/gnunet-service-dht-new.c
index 17330ddb6..e4ea3891b 100644
--- a/src/dht/gnunet-service-dht-new.c
+++ b/src/dht/gnunet-service-dht-new.c
@@ -23,120 +23,43 @@
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
26 *
27 * TODO:
28 * - use OPTION_MULTIPLE instead of linked list for the forward_list.hashmap
29 * - use different 'struct DHT_MessageContext' for the different types of
30 * messages (currently rather confusing, especially with things like
31 * peer bloom filters occuring when processing replies).
32 */ 26 */
33
34#include "platform.h" 27#include "platform.h"
35#include "gnunet_block_lib.h" 28#include "gnunet_block_lib.h"
36#include "gnunet_client_lib.h"
37#include "gnunet_getopt_lib.h"
38#include "gnunet_os_lib.h"
39#include "gnunet_protocols.h"
40#include "gnunet_service_lib.h"
41#include "gnunet_nse_service.h"
42#include "gnunet_core_service.h"
43#include "gnunet_signal_lib.h"
44#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
45#include "gnunet_datacache_lib.h"
46#include "gnunet_transport_service.h" 30#include "gnunet_transport_service.h"
47#include "gnunet_hello_lib.h" 31#include "gnunet_hello_lib.h"
48#include "gnunet_dht_service.h" 32#include "gnunet_dht_service.h"
49#include "gnunet_statistics_service.h" 33#include "gnunet_statistics_service.h"
50#include "dht.h" 34#include "gnunet-service-dht.h"
51#include <fenv.h> 35#include "gnunet-service-dht_clients.h"
52 36#include "gnunet-service-dht_datacache.h"
53 37#include "gnunet-service-dht_neighbours.h"
54/** 38#include "gnunet-service-dht_nse.h"
55 * Defines whether find peer requests send their HELLO's outgoing, 39#include "gnunet-service-dht_routing.h"
56 * or expect replies to contain hellos.
57 */
58#define FIND_PEER_WITH_HELLO GNUNET_YES
59
60#define DEFAULT_CORE_QUEUE_SIZE 32
61 40
62/**
63 * Minimum number of peers we need for "good" routing,
64 * any less than this and we will allow messages to
65 * travel much further through the network!
66 */
67#define MINIMUM_PEER_THRESHOLD 20
68 41
69/**
70 * How long do we wait at most when queueing messages with core
71 * that we are sending on behalf of other peers.
72 */
73#define DHT_DEFAULT_P2P_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
74
75/**
76 * Default importance for handling messages on behalf of other peers.
77 */
78#define DHT_DEFAULT_P2P_IMPORTANCE 0
79 42
80/** 43/**
81 * How long to keep recent requests around by default. 44 * Handle for the statistics service.
82 */
83#define DEFAULT_RECENT_REMOVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
84
85/**
86 * Default time to wait to send find peer messages sent by the dht service.
87 */
88#define DHT_DEFAULT_FIND_PEER_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
89
90/**
91 * Default importance for find peer messages sent by the dht service.
92 */
93#define DHT_DEFAULT_FIND_PEER_IMPORTANCE 8
94
95/**
96 * Default replication parameter for find peer messages sent by the dht service.
97 */
98#define DHT_DEFAULT_FIND_PEER_REPLICATION 4
99
100/**
101 * How long at least to wait before sending another find peer request.
102 */
103#define DHT_MINIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
104
105/**
106 * How long at most to wait before sending another find peer request.
107 */
108#define DHT_MAXIMUM_FIND_PEER_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 8)
109
110/**
111 * How often to update our preference levels for peers in our routing tables.
112 */ 45 */
113#define DHT_DEFAULT_PREFERENCE_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 46struct GNUNET_STATISTICS_Handle *GDS_stats;
114 47
115/** 48/**
116 * How long at most on average will we allow a reply forward to take 49 * Our handle to the BLOCK library.
117 * (before we quit sending out new requests)
118 */ 50 */
119#define MAX_REQUEST_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 51struct GNUNET_BLOCK_Context *GDS_block_context;
120 52
121/** 53/**
122 * How many time differences between requesting a core send and 54 * The configuration the DHT service is running with
123 * the actual callback to remember.
124 */ 55 */
125#define MAX_REPLY_TIMES 8 56const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
126
127
128
129 57
130/** 58/**
131 * How many peers have we added since we sent out our last 59 * Our HELLO
132 * find peer request?
133 */ 60 */
134static unsigned int newly_found_peers; 61struct GNUNET_MessageHeader *GDS_my_hello;
135 62
136/**
137 * Handle for the statistics service.
138 */
139struct GNUNET_STATISTICS_Handle *stats;
140 63
141/** 64/**
142 * Handle to get our current HELLO. 65 * Handle to get our current HELLO.
@@ -144,474 +67,26 @@ struct GNUNET_STATISTICS_Handle *stats;
144static struct GNUNET_TRANSPORT_GetHelloHandle *ghh; 67static struct GNUNET_TRANSPORT_GetHelloHandle *ghh;
145 68
146/** 69/**
147 * The configuration the DHT service is running with
148 */
149static const struct GNUNET_CONFIGURATION_Handle *cfg;
150
151/**
152 * Handle to the core service
153 */
154static struct GNUNET_CORE_Handle *coreAPI;
155
156/**
157 * Handle to the transport service, for getting our hello 70 * Handle to the transport service, for getting our hello
158 */ 71 */
159static struct GNUNET_TRANSPORT_Handle *transport_handle; 72static struct GNUNET_TRANSPORT_Handle *transport_handle;
160 73
161/**
162 * The identity of our peer.
163 */
164static struct GNUNET_PeerIdentity my_identity;
165
166/**
167 * Our HELLO
168 */
169static struct GNUNET_MessageHeader *my_hello;
170
171/**
172 * Task to run when we shut down, cleaning up all our trash
173 */
174static GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
175
176/**
177 * Recently seen find peer requests.
178 */
179static struct GNUNET_CONTAINER_MultiHashMap *recent_find_peer_requests;
180
181/**
182 * Our handle to the BLOCK library.
183 */
184static struct GNUNET_BLOCK_Context *block_context;
185
186
187
188
189/**
190 * Given the largest send delay, artificially decrease it
191 * so the next time around we may have a chance at sending
192 * again.
193 */
194static void
195decrease_max_send_delay (struct GNUNET_TIME_Relative max_time)
196{
197 unsigned int i;
198
199 for (i = 0; i < MAX_REPLY_TIMES; i++)
200 {
201 if (reply_times[i].rel_value == max_time.rel_value)
202 {
203 reply_times[i].rel_value = reply_times[i].rel_value / 2;
204 return;
205 }
206 }
207}
208
209
210/**
211 * Find the maximum send time of the recently sent values.
212 *
213 * @return the average time between asking core to send a message
214 * and when the buffer for copying it is passed
215 */
216static struct GNUNET_TIME_Relative
217get_max_send_delay ()
218{
219 unsigned int i;
220 struct GNUNET_TIME_Relative max_time;
221
222 max_time = GNUNET_TIME_relative_get_zero ();
223
224 for (i = 0; i < MAX_REPLY_TIMES; i++)
225 {
226 if (reply_times[i].rel_value > max_time.rel_value)
227 max_time.rel_value = reply_times[i].rel_value;
228 }
229#if DEBUG_DHT
230 if (max_time.rel_value > MAX_REQUEST_TIME.rel_value)
231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Max send delay was %llu\n",
232 (unsigned long long) max_time.rel_value);
233#endif
234 return max_time;
235}
236
237
238static void
239increment_stats (const char *value)
240{
241 if (stats == NULL)
242 return;
243 GNUNET_STATISTICS_update (stats, value, 1, GNUNET_NO);
244}
245
246
247static void
248decrement_stats (const char *value)
249{
250 if (stats == NULL)
251 return;
252 GNUNET_STATISTICS_update (stats, value, -1, GNUNET_NO);
253}
254
255
256
257/**
258 * Compute the distance between have and target as a 32-bit value.
259 * Differences in the lower bits must count stronger than differences
260 * in the higher bits.
261 *
262 * @return 0 if have==target, otherwise a number
263 * that is larger as the distance between
264 * the two hash codes increases
265 */
266static unsigned int
267distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
268{
269 unsigned int bucket;
270 unsigned int msb;
271 unsigned int lsb;
272 unsigned int i;
273
274 /* We have to represent the distance between two 2^9 (=512)-bit
275 * numbers as a 2^5 (=32)-bit number with "0" being used for the
276 * two numbers being identical; furthermore, we need to
277 * guarantee that a difference in the number of matching
278 * bits is always represented in the result.
279 *
280 * We use 2^32/2^9 numerical values to distinguish between
281 * hash codes that have the same LSB bit distance and
282 * use the highest 2^9 bits of the result to signify the
283 * number of (mis)matching LSB bits; if we have 0 matching
284 * and hence 512 mismatching LSB bits we return -1 (since
285 * 512 itself cannot be represented with 9 bits) */
286
287 /* first, calculate the most significant 9 bits of our
288 * result, aka the number of LSBs */
289 bucket = GNUNET_CRYPTO_hash_matching_bits (target, have);
290 /* bucket is now a value between 0 and 512 */
291 if (bucket == 512)
292 return 0; /* perfect match */
293 if (bucket == 0)
294 return (unsigned int) -1; /* LSB differs; use max (if we did the bit-shifting
295 * below, we'd end up with max+1 (overflow)) */
296
297 /* calculate the most significant bits of the final result */
298 msb = (512 - bucket) << (32 - 9);
299 /* calculate the 32-9 least significant bits of the final result by
300 * looking at the differences in the 32-9 bits following the
301 * mismatching bit at 'bucket' */
302 lsb = 0;
303 for (i = bucket + 1;
304 (i < sizeof (GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++)
305 {
306 if (GNUNET_CRYPTO_hash_get_bit (target, i) !=
307 GNUNET_CRYPTO_hash_get_bit (have, i))
308 lsb |= (1 << (bucket + 32 - 9 - i)); /* first bit set will be 10,
309 * last bit set will be 31 -- if
310 * i does not reach 512 first... */
311 }
312 return msb | lsb;
313}
314
315 74
316/** 75/**
317 * Return a number that is larger the closer the 76 * Receive the HELLO from transport service, free current and replace
318 * "have" GNUNET_hash code is to the "target". 77 * if necessary.
319 *
320 * @return inverse distance metric, non-zero.
321 * Must fudge the value if NO bits match.
322 */
323static unsigned int
324inverse_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have)
325{
326 if (GNUNET_CRYPTO_hash_matching_bits (target, have) == 0)
327 return 1; /* Never return 0! */
328 return ((unsigned int) -1) - distance (target, have);
329}
330
331
332
333/* Forward declaration */
334static void
335update_core_preference (void *cls,
336 const struct GNUNET_SCHEDULER_TaskContext *tc);
337
338
339/**
340 * Function called with statistics about the given peer.
341 *
342 * @param cls closure
343 * @param peer identifies the peer
344 * @param bpm_out set to the current bandwidth limit (sending) for this peer
345 * @param amount set to the amount that was actually reserved or unreserved;
346 * either the full requested amount or zero (no partial reservations)
347 * @param res_delay if the reservation could not be satisfied (amount was 0), how
348 * long should the client wait until re-trying?
349 * @param preference current traffic preference for the given peer
350 */
351static void
352update_core_preference_finish (void *cls,
353 const struct GNUNET_PeerIdentity *peer,
354 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
355 int32_t amount,
356 struct GNUNET_TIME_Relative res_delay,
357 uint64_t preference)
358{
359 struct PeerInfo *peer_info = cls;
360
361 peer_info->info_ctx = NULL;
362 GNUNET_SCHEDULER_add_delayed (DHT_DEFAULT_PREFERENCE_INTERVAL,
363 &update_core_preference, peer_info);
364}
365
366static void
367update_core_preference (void *cls,
368 const struct GNUNET_SCHEDULER_TaskContext *tc)
369{
370 struct PeerInfo *peer = cls;
371 uint64_t preference;
372 unsigned int matching;
373
374 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
375 {
376 return;
377 }
378 matching =
379 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey,
380 &peer->id.hashPubKey);
381 if (matching >= 64)
382 {
383#if DEBUG_DHT
384 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
385 "Peer identifier matches by %u bits, only shifting as much as we can!\n",
386 matching);
387#endif
388 matching = 63;
389 }
390 preference = 1LL << matching;
391 peer->info_ctx =
392 GNUNET_CORE_peer_change_preference (coreAPI, &peer->id,
393 GNUNET_TIME_UNIT_FOREVER_REL,
394 GNUNET_BANDWIDTH_VALUE_MAX, 0,
395 preference,
396 &update_core_preference_finish, peer);
397}
398
399
400
401/**
402 * Server handler for initiating local dht find peer requests
403 *
404 * @param find_msg the actual find peer message
405 * @param msg_ctx struct containing pertinent information about the request
406 *
407 */
408static void
409handle_dht_find_peer (const struct GNUNET_MessageHeader *find_msg,
410 struct DHT_MessageContext *msg_ctx)
411{
412 struct GNUNET_MessageHeader *find_peer_result;
413 struct GNUNET_DHT_FindPeerMessage *find_peer_message;
414 struct DHT_MessageContext *new_msg_ctx;
415 struct GNUNET_CONTAINER_BloomFilter *incoming_bloom;
416 size_t hello_size;
417 size_t tsize;
418 GNUNET_HashCode *recent_hash;
419 struct GNUNET_MessageHeader *other_hello;
420 size_t other_hello_size;
421 struct GNUNET_PeerIdentity peer_id;
422
423 find_peer_message = (struct GNUNET_DHT_FindPeerMessage *) find_msg;
424 GNUNET_break_op (ntohs (find_msg->size) >=
425 (sizeof (struct GNUNET_DHT_FindPeerMessage)));
426 if (ntohs (find_msg->size) < sizeof (struct GNUNET_DHT_FindPeerMessage))
427 return;
428 other_hello = NULL;
429 other_hello_size = 0;
430 if (ntohs (find_msg->size) > sizeof (struct GNUNET_DHT_FindPeerMessage))
431 {
432 other_hello_size =
433 ntohs (find_msg->size) - sizeof (struct GNUNET_DHT_FindPeerMessage);
434 other_hello = GNUNET_malloc (other_hello_size);
435 memcpy (other_hello, &find_peer_message[1], other_hello_size);
436 if ((GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) other_hello) == 0)
437 || (GNUNET_OK !=
438 GNUNET_HELLO_get_id ((struct GNUNET_HELLO_Message *) other_hello,
439 &peer_id)))
440 {
441 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
442 "Received invalid HELLO message in find peer request!\n");
443 GNUNET_free (other_hello);
444 return;
445 }
446#if FIND_PEER_WITH_HELLO
447 if (GNUNET_YES == consider_peer (&peer_id))
448 {
449 increment_stats (STAT_HELLOS_PROVIDED);
450 GNUNET_TRANSPORT_offer_hello (transport_handle, other_hello, NULL, NULL);
451 GNUNET_CORE_peer_request_connect (coreAPI, &peer_id, NULL, NULL);
452 route_message (find_msg, msg_ctx);
453 GNUNET_free (other_hello);
454 return;
455 }
456 else /* We don't want this peer! */
457 {
458 route_message (find_msg, msg_ctx);
459 GNUNET_free (other_hello);
460 return;
461 }
462#endif
463 }
464
465#if DEBUG_DHT
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
467 "`%s:%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n",
468 my_short_id, "DHT", "FIND PEER", GNUNET_h2s (&msg_ctx->key),
469 ntohs (find_msg->size), sizeof (struct GNUNET_MessageHeader));
470#endif
471 if (my_hello == NULL)
472 {
473#if DEBUG_DHT
474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
475 "`%s': Our HELLO is null, can't return.\n", "DHT");
476#endif
477 GNUNET_free_non_null (other_hello);
478 route_message (find_msg, msg_ctx);
479 return;
480 }
481
482 incoming_bloom =
483 GNUNET_CONTAINER_bloomfilter_init (find_peer_message->bloomfilter,
484 DHT_BLOOM_SIZE, DHT_BLOOM_K);
485 if (GNUNET_YES ==
486 GNUNET_CONTAINER_bloomfilter_test (incoming_bloom,
487 &my_identity.hashPubKey))
488 {
489 increment_stats (STAT_BLOOM_FIND_PEER);
490 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom);
491 GNUNET_free_non_null (other_hello);
492 route_message (find_msg, msg_ctx);
493 return; /* We match the bloomfilter, do not send a response to this peer (they likely already know us!) */
494 }
495 GNUNET_CONTAINER_bloomfilter_free (incoming_bloom);
496
497 /**
498 * Ignore any find peer requests from a peer we have seen very recently.
499 */
500 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (recent_find_peer_requests, &msg_ctx->key)) /* We have recently responded to a find peer request for this peer! */
501 {
502 increment_stats ("# dht find peer requests ignored (recently seen!)");
503 GNUNET_free_non_null (other_hello);
504 return;
505 }
506
507 /**
508 * Use this check to only allow the peer to respond to find peer requests if
509 * it would be beneficial to have the requesting peer in this peers routing
510 * table. Can be used to thwart peers flooding the network with find peer
511 * requests that we don't care about. However, if a new peer is joining
512 * the network and has no other peers this is a problem (assume all buckets
513 * full, no one will respond!).
514 */
515 memcpy (&peer_id.hashPubKey, &msg_ctx->key, sizeof (GNUNET_HashCode));
516 if (GNUNET_NO == consider_peer (&peer_id))
517 {
518 increment_stats ("# dht find peer requests ignored (do not need!)");
519 GNUNET_free_non_null (other_hello);
520 route_message (find_msg, msg_ctx);
521 return;
522 }
523
524 recent_hash = GNUNET_malloc (sizeof (GNUNET_HashCode));
525 memcpy (recent_hash, &msg_ctx->key, sizeof (GNUNET_HashCode));
526 if (GNUNET_SYSERR !=
527 GNUNET_CONTAINER_multihashmap_put (recent_find_peer_requests,
528 &msg_ctx->key, NULL,
529 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
530 {
531#if DEBUG_DHT
532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
533 "Adding recent remove task for key `%s`!\n",
534 GNUNET_h2s (&msg_ctx->key));
535#endif
536 /* Only add a task if there wasn't one for this key already! */
537 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
538 (GNUNET_TIME_UNIT_SECONDS, 30),
539 &remove_recent_find_peer, recent_hash);
540 }
541 else
542 {
543 GNUNET_free (recent_hash);
544#if DEBUG_DHT
545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
546 "Received duplicate find peer request too soon!\n");
547#endif
548 }
549
550 /* Simplistic find_peer functionality, always return our hello */
551 hello_size = ntohs (my_hello->size);
552 tsize = hello_size + sizeof (struct GNUNET_MessageHeader);
553
554 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
555 {
556 GNUNET_break_op (0);
557 GNUNET_free_non_null (other_hello);
558 return;
559 }
560
561 find_peer_result = GNUNET_malloc (tsize);
562 find_peer_result->type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT);
563 find_peer_result->size = htons (tsize);
564 memcpy (&find_peer_result[1], my_hello, hello_size);
565#if DEBUG_DHT
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
567 "`%s': Sending hello size %d to requesting peer.\n", "DHT",
568 hello_size);
569#endif
570
571 new_msg_ctx = GNUNET_malloc (sizeof (struct DHT_MessageContext));
572 memcpy (new_msg_ctx, msg_ctx, sizeof (struct DHT_MessageContext));
573 new_msg_ctx->peer = my_identity;
574 new_msg_ctx->bloom =
575 GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, DHT_BLOOM_K);
576 new_msg_ctx->hop_count = 0;
577 new_msg_ctx->importance = DHT_DEFAULT_P2P_IMPORTANCE + 2; /* Make find peer requests a higher priority */
578 new_msg_ctx->timeout = DHT_DEFAULT_P2P_TIMEOUT;
579 increment_stats (STAT_FIND_PEER_ANSWER);
580 if (GNUNET_DHT_RO_RECORD_ROUTE ==
581 (msg_ctx->msg_options & GNUNET_DHT_RO_RECORD_ROUTE))
582 {
583 new_msg_ctx->msg_options = GNUNET_DHT_RO_RECORD_ROUTE;
584 new_msg_ctx->path_history_len = msg_ctx->path_history_len;
585 /* Assign to previous msg_ctx path history, caller should free after our return */
586 new_msg_ctx->path_history = msg_ctx->path_history;
587 }
588 route_result_message (find_peer_result, new_msg_ctx);
589 GNUNET_free (new_msg_ctx);
590 GNUNET_free_non_null (other_hello);
591 GNUNET_free (find_peer_result);
592 route_message (find_msg, msg_ctx);
593}
594
595
596
597/**
598 * Receive the HELLO from transport service,
599 * free current and replace if necessary.
600 * 78 *
601 * @param cls NULL 79 * @param cls NULL
602 * @param message HELLO message of peer 80 * @param message HELLO message of peer
603 */ 81 */
604static void 82static void
605process_hello (void *cls, const struct GNUNET_MessageHeader *message) 83process_hello (void *cls,
84 const struct GNUNET_MessageHeader *message)
606{ 85{
607#if DEBUG_DHT
608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
609 "Received our `%s' from transport service\n", "HELLO");
610#endif
611 GNUNET_assert (message != NULL); 86 GNUNET_assert (message != NULL);
612 GNUNET_free_non_null (my_hello); 87 GNUNET_free_non_null (GDS_my_hello);
613 my_hello = GNUNET_malloc (ntohs (message->size)); 88 GDS_my_hello = GNUNET_malloc (ntohs (message->size));
614 memcpy (my_hello, message, ntohs (message->size)); 89 memcpy (GDS_my_hello, message, ntohs (message->size));
615} 90}
616 91
617 92
@@ -631,7 +106,6 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
631 } 106 }
632 if (transport_handle != NULL) 107 if (transport_handle != NULL)
633 { 108 {
634 GNUNET_free_non_null (my_hello);
635 GNUNET_TRANSPORT_disconnect (transport_handle); 109 GNUNET_TRANSPORT_disconnect (transport_handle);
636 transport_handle = NULL; 110 transport_handle = NULL;
637 } 111 }
@@ -640,20 +114,21 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
640 GDS_ROUTING_done (); 114 GDS_ROUTING_done ();
641 GDS_CLIENT_done (); 115 GDS_CLIENT_done ();
642 GDS_NSE_done (); 116 GDS_NSE_done ();
643 if (stats != NULL) 117 if (GDS_block_context != NULL)
644 { 118 {
645 GNUNET_STATISTICS_destroy (stats, GNUNET_YES); 119 GNUNET_BLOCK_context_destroy (GDS_block_context);
646 stats = NULL; 120 GDS_block_context = NULL;
647 } 121 }
648 if (block_context != NULL) 122 if (GDS_stats != NULL)
649 { 123 {
650 GNUNET_BLOCK_context_destroy (block_context); 124 GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES);
651 block_context = NULL; 125 GDS_stats = NULL;
652 } 126 }
127 GNUNET_free_non_null (GDS_my_hello);
128 GDS_my_hello = NULL;
653} 129}
654 130
655 131
656
657/** 132/**
658 * Process dht requests. 133 * Process dht requests.
659 * 134 *
@@ -665,60 +140,31 @@ static void
665run (void *cls, struct GNUNET_SERVER_Handle *server, 140run (void *cls, struct GNUNET_SERVER_Handle *server,
666 const struct GNUNET_CONFIGURATION_Handle *c) 141 const struct GNUNET_CONFIGURATION_Handle *c)
667{ 142{
668 struct GNUNET_TIME_Relative next_send_time; 143 GDS_cfg = c;
669 unsigned long long temp_config_num; 144 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg);
670 145 GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg);
671 cfg = c; 146 GDS_ROUTING_init ();
147 GDS_NSE_init ();
672 GDS_DATACACHE_init (); 148 GDS_DATACACHE_init ();
673 coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */ 149 GDS_CLIENT_init (server);
674 DEFAULT_CORE_QUEUE_SIZE, /* queue size */ 150 if (GNUNET_OK !=
675 NULL, /* Closure passed to DHT functions */ 151 GDS_NEIGHBOURS_init ())
676 &core_init, /* Call core_init once connected */ 152 {
677 &handle_core_connect, /* Handle connects */ 153 shutdown_task (NULL, NULL);
678 &handle_core_disconnect, /* remove peers on disconnects */ 154 return;
679 NULL, /* Do we care about "status" updates? */ 155 }
680 NULL, /* Don't want notified about all incoming messages */ 156 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
681 GNUNET_NO, /* For header only inbound notification */ 157 &shutdown_task, NULL);
682 NULL, /* Don't want notified about all outbound messages */
683 GNUNET_NO, /* For header only outbound notification */
684 core_handlers); /* Register these handlers */
685
686 if (coreAPI == NULL)
687 return;
688 transport_handle = 158 transport_handle =
689 GNUNET_TRANSPORT_connect (cfg, NULL, NULL, NULL, NULL, NULL); 159 GNUNET_TRANSPORT_connect (GDS_cfg, NULL, NULL, NULL, NULL, NULL);
690 if (transport_handle != NULL) 160 if (transport_handle == NULL)
691 ghh = GNUNET_TRANSPORT_get_hello (transport_handle, &process_hello, NULL); 161 {
692 else 162 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
693 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 163 _("Failed to connect to transport service!\n"));
694 "Failed to connect to transport service!\n"); 164 return;
695 block_context = GNUNET_BLOCK_context_create (cfg); 165 }
696 lowest_bucket = MAX_BUCKETS - 1; 166 ghh = GNUNET_TRANSPORT_get_hello (transport_handle,
697 all_known_peers = GNUNET_CONTAINER_multihashmap_create (MAX_BUCKETS / 8); 167 &process_hello, NULL);
698 GNUNET_assert (all_known_peers != NULL);
699
700 if (GNUNET_OK ==
701 GNUNET_CONFIGURATION_get_value_number (cfg, "DHT", "bucket_size",
702 &temp_config_num))
703 {
704 bucket_size = (unsigned int) temp_config_num;
705 }
706
707 stats = GNUNET_STATISTICS_create ("dht", cfg);
708 next_send_time.rel_value =
709 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
710 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
711 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value /
712 2) -
713 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
714 find_peer_context.start = GNUNET_TIME_absolute_get ();
715 GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_peer_message,
716 &find_peer_context);
717
718 /* Scheduled the task to clean up when shutdown is called */
719 cleanup_task =
720 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
721 &shutdown_task, NULL);
722} 168}
723 169
724 170
@@ -733,8 +179,10 @@ int
733main (int argc, char *const *argv) 179main (int argc, char *const *argv)
734{ 180{
735 return (GNUNET_OK == 181 return (GNUNET_OK ==
736 GNUNET_SERVICE_run (argc, argv, "dht", GNUNET_SERVICE_OPTION_NONE, &run, 182 GNUNET_SERVICE_run (argc, argv,
737 NULL)) ? 0 : 1; 183 "gnunet-service-dht",
184 GNUNET_SERVICE_OPTION_NONE,
185 &run, NULL)) ? 0 : 1;
738} 186}
739 187
740/* end of gnunet-service-dht.c */ 188/* end of gnunet-service-dht.c */
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index c2e16151d..04f3e9fb3 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -31,7 +31,7 @@
31/** 31/**
32 * Configuration we use. 32 * Configuration we use.
33 */ 33 */
34extern struct GNUNET_ConfigurationHandle *GDS_cfg; 34extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
35 35
36 36
37/** 37/**
@@ -40,4 +40,20 @@ extern struct GNUNET_ConfigurationHandle *GDS_cfg;
40extern struct GNUNET_BLOCK_Context *GDS_block_context; 40extern struct GNUNET_BLOCK_Context *GDS_block_context;
41 41
42 42
43/**
44 * Handle for the statistics service.
45 */
46extern struct GNUNET_STATISTICS_Handle *GDS_stats;
47
48/**
49 * The identity of our peer.
50 */
51extern struct GNUNET_PeerIdentity GDS_my_identity;
52
53/**
54 * Our HELLO
55 */
56extern struct GNUNET_MessageHeader *GDS_my_hello;
57
58
43#endif 59#endif
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index 8790d8fbb..154d8d98e 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -26,21 +26,13 @@
26 */ 26 */
27 27
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_block_lib.h"
30#include "gnunet_util_lib.h"
31#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
32#include "gnunet_nse_service.h"
33#include "gnunet_core_service.h"
34#include "gnunet_datacache_lib.h"
35#include "gnunet_transport_service.h"
36#include "gnunet_hello_lib.h"
37#include "gnunet_dht_service.h"
38#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
39#include "dht_new.h" 31#include "gnunet-service-dht.h"
40#include <fenv.h>
41#include "gnunet-service-dht_clients.h" 32#include "gnunet-service-dht_clients.h"
42#include "gnunet-service-dht_datacache.h" 33#include "gnunet-service-dht_datacache.h"
43#include "gnunet-service-dht_neighbours.h" 34#include "gnunet-service-dht_neighbours.h"
35#include "dht_new.h"
44 36
45 37
46/** 38/**
@@ -179,7 +171,7 @@ struct ClientQueryRecord
179 /** 171 /**
180 * The type for the data for the GET request. 172 * The type for the data for the GET request.
181 */ 173 */
182 enum GNUNET_BLOCK_Type msg_type; 174 enum GNUNET_BLOCK_Type type;
183 175
184}; 176};
185 177
@@ -220,7 +212,7 @@ static GNUNET_SCHEDULER_TaskIdentifier retry_task;
220static struct ClientList * 212static struct ClientList *
221find_active_client (struct GNUNET_SERVER_Client *client) 213find_active_client (struct GNUNET_SERVER_Client *client)
222{ 214{
223 struct ClientList *pos = client_list; 215 struct ClientList *pos = client_head;
224 struct ClientList *ret; 216 struct ClientList *ret;
225 217
226 while (pos != NULL) 218 while (pos != NULL)
@@ -259,9 +251,9 @@ remove_client_records (void *cls, const GNUNET_HashCode * key, void *value)
259 GNUNET_CONTAINER_multihashmap_remove (forward_map, 251 GNUNET_CONTAINER_multihashmap_remove (forward_map,
260 key, record)); 252 key, record));
261 GNUNET_CONTAINER_heap_remove_node (record->hnode); 253 GNUNET_CONTAINER_heap_remove_node (record->hnode);
262 GNUNET_ARRAY_append (record->seen_replies, 254 GNUNET_array_append (record->seen_replies,
263 record->seen_replies_count, 255 record->seen_replies_count,
264 0); 256 *key);
265 GNUNET_free (record); 257 GNUNET_free (record);
266 return GNUNET_YES; 258 return GNUNET_YES;
267} 259}
@@ -279,36 +271,24 @@ static void
279handle_client_disconnect (void *cls, 271handle_client_disconnect (void *cls,
280 struct GNUNET_SERVER_Client *client) 272 struct GNUNET_SERVER_Client *client)
281{ 273{
282 struct ClientList *pos = client_list; 274 struct ClientList *pos;
283 struct ClientList *found;
284 struct PendingMessage *reply; 275 struct PendingMessage *reply;
285 276
286 found = NULL; 277 pos = find_active_client (client);
287 while (pos != NULL) 278 GNUNET_CONTAINER_DLL_remove (client_head,
288 { 279 client_tail,
289 if (pos->client_handle == client) 280 pos);
290 { 281 if (pos->transmit_handle != NULL)
291 GNUNET_CONTAINER_DLL_remove (client_head, 282 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->transmit_handle);
292 client_tail, 283 while (NULL != (reply = pos->pending_head))
293 pos);
294 found = pos;
295 break;
296 }
297 pos = pos->next;
298 }
299 if (found == NULL)
300 return;
301 if (found->transmit_handle != NULL)
302 GNUNET_CONNECTION_notify_transmit_ready_cancel (found->transmit_handle);
303 while (NULL != (reply = found->pending_head))
304 { 284 {
305 GNUNET_CONTAINER_DLL_remove (found->pending_head, found->pending_tail, 285 GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail,
306 reply); 286 reply);
307 GNUNET_free (reply); 287 GNUNET_free (reply);
308 } 288 }
309 GNUNET_CONTAINER_multihashmap_iterate (forward_list.hashmap, 289 GNUNET_CONTAINER_multihashmap_iterate (forward_map,
310 &remove_client_records, found); 290 &remove_client_records, pos);
311 GNUNET_free (found); 291 GNUNET_free (pos);
312} 292}
313 293
314 294
@@ -321,22 +301,24 @@ static void
321transmit_request (struct ClientQueryRecord *cqr) 301transmit_request (struct ClientQueryRecord *cqr)
322{ 302{
323 int32_t reply_bf_mutator; 303 int32_t reply_bf_mutator;
304 struct GNUNET_CONTAINER_BloomFilter *reply_bf;
324 305
325 reply_bf_mutator = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 306 reply_bf_mutator = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
326 UINT32_MAX); 307 UINT32_MAX);
327 reply_bf = GNUNET_BLOCK_construct_bloomfilter (reply_bf_mutator, 308 reply_bf = GNUNET_BLOCK_construct_bloomfilter (reply_bf_mutator,
328 cqr->seen_replies, 309 cqr->seen_replies,
329 cqr->seen_replies_count); 310 cqr->seen_replies_count);
330 GST_NEIGHBOURS_handle_get (cqr->msg_type, 311 GDS_NEIGHBOURS_handle_get (cqr->type,
331 cqr->msg_options, 312 cqr->msg_options,
332 cqr->replication, 313 cqr->replication,
314 0 /* hop count */,
333 &cqr->key, 315 &cqr->key,
334 cqr->xquery, 316 cqr->xquery,
335 cqr->xquery_size, 317 cqr->xquery_size,
336 reply_bf, 318 reply_bf,
337 reply_bf_mutator, 319 reply_bf_mutator,
338 NULL /* no peers blocked initially */); 320 NULL /* no peers blocked initially */);
339 GNUNET_CONTAINER_bloomfilter_destroy (reply_bf); 321 GNUNET_CONTAINER_bloomfilter_free (reply_bf);
340 322
341 /* exponential back-off for retries, max 1h */ 323 /* exponential back-off for retries, max 1h */
342 cqr->retry_frequency = 324 cqr->retry_frequency =
@@ -368,7 +350,7 @@ transmit_next_request_task (void *cls,
368 { 350 {
369 cqr->hnode = NULL; 351 cqr->hnode = NULL;
370 delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); 352 delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time);
371 if (delay.value > 0) 353 if (delay.rel_value > 0)
372 { 354 {
373 cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 355 cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
374 cqr->retry_time.abs_value); 356 cqr->retry_time.abs_value);
@@ -412,18 +394,21 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
412 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 394 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
413 &dht_msg[1]); 395 &dht_msg[1]);
414 /* store locally */ 396 /* store locally */
415 GST_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 397 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
416 &dht_msg->key, 398 &dht_msg->key,
417 0, NULL, 399 0, NULL,
418 ntohl (dht_msg->type), 400 ntohl (dht_msg->type),
419 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 401 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
420 &dht_msg[1]); 402 &dht_msg[1]);
421 /* route to other peers */ 403 /* route to other peers */
422 GST_NEIGHBOURS_handle_put (ntohl (dht_msg->type), 404 GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type),
423 ntohl (dht_msg->options), 405 ntohl (dht_msg->options),
424 ntohl (dht_msg->desired_replication_level), 406 ntohl (dht_msg->desired_replication_level),
425 GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 407 GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
408 0 /* hop count */,
409 NULL /* peer bloom filter */,
426 &dht_msg->key, 410 &dht_msg->key,
411 0, NULL,
427 &dht_msg[1], 412 &dht_msg[1],
428 size - sizeof (struct GNUNET_DHT_ClientPutMessage)); 413 size - sizeof (struct GNUNET_DHT_ClientPutMessage));
429 GNUNET_SERVER_receive_done (client, GNUNET_OK); 414 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -444,8 +429,6 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
444 const struct GNUNET_MessageHeader *message) 429 const struct GNUNET_MessageHeader *message)
445{ 430{
446 const struct GNUNET_DHT_ClientGetMessage *get; 431 const struct GNUNET_DHT_ClientGetMessage *get;
447 const struct GNUNET_MessageHeader *enc_msg;
448
449 struct ClientQueryRecord *cqr; 432 struct ClientQueryRecord *cqr;
450 size_t xquery_size; 433 size_t xquery_size;
451 const char* xquery; 434 const char* xquery;
@@ -475,8 +458,8 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
475 cqr->xquery_size = xquery_size; 458 cqr->xquery_size = xquery_size;
476 cqr->replication = ntohl (get->desired_replication_level); 459 cqr->replication = ntohl (get->desired_replication_level);
477 cqr->msg_options = ntohl (get->options); 460 cqr->msg_options = ntohl (get->options);
478 cqr->msg_type = ntohl (get->type); 461 cqr->type = ntohl (get->type);
479 GNUNET_CONTAINER_multihashmap_put (forward_map, KEY, cqr, 462 GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr,
480 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 463 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
481 /* start remote requests */ 464 /* start remote requests */
482 if (GNUNET_SCHEDULER_NO_TASK != retry_task) 465 if (GNUNET_SCHEDULER_NO_TASK != retry_task)
@@ -484,7 +467,7 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
484 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); 467 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL);
485 /* perform local lookup */ 468 /* perform local lookup */
486 GDS_DATACACHE_handle_get (&get->key, 469 GDS_DATACACHE_handle_get (&get->key,
487 cqr->msg_type, 470 cqr->type,
488 cqr->xquery, 471 cqr->xquery,
489 xquery_size, 472 xquery_size,
490 NULL, 0); 473 NULL, 0);
@@ -493,9 +476,9 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
493 476
494 477
495/** 478/**
496 * Closure for 'remove_by_uid'. 479 * Closure for 'remove_by_unique_id'.
497 */ 480 */
498struct RemoveByUidContext 481struct RemoveByUniqueIdContext
499{ 482{
500 /** 483 /**
501 * Client that issued the removal request. 484 * Client that issued the removal request.
@@ -505,26 +488,26 @@ struct RemoveByUidContext
505 /** 488 /**
506 * Unique ID of the request. 489 * Unique ID of the request.
507 */ 490 */
508 uint64_t uid; 491 uint64_t unique_id;
509}; 492};
510 493
511 494
512/** 495/**
513 * Iterator over hash map entries that frees all entries 496 * Iterator over hash map entries that frees all entries
514 * that match the given client and UID. 497 * that match the given client and unique ID.
515 * 498 *
516 * @param cls UID and client to search for in source routes 499 * @param cls unique ID and client to search for in source routes
517 * @param key current key code 500 * @param key current key code
518 * @param value value in the hash map, a ClientQueryRecord 501 * @param value value in the hash map, a ClientQueryRecord
519 * @return GNUNET_YES (we should continue to iterate) 502 * @return GNUNET_YES (we should continue to iterate)
520 */ 503 */
521static int 504static int
522remove_by_uid (void *cls, const GNUNET_HashCode * key, void *value) 505remove_by_unique_id (void *cls, const GNUNET_HashCode * key, void *value)
523{ 506{
524 const struct RemoveByUidContext *ctx = cls; 507 const struct RemoveByUniqueIdContext *ctx = cls;
525 struct ClientQueryRecord *record = value; 508 struct ClientQueryRecord *record = value;
526 509
527 if (record->uid != ctx->uid) 510 if (record->unique_id != ctx->unique_id)
528 return GNUNET_YES; 511 return GNUNET_YES;
529 return remove_client_records (ctx->client, key, record); 512 return remove_client_records (ctx->client, key, record);
530} 513}
@@ -545,12 +528,13 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client,
545{ 528{
546 const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg = 529 const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg =
547 (const struct GNUNET_DHT_ClientGetStopMessage *) message; 530 (const struct GNUNET_DHT_ClientGetStopMessage *) message;
531 struct RemoveByUniqueIdContext ctx;
548 532
549 ctx.client = find_active_client (client); 533 ctx.client = find_active_client (client);
550 ctx.uid = &dht_stop_msg.unique_id); 534 ctx.unique_id = dht_stop_msg->unique_id;
551 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, 535 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
552 &dht_stop_msg->key, 536 &dht_stop_msg->key,
553 &remove_by_uid, 537 &remove_by_unique_id,
554 &ctx); 538 &ctx);
555 GNUNET_SERVER_receive_done (client, GNUNET_OK); 539 GNUNET_SERVER_receive_done (client, GNUNET_OK);
556} 540}
@@ -693,7 +677,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
693 struct ForwardReplyContext *frc = cls; 677 struct ForwardReplyContext *frc = cls;
694 struct ClientQueryRecord *record = value; 678 struct ClientQueryRecord *record = value;
695 struct PendingMessage *pm; 679 struct PendingMessage *pm;
696 struct ReplyMessage *reply; 680 struct GNUNET_DHT_ClientResultMessage *reply;
697 enum GNUNET_BLOCK_EvaluationResult eval; 681 enum GNUNET_BLOCK_EvaluationResult eval;
698 int do_free; 682 int do_free;
699 GNUNET_HashCode ch; 683 GNUNET_HashCode ch;
@@ -724,7 +708,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
724 do_free = GNUNET_YES; 708 do_free = GNUNET_YES;
725 break; 709 break;
726 case GNUNET_BLOCK_EVALUATION_OK_MORE: 710 case GNUNET_BLOCK_EVALUATION_OK_MORE:
727 GNUNET_ARRAY_append (record->seen_replies, 711 GNUNET_array_append (record->seen_replies,
728 record->seen_replies_count, 712 record->seen_replies_count,
729 ch); 713 ch);
730 do_free = GNUNET_NO; 714 do_free = GNUNET_NO;
@@ -763,7 +747,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
763 sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size)); 747 sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size));
764 pm->next = pm->prev = NULL; 748 pm->next = pm->prev = NULL;
765 } 749 }
766 reply = (struct ReplyMessage*) &pm[1]; 750 reply = (struct GNUNET_DHT_ClientResultMessage*) &pm[1];
767 reply->unique_id = record->unique_id; 751 reply->unique_id = record->unique_id;
768 add_pending_message (record->client, pm); 752 add_pending_message (record->client, pm);
769 if (GNUNET_YES == do_free) 753 if (GNUNET_YES == do_free)
@@ -800,14 +784,14 @@ GDS_CLIENT_handle_reply (struct GNUNET_TIME_Absolute expiration,
800{ 784{
801 struct ForwardReplyContext frc; 785 struct ForwardReplyContext frc;
802 struct PendingMessage *pm; 786 struct PendingMessage *pm;
803 struct ReplyMessage *reply; 787 struct GNUNET_DHT_ClientResultMessage *reply;
804 struct GNUNET_PeerIdentity *paths; 788 struct GNUNET_PeerIdentity *paths;
805 size_t msize; 789 size_t msize;
806 790
807 if (NULL == 791 if (NULL ==
808 GNUNET_CONTAINER_multihashmap_get (foward_map, key)) 792 GNUNET_CONTAINER_multihashmap_get (forward_map, key))
809 return; /* no matching request, fast exit! */ 793 return; /* no matching request, fast exit! */
810 msize = sizeof(struct ReplyMessage) + data_size + 794 msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size +
811 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity); 795 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
812 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 796 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
813 { 797 {
@@ -816,7 +800,7 @@ GDS_CLIENT_handle_reply (struct GNUNET_TIME_Absolute expiration,
816 return; 800 return;
817 } 801 }
818 pm = (struct PendingMessage *) GNUNET_malloc (msize + sizeof (struct PendingMessage)); 802 pm = (struct PendingMessage *) GNUNET_malloc (msize + sizeof (struct PendingMessage));
819 reply = (struct ReplyMessage*) &pm[1]; 803 reply = (struct GNUNET_DHT_ClientResultMessage*) &pm[1];
820 pm->msg = &reply->header; 804 pm->msg = &reply->header;
821 reply->header.size = htons ((uint16_t) msize); 805 reply->header.size = htons ((uint16_t) msize);
822 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); 806 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
@@ -827,9 +811,9 @@ GDS_CLIENT_handle_reply (struct GNUNET_TIME_Absolute expiration,
827 reply->expiration = GNUNET_TIME_absolute_hton (expiration); 811 reply->expiration = GNUNET_TIME_absolute_hton (expiration);
828 reply->key = *key; 812 reply->key = *key;
829 paths = (struct GNUNET_PeerIdentity*) &reply[1]; 813 paths = (struct GNUNET_PeerIdentity*) &reply[1];
830 mempcy (paths, get_path, 814 memcpy (paths, get_path,
831 sizeof (struct GNUNET_PeerIdentity) * get_path_length); 815 sizeof (struct GNUNET_PeerIdentity) * get_path_length);
832 mempcy (&paths[get_path_length], 816 memcpy (&paths[get_path_length],
833 put_path, sizeof (struct GNUNET_PeerIdentity) * put_path_length); 817 put_path, sizeof (struct GNUNET_PeerIdentity) * put_path_length);
834 memcpy (&paths[get_path_length + put_path_length], 818 memcpy (&paths[get_path_length + put_path_length],
835 data, 819 data,
@@ -839,13 +823,13 @@ GDS_CLIENT_handle_reply (struct GNUNET_TIME_Absolute expiration,
839 frc.data = data; 823 frc.data = data;
840 frc.data_size = data_size; 824 frc.data_size = data_size;
841 frc.type = type; 825 frc.type = type;
842 GNUNET_CONTAINER_multihashmap_get_multiple (foward_map, key, 826 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, key,
843 &forward_reply, 827 &forward_reply,
844 &frc); 828 &frc);
845 if (GNUNET_NO == frc.do_copy) 829 if (GNUNET_NO == frc.do_copy)
846 { 830 {
847 /* did not match any of the requests, free! */ 831 /* did not match any of the requests, free! */
848 GNUNET_free (buf); 832 GNUNET_free (pm);
849 } 833 }
850} 834}
851 835
@@ -865,7 +849,7 @@ GDS_CLIENT_init (struct GNUNET_SERVER_Handle *server)
865 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0}, 849 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0},
866 {&handle_dht_local_get_stop, NULL, 850 {&handle_dht_local_get_stop, NULL,
867 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, 851 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP,
868 sizeof (struct GNUNET_DHT_StopMessage) }, 852 sizeof (struct GNUNET_DHT_ClientGetStopMessage) },
869 {NULL, NULL, 0, 0} 853 {NULL, NULL, 0, 0}
870 }; 854 };
871 forward_map = GNUNET_CONTAINER_multihashmap_create (1024); 855 forward_map = GNUNET_CONTAINER_multihashmap_create (1024);
diff --git a/src/dht/gnunet-service-dht_clients.h b/src/dht/gnunet-service-dht_clients.h
index 0bb548f71..d6d99540f 100644
--- a/src/dht/gnunet-service-dht_clients.h
+++ b/src/dht/gnunet-service-dht_clients.h
@@ -27,6 +27,8 @@
27#ifndef GNUNET_SERVICE_DHT_CLIENTS_H 27#ifndef GNUNET_SERVICE_DHT_CLIENTS_H
28#define GNUNET_SERVICE_DHT_CLIENTS_H 28#define GNUNET_SERVICE_DHT_CLIENTS_H
29 29
30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
30 32
31/** 33/**
32 * Handle a reply we've received from another peer. If the reply 34 * Handle a reply we've received from another peer. If the reply
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 48d9d72a6..8a566ec0e 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1509,6 +1509,8 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer,
1509 1509
1510/** 1510/**
1511 * Initialize neighbours subsystem. 1511 * Initialize neighbours subsystem.
1512 *
1513 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1512 */ 1514 */
1513int 1515int
1514GDS_NEIGHBOURS_init () 1516GDS_NEIGHBOURS_init ()
@@ -1527,7 +1529,7 @@ GDS_NEIGHBOURS_init ()
1527 &temp_config_num)) 1529 &temp_config_num))
1528 bucket_size = (unsigned int) temp_config_num; 1530 bucket_size = (unsigned int) temp_config_num;
1529 coreAPI = GNUNET_CORE_connect (GDS_cfg, 1531 coreAPI = GNUNET_CORE_connect (GDS_cfg,
1530 DEFAULT_CORE_QUEUE_SIZE, 1532 1,
1531 NULL, 1533 NULL,
1532 &core_init, 1534 &core_init,
1533 &handle_core_connect, 1535 &handle_core_connect,
@@ -1539,6 +1541,18 @@ GDS_NEIGHBOURS_init ()
1539 if (coreAPI == NULL) 1541 if (coreAPI == NULL)
1540 return GNUNET_SYSERR; 1542 return GNUNET_SYSERR;
1541 all_known_peers = GNUNET_CONTAINER_multihashmap_create (256); 1543 all_known_peers = GNUNET_CONTAINER_multihashmap_create (256);
1544#if 0
1545 // FIXME!
1546 next_send_time.rel_value =
1547 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value +
1548 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1549 (DHT_MAXIMUM_FIND_PEER_INTERVAL.rel_value /
1550 2) -
1551 DHT_MINIMUM_FIND_PEER_INTERVAL.rel_value);
1552 find_peer_task = GNUNET_SCHEDULER_add_delayed (next_send_time,
1553 &send_find_peer_message,
1554 &find_peer_context);
1555#endif
1542 return GNUNET_OK; 1556 return GNUNET_OK;
1543} 1557}
1544 1558
@@ -1549,7 +1563,8 @@ GDS_NEIGHBOURS_init ()
1549void 1563void
1550GDS_NEIGHBOURS_done () 1564GDS_NEIGHBOURS_done ()
1551{ 1565{
1552 GNUNET_assert (coreAPI != NULL); 1566 if (coreAPI == NULL)
1567 return;
1553 GNUNET_CORE_disconnect (coreAPI); 1568 GNUNET_CORE_disconnect (coreAPI);
1554 coreAPI = NULL; 1569 coreAPI = NULL;
1555 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_get_size (all_known_peers)); 1570 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_get_size (all_known_peers));
@@ -1564,3 +1579,76 @@ GDS_NEIGHBOURS_done ()
1564 1579
1565 1580
1566/* end of gnunet-service-dht_neighbours.c */ 1581/* end of gnunet-service-dht_neighbours.c */
1582
1583
1584#if 0
1585
1586/* Forward declaration */
1587static void
1588update_core_preference (void *cls,
1589 const struct GNUNET_SCHEDULER_TaskContext *tc);
1590
1591
1592/**
1593 * Function called with statistics about the given peer.
1594 *
1595 * @param cls closure
1596 * @param peer identifies the peer
1597 * @param bpm_out set to the current bandwidth limit (sending) for this peer
1598 * @param amount set to the amount that was actually reserved or unreserved;
1599 * either the full requested amount or zero (no partial reservations)
1600 * @param res_delay if the reservation could not be satisfied (amount was 0), how
1601 * long should the client wait until re-trying?
1602 * @param preference current traffic preference for the given peer
1603 */
1604static void
1605update_core_preference_finish (void *cls,
1606 const struct GNUNET_PeerIdentity *peer,
1607 struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
1608 int32_t amount,
1609 struct GNUNET_TIME_Relative res_delay,
1610 uint64_t preference)
1611{
1612 struct PeerInfo *peer_info = cls;
1613
1614 peer_info->info_ctx = NULL;
1615 GNUNET_SCHEDULER_add_delayed (DHT_DEFAULT_PREFERENCE_INTERVAL,
1616 &update_core_preference, peer_info);
1617}
1618
1619
1620static void
1621update_core_preference (void *cls,
1622 const struct GNUNET_SCHEDULER_TaskContext *tc)
1623{
1624 struct PeerInfo *peer = cls;
1625 uint64_t preference;
1626 unsigned int matching;
1627
1628 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
1629 {
1630 return;
1631 }
1632 matching =
1633 GNUNET_CRYPTO_hash_matching_bits (&my_identity.hashPubKey,
1634 &peer->id.hashPubKey);
1635 if (matching >= 64)
1636 {
1637#if DEBUG_DHT
1638 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1639 "Peer identifier matches by %u bits, only shifting as much as we can!\n",
1640 matching);
1641#endif
1642 matching = 63;
1643 }
1644 preference = 1LL << matching;
1645 peer->info_ctx =
1646 GNUNET_CORE_peer_change_preference (core_api, &peer->id,
1647 GNUNET_TIME_UNIT_FOREVER_REL,
1648 GNUNET_BANDWIDTH_VALUE_MAX, 0,
1649 preference,
1650 &update_core_preference_finish, peer);
1651}
1652
1653
1654#endif
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h
index 70723deac..e679b4162 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -27,6 +27,9 @@
27#ifndef GNUNET_SERVICE_DHT_NEIGHBOURS_H 27#ifndef GNUNET_SERVICE_DHT_NEIGHBOURS_H
28#define GNUNET_SERVICE_DHT_NEIGHBOURS_H 28#define GNUNET_SERVICE_DHT_NEIGHBOURS_H
29 29
30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
32#include "gnunet_dht_service.h"
30 33
31/** 34/**
32 * Perform a PUT operation. Forwards the given request to other 35 * Perform a PUT operation. Forwards the given request to other
@@ -51,7 +54,7 @@ void
51GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, 54GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
52 enum GNUNET_DHT_RouteOption options, 55 enum GNUNET_DHT_RouteOption options,
53 uint32_t desired_replication_level, 56 uint32_t desired_replication_level,
54 GNUNET_TIME_Absolute expiration_time, 57 struct GNUNET_TIME_Absolute expiration_time,
55 uint32_t hop_count, 58 uint32_t hop_count,
56 struct GNUNET_CONTAINER_BloomFilter *bf, 59 struct GNUNET_CONTAINER_BloomFilter *bf,
57 const GNUNET_HashCode *key, 60 const GNUNET_HashCode *key,
@@ -108,9 +111,9 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
108 * @param data_size number of bytes in data 111 * @param data_size number of bytes in data
109 */ 112 */
110void 113void
111GDS_NEIGHBOURS_handle_reply (const GNUNET_PeerIdentity *target, 114GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
112 enum GNUNET_BLOCK_Type type, 115 enum GNUNET_BLOCK_Type type,
113 GNUNET_TIME_Absolute expiration_time, 116 struct GNUNET_TIME_Absolute expiration_time,
114 const GNUNET_HashCode *key, 117 const GNUNET_HashCode *key,
115 unsigned int put_path_length, 118 unsigned int put_path_length,
116 struct GNUNET_PeerIdentity *put_path, 119 struct GNUNET_PeerIdentity *put_path,
@@ -122,10 +125,13 @@ GDS_NEIGHBOURS_handle_reply (const GNUNET_PeerIdentity *target,
122 125
123/** 126/**
124 * Initialize neighbours subsystem. 127 * Initialize neighbours subsystem.
128 *
129 * @return GNUNET_OK on success, GNUNET_SYSERR on error
125 */ 130 */
126void 131int
127GDS_NEIGHBOURS_init (void); 132GDS_NEIGHBOURS_init (void);
128 133
134
129/** 135/**
130 * Shutdown neighbours subsystem. 136 * Shutdown neighbours subsystem.
131 */ 137 */
diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c
index 0715465f5..a6e20fb57 100644
--- a/src/dht/gnunet-service-dht_nse.c
+++ b/src/dht/gnunet-service-dht_nse.c
@@ -23,6 +23,8 @@
23 * @brief GNUnet DHT integration with NSE 23 * @brief GNUnet DHT integration with NSE
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h"
27#include "gnunet_nse_service.h"
26#include "gnunet-service-dht.h" 28#include "gnunet-service-dht.h"
27#include "gnunet-service-dht_nse.h" 29#include "gnunet-service-dht_nse.h"
28 30
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h
index 3dbae1ee7..6b2246f31 100644
--- a/src/dht/gnunet-service-dht_routing.h
+++ b/src/dht/gnunet-service-dht_routing.h
@@ -26,6 +26,9 @@
26#ifndef GNUNET_SERVICE_DHT_ROUTING_H 26#ifndef GNUNET_SERVICE_DHT_ROUTING_H
27#define GNUNET_SERVICE_DHT_ROUTING_H 27#define GNUNET_SERVICE_DHT_ROUTING_H
28 28
29#include "gnunet_util_lib.h"
30#include "gnunet_block_lib.h"
31
29 32
30/** 33/**
31 * Handle a reply (route to origin). Only forwards the reply back to 34 * Handle a reply (route to origin). Only forwards the reply back to
@@ -45,8 +48,8 @@
45 * @param data_size number of bytes in data 48 * @param data_size number of bytes in data
46 */ 49 */
47void 50void
48GDS_ROUTING_process (uint32_t type, 51GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
49 GNUNET_TIME_Absolute expiration_time, 52 struct GNUNET_TIME_Absolute expiration_time,
50 const GNUNET_HashCode *key, 53 const GNUNET_HashCode *key,
51 unsigned int put_path_length, 54 unsigned int put_path_length,
52 const struct GNUNET_PeerIdentity *put_path, 55 const struct GNUNET_PeerIdentity *put_path,
@@ -68,8 +71,8 @@ GDS_ROUTING_process (uint32_t type,
68 * @param reply_bf_mutator mutator for reply_bf 71 * @param reply_bf_mutator mutator for reply_bf
69*/ 72*/
70void 73void
71GDS_ROUTING_add (const GNUNET_PeerIdentity *sender, 74GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
72 uint32_t type, 75 enum GNUNET_BLOCK_Type type,
73 const GNUNET_HashCode *key, 76 const GNUNET_HashCode *key,
74 const void *xquery, 77 const void *xquery,
75 size_t xquery_size, 78 size_t xquery_size,