-also don't need xdht routing subsystem for wdht
[oweals/gnunet.git] / src / dht / gnunet-service-wdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2014 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-xdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-wdht_clients.h"
41 #include "gnunet-service-wdht_datacache.h"
42 #include "gnunet-service-wdht_neighbours.h"
43 #include <fenv.h>
44 #include "dht.h"
45
46 #define DEBUG(...)                                           \
47   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
48
49 /**
50  * FIXME
51  */
52 #define FOO_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
53
54
55 GNUNET_NETWORK_STRUCT_BEGIN
56
57 /**
58  * Setup a finger using the underlay topology ("social network").
59  */
60 struct FingerSetupMessage
61 {
62   /**
63    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP
64    */
65   struct GNUNET_MessageHeader header;
66
67   /**
68    * Number of hops this message has taken so far, we stop at
69    * log(NSE), in NBO.
70    */
71   uint16_t hops_taken GNUNET_PACKED;
72
73   /**
74    * Layer for the request, in NBO.
75    */
76   uint16_t layer GNUNET_PACKED;
77
78   /**
79    * Unique (random) identifier this peer will use to
80    * identify the finger (in future messages).
81    */
82   struct GNUNET_HashCode finger_id;
83
84 };
85
86
87 /**
88  * Response to a `struct FingerSetupMessage`.
89  */
90 struct FingerSetupResponseMessage
91 {
92   /**
93    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP_RESPONSE
94    */
95   struct GNUNET_MessageHeader header;
96
97   /**
98    * Zero, for alignment.
99    */
100   uint32_t reserved GNUNET_PACKED;
101
102   /**
103    * Unique (random) identifier this peer will use to
104    * identify the finger (in future messages).
105    */
106   struct GNUNET_HashCode finger_id;
107
108   /**
109    * Random location in the respective layer where the
110    * random path of the finger setup terminated.
111    */
112   struct GNUNET_HashCode location;
113
114 };
115
116
117 /**
118  * Response to an event that causes a finger to die.
119  */
120 struct FingerDestroyMessage
121 {
122   /**
123    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_DESTROY
124    */
125   struct GNUNET_MessageHeader header;
126
127   /**
128    * Zero, for alignment.
129    */
130   uint32_t reserved GNUNET_PACKED;
131
132   /**
133    * Unique (random) identifier this peer will use to
134    * identify the finger (in future messages).
135    */
136   struct GNUNET_HashCode finger_id;
137
138 };
139
140
141 /**
142  * Send a message along a finger.
143  */
144 struct FingerRouteMessage
145 {
146   /**
147    * Type: #GNUNET_MESSAGE_TYPE_WDHT_FINGER_ROUTE
148    */
149   struct GNUNET_MessageHeader header;
150
151   /**
152    * Zero, for alignment.
153    */
154   uint32_t reserved GNUNET_PACKED;
155
156   /**
157    * Unique (random) identifier this peer will use to
158    * identify the finger (in future messages).
159    */
160   struct GNUNET_HashCode finger_id;
161
162   /* followed by payload to send along the finger */
163 };
164
165
166 /**
167  * P2P PUT message
168  */
169 struct PeerPutMessage
170 {
171   /**
172    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_PUT
173    */
174   struct GNUNET_MessageHeader header;
175
176   /**
177    * Processing options
178    */
179   uint32_t options GNUNET_PACKED;
180
181   /**
182    * Content type.
183    */
184   uint32_t block_type GNUNET_PACKED;
185
186   /**
187    * Hop count
188    */
189   uint32_t hop_count GNUNET_PACKED;
190
191   /**
192    * Replication level for this message
193    * In the current implementation, this value is not used.
194    */
195   uint32_t desired_replication_level GNUNET_PACKED;
196
197   /**
198    * Length of the PUT path that follows (if tracked).
199    */
200   uint32_t put_path_length GNUNET_PACKED;
201
202   /**
203    * When does the content expire?
204    */
205   struct GNUNET_TIME_AbsoluteNBO expiration_time;
206
207   /**
208    * The key to store the value under.
209    */
210   struct GNUNET_HashCode key GNUNET_PACKED;
211
212   /* put path (if tracked) */
213
214   /* Payload */
215
216 };
217
218 /**
219  * P2P GET message
220  */
221 struct PeerGetMessage
222 {
223   /**
224    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_GET
225    */
226   struct GNUNET_MessageHeader header;
227
228   /**
229    * Processing options
230    */
231   uint32_t options GNUNET_PACKED;
232
233   /**
234    * Desired content type.
235    */
236   uint32_t block_type GNUNET_PACKED;
237
238   /**
239    * Hop count
240    */
241   uint32_t hop_count GNUNET_PACKED;
242
243   /**
244    * Desired replication level for this request.
245    * In the current implementation, this value is not used.
246    */
247   uint32_t desired_replication_level GNUNET_PACKED;
248
249   /**
250    * Total number of peers in get path.
251    */
252   unsigned int get_path_length;
253
254   /**
255    * The key we are looking for.
256    */
257   struct GNUNET_HashCode key;
258
259   /* Get path. */
260   /* struct GNUNET_PeerIdentity[]*/
261 };
262
263
264 /**
265  * P2P Result message
266  */
267 struct PeerGetResultMessage
268 {
269   /**
270    * Type: #GNUNET_MESSAGE_TYPE_WDHT_P2P_GET_RESULT
271    */
272   struct GNUNET_MessageHeader header;
273
274   /**
275    * The type for the data.
276    */
277   uint32_t type GNUNET_PACKED;
278
279   /**
280    * Number of peers recorded in the outgoing path from source to the
281    * stored location of this message.
282    */
283   uint32_t put_path_length GNUNET_PACKED;
284
285   /**
286    * Length of the GET path that follows (if tracked).
287    */
288   uint32_t get_path_length GNUNET_PACKED;
289
290   /**
291    * Peer which queried for get and should get the result.
292    */
293   struct GNUNET_PeerIdentity querying_peer;
294
295   /**
296    * When does the content expire?
297    */
298   struct GNUNET_TIME_Absolute expiration_time;
299
300   /**
301    * The key of the corresponding GET request.
302    */
303   struct GNUNET_HashCode key;
304
305   /* put path (if tracked) */
306
307   /* get path (if tracked) */
308
309   /* Payload */
310
311 };
312
313 GNUNET_NETWORK_STRUCT_END
314
315 /**
316  * Entry in friend_peermap.
317  */
318 struct FriendInfo;
319
320
321 /**
322  * Information we keep per trail.
323  */
324 struct Trail
325 {
326
327   /**
328    * MDLL entry in the list of all trails with the same predecessor.
329    */
330   struct Tail *prev_succ;
331
332   /**
333    * MDLL entry in the list of all trails with the same predecessor.
334    */
335   struct Tail *next_succ;
336
337   /**
338    * MDLL entry in the list of all trails with the same predecessor.
339    */
340   struct Tail *prev_pred;
341
342   /**
343    * MDLL entry in the list of all trails with the same predecessor.
344    */
345   struct Tail *next_pred;
346
347   /**
348    * Our predecessor in the trail, NULL if we are initiator (?).
349    */
350   struct FriendInfo *pred;
351
352   /**
353    * Our successor in the trail, NULL if we are the last peer.
354    */
355   struct FriendInfo *succ;
356
357   /**
358    * Identifier of the trail with the predecessor.
359    */
360   struct GNUNET_HashCode pred_id;
361
362   /**
363    * Identifier of the trail with the successor.
364    */
365   struct GNUNET_HashCode succ_id;
366
367   /**
368    * When does this trail expire.
369    */
370   struct GNUNET_TIME_Absolute expiration_time;
371
372 };
373
374
375 /**
376  *  Entry in friend_peermap.
377  */
378 struct FriendInfo
379 {
380   /**
381    * Friend Identity
382    */
383   struct GNUNET_PeerIdentity id;
384
385   struct Tail *pred_head;
386
387   struct Tail *pred_tail;
388
389   struct Tail *succ_head;
390
391   struct Tail *succ_tail;
392
393   /**
394    * Core handle for sending messages to this friend.
395    * FIXME: use MQ?
396    */
397   struct GNUNET_CORE_TransmitHandle *th;
398
399 };
400
401
402
403 /**
404  * Task to timeout trails that have expired.
405  */
406 static struct GNUNET_SCHEDULER_Task *trail_timeout_task;
407
408 /**
409  * Identity of this peer.
410  */
411 static struct GNUNET_PeerIdentity my_identity;
412
413 /**
414  * Peer map of all the friends of a peer
415  */
416 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
417
418 /**
419  * Tail map, mapping tail identifiers to `struct Trail`s
420  */
421 static struct GNUNET_CONTAINER_MultiHashMap *tail_map;
422
423 /**
424  * Tail heap, organizing trails by expiration time.
425  */
426 static struct GNUNET_CONTAINER_Heap *tail_heap;
427
428 /**
429  * Handle to CORE.
430  */
431 static struct GNUNET_CORE_Handle *core_api;
432
433
434
435
436
437
438
439 /**
440  * Construct a trail setup message and forward it to target_friend
441  * @param source_peer Peer which wants to setup the trail
442  * @param ultimate_destination_finger_value Peer identity closest to this value
443  *                                          will be finger to @a source_peer
444  * @param best_known_destination Best known destination (could be finger or friend)
445  *                               which should get this message. In case it is
446  *                               friend, then it is same as target_friend
447  * @param target_friend Friend to which message is forwarded now.
448  * @param trail_length Total number of peers in trail setup so far.
449  * @param trail_peer_list Trail setup so far
450  * @param is_predecessor Is @a source_peer looking for trail to a predecessor or not.
451  * @param trail_id Unique identifier for the trail we are trying to setup.
452  * @param intermediate_trail_id Trail id of intermediate trail to reach to
453  *                              best_known_destination when its a finger. If not
454  *                              used then set to 0.
455  */
456 void
457 GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity source_peer,
458                                  uint64_t ultimate_destination_finger_value,
459                                  struct GNUNET_PeerIdentity best_known_destination,
460                                  struct FriendInfo *target_friend,
461                                  unsigned int trail_length,
462                                  const struct GNUNET_PeerIdentity *trail_peer_list,
463                                  unsigned int is_predecessor,
464                                  struct GNUNET_HashCode trail_id,
465                                  struct GNUNET_HashCode intermediate_trail_id)
466 {
467   struct P2PPendingMessage *pending;
468   struct PeerTrailSetupMessage *tsm;
469   struct GNUNET_PeerIdentity *peer_list;
470   size_t msize;
471
472   msize = sizeof (struct PeerTrailSetupMessage) +
473           (trail_length * sizeof (struct GNUNET_PeerIdentity));
474
475   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
476   {
477     GNUNET_break (0);
478     return;
479   }
480
481   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
482   {
483     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
484                                 1, GNUNET_NO);
485   }
486   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
487   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
488   tsm = (struct PeerTrailSetupMessage *) &pending[1];
489   pending->msg = &(tsm->header);
490   tsm->header.size = htons (msize);
491   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP);
492   tsm->final_destination_finger_value = GNUNET_htonll (ultimate_destination_finger_value);
493   tsm->source_peer = source_peer;
494   tsm->best_known_destination = best_known_destination;
495   tsm->is_predecessor = htonl (is_predecessor);
496   tsm->trail_id = trail_id;
497   tsm->intermediate_trail_id = intermediate_trail_id;
498
499   if (trail_length > 0)
500   {
501     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
502     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
503   }
504
505   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
506   target_friend->pending_count++;
507   process_friend_queue (target_friend);
508 }
509
510
511 /**
512  * Construct a trail setup result message and forward it to target friend.
513  * @param querying_peer Peer which sent the trail setup request and should get
514  *                      the result back.
515  * @param Finger Peer to which the trail has been setup to.
516  * @param target_friend Friend to which this message should be forwarded.
517  * @param trail_length Numbers of peers in the trail.
518  * @param trail_peer_list Peers which are part of the trail from
519  *                        querying_peer to Finger, NOT including them.
520  * @param is_predecessor Is @a Finger predecessor to @a querying_peer ?
521  * @param ultimate_destination_finger_value Value to which @a finger is the closest
522  *                                          peer.
523  * @param trail_id Unique identifier of the trail.
524  */
525 void
526 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity querying_peer,
527                                         struct GNUNET_PeerIdentity finger,
528                                         struct FriendInfo *target_friend,
529                                         unsigned int trail_length,
530                                         const struct GNUNET_PeerIdentity *trail_peer_list,
531                                         unsigned int is_predecessor,
532                                         uint64_t ultimate_destination_finger_value,
533                                         struct GNUNET_HashCode trail_id)
534 {
535   struct P2PPendingMessage *pending;
536   struct PeerTrailSetupResultMessage *tsrm;
537   struct GNUNET_PeerIdentity *peer_list;
538   size_t msize;
539
540   msize = sizeof (struct PeerTrailSetupResultMessage) +
541           (trail_length * sizeof (struct GNUNET_PeerIdentity));
542
543   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
544   {
545     GNUNET_break (0);
546     return;
547   }
548
549   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
550   {
551     GNUNET_STATISTICS_update (GDS_stats,
552                               gettext_noop ("# P2P messages dropped due to full queue"),
553                               1, GNUNET_NO);
554   }
555
556   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
557   pending->importance = 0;
558   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
559   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1];
560   pending->msg = &tsrm->header;
561   tsrm->header.size = htons (msize);
562   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT);
563   tsrm->querying_peer = querying_peer;
564   tsrm->finger_identity = finger;
565   tsrm->is_predecessor = htonl (is_predecessor);
566   tsrm->trail_id = trail_id;
567   tsrm->ulitmate_destination_finger_value =
568           GNUNET_htonll (ultimate_destination_finger_value);
569   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
570   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
571
572   /* Send the message to chosen friend. */
573   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
574   target_friend->pending_count++;
575   process_friend_queue (target_friend);
576 }
577
578 /**
579  * Send notify successor confirmation message.
580  * @param trail_id Unique Identifier of the trail.
581  * @param trail_direction Destination to Source.
582  * @param target_friend Friend to get this message next.
583  */
584 void
585 GDS_NEIGHBOURS_send_notify_succcessor_confirmation (struct GNUNET_HashCode trail_id,
586                                                     unsigned int trail_direction,
587                                                      struct FriendInfo *target_friend)
588 {
589   struct PeerNotifyConfirmationMessage *ncm;
590   struct P2PPendingMessage *pending;
591   size_t msize;
592
593   msize = sizeof (struct PeerNotifyConfirmationMessage);
594   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
595   {
596     GNUNET_break (0);
597     return;
598   }
599
600   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
601   {
602     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
603                                 1, GNUNET_NO);
604   }
605
606   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
607   pending->importance = 0;    /* FIXME */
608   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
609   ncm = (struct PeerNotifyConfirmationMessage *) &pending[1];
610   pending->msg = &ncm->header;
611   ncm->header.size = htons (msize);
612   ncm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION);
613   ncm->trail_id = trail_id;
614   ncm->trail_direction = htonl (trail_direction);
615
616   /* Send the message to chosen friend. */
617   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
618   target_friend->pending_count++;
619   process_friend_queue (target_friend);
620 }
621
622
623 /**
624  * Send trail rejection message to target friend
625  * @param source_peer Peer which is trying to setup the trail.
626  * @param ultimate_destination_finger_value Peer closest to this value will be
627  *                                          @a source_peer's finger
628  * @param congested_peer Peer which sent this message as it is congested.
629  * @param is_predecessor Is source_peer looking for trail to a predecessor or not.
630  * @param trail_peer_list Trails seen so far in trail setup before getting rejected
631  *                        by congested_peer. This does NOT include @a source_peer
632  *                        and congested_peer.
633  * @param trail_length Total number of peers in trail_peer_list, NOT including
634  *                     @a source_peer and @a congested_peer
635  * @param trail_id Unique identifier of this trail.
636  * @param congestion_timeout Duration given by congested peer as an estimate of
637  *                           how long it may remain congested.
638  */
639 void
640 GDS_NEIGHBOURS_send_trail_rejection (struct GNUNET_PeerIdentity source_peer,
641                                      uint64_t ultimate_destination_finger_value,
642                                      struct GNUNET_PeerIdentity congested_peer,
643                                      unsigned int is_predecessor,
644                                      const struct GNUNET_PeerIdentity *trail_peer_list,
645                                      unsigned int trail_length,
646                                      struct GNUNET_HashCode trail_id,
647                                      struct FriendInfo *target_friend,
648                                      const struct GNUNET_TIME_Relative congestion_timeout)
649 {
650   struct PeerTrailRejectionMessage *trm;
651   struct P2PPendingMessage *pending;
652   struct GNUNET_PeerIdentity *peer_list;
653   size_t msize;
654
655   msize = sizeof (struct PeerTrailRejectionMessage) +
656           (trail_length * sizeof (struct GNUNET_PeerIdentity));
657
658   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
659   {
660     GNUNET_break (0);
661     return;
662   }
663
664   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
665   {
666     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
667                                 1, GNUNET_NO);
668   }
669
670   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
671   pending->importance = 0;
672   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
673   trm = (struct PeerTrailRejectionMessage *)&pending[1];
674   pending->msg = &trm->header;
675   trm->header.size = htons (msize);
676   trm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION);
677   trm->source_peer = source_peer;
678   trm->congested_peer = congested_peer;
679   trm->congestion_time = congestion_timeout;
680   trm->is_predecessor = htonl (is_predecessor);
681   trm->trail_id = trail_id;
682   trm->ultimate_destination_finger_value =
683           GNUNET_htonll (ultimate_destination_finger_value);
684
685   peer_list = (struct GNUNET_PeerIdentity *) &trm[1];
686   if (trail_length > 0)
687   {
688     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
689   }
690
691   /* Send the message to chosen friend. */
692   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
693   target_friend->pending_count++;
694   process_friend_queue (target_friend);
695 }
696
697
698 /**
699  * Construct a verify successor message and forward it to target_friend.
700  * @param source_peer Peer which wants to verify its successor.
701  * @param successor Peer which is @a source_peer's current successor.
702  * @param trail_id Unique Identifier of trail from @a source_peer to @a successor,
703  *                 NOT including them.
704  * @param trail List of peers which are part of trail to reach from @a source_peer
705  *              to @a successor, NOT including them.
706  * @param trail_length Total number of peers in @a trail.
707  * @param target_friend Next friend to get this message.
708  */
709 void
710 GDS_NEIGHBOURS_send_verify_successor_message (struct GNUNET_PeerIdentity source_peer,
711                                               struct GNUNET_PeerIdentity successor,
712                                               struct GNUNET_HashCode trail_id,
713                                               struct GNUNET_PeerIdentity *trail,
714                                               unsigned int trail_length,
715                                               struct FriendInfo *target_friend)
716 {
717   struct PeerVerifySuccessorMessage *vsm;
718   struct P2PPendingMessage *pending;
719   struct GNUNET_PeerIdentity *peer_list;
720   size_t msize;
721
722   msize = sizeof (struct PeerVerifySuccessorMessage) +
723          (trail_length * sizeof (struct GNUNET_PeerIdentity));
724
725   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
726   {
727     GNUNET_break (0);
728     return;
729   }
730
731   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
732   {
733     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
734                                 1, GNUNET_NO);
735   }
736
737   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
738   pending->importance = 0;    /* FIXME */
739   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
740   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
741   pending->msg = &vsm->header;
742   vsm->header.size = htons (msize);
743   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR);
744   vsm->source_peer = source_peer;
745   vsm->successor = successor;
746   vsm->trail_id = trail_id;
747   peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
748   memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
749
750   /* Send the message to chosen friend. */
751   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
752   target_friend->pending_count++;
753   process_friend_queue (target_friend);
754 }
755
756
757 /**
758  * FIXME: In every function we pass target friend except for this one.
759  * so, either change everything or this one. also, should se just store
760  * the pointer to friend in routing table rather than gnunet_peeridentity.
761  * if yes then we should keep friend info in.h  andmake lot of changes.
762  * Construct a trail teardown message and forward it to target friend.
763  *
764  * @param trail_id Unique identifier of the trail.
765  * @param trail_direction Direction of trail.
766  * @param target_friend Friend to get this message.
767  */
768 void
769 GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id,
770                                     unsigned int trail_direction,
771                                     const struct GNUNET_PeerIdentity *peer)
772 {
773   struct PeerTrailTearDownMessage *ttdm;
774   struct P2PPendingMessage *pending;
775   struct FriendInfo *target_friend;
776   size_t msize;
777
778   msize = sizeof (struct PeerTrailTearDownMessage);
779   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
780   {
781     GNUNET_break (0);
782     return;
783   }
784
785   if (NULL == (target_friend =
786                GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer)))
787   {
788     /* FIXME: In what case friend can be null. ?*/
789     GNUNET_break (0);
790     return;
791   }
792
793   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
794   {
795     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
796                                 1, GNUNET_NO);
797   }
798
799   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
800   pending->importance = 0;    /* FIXME */
801   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
802   ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
803   pending->msg = &ttdm->header;
804   ttdm->header.size = htons (msize);
805   ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN);
806   ttdm->trail_id = *trail_id;
807   ttdm->trail_direction = htonl (trail_direction);
808
809   /* Send the message to chosen friend. */
810   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
811   target_friend->pending_count++;
812   process_friend_queue (target_friend);
813 }
814
815
816 /**
817  * Construct a verify successor result message and send it to target_friend
818  * @param querying_peer Peer which sent the verify successor message.
819  * @param source_successor Current_successor of @a querying_peer.
820  * @param current_predecessor Current predecessor of @a successor. Could be same
821  *                            or different from @a querying_peer.
822  * @param trail_id Unique identifier of the trail from @a querying_peer to
823  *                 @a successor, NOT including them.
824  * @param trail List of peers which are part of trail from @a querying_peer to
825  *                 @a successor, NOT including them.
826  * @param trail_length Total number of peers in @a trail
827  * @param trail_direction Direction in which we are sending the message. In this
828  *                        case we are sending result from @a successor to @a querying_peer.
829  * @param target_friend Next friend to get this message.
830  */
831 void
832 GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity querying_peer,
833                                              struct GNUNET_PeerIdentity current_successor,
834                                              struct GNUNET_PeerIdentity probable_successor,
835                                              struct GNUNET_HashCode trail_id,
836                                              const struct GNUNET_PeerIdentity *trail,
837                                              unsigned int trail_length,
838                                              enum GDS_ROUTING_trail_direction trail_direction,
839                                              struct FriendInfo *target_friend)
840 {
841   struct PeerVerifySuccessorResultMessage *vsmr;
842   struct P2PPendingMessage *pending;
843   struct GNUNET_PeerIdentity *peer_list;
844   size_t msize;
845
846   msize = sizeof (struct PeerVerifySuccessorResultMessage) +
847           (trail_length * sizeof(struct GNUNET_PeerIdentity));
848
849   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
850   {
851     GNUNET_break (0);
852     return;
853   }
854
855   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
856   {
857     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
858                                 1, GNUNET_NO);
859   }
860
861   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
862   pending->importance = 0;    /* FIXME */
863   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
864   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
865   pending->msg = &vsmr->header;
866   vsmr->header.size = htons (msize);
867   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT);
868   vsmr->querying_peer = querying_peer;
869   vsmr->current_successor = current_successor;
870   vsmr->probable_successor = probable_successor;
871   vsmr->trail_direction = htonl (trail_direction);
872   vsmr->trail_id = trail_id;
873   peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
874   memcpy (peer_list, trail, trail_length * sizeof (struct GNUNET_PeerIdentity));
875
876    /* Send the message to chosen friend. */
877   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
878   target_friend->pending_count++;
879   process_friend_queue (target_friend);
880 }
881
882 /**
883  * Construct a Put message and send it to target_peer.
884  * @param key Key for the content
885  * @param block_type Type of the block
886  * @param options Routing options
887  * @param desired_replication_level Desired replication count
888  * @param best_known_dest Peer to which this message should reach eventually,
889  *                        as it is best known destination to me.
890  * @param intermediate_trail_id Trail id in case
891  * @param target_peer Peer to which this message will be forwarded.
892  * @param hop_count Number of hops traversed so far.
893  * @param put_path_length Total number of peers in @a put_path
894  * @param put_path Number of peers traversed so far
895  * @param expiration_time When does the content expire
896  * @param data Content to store
897  * @param data_size Size of content @a data in bytes
898  */
899 void
900 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
901                          enum GNUNET_BLOCK_Type block_type,
902                                            enum GNUNET_DHT_RouteOption options,
903                                            uint32_t desired_replication_level,
904                                            struct GNUNET_PeerIdentity best_known_dest,
905                                            struct GNUNET_HashCode intermediate_trail_id,
906                                            struct GNUNET_PeerIdentity *target_peer,
907                          uint32_t hop_count,
908                          uint32_t put_path_length,
909                          struct GNUNET_PeerIdentity *put_path,
910                          struct GNUNET_TIME_Absolute expiration_time,
911                          const void *data, size_t data_size)
912 {
913   struct PeerPutMessage *ppm;
914   struct P2PPendingMessage *pending;
915   struct FriendInfo *target_friend;
916   struct GNUNET_PeerIdentity *pp;
917   size_t msize;
918
919   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
920           sizeof (struct PeerPutMessage);
921   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
922   {
923     put_path_length = 0;
924     msize = data_size + sizeof (struct PeerPutMessage);
925   }
926
927   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
928   {
929     DEBUG("msize = %lu\n",msize);
930     GNUNET_break (0);
931     return;
932   }
933
934   GNUNET_assert (NULL !=
935                  (target_friend =
936                   GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer)));
937   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
938   pending->timeout = expiration_time;
939   ppm = (struct PeerPutMessage *) &pending[1];
940   pending->msg = &ppm->header;
941   ppm->header.size = htons (msize);
942   ppm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT);
943   ppm->options = htonl (options);
944   ppm->block_type = htonl (block_type);
945   ppm->hop_count = htonl (hop_count + 1);
946   ppm->desired_replication_level = htonl (desired_replication_level);
947   ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
948   ppm->best_known_destination = best_known_dest;
949   ppm->intermediate_trail_id = intermediate_trail_id;
950   ppm->key = *key;
951   pp = (struct GNUNET_PeerIdentity *) &ppm[1];
952   ppm->put_path_length = htonl (put_path_length);
953   if(put_path_length > 0)
954   {
955     memcpy (pp, put_path,
956             sizeof (struct GNUNET_PeerIdentity) * put_path_length);
957   }
958   memcpy (&pp[put_path_length], data, data_size);
959   GNUNET_assert (NULL != target_friend);
960   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
961   target_friend->pending_count++;
962   process_friend_queue (target_friend);
963 }
964
965
966 /**
967  * Handle the put request from the client.
968  * @param key Key for the content
969  * @param block_type Type of the block
970  * @param options Routing options
971  * @param desired_replication_level Desired replication count
972  * @param expiration_time When does the content expire
973  * @param data Content to store
974  * @param data_size Size of content @a data in bytes
975  */
976 void
977 GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
978                            enum GNUNET_BLOCK_Type block_type,
979                            enum GNUNET_DHT_RouteOption options,
980                            uint32_t desired_replication_level,
981                            struct GNUNET_TIME_Absolute expiration_time,
982                            const void *data, size_t data_size)
983 {
984   struct GNUNET_PeerIdentity best_known_dest;
985   struct GNUNET_HashCode intermediate_trail_id;
986   struct GNUNET_PeerIdentity next_hop;
987   uint64_t key_value;
988   struct Closest_Peer successor;
989
990   memcpy (&key_value, key, sizeof (uint64_t));
991   key_value = GNUNET_ntohll (key_value);
992   successor = find_local_best_known_next_hop (key_value,
993                                               GDS_FINGER_TYPE_NON_PREDECESSOR);
994   best_known_dest = successor.best_known_destination;
995   next_hop = successor.next_hop;
996   intermediate_trail_id = successor.trail_id;
997
998   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, &my_identity))
999   {
1000     DEBUG("\n PUT_REQUEST_SUCCESSFUL for key = %s",GNUNET_h2s(key));
1001     /* I am the destination. */
1002     GDS_DATACACHE_handle_put (expiration_time, key, 0, NULL,
1003                               block_type,data_size,data);
1004     GDS_CLIENTS_process_put (options, block_type, 0,
1005                              ntohl (desired_replication_level),
1006                              1, &my_identity, expiration_time, //FIXME: GNUNETnthoh something on expiration time.
1007                              key, data, data_size);
1008     return;
1009   }
1010   /* In case we are sending the request to  a finger, then send across all of its
1011    trail.*/
1012 #if ENABLE_MALICIOUS
1013   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&successor.best_known_destination,
1014                                             &successor.next_hop))
1015   {
1016     struct FingerInfo *next_hop_finger;
1017     unsigned int i;
1018
1019     next_hop_finger = &finger_table[successor.finger_table_index];
1020     for (i = 0; i < next_hop_finger->trails_count; i++)
1021     {
1022       if (GNUNET_YES == next_hop_finger->trail_list[i].is_present)
1023       {
1024         if(0 == next_hop_finger->trail_list[i].trail_length)
1025         {
1026            GDS_NEIGHBOURS_send_put (key, block_type, options, desired_replication_level,
1027                                     best_known_dest, intermediate_trail_id, &next_hop,
1028                                     0, 1, &my_identity, expiration_time,
1029                                     data, data_size);
1030            return;
1031         }
1032         next_hop = next_hop_finger->trail_list[i].trail_head->peer;
1033         GDS_NEIGHBOURS_send_put (key, block_type, options, desired_replication_level,
1034                                  best_known_dest,
1035                                  next_hop_finger->trail_list[i].trail_id,
1036                                  &next_hop, 0, 1, &my_identity,
1037                                  expiration_time,
1038                                  data, data_size);
1039        }
1040     }
1041     return;
1042   }
1043 #endif
1044  GDS_NEIGHBOURS_send_put (key, block_type, options, desired_replication_level,
1045                           best_known_dest, intermediate_trail_id, &next_hop,
1046                           0, 1, &my_identity, expiration_time,
1047                           data, data_size);
1048 }
1049
1050 /**
1051  * Construct a Get message and send it to target_peer.
1052  * @param key Key for the content
1053  * @param block_type Type of the block
1054  * @param options Routing options
1055  * @param desired_replication_level Desired replication count
1056  * @param best_known_dest Peer which should get this message. Same as target peer
1057  *                        if best_known_dest is a friend else its a finger.
1058  * @param intermediate_trail_id  Trail id to reach to @a best_known_dest
1059  *                              in case it is a finger else set to 0.
1060  * @param target_peer Peer to which this message will be forwarded.
1061  * @param hop_count Number of hops traversed so far.
1062  * @param data Content to store
1063  * @param data_size Size of content @a data in bytes
1064  * @param get_path_length Total number of peers in @a get_path
1065  * @param get_path Number of peers traversed so far
1066  */
1067 void
1068 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
1069                          enum GNUNET_BLOCK_Type block_type,
1070                          enum GNUNET_DHT_RouteOption options,
1071                          uint32_t desired_replication_level,
1072                          struct GNUNET_PeerIdentity best_known_dest,
1073                          struct GNUNET_HashCode intermediate_trail_id,
1074                          struct GNUNET_PeerIdentity *target_peer,
1075                          uint32_t hop_count,
1076                          uint32_t get_path_length,
1077                          struct GNUNET_PeerIdentity *get_path)
1078 {
1079   struct PeerGetMessage *pgm;
1080   struct P2PPendingMessage *pending;
1081   struct FriendInfo *target_friend;
1082   struct GNUNET_PeerIdentity *gp;
1083   size_t msize;
1084
1085   msize = sizeof (struct PeerGetMessage) +
1086           (get_path_length * sizeof (struct GNUNET_PeerIdentity));
1087
1088   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1089   {
1090     GNUNET_break (0);
1091     return;
1092   }
1093   GNUNET_assert (NULL !=
1094                  (target_friend =
1095                   GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer)));
1096
1097   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1098   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
1099   pending->importance = 0;    /* FIXME */
1100   pgm = (struct PeerGetMessage *) &pending[1];
1101   pending->msg = &pgm->header;
1102   pgm->header.size = htons (msize);
1103   pgm->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_GET);
1104   pgm->get_path_length = htonl (get_path_length);
1105   pgm->best_known_destination = best_known_dest;
1106   pgm->key = *key;
1107   pgm->intermediate_trail_id = intermediate_trail_id;
1108   pgm->hop_count = htonl (hop_count + 1);
1109   pgm->get_path_length = htonl (get_path_length);
1110   gp = (struct GNUNET_PeerIdentity *) &pgm[1];
1111   memcpy (gp, get_path,
1112           sizeof (struct GNUNET_PeerIdentity) * get_path_length);
1113   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1114   target_friend->pending_count++;
1115   process_friend_queue (target_friend);
1116 }
1117
1118
1119 /**
1120  * Handle the get request from the client file. If I am destination do
1121  * datacache put and return. Else find the target friend and forward message
1122  * to it.
1123  * @param key Key for the content
1124  * @param block_type Type of the block
1125  * @param options Routing options
1126  * @param desired_replication_level Desired replication count
1127  */
1128 void
1129 GDS_NEIGHBOURS_handle_get(const struct GNUNET_HashCode *key,
1130                           enum GNUNET_BLOCK_Type block_type,
1131                           enum GNUNET_DHT_RouteOption options,
1132                           uint32_t desired_replication_level)
1133 {
1134   struct Closest_Peer successor;
1135   struct GNUNET_PeerIdentity best_known_dest;
1136   struct GNUNET_HashCode intermediate_trail_id;
1137   uint64_t key_value;
1138
1139   memcpy (&key_value, key, sizeof (uint64_t));
1140   key_value = GNUNET_ntohll (key_value);
1141
1142   successor = find_local_best_known_next_hop (key_value,
1143                                               GDS_FINGER_TYPE_NON_PREDECESSOR);
1144
1145   best_known_dest = successor.best_known_destination;
1146   intermediate_trail_id = successor.trail_id;
1147
1148   /* I am the destination. I have the data. */
1149   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
1150                                             &best_known_dest))
1151   {
1152     GDS_DATACACHE_handle_get (key,block_type, NULL, 0,
1153                               NULL, 0, 1, &my_identity, NULL,&my_identity);
1154     return;
1155   }
1156
1157 #if ENABLE_MALICIOUS
1158   struct GNUNET_PeerIdentity next_hop;
1159   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&successor.best_known_destination,
1160                                             &successor.next_hop))
1161   {
1162     struct FingerInfo *next_hop_finger;
1163     unsigned int i;
1164
1165     next_hop_finger = &finger_table[successor.finger_table_index];
1166     for (i = 0; i < next_hop_finger->trails_count; i++)
1167     {
1168       if (GNUNET_YES == next_hop_finger->trail_list[i].is_present)
1169       {
1170         if(0 == next_hop_finger->trail_list[i].trail_length)
1171         {
1172            GDS_NEIGHBOURS_send_get (key, block_type, options,
1173                                     desired_replication_level,
1174                                     best_known_dest,intermediate_trail_id,
1175                                     &successor.next_hop,
1176                                     0, 1, &my_identity);
1177            return;
1178         }
1179         next_hop = next_hop_finger->trail_list[i].trail_head->peer;
1180         GDS_NEIGHBOURS_send_get (key, block_type, options, desired_replication_level,
1181                                  best_known_dest,
1182                                  next_hop_finger->trail_list[i].trail_id,
1183                                  &next_hop, 0, 1, &my_identity);
1184        }
1185     }
1186     return;
1187   }
1188 #endif
1189   GDS_NEIGHBOURS_send_get (key, block_type, options, desired_replication_level,
1190                            best_known_dest,intermediate_trail_id, &successor.next_hop,
1191                            0, 1, &my_identity);
1192 }
1193
1194
1195 /**
1196  * Send the get result to requesting client.
1197  *
1198  * @param key Key of the requested data.
1199  * @param type Block type
1200  * @param target_peer Next peer to forward the message to.
1201  * @param source_peer Peer which has the data for the key.
1202  * @param put_path_length Number of peers in @a put_path
1203  * @param put_path Path taken to put the data at its stored location.
1204  * @param get_path_length Number of peers in @a get_path
1205  * @param get_path Path taken to reach to the location of the key.
1206  * @param expiration When will this result expire?
1207  * @param data Payload to store
1208  * @param data_size Size of the @a data
1209  */
1210 void
1211 GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
1212                                 enum GNUNET_BLOCK_Type type,
1213                                 const struct GNUNET_PeerIdentity *target_peer,
1214                                 const struct GNUNET_PeerIdentity *source_peer,
1215                                 unsigned int put_path_length,
1216                                 const struct GNUNET_PeerIdentity *put_path,
1217                                 unsigned int get_path_length,
1218                                 const struct GNUNET_PeerIdentity *get_path,
1219                                 struct GNUNET_TIME_Absolute expiration,
1220                                 const void *data, size_t data_size)
1221 {
1222   struct PeerGetResultMessage *get_result;
1223   struct GNUNET_PeerIdentity *paths;
1224   struct P2PPendingMessage *pending;
1225   struct FriendInfo *target_friend;
1226   int current_path_index;
1227   size_t msize;
1228
1229   msize = (put_path_length + get_path_length )* sizeof (struct GNUNET_PeerIdentity) +
1230           data_size +
1231           sizeof (struct PeerGetResultMessage);
1232
1233   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1234   {
1235     put_path_length = 0;
1236     msize = msize - put_path_length * sizeof (struct GNUNET_PeerIdentity);
1237   }
1238
1239   if (msize >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1240   {
1241     GNUNET_break(0);
1242     return;
1243   }
1244   current_path_index = 0;
1245   if(get_path_length > 0)
1246   {
1247     current_path_index = search_my_index(get_path, get_path_length);
1248     if (-1 == current_path_index)
1249     {
1250       GNUNET_break (0);
1251       return;
1252     }
1253     if ((get_path_length + 1) == current_path_index)
1254     {
1255       DEBUG ("Peer found twice in get path. Not allowed \n");
1256       GNUNET_break (0);
1257       return;
1258     }
1259   }
1260   if (0 == current_path_index)
1261   {
1262     DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s",GNUNET_h2s(key),GNUNET_i2s(&my_identity));
1263     GDS_CLIENTS_handle_reply (expiration, key, get_path_length,
1264                               get_path, put_path_length,
1265                               put_path, type, data_size, data);
1266     return;
1267   }
1268
1269   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1270   pending->timeout = GNUNET_TIME_relative_to_absolute (PENDING_MESSAGE_TIMEOUT);
1271   pending->importance = 0;
1272   get_result = (struct PeerGetResultMessage *)&pending[1];
1273   pending->msg = &get_result->header;
1274   get_result->header.size = htons (msize);
1275   get_result->header.type = htons (GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT);
1276   get_result->key = *key;
1277   get_result->querying_peer = *source_peer;
1278   get_result->expiration_time = expiration;
1279   get_result->get_path_length = htonl (get_path_length);
1280   get_result->put_path_length = htonl (put_path_length);
1281   paths = (struct GNUNET_PeerIdentity *)&get_result[1];
1282   memcpy (paths, put_path,
1283           put_path_length * sizeof (struct GNUNET_PeerIdentity));
1284   memcpy (&paths[put_path_length], get_path,
1285           get_path_length * sizeof (struct GNUNET_PeerIdentity));
1286   memcpy (&paths[put_path_length + get_path_length], data, data_size);
1287
1288   GNUNET_assert (NULL !=
1289                 (target_friend =
1290                  GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1291                                                     &get_path[current_path_index - 1])));
1292   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1293   target_friend->pending_count++;
1294   process_friend_queue (target_friend);
1295 }
1296
1297
1298 /**
1299  * Method called whenever a peer disconnects.
1300  *
1301  * @param cls closure
1302  * @param peer peer identity this notification is about
1303  */
1304 static void
1305 handle_core_disconnect (void *cls,
1306                         const struct GNUNET_PeerIdentity *peer)
1307 {
1308   struct FriendInfo *remove_friend;
1309
1310   /* If disconnected to own identity, then return. */
1311   if (0 == memcmp (&my_identity,
1312                    peer,
1313                    sizeof (struct GNUNET_PeerIdentity)))
1314     return;
1315
1316   if (NULL == (remove_friend =
1317                GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1318                                                   peer)))
1319   {
1320     GNUNET_break (0);
1321     return;
1322   }
1323
1324   GNUNET_assert (GNUNET_YES ==
1325                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
1326                                                        peer,
1327                                                        remove_friend));
1328   /* FIXME: do stuff */
1329 }
1330
1331
1332 /**
1333  * Method called whenever a peer connects.
1334  *
1335  * @param cls closure
1336  * @param peer_identity peer identity this notification is about
1337  */
1338 static void
1339 handle_core_connect (void *cls,
1340                      const struct GNUNET_PeerIdentity *peer_identity)
1341 {
1342   struct FriendInfo *friend;
1343
1344   /* Check for connect to self message */
1345   if (0 == memcmp (&my_identity,
1346                    peer_identity,
1347                    sizeof (struct GNUNET_PeerIdentity)))
1348     return;
1349
1350   /* If peer already exists in our friend_peermap, then exit. */
1351   if (GNUNET_YES ==
1352       GNUNET_CONTAINER_multipeermap_contains (friend_peermap,
1353                                               peer_identity))
1354   {
1355     GNUNET_break (0);
1356     return;
1357   }
1358
1359   friend = GNUNET_new (struct FriendInfo);
1360   friend->id = *peer_identity;
1361
1362   GNUNET_assert (GNUNET_OK ==
1363                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
1364                                                     peer_identity,
1365                                                     friend,
1366                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1367   /* do work? */
1368 }
1369
1370
1371 /**
1372  * To be called on core init/fail.
1373  *
1374  * @param cls service closure
1375  * @param identity the public identity of this peer
1376  */
1377 static void
1378 core_init (void *cls,
1379            const struct GNUNET_PeerIdentity *identity)
1380 {
1381   my_identity = *identity;
1382 }
1383
1384
1385 /**
1386  * Handle a `struct FingerSetupMessage`.
1387  *
1388  * @param cls closure (NULL)
1389  * @param peer sender identity
1390  * @param message the setup message
1391  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1392  */
1393 static int
1394 handle_dht_p2p_finger_setup (void *cls,
1395                              const struct GNUNET_PeerIdentity *peer,
1396                              const struct GNUNET_MessageHeader *message)
1397 {
1398   const struct FingerSetupMessage *fsm;
1399
1400   fsm = (const struct FingerSetupMessage *) message;
1401
1402   return GNUNET_OK;
1403 }
1404
1405
1406
1407 /**
1408  * Initialize neighbours subsystem.
1409  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1410  */
1411 int
1412 GDS_NEIGHBOURS_init (void)
1413 {
1414   static const struct GNUNET_CORE_MessageHandler core_handlers[] = {
1415     { &handle_dht_p2p_finger_setup,
1416       GNUNET_MESSAGE_TYPE_WDHT_FINGER_SETUP,
1417       sizeof (struct FingerSetupMessage) },
1418     {NULL, 0, 0}
1419   };
1420
1421 #if ENABLE_MALICIOUS
1422   act_malicious = 0;
1423 #endif
1424
1425   core_api =
1426     GNUNET_CORE_connect (GDS_cfg, NULL,
1427                          &core_init,
1428                          &handle_core_connect,
1429                          &handle_core_disconnect,
1430                          NULL, GNUNET_NO,
1431                          NULL, GNUNET_NO,
1432                          core_handlers);
1433
1434   if (NULL == core_api)
1435     return GNUNET_SYSERR;
1436
1437   //TODO: check size of this peer map?
1438   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
1439   return GNUNET_OK;
1440 }
1441
1442
1443 /**
1444  * Shutdown neighbours subsystem.
1445  */
1446 void
1447 GDS_NEIGHBOURS_done (void)
1448 {
1449   if (NULL == core_api)
1450     return;
1451   GNUNET_CORE_disconnect (core_api);
1452   core_api = NULL;
1453
1454   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
1455   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
1456   friend_peermap = NULL;
1457 }
1458
1459
1460 /**
1461  * Get my identity
1462  *
1463  * @return my identity
1464  */
1465 struct GNUNET_PeerIdentity
1466 GDS_NEIGHBOURS_get_my_id (void)
1467 {
1468   return my_identity;
1469 }
1470
1471 /* end of gnunet-service-wdht_neighbours.c */