Updated find successor
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2013 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_nse_service.h"
34 #include "gnunet_ats_service.h"
35 #include "gnunet_core_service.h"
36 #include "gnunet_datacache_lib.h"
37 #include "gnunet_transport_service.h"
38 #include "gnunet_hello_lib.h"
39 #include "gnunet_dht_service.h"
40 #include "gnunet_statistics_service.h"
41 #include "gnunet-service-xdht.h"
42 #include "gnunet-service-xdht_clients.h"
43 #include "gnunet-service-xdht_datacache.h"
44 #include "gnunet-service-xdht_hello.h"
45 #include "gnunet-service-xdht_neighbours.h"
46 #include "gnunet-service-xdht_nse.h"
47 #include "gnunet-service-xdht_routing.h"
48 #include <fenv.h>
49 #include "dht.h"
50
51 /**
52  * Maximum possible fingers of a peer.
53  */
54 #define MAX_FINGERS 64
55
56 /**
57  * Maximum allowed number of pending messages per friend peer.
58  */
59 #define MAXIMUM_PENDING_PER_FRIEND 64
60
61 /**
62  * How long at least to wait before sending another find finger trail request.
63  */
64 #define DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
65
66 /**
67  * How long at most to wait before sending another find finger trail request.
68  */
69 #define DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 10)
70
71 /**
72  * How long at most to wait for transmission of a GET request to another peer?
73  */
74 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
75
76 GNUNET_NETWORK_STRUCT_BEGIN
77   
78 /**
79  * P2P PUT message
80  */
81 struct PeerPutMessage
82 {
83   /**
84    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
85    */
86   struct GNUNET_MessageHeader header;
87
88   /**
89    * Processing options
90    */
91   uint32_t options GNUNET_PACKED;
92
93   /**
94    * Content type.
95    */
96   uint32_t type GNUNET_PACKED;
97
98   /**
99    * Hop count
100    */
101   uint32_t hop_count GNUNET_PACKED;
102
103   /**
104    * Replication level for this message
105    */
106   uint32_t desired_replication_level GNUNET_PACKED;
107
108   /**
109    * Length of the PUT path that follows (if tracked).
110    */
111   uint32_t put_path_length GNUNET_PACKED;
112
113   /**
114    * When does the content expire?
115    */
116   struct GNUNET_TIME_AbsoluteNBO expiration_time;
117
118   /**
119    * Bloomfilter (for peer identities) to stop circular routes
120    */
121   char bloomfilter[DHT_BLOOM_SIZE];
122
123   /**
124    * The key we are storing under.
125    */
126   struct GNUNET_HashCode key;
127
128   /* put path (if tracked) */
129
130   /* Payload */
131
132 };
133
134
135 /**
136  * P2P Result message
137  */
138 struct PeerResultMessage
139 {
140   /**
141    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT
142    */
143   struct GNUNET_MessageHeader header;
144
145   /**
146    * Content type.
147    */
148   uint32_t type GNUNET_PACKED;
149
150   /**
151    * Length of the PUT path that follows (if tracked).
152    */
153   uint32_t put_path_length GNUNET_PACKED;
154
155   /**
156    * Length of the GET path that follows (if tracked).
157    */
158   uint32_t get_path_length GNUNET_PACKED;
159
160   /**
161    * When does the content expire?
162    */
163   struct GNUNET_TIME_AbsoluteNBO expiration_time;
164
165   /**
166    * The key of the corresponding GET request.
167    */
168   struct GNUNET_HashCode key;
169
170   /* put path (if tracked) */
171
172   /* get path (if tracked) */
173
174   /* Payload */
175
176 };
177
178
179 /**
180  * P2P GET message
181  */
182 struct PeerGetMessage
183 {
184   /**
185    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
186    */
187   struct GNUNET_MessageHeader header;
188
189   /**
190    * Processing options
191    */
192   uint32_t options GNUNET_PACKED;
193
194   /**
195    * Desired content type.
196    */
197   uint32_t type GNUNET_PACKED;
198
199   /**
200    * Hop count
201    */
202   uint32_t hop_count GNUNET_PACKED;
203
204   /**
205    * Desired replication level for this request.
206    */
207   uint32_t desired_replication_level GNUNET_PACKED;
208
209   /**
210    * Size of the extended query.
211    */
212   uint32_t xquery_size;
213
214   /**
215    * Bloomfilter mutator.
216    */
217   uint32_t bf_mutator;
218
219   /**
220    * Bloomfilter (for peer identities) to stop circular routes
221    */
222   char bloomfilter[DHT_BLOOM_SIZE];
223
224   /**
225    * The key we are looking for.
226    */
227   struct GNUNET_HashCode key;
228
229 };
230
231
232 /**
233  * A destination can be either a friend, finger or me.
234  * Used in trail setup to understand if the message is sent to an intermediate
235  * finger or a friend.
236  */
237 enum current_destination_type
238 {
239   FRIEND ,
240   FINGER ,
241   MY_ID ,
242   VALUE
243 };
244
245
246 /**
247  * P2P Trail setup message
248  */
249 struct PeerTrailSetupMessage
250 {
251   
252   /**
253    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
254    */
255   struct GNUNET_MessageHeader header;
256
257   /**
258    * Source peer which wants to setup the trail to one of its finger. 
259    */
260   struct GNUNET_PeerIdentity source_peer;
261
262   /**
263    * Finger id to which we want to set up the trail to. 
264    */
265   uint64_t destination_finger;
266   
267   /**
268    * If set to 1, then we are looking for trail to our immediate successor. 
269    */
270   unsigned int successor_flag;
271   
272   /**
273    * If set to 1, then we are looking for trail to our immediate predecessor. 
274    */
275   unsigned int predecessor_flag;
276   
277   /**
278    * Peer which gets this message can be either an intermediate finger or friend. 
279    */
280   enum current_destination_type current_destination_type;
281   
282   /**
283    * Peer to which this packet is forwarded.
284    */
285   struct GNUNET_PeerIdentity current_destination;
286   
287   /**
288    * Index into finger peer map. 
289    */
290   unsigned int finger_map_index;
291   
292   /**
293    * Number of entries in trail list.
294    */
295   uint32_t trail_length GNUNET_PACKED;
296   
297 };
298
299
300 /**
301  * P2P Trail setup Result message
302  */
303 struct PeerTrailSetupResultMessage
304 {
305   
306   /**
307    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_RESULT_SETUP
308    */
309   struct GNUNET_MessageHeader header;
310   
311   /**
312    * Finger to which we have found the path. 
313    */
314   struct GNUNET_PeerIdentity finger;
315
316   /**
317    * Peer which was looking for the trail to finger. 
318    */
319   struct GNUNET_PeerIdentity destination_peer;
320
321   /**
322    * Peer to which this packet is forwarded next.
323    */
324   struct GNUNET_PeerIdentity current_destination;
325   
326   /**
327    * Index at which peer list should be accessed. 
328    */
329   unsigned int current_index;
330   
331   /**
332    * If set to 1, then this trail is the trail to our successor. 
333    */
334   unsigned int successor_flag;
335   
336   /**
337    * If set to 1, then this trail is the trail to our predecessor. 
338    */
339   unsigned int predecessor_flag;
340   
341   /**
342    * Index into finger peer map
343    */
344   unsigned int finger_map_index;
345   
346   /**
347    * Number of entries in trail list.
348    */
349   uint32_t trail_length GNUNET_PACKED;
350   
351 };
352
353
354 /**
355  * P2P verify successor message. 
356  */
357 struct PeerVerifySuccessorMessage
358 {
359   
360   /**
361    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
362    */
363   struct GNUNET_MessageHeader header;
364   
365   /**
366    * Source peer which wants to verify its successor. 
367    */
368   struct GNUNET_PeerIdentity source_peer;
369   
370   /**
371    * My current successor.
372    */
373   struct GNUNET_PeerIdentity successor;
374   
375   /**
376    * Total number of peers in trail to current successor.
377    */
378   unsigned int trail_length;
379   
380   /**
381    * Index in trail which points to next destination to send this message.
382    */
383   unsigned int current_trail_index;
384   
385 };
386
387
388 /**
389  * P2P verify successor result message. 
390  */
391 struct PeerVerifySuccessorResultMessage
392 {
393   
394   /**
395    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
396    */
397   struct GNUNET_MessageHeader header;
398   
399   /**
400    * Destination peer which sent the request to verify its successor. 
401    */
402   struct GNUNET_PeerIdentity destination_peer;
403   
404   /**
405    * Successor to which PeerVerifySuccessorMessage was sent.
406    */
407   struct GNUNET_PeerIdentity source_successor;
408   
409   /**
410    * source_successor's predecessor
411    */
412   struct GNUNET_PeerIdentity my_predecessor;
413   
414   /**
415    * Total number of peers in trail.
416    * If source_successor is not destination peer, then trail is from destination_peer
417    * to my_predecessor.
418    * If source_successor is destination peer, then trail is from destination_peer
419    * to source_successor.
420    */
421   unsigned int trail_length;
422   
423   /**
424    * Index in trail which points to next destination to send this message.
425    */
426   unsigned int current_index;
427   
428 };
429
430 /**
431  * P2P notify new successor message.
432  */
433 struct PeerNotifyNewSuccessorMessage
434 {
435   /**
436    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
437    */
438   struct GNUNET_MessageHeader header;
439   
440   /**
441    * Source peer which wants to notify its new successor. 
442    */
443   struct GNUNET_PeerIdentity source_peer;
444   
445   /**
446    * New successor identity.
447    */
448   struct GNUNET_PeerIdentity destination_peer;
449   
450   /**
451    * Number of peers in trail from source_peer to new successor.
452    */
453   unsigned int trail_length;
454   
455   /**
456    * Index in trail which points to next destination to send this message.
457    */
458   unsigned int current_index;
459   
460 };
461
462
463 GNUNET_NETWORK_STRUCT_END
464
465
466 /**
467  * Linked list of messages to send to a particular other peer.
468  */
469 struct P2PPendingMessage
470 {
471   /**
472    * Pointer to next item in the list
473    */
474   struct P2PPendingMessage *next;
475
476   /**
477    * Pointer to previous item in the list
478    */
479   struct P2PPendingMessage *prev;
480
481   /**
482    * When does this message time out?
483    */
484   struct GNUNET_TIME_Absolute timeout;
485
486    /**
487    * Message importance level.  FIXME: used? useful?
488    */
489   unsigned int importance;
490
491   /**
492    * Actual message to be sent, allocated at the end of the struct:
493    * // msg = (cast) &pm[1];
494    * // memcpy (&pm[1], data, len);
495    */
496   const struct GNUNET_MessageHeader *msg;
497
498 };
499
500
501  /**
502   * Linked List of peers which are part of trail to reach a particular Finger.
503   */
504 struct TrailPeerList
505 {
506    /**
507     * Pointer to next item in the list
508     */
509    struct TrailPeerList *next;
510
511    /**
512     * Pointer to previous item in the list
513     */
514    struct TrailPeerList *prev;
515    
516    /**
517     * An element in this trail list
518     */
519    struct GNUNET_PeerIdentity peer;
520   
521 };
522
523
524 /** 
525  *  Entry in friend_peermap.
526  */
527 struct FriendInfo
528 {
529   /**
530    * Friend Identity 
531    */
532   struct GNUNET_PeerIdentity id;
533
534   /**
535    * Count of outstanding messages for this friend.
536    */
537   unsigned int pending_count;
538   
539   /**
540    * Head of pending messages to be sent to this friend.
541    */
542  struct P2PPendingMessage *head;
543
544  /**
545   * Tail of pending messages to be sent to this friend.
546   */
547  struct P2PPendingMessage *tail;
548  
549  /**
550   * Core handle for sending messages to this friend.
551   */
552  struct GNUNET_CORE_TransmitHandle *th;
553
554 };
555
556
557 /**
558  * Entry in finger_peermap.
559  */
560 struct FingerInfo
561 {
562   /**
563    * Finger identity.
564    */
565   struct GNUNET_PeerIdentity finger_identity;
566   
567   /**
568    * If 1, then this finger entry is my first finger(successor).
569    */
570   unsigned int successor;
571   
572   /**
573    * If 1, then this finger entry is my first predecessor.
574    */
575   unsigned int predecessor;
576   
577   /**
578    * Index in finger peer map
579    */
580   unsigned int finger_map_index;
581   
582   /**
583    * Total number of entries in trail from me to finger. 
584    */
585   unsigned int trail_length;
586   
587   /**
588    * Head of trail to reach this finger.
589    */
590   struct TrailPeerList *head;
591   
592   /**
593    * Tail of trail to reach this finger.
594    */
595   struct TrailPeerList *tail;
596   
597 };
598
599 /**
600  * Data structure passed to sorting algorithm in find_successor.
601  */
602 struct Sorting_List
603 {
604   /* 64 bit value of peer identity */
605   uint64_t peer_id;
606   
607   /* Type : MY_ID, FINGER, FINGER */
608   enum current_destination_type type;
609   
610   /* Pointer to original data structure linked to peer id. */
611   void *data;
612 };
613
614
615 /**
616  * Task that sends FIND FINGER TRAIL requests.
617  */
618 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
619
620 /**
621  * 
622  * Task that periodically checks for who is my successor. 
623  */
624 static GNUNET_SCHEDULER_TaskIdentifier verify_successor;
625
626 /**
627  * Identity of this peer.
628  */
629 static struct GNUNET_PeerIdentity my_identity;
630
631 /**
632  * Hash map of all the friends of a peer
633  */
634 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
635
636 /**
637  * Hash map of all the fingers of a peer
638  */
639 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
640
641 /**
642  * Handle to ATS.
643  */
644 static struct GNUNET_ATS_PerformanceHandle *atsAPI;
645
646 /**
647  * Handle to CORE.
648  */
649 static struct GNUNET_CORE_Handle *core_api;
650
651 /**
652  * FIXME: Is it safe to assume its initialized to 0 by default.
653  * The current finger index that we have found trail to.
654  */
655 static unsigned int current_finger_index;
656
657
658 /**
659  * Called when core is ready to send a message we asked for
660  * out to the destination.
661  *
662  * @param cls the 'struct PeerInfo' of the target peer
663  * @param size number of bytes available in buf
664  * @param buf where the callee should write the message
665  * @return number of bytes written to buf
666  */
667 static size_t
668 core_transmit_notify (void *cls, size_t size, void *buf)
669 {
670   struct FriendInfo *peer = cls;
671   char *cbuf = buf;
672   struct P2PPendingMessage *pending;
673   size_t off;
674   size_t msize;
675   
676   peer->th = NULL;
677   while ((NULL != (pending = peer->head)) &&
678          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
679   {
680     peer->pending_count--;
681     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
682     GNUNET_free (pending);
683   }
684   if (NULL == pending)
685   {
686     /* no messages pending */
687     return 0;
688   }
689   if (NULL == buf)
690   {
691     peer->th =
692         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
693                                            GNUNET_CORE_PRIO_BEST_EFFORT,
694                                            GNUNET_TIME_absolute_get_remaining
695                                            (pending->timeout), &peer->id,
696                                            ntohs (pending->msg->size),
697                                            &core_transmit_notify, peer);
698     GNUNET_break (NULL != peer->th);
699     return 0;
700   }
701   off = 0;
702   while ((NULL != (pending = peer->head)) &&
703          (size - off >= (msize = ntohs (pending->msg->size))))
704   {
705     GNUNET_STATISTICS_update (GDS_stats,
706                               gettext_noop
707                               ("# Bytes transmitted to other peers"), msize,
708                               GNUNET_NO);
709     memcpy (&cbuf[off], pending->msg, msize);
710     off += msize;
711     peer->pending_count--;
712     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
713     GNUNET_free (pending);
714   }
715   if (peer->head != NULL)
716   {
717     peer->th =
718         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
719                                            GNUNET_CORE_PRIO_BEST_EFFORT,
720                                            GNUNET_TIME_absolute_get_remaining
721                                            (pending->timeout), &peer->id, msize,
722                                            &core_transmit_notify, peer);
723     GNUNET_break (NULL != peer->th);
724   }
725   return off;
726 }
727
728
729 /**
730  * Transmit all messages in the friend's message queue.
731  *
732  * @param peer message queue to process
733  */
734 static void
735 process_friend_queue (struct FriendInfo *peer)
736 {
737   struct P2PPendingMessage *pending;
738   
739   if (NULL == (pending = peer->head))
740     return;
741   if (NULL != peer->th)
742     return;
743   
744   GNUNET_STATISTICS_update (GDS_stats,
745                             gettext_noop
746                             ("# Bytes of bandwidth requested from core"),
747                             ntohs (pending->msg->size), GNUNET_NO);
748   
749   /* FIXME: Are we correctly initializing importance and pending. */
750   peer->th =
751       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
752                                          pending->importance,
753                                          GNUNET_TIME_absolute_get_remaining
754                                          (pending->timeout), &peer->id,
755                                          ntohs (pending->msg->size),
756                                          &core_transmit_notify, peer);
757   GNUNET_break (NULL != peer->th);
758 }
759
760
761 /**
762  * Setup the trail message and forward it to a friend. 
763  * @param source_peer Peer which wants to set up the trail to one of its finger.
764  * @param destination_finger Peer to which we want to set up the trail to.
765  * @param target_friend Current friend to which this message should be forwarded.
766  * @param trail_length Numbers of peers in the trail.
767  * @param trail_peer_list peers this request has traversed so far
768  * @param successor_flag If 1 then we are looking for trail to our successor.
769  * @param predecessor_flag If 1, then we are looking for trail to our predecessor.  
770  * @param current_finger_index Finger index in finger peer map 
771  */
772 void
773 GDS_NEIGHBOURS_send_trail_setup (struct GNUNET_PeerIdentity *source_peer,
774                                   uint64_t destination_finger,
775                                   struct FriendInfo *target_friend,
776                                   unsigned int trail_length,
777                                   struct GNUNET_PeerIdentity *trail_peer_list,
778                                   unsigned int successor_flag,
779                                   unsigned int predecessor_flag,
780                                   unsigned int current_finger_index)
781 {
782   struct P2PPendingMessage *pending;
783   struct PeerTrailSetupMessage *tsm;
784   struct GNUNET_PeerIdentity *peer_list;
785   size_t msize;
786   
787   msize = sizeof (struct PeerTrailSetupMessage) + 
788           (trail_length * sizeof (struct GNUNET_PeerIdentity));
789   
790   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
791   {
792     GNUNET_break (0);
793     return;
794   }
795   
796   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
797   {  
798     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
799                                 1, GNUNET_NO);
800   }
801   
802   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
803   pending->importance = 0;    /* FIXME */
804   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
805   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
806   pending->msg = &tsm->header;
807   tsm->header.size = htons (msize);
808   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
809   memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
810   memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
811   memcpy (&(tsm->current_destination), &(target_friend->id), 
812           sizeof (struct GNUNET_PeerIdentity));
813   tsm->current_destination_type = htonl (FRIEND); 
814   tsm->trail_length = htonl (trail_length); 
815   tsm->finger_map_index = htonl (current_finger_index);
816   if(1 == successor_flag)
817   {
818     tsm->successor_flag = htonl(1);
819     tsm->predecessor_flag = htonl (0);
820   }
821   else if (1 == predecessor_flag)
822   {
823     tsm->predecessor_flag = htonl(1);
824     tsm->successor_flag = htonl(0);
825   }
826   else
827   {
828     tsm->successor_flag = htonl(0);
829     tsm->predecessor_flag = htonl(0);
830   }
831   
832   peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
833   memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
834   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
835   target_friend->pending_count++;
836   process_friend_queue (target_friend);
837   
838 }
839
840
841 /**
842  * Handle a tail setup result message. 
843  * @param destination_peer Peer which will get the trail to one of its finger.
844  * @param source_finger Peer to which the trail has been setup to.
845  * @param target_friend Friend to which this message should be forwarded.
846  * @param trail_length Numbers of peers in the trail.
847  * @param trail_peer_list Peers which are part of the trail from source to destination.
848  * @param current_trail_index Index in trail_peer_list. 
849  * @param successor_flag If 1, then this is the trail to our successor.
850  * @param predecessor_flag If 1, then this is the trail to our predecessor.  
851  * @param finger_map_index Finger index in finger peer map 
852  */
853 void
854 GDS_NEIGHBOURS_send_trail_setup_result (struct GNUNET_PeerIdentity *destination_peer,
855                                           struct GNUNET_PeerIdentity *source_finger,
856                                           struct FriendInfo *target_friend,
857                                           unsigned int trail_length,
858                                           struct GNUNET_PeerIdentity *trail_peer_list,
859                                           unsigned int current_trail_index,
860                                           unsigned int successor_flag,
861                                           unsigned int predecessor_flag,
862                                           unsigned int finger_map_index)
863 {
864   struct P2PPendingMessage *pending;
865   struct PeerTrailSetupResultMessage *tsrm;
866   struct GNUNET_PeerIdentity *peer_list;
867   size_t msize;
868   
869   msize = sizeof (struct PeerTrailSetupResultMessage) + 
870           (trail_length * sizeof (struct GNUNET_PeerIdentity));
871   
872   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
873   {
874     GNUNET_break (0);
875     return;
876   }
877   
878   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
879   {  
880     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
881                                 1, GNUNET_NO);
882   }
883
884   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
885   pending->importance = 0;    
886   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
887   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
888   pending->msg = &tsrm->header;
889   tsrm->header.size = htons (msize);
890   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
891   memcpy (&(tsrm->current_destination), &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
892   memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
893   memcpy (&(tsrm->finger), source_finger, sizeof (struct GNUNET_PeerIdentity));
894   tsrm->trail_length = htonl (trail_length);
895   tsrm->current_index = htonl (current_trail_index);
896   tsrm->successor_flag = htonl (successor_flag);
897   tsrm->predecessor_flag = htonl (predecessor_flag);
898   tsrm->finger_map_index = htonl (finger_map_index);
899   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
900   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
901   
902   /* Send the message to chosen friend. */
903   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
904   target_friend->pending_count++;
905   process_friend_queue (target_friend);
906 }
907
908
909 /**
910  * Construct a PeerVerifySuccessor message and send it to friend.
911  * @param source_peer Peer which wants to verify its successor
912  * @param successor Peer which is our current successor
913  * @param target_friend Friend to which this message should be forwarded.
914  * @param trail_peer_list Peer which are part of trail from source to destination
915  * @param trail_length Number of peers in the trail list.
916  * @param current_trail_index Index in the trial list at which receiving peer should
917  *                            get the next element.
918  */
919 void GDS_NEIGHBOURS_send_verify_successor(struct GNUNET_PeerIdentity *source_peer,
920                                             struct GNUNET_PeerIdentity *successor,
921                                             struct FriendInfo *target_friend,
922                                             struct GNUNET_PeerIdentity *trail_peer_list,
923                                             unsigned int trail_length,
924                                             unsigned int current_trail_index)
925 {
926   struct PeerVerifySuccessorMessage *vsm;
927   struct P2PPendingMessage *pending;
928   struct GNUNET_PeerIdentity *peer_list;
929   size_t msize;
930   
931   msize = sizeof (struct PeerVerifySuccessorMessage) + 
932           (trail_length * sizeof (struct GNUNET_PeerIdentity));
933   
934   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
935   {
936     GNUNET_break (0);
937     return;
938   }
939  
940   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
941   {  
942     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
943                                 1, GNUNET_NO);
944   }
945   
946   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
947   pending->importance = 0;    /* FIXME */
948   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
949   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
950   pending->msg = &vsm->header;
951   vsm->header.size = htons (msize);
952   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
953   memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
954   memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
955   vsm->trail_length = htonl (trail_length);
956   vsm->current_trail_index = htonl (current_trail_index);
957   peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
958   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
959   
960   /* Send the message to chosen friend. */
961   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
962   target_friend->pending_count++;
963   process_friend_queue (target_friend);
964   
965 }
966
967
968 /**
969  * Construct a PeerVerifySuccessorResult message and send it to friend.
970  * @param destination_peer Peer which sent verify successor message
971  * @param source_successor Peer to which verify successor message was sent.
972  * @param my_predecessor source_successor predecessor.
973  * @param target_friend Friend to which this message should be forwarded.
974  * @param trail_peer_list Peer which are part of trail from source to destination
975  * @param trail_length Number of peers in the trail list.
976  * @param current_trail_index Index in the trial list at which receiving peer should
977  *                            get the next element.
978  */
979 void GDS_NEIGHBOURS_send_verify_successor_result (struct GNUNET_PeerIdentity *destination_peer,
980                                                     struct GNUNET_PeerIdentity *source_successor,
981                                                     struct GNUNET_PeerIdentity *my_predecessor,
982                                                     struct FriendInfo *target_friend,
983                                                     struct GNUNET_PeerIdentity *trail_peer_list,
984                                                     unsigned int trail_length,
985                                                     unsigned int current_trail_index)
986 {
987   struct PeerVerifySuccessorResultMessage *vsmr;
988   struct P2PPendingMessage *pending;
989   struct GNUNET_PeerIdentity *peer_list;
990   size_t msize;
991   
992   msize = sizeof (struct PeerVerifySuccessorResultMessage) + 
993           (trail_length * sizeof(struct GNUNET_PeerIdentity));
994   
995   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
996   {
997     GNUNET_break (0);
998     return;
999   }
1000   
1001   
1002   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1003   {  
1004     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1005                                 1, GNUNET_NO);
1006   }
1007   
1008   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1009   pending->importance = 0;    /* FIXME */
1010   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1011   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1012   pending->msg = &vsmr->header;
1013   vsmr->header.size = htons (msize);
1014   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1015   memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1016   memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
1017   memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
1018   vsmr->trail_length = htonl (trail_length);
1019   vsmr->current_index = htonl (current_trail_index);
1020   
1021   peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1022   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1023   
1024    /* Send the message to chosen friend. */
1025   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1026   target_friend->pending_count++;
1027   process_friend_queue (target_friend);
1028 }
1029
1030
1031 /**
1032  * Construct a PeerNotifyNewSuccessor message and send it to friend.
1033  * @param source_peer Peer which is sending notify message to its new successor.
1034  * @param destination_peer Peer which is the new destination.
1035  * @param target_friend Next friend to pass this message to. 
1036  * @param peer_list List of peers in the trail to reach to destination_peer.
1037  * @param current_trail_index Index of peer_list for next target friend position. 
1038  * @param trail_length Total number of peers in peer list 
1039  */
1040 void 
1041 GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_peer,
1042                                      struct GNUNET_PeerIdentity *destination_peer,
1043                                      struct FriendInfo *target_friend,
1044                                      struct GNUNET_PeerIdentity *trail_peer_list,
1045                                      unsigned int trail_length,
1046                                      unsigned int current_trail_index)
1047 {
1048   struct PeerNotifyNewSuccessorMessage *nsm;
1049   struct P2PPendingMessage *pending;
1050   struct GNUNET_PeerIdentity *peer_list;
1051   size_t msize;
1052   
1053   msize = sizeof (struct PeerNotifyNewSuccessorMessage) + 
1054           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1055   
1056   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1057   {
1058     GNUNET_break (0);
1059     return;
1060   }
1061   
1062   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1063   {  
1064     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1065                                 1, GNUNET_NO);
1066   }
1067   
1068   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1069   pending->importance = 0;    /* FIXME */
1070   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1071   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1072   pending->msg = &nsm->header;
1073   nsm->header.size = htons (msize);
1074   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1075   memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1076   memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1077   nsm->trail_length = htonl (trail_length);
1078   nsm->current_index = htonl (current_trail_index);
1079   
1080   peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1081   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1082   
1083    /* Send the message to chosen friend. */
1084   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1085   target_friend->pending_count++;
1086   process_friend_queue (target_friend);
1087 }
1088
1089
1090 /**FIXME: Old implementation just to remove error
1091  * TODO: Modify this function to handle our get request. 
1092  * Perform a GET operation.  Forwards the given request to other
1093  * peers.  Does not lookup the key locally.  May do nothing if this is
1094  * the only peer in the network (or if we are the closest peer in the
1095  * network).
1096  *
1097  * @param type type of the block
1098  * @param options routing options
1099  * @param desired_replication_level desired replication count
1100  * @param hop_count how many hops did this request traverse so far?
1101  * @param key key for the content
1102  * @param xquery extended query
1103  * @param xquery_size number of bytes in @a xquery
1104  * @param reply_bf bloomfilter to filter duplicates
1105  * @param reply_bf_mutator mutator for @a reply_bf
1106  * @param peer_bf filter for peers not to select (again)
1107  */
1108 void
1109 GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
1110                            enum GNUNET_DHT_RouteOption options,
1111                            uint32_t desired_replication_level,
1112                            uint32_t hop_count, const struct GNUNET_HashCode * key,
1113                            const void *xquery, size_t xquery_size,
1114                            const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
1115                            uint32_t reply_bf_mutator,
1116                            struct GNUNET_CONTAINER_BloomFilter *peer_bf)
1117 {
1118
1119   /*
1120    1. take the key, get the 64 bit value of the key.
1121    2. call find_successor to get the successor of the key.
1122    3. successor can be either a friend or finger.
1123    4. update the field in get message to reflect if its a friend or finger table
1124    5. add the put message to pending message and send it. 
1125    */
1126   
1127 }
1128
1129 /**FIXME: Old implementation just to remove error.
1130  * TODO: Modify this function to handle our put request. 
1131  * Perform a PUT operation.   Forwards the given request to other
1132  * peers.   Does not store the data locally.  Does not give the
1133  * data to local clients.  May do nothing if this is the only
1134  * peer in the network (or if we are the closest peer in the
1135  * network).
1136  *
1137  * @param type type of the block
1138  * @param options routing options
1139  * @param desired_replication_level desired replication count
1140  * @param expiration_time when does the content expire
1141  * @param hop_count how many hops has this message traversed so far
1142  * @param bf Bloom filter of peers this PUT has already traversed
1143  * @param key key for the content
1144  * @param put_path_length number of entries in @a put_path
1145  * @param put_path peers this request has traversed so far (if tracked)
1146  * @param data payload to store
1147  * @param data_size number of bytes in @a data
1148  */
1149 void
1150 GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1151                            enum GNUNET_DHT_RouteOption options,
1152                            uint32_t desired_replication_level,
1153                            struct GNUNET_TIME_Absolute expiration_time,
1154                            uint32_t hop_count,
1155                            struct GNUNET_CONTAINER_BloomFilter *bf,
1156                            const struct GNUNET_HashCode *key,
1157                            unsigned int put_path_length,
1158                            struct GNUNET_PeerIdentity *put_path,
1159                            const void *data, size_t data_size)
1160 {
1161
1162    /*
1163    1. take the key, get the 64 bit value of the key.
1164    2. call find_successor to get the successor of the key.
1165    3. successor can be either a friend or finger.
1166    4. update the field in put message to reflect if its a friend or finger table
1167    5. add the put message to pending message and send it. 
1168    */
1169   /* SUPU: Call is made to this function from client. It does not seem to be
1170    waiting for a confirmation So, once we got the request, we use the key and
1171    try to find the closest successor, but in this case when we reach to the
1172    closest successor in handle_dht_p2p_put, then just do datacache_put. As the calling 
1173    function does not need any confirmation, we don't need the result back. */
1174 }
1175
1176
1177 /** 
1178  * Randomly choose one of your friends from the friends_peer map
1179  * @return Friend
1180  */
1181 static struct FriendInfo *
1182 select_random_friend()
1183 {  
1184   unsigned int current_size;
1185   unsigned int *index; 
1186   unsigned int j = 0;
1187   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1188   struct GNUNET_PeerIdentity key_ret;
1189   struct FriendInfo *friend;
1190   
1191   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1192   
1193   /* Element stored at this index in friend_peermap should be selected friend. */
1194   index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1195   
1196   /* Create an iterator for friend_peermap. */
1197   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1198   
1199   /* Set the position of iterator to index. */
1200   while(j < (*index))
1201   {
1202     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1203     {
1204       j++;
1205     }
1206     else 
1207       return NULL;
1208   }  
1209   
1210   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1211   {
1212     return friend;
1213   }
1214
1215   return NULL;
1216 }
1217
1218
1219 /**
1220  * Compute finger_identity to which we want to setup the trail
1221  * @return finger_identity 
1222  */
1223 static uint64_t *
1224 compute_finger_identity()
1225 {
1226   uint64_t *my_id64 ;
1227   uint64_t *finger_identity64;
1228   
1229   my_id64 = GNUNET_malloc (sizeof (uint64_t));
1230   finger_identity64 = GNUNET_malloc (sizeof (uint64_t));
1231
1232   memcpy (my_id64, &(my_identity.public_key.q_y), sizeof (uint64_t));
1233   *finger_identity64 = fmod ((*my_id64 + pow (2,current_finger_index)),( (pow (2,MAX_FINGERS))));
1234   
1235   return finger_identity64;
1236 }
1237
1238
1239 /**
1240  * Compute immediate predecessor identity in the network.
1241  * @return peer identity of immediate predecessor.
1242  */
1243 static uint64_t *
1244 compute_predecessor_identity()
1245 {
1246   uint64_t *my_id ;
1247   uint64_t *predecessor;
1248   
1249   my_id = GNUNET_malloc (sizeof (uint64_t));
1250   predecessor = GNUNET_malloc (sizeof (uint64_t));
1251   
1252   memcpy (my_id, &(my_identity.public_key.q_y), sizeof (uint64_t));
1253   *predecessor = fmod ((*my_id -1), (pow (2,MAX_FINGERS)));
1254           
1255   return predecessor;
1256 }
1257
1258
1259 /**
1260  * SUPU: You should pass the trail index from where next peer should read. read
1261  * position should be set and after you read you should update the read position
1262  * for next peer in the trail list. 
1263  * Periodically ping your successor to ask its current predecessor
1264  * 
1265  * @param cls closure for this task
1266  * @param tc the context under which the task is running
1267  */
1268 static void
1269 send_verify_successor_message (void *cls,
1270                                const struct GNUNET_SCHEDULER_TaskContext *tc )
1271 {
1272   struct GNUNET_TIME_Relative next_send_time;
1273   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1274   struct GNUNET_PeerIdentity key_ret;
1275   struct FriendInfo *target_friend;
1276   struct GNUNET_PeerIdentity *next_hop;
1277   struct GNUNET_PeerIdentity *peer_list;
1278   unsigned int finger_trail_current_index;
1279   struct FingerInfo *finger;
1280   unsigned int finger_index;
1281   unsigned int i;
1282   
1283   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1284   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1285   {
1286     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1287                                                                  (const void **)&finger)) 
1288     {
1289       if (1 == finger->successor)
1290         break;
1291     }
1292   }
1293   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1294  
1295   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->trail_length);
1296   
1297   /* Iterate over your linked list of trail and copy it into peer_list. */
1298   struct TrailPeerList *iterate;
1299   iterate = finger->head;
1300   i = 0;
1301   while ( i < (finger->trail_length))
1302   {
1303     memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1304     iterate = iterate->next;
1305     i++;
1306   }
1307  
1308   /* element stored at location 0 is my own identity. element stored at location 1
1309    is the next hop. */
1310    next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1311    memcpy (next_hop, &peer_list[1], sizeof (struct GNUNET_PeerIdentity));
1312   /* Find the friend corresponding to this next hop. */
1313   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1314   finger_trail_current_index = 2; 
1315   
1316   GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1317                                           &(finger->finger_identity),
1318                                           target_friend,
1319                                           peer_list,
1320                                           finger->trail_length,
1321                                           finger_trail_current_index);
1322   
1323   
1324   /* FIXME: Use a random value so that this message is send not at the same
1325    interval as send_find_finger_trail_message. */
1326   next_send_time.rel_value_us =
1327       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1328       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1329                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1330                                 (current_finger_index + 50));
1331  
1332   verify_successor =
1333       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_verify_successor_message,
1334                                     NULL);
1335 }
1336
1337
1338 /**
1339  * Task to send a find finger trail message. We attempt to find trail
1340  * to our fingers, successor and predecessor in the network.
1341  *
1342  * @param cls closure for this task
1343  * @param tc the context under which the task is running
1344  */
1345 static void
1346 send_find_finger_trail_message (void *cls,
1347                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1348 {
1349   struct FriendInfo *target_friend;
1350   struct GNUNET_TIME_Relative next_send_time;
1351   struct GNUNET_PeerIdentity *peer_list;
1352   unsigned int successor_flag;
1353   unsigned int predecessor_flag;
1354   uint64_t *finger_identity;
1355   unsigned int finger_index;
1356   
1357   /* Initialize flag values */
1358   predecessor_flag = 0;
1359   successor_flag = 0;
1360   
1361   if (1 == current_finger_index)
1362   {
1363     /* We have started the process to find the successor. We should search 
1364      for our predecessor. */
1365     finger_identity = compute_predecessor_identity();  
1366     predecessor_flag = 1; 
1367     goto select_friend;
1368   }
1369   else
1370   {
1371     finger_identity = compute_finger_identity();
1372   }
1373   
1374   if(0 == current_finger_index)
1375   {
1376     /* We are searching for our successor in the network. */
1377     successor_flag = 1;
1378   }
1379   
1380   select_friend:
1381   finger_index = current_finger_index;
1382   current_finger_index = ( current_finger_index + 1) % MAX_FINGERS;
1383   
1384   target_friend = select_random_friend();
1385   
1386   /* We found a friend.*/
1387   if(NULL != target_friend)
1388   { 
1389     /* Add yourself and selected friend in the trail list. */
1390     unsigned int trail_length = 2;
1391     peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * trail_length);
1392     memcpy (&peer_list[0], &(my_identity), sizeof (struct GNUNET_PeerIdentity)); 
1393     memcpy (&peer_list[1], &(target_friend->id), sizeof (struct GNUNET_PeerIdentity)); 
1394     
1395    /* TODO send trail setup */ 
1396    GDS_NEIGHBOURS_send_trail_setup (&my_identity, *finger_identity, 
1397                                       target_friend, trail_length, peer_list,
1398                                       successor_flag, predecessor_flag, 
1399                                       finger_index);
1400   }
1401   
1402   /* FIXME: Should we be using current_finger_index to generate random interval.*/
1403   next_send_time.rel_value_us =
1404       DHT_MINIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1405       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1406                                 DHT_MAXIMUM_FIND_FINGER_TRAIL_INTERVAL.rel_value_us /
1407                                 (current_finger_index + 10));
1408  
1409   find_finger_trail_task =
1410       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1411                                     NULL);
1412 }
1413
1414
1415 /**
1416  * Method called whenever a peer connects.
1417  *
1418  * @param cls closure
1419  * @param peer_identity peer identity this notification is about
1420  */
1421 static void
1422 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
1423 {
1424   struct FriendInfo *friend;
1425
1426   /* Check for connect to self message */
1427   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
1428     return;
1429   
1430   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
1431   
1432   /* If peer already exists in our friend_peermap, then exit. */
1433   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
1434   {
1435     GNUNET_break (0);
1436     return;
1437   }
1438
1439   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
1440                             GNUNET_NO);
1441
1442   
1443   friend = GNUNET_new (struct FriendInfo);
1444   friend->id = *peer_identity;
1445   
1446   GNUNET_assert (GNUNET_OK ==
1447                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
1448                                                     peer_identity, friend,
1449                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1450
1451   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
1452   if (1 == GNUNET_CONTAINER_multipeermap_size (friend_peermap))
1453     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
1454 }
1455
1456
1457 /**
1458  * Method called whenever a peer disconnects.
1459  *
1460  * @param cls closure
1461  * @param peer peer identity this notification is about
1462  */
1463 static void
1464 handle_core_disconnect (void *cls,
1465                         const struct GNUNET_PeerIdentity *peer)
1466 {
1467   struct FriendInfo *remove_friend;
1468   
1469   /* Check for self message. */
1470   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
1471     return;
1472   
1473   /* Search for peer to remove in your friend_peermap. */
1474   remove_friend =
1475       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
1476   
1477   if (NULL == remove_friend)
1478   {
1479     GNUNET_break (0);
1480     return;
1481   }
1482   
1483   /* Remove the friend from friend_peermap. */
1484   GNUNET_assert (GNUNET_YES ==
1485                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
1486                                                        peer,
1487                                                        remove_friend));
1488   
1489   /* If the peer is removed then all the trail which goes through this
1490    peer also becomes invalid. */
1491   /* FIXME: Iterate over finger peermap, get the trail index and find all the
1492    finger whose trail's first peer was this peer. and remove them from finger
1493    peermap. Assumption that in send_find_finger_trail we will eventually reach
1494    to this finger and we will setup up the new trail. 
1495    So, we need a threshold on number of trail thats can go through a node 
1496    so that if that nodes go away then also our system is up and runnning. 
1497    Where can we specify that threshold.*/
1498 }
1499
1500
1501 /**
1502  * To be called on core init/fail.
1503  *
1504  * @param cls service closure
1505  * @param identity the public identity of this peer
1506  */
1507 static void
1508 core_init (void *cls,
1509            const struct GNUNET_PeerIdentity *identity)
1510 {
1511   my_identity = *identity;
1512 }
1513
1514
1515 /**
1516  * Core handler for p2p put requests.
1517  *
1518  * @param cls closure
1519  * @param peer sender of the request
1520  * @param message message
1521  * @param peer peer identity this notification is about
1522  * @return #GNUNET_OK to keep the connection open,
1523  *         #GNUNET_SYSERR to close it (signal serious error)
1524  */
1525 static int
1526 handle_dht_p2p_put (void *cls,
1527                     const struct GNUNET_PeerIdentity *peer,
1528                     const struct GNUNET_MessageHeader *message)
1529 {
1530     /**
1531     1. Check if destination is friend or finger.
1532     2. If finger then get the next hop from routing table and 
1533      * call GDS_NEGIHBOURS_handle_get.
1534     3. If friend then call find_successor to get the next hop and again
1535      * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1536      4. If you are the destination then do datacache_store.
1537      */
1538   return 0;
1539 }
1540
1541
1542 /**
1543  * Core handler for p2p get requests.
1544  *
1545  * @param cls closure
1546  * @param peer sender of the request
1547  * @param message message
1548  * @return #GNUNET_OK to keep the connection open,
1549  *         #GNUNET_SYSERR to close it (signal serious error)
1550  */
1551 static int
1552 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1553                     const struct GNUNET_MessageHeader *message)
1554 {
1555   /**
1556     1. Check if destination is friend or finger.
1557     2. If finger then get the next hop from routing table and 
1558      * call GDS_NEGIHBOURS_handle_get.
1559     3. If friend then call find_successor to get the next hop and again
1560      * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1561      4. If you are the destination then send the data back to source peer
1562    * Assuming we have trail setup we can
1563    * either store the whole trail or again do the search process..
1564      */
1565   return 0;
1566 }
1567
1568 /**
1569  * FIXME: For redundant routing, we may start looking for different
1570  * paths to reach to same finger. So, in send_find_finger, we are starting
1571  * the search for trail to a finger, even if we already have found trail to
1572  * reach to it. There are several reasons for doing so
1573  * 1. We may reach to a closer successor than we have at the moment. So, we
1574  * should keep looking for the successor.
1575  * 2. We may reach to the same successor but through a shorter path.
1576  * 3. As I don't know how keys are distributed and how put/get will react 
1577  * because of this, I have to think further before implementing it. 
1578  * Add an entry in finger table. 
1579  * @param finger Finger to be added to finger table
1580  * @param peer_list peers this request has traversed so far
1581  * @param trail_length Numbers of peers in the trail.
1582  */
1583 static 
1584 void finger_table_add (struct GNUNET_PeerIdentity *finger,
1585                        struct GNUNET_PeerIdentity *peer_list,
1586                        unsigned int trail_length,
1587                        unsigned int successor_flag,
1588                        unsigned int predecessor_flag,
1589                        unsigned int finger_map_index)
1590 {
1591   struct FingerInfo *new_finger_entry;
1592   unsigned int i = 0;
1593  /** SUPU: when we add an entry then we should look if
1594   * we already have an entry for that index. If yes, then
1595   * 1) if both the finger identity are same, and same first friend, then choose
1596   * the one with shorter trail length.
1597   * 2) if the finger identity is different, then keep the one which is closest.*/
1598  
1599   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (finger_peermap, finger))
1600   {
1601     exit(0);
1602 #if 0 
1603     /* Optimization. For the moment we just ignore and do nothing.*/
1604     /* We already have an entry for this finger. */
1605     struct GNUNET_PeerIdentity *first_friend;
1606     struct FingerInfo *exisiting_finger_entry;
1607     
1608     struct TrailPeerList *iterator;
1609     iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1610     exisiting_finger_entry = GNUNET_CONTAINER_multipeermap_get(finger_peermap, finger);
1611     iterator = exisiting_finger_entry->head;
1612     memcpy (first_friend, &(iterator->peer), sizeof(struct GNUNET_PeerIdentity));
1613     
1614     if(0 == GNUNET_CRYPTO_cmp_peer_identity(first_friend, finger))
1615     {
1616       
1617     }
1618 #endif
1619   }
1620   
1621   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1622   memcpy (&(new_finger_entry->finger_identity), finger, sizeof (struct GNUNET_PeerIdentity));
1623  
1624
1625   /* Insert elements of peer_list into TrailPeerList. */
1626   i = 0;
1627   while (i < trail_length)
1628   {
1629     struct TrailPeerList *element;
1630     element = GNUNET_malloc (sizeof (struct TrailPeerList));
1631     element->next = NULL;
1632     element->prev = NULL;
1633     
1634     memcpy (&(element->peer), &peer_list[i], sizeof(struct GNUNET_PeerIdentity));
1635     GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1636     i++;
1637   }
1638   
1639   
1640   new_finger_entry->successor = successor_flag;
1641   new_finger_entry->predecessor = predecessor_flag;
1642   new_finger_entry->finger_map_index = finger_map_index;
1643   new_finger_entry->trail_length = trail_length;
1644   
1645   
1646   GNUNET_assert (GNUNET_OK ==
1647                  GNUNET_CONTAINER_multipeermap_put (finger_peermap,
1648                                                     &(new_finger_entry->finger_identity),
1649                                                     new_finger_entry,
1650                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1651   
1652   /*FIXME: Is it really a good time to call verify successor message. */
1653   if (1 == GNUNET_CONTAINER_multipeermap_size (finger_peermap))
1654   {
1655     verify_successor = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL);
1656   }
1657 }
1658
1659
1660 /**
1661  * FIXME: Also copy the trail list in reverse direction that is the path to
1662  * reach to your predecessor. 
1663  * Replace your predecessor with new predecessor.
1664  * @param predecessor My new predecessor
1665  * @param peer_list Trail list to reach to my new predecessor
1666  * @param trail_length Number of peers in the trail.
1667  */
1668 static void
1669 update_predecessor (struct GNUNET_PeerIdentity *predecessor,
1670                     struct GNUNET_PeerIdentity *peer_list,
1671                     unsigned int trail_length)
1672 {
1673   struct GNUNET_PeerIdentity *trail_peer_list;
1674   struct FingerInfo *new_finger_entry;
1675   struct FingerInfo *finger;
1676   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1677   struct GNUNET_PeerIdentity key_ret;
1678   int finger_index;
1679   int i;
1680   int j;
1681   int flag = 0;
1682   
1683   /* Check if you already have a predecessor. Then remove it and add the new 
1684    entry. */
1685   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1686   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1687   {
1688     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1689                                                                  (const void **)&finger)) 
1690     {
1691       if (1 == finger->predecessor)
1692       { 
1693         flag = 1;
1694         break;
1695       }
1696     }
1697   }
1698   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1699   /* check if you come out of the loop or because of the conditoin*/
1700   if (flag == 0)
1701   {
1702     goto add_new_predecessor;
1703   }
1704   else
1705   {
1706     if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains(finger_peermap, &(finger->finger_identity)))
1707     {
1708       /* compare peer ids of new finger and old finger if they are same don't remove and exit 
1709       if different then remove and exit. */
1710       if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&(finger->finger_identity), predecessor))
1711       {
1712         //goto do_nothing;
1713         exit(0);
1714       }
1715       else
1716       {
1717         if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove(finger_peermap, &(finger->finger_identity), finger))
1718         {
1719           goto add_new_predecessor;
1720         }
1721         else
1722           //goto do_nothing;
1723           exit(0);
1724       }
1725     }
1726   }
1727   
1728   add_new_predecessor:
1729   i = trail_length - 1;
1730   j = 0;
1731   trail_peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * 
1732                                    trail_length);
1733   while (i > 0)
1734   {
1735     memcpy( &trail_peer_list[j], &peer_list[i], sizeof (struct GNUNET_PeerIdentity));
1736     i--;
1737     j++;
1738   }
1739   memcpy (&trail_peer_list[j], &peer_list[i], sizeof(struct GNUNET_PeerIdentity));
1740   
1741   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
1742   memcpy (&(new_finger_entry->finger_identity), predecessor, sizeof (struct GNUNET_PeerIdentity));
1743   new_finger_entry->finger_map_index = 1;
1744   new_finger_entry->predecessor = 1;
1745   new_finger_entry->successor = 0;
1746   new_finger_entry->trail_length = trail_length;
1747   
1748   i = 0;
1749   while (i < trail_length)
1750   {
1751     struct TrailPeerList *element;
1752     element = GNUNET_malloc (sizeof (struct TrailPeerList));
1753     element->next = NULL;
1754     element->prev = NULL;
1755     
1756     memcpy (&(element->peer), &trail_peer_list[i], sizeof(struct GNUNET_PeerIdentity));
1757     GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
1758     i++;
1759   }
1760 }
1761
1762
1763 /**
1764  * Compare two peer identities.
1765  * @param p1 Peer identity
1766  * @param p2 Peer identity
1767  * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. 
1768  */
1769   static int
1770 compare_peer_id (const void *p1, const void *p2)
1771 {
1772   struct Sorting_List *p11;
1773   struct Sorting_List *p22;
1774   int ret;
1775   p11 = GNUNET_malloc (sizeof (struct Sorting_List));
1776   p22 = GNUNET_malloc (sizeof (struct Sorting_List));
1777   p11 = (struct Sorting_List *)p1;
1778   p22 = (struct Sorting_List *)p2;
1779   ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : 
1780           ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
1781   return ret;
1782 }
1783
1784   
1785 /**
1786  * Returns the previous element of value in all_known_peers.
1787  * @param all_known_peers list of all the peers
1788  * @param value value we have to search in the all_known_peers.
1789  * @return 
1790  */
1791 static struct Sorting_List *
1792 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1793               unsigned int size)
1794 {
1795   int first;
1796   int last;
1797   int middle;
1798   
1799   first = 0;
1800   last = size - 1;
1801   middle = (first + last)/2;
1802   
1803   while(first <= last)
1804   {
1805     if(all_known_peers[middle].peer_id < value)
1806     {
1807       first = middle + 1; 
1808     }
1809     else if(all_known_peers[middle].peer_id == value)
1810     {
1811       if(middle == (size -1))
1812       {
1813         return &all_known_peers[0];
1814       }
1815       else
1816       {
1817         return &all_known_peers[middle+1];
1818       }
1819     }
1820     else
1821     {
1822        last = middle - 1;
1823     }
1824   
1825     middle = (first + last)/2;  
1826   }
1827   return NULL;
1828 }
1829
1830
1831 /**
1832  * Find closest successor for the value.
1833  * @param value Value for which we are looking for successor
1834  * @param current_destination NULL if my_identity is successor else finger/friend 
1835  * identity 
1836  * @param type Next destination type
1837  * @return Peer identity of next destination i.e. successor of value. 
1838  */
1839 static struct GNUNET_PeerIdentity *
1840 find_successor(uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1841                enum current_destination_type *type)
1842 {
1843   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
1844   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1845   struct GNUNET_PeerIdentity key_ret;
1846   struct FriendInfo *friend;
1847   struct FingerInfo *finger;
1848   unsigned int finger_index;
1849   unsigned int friend_index;
1850   struct Sorting_List *successor;
1851   unsigned int size;
1852   int j;
1853   
1854   /* 2 is added in size for my_identity and value which will part of all_known_peers. */
1855   size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
1856          GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
1857          2;
1858   
1859   struct Sorting_List all_known_peers[size];
1860   
1861   int k;
1862   for (k = 0; k < size; k++)
1863     all_known_peers[k].peer_id = 0;
1864   
1865   /* Copy your identity at 0th index in all_known_peers. */
1866   j = 0;
1867   memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
1868   all_known_peers[j].type = MY_ID;
1869   all_known_peers[j].data = 0;
1870   j++;
1871   
1872   /* Copy value */
1873   all_known_peers[j].peer_id = value;
1874   all_known_peers[j].type = VALUE;
1875   all_known_peers[j].data = 0;
1876   j++;
1877   
1878   /* Iterate over friend peer map and copy all the elements into array. */
1879   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 
1880   for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
1881   {
1882     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 
1883     {
1884       memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
1885       all_known_peers[j].type = FRIEND;
1886       all_known_peers[j].data = friend;
1887       j++;
1888     }
1889   }
1890   
1891   /* Iterate over finger map and copy all the entries into all_known_peers array. */
1892   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1893   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1894   {
1895     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 
1896     {
1897       memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
1898       all_known_peers[j].type = FINGER;
1899       all_known_peers[j].data = finger;
1900       j++;
1901     }
1902   }
1903   
1904   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1905   GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter);   
1906   
1907   qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
1908   
1909   /* search value in all_known_peers array. */
1910   successor = find_closest_successor (all_known_peers, value, size);
1911  
1912   if (successor->type == MY_ID)
1913   {
1914     *type = MY_ID;
1915     return NULL;
1916   }
1917   else if (successor->type == FRIEND)
1918   {
1919     *type = FRIEND;
1920     struct FriendInfo *target_friend;
1921     target_friend = (struct FriendInfo *)successor->data;
1922     memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
1923     return current_destination;
1924   }
1925   else if (successor->type == FINGER)
1926   {
1927     *type = FINGER;
1928     struct GNUNET_PeerIdentity *next_hop;
1929     struct FingerInfo *finger;
1930     struct TrailPeerList *iterator;
1931     iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
1932     finger = successor->data;
1933     iterator = finger->head->next;
1934     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1935     memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
1936     memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
1937     return next_hop;
1938   }
1939   else
1940   {
1941    type = NULL;
1942    return NULL;
1943   }
1944 }
1945
1946
1947 /**
1948  * SUPU: The first element in the trail setup message is your identity.
1949  * in this function you should increment the trail length. 
1950  * Handle a PeerTrailSetupMessage. 
1951  * @param cls closure
1952  * @param message message
1953  * @param peer peer identity this notification is about
1954  * @return GNUNET_OK on success, GNUNET_SYSERR on error
1955  */
1956 static int
1957 handle_dht_p2p_trail_setup(void *cls, const struct GNUNET_PeerIdentity *peer,
1958                     const struct GNUNET_MessageHeader *message)
1959 {
1960   struct PeerTrailSetupMessage *trail_setup; 
1961   struct GNUNET_PeerIdentity *next_hop; 
1962   struct FriendInfo *target_friend;
1963   size_t msize;
1964   uint32_t trail_length;
1965   enum current_destination_type peer_type;
1966   struct GNUNET_PeerIdentity *trail_peer_list; 
1967   uint32_t current_trail_index;
1968   unsigned int finger_map_index;
1969   struct GNUNET_PeerIdentity *next_peer;
1970   unsigned int successor_flag;
1971   unsigned int predecessor_flag;
1972   uint64_t value;
1973   struct GNUNET_PeerIdentity *current_destination;
1974   current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1975   
1976   /* parse and validate message. */
1977   msize = ntohs (message->size);
1978   if (msize < sizeof (struct PeerTrailSetupMessage))
1979   {
1980     GNUNET_break_op (0);
1981     return GNUNET_YES;
1982   }
1983   
1984   
1985   trail_setup = (struct PeerTrailSetupMessage *) message; 
1986   trail_length = ntohl (trail_setup->trail_length); 
1987   peer_type = ntohl (trail_setup->current_destination_type);
1988   finger_map_index = ntohl (trail_setup->finger_map_index);
1989   successor_flag = ntohl (trail_setup->successor_flag);
1990   predecessor_flag = ntohl (trail_setup->predecessor_flag);
1991   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_setup[1];
1992   value = trail_setup->destination_finger;
1993   
1994   if ((msize <
1995        sizeof (struct PeerTrailSetupMessage) +
1996        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
1997       (trail_length >
1998        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
1999   {
2000     GNUNET_break_op (0);
2001     return GNUNET_YES; 
2002   }
2003
2004   GNUNET_STATISTICS_update (GDS_stats,
2005                             gettext_noop ("# TRAIL SETUP requests received"), 1,
2006                             GNUNET_NO);
2007   GNUNET_STATISTICS_update (GDS_stats,
2008                             gettext_noop ("# TRAIL SETUP bytes received"), msize,
2009                             GNUNET_NO);
2010   
2011   if (peer_type == FRIEND)
2012   {
2013     if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2014                                                &my_identity)))
2015     {
2016       next_hop = find_successor (value,
2017                                  current_destination,
2018                                  &(peer_type));
2019     }
2020     else
2021       return GNUNET_SYSERR; 
2022   }
2023   else if (peer_type == FINGER)
2024   {
2025     if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_setup->current_destination),
2026                                                &my_identity)))
2027     {
2028       next_hop = GDS_ROUTING_search (&(trail_setup->source_peer),
2029                                      &(trail_setup->current_destination));
2030       
2031       #if 0
2032       /* This is an optimization. Uncomment when basic code is running first. */
2033       /* I am part of trail.*/
2034       struct GNUNET_PeerIdentity *next_peer_routing_table;
2035       next_peer_routing_table = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2036       next_peer_routing_table = GDS_ROUTING_search (&(trail_setup->source_peer),
2037                                      &(trail_setup->current_destination));
2038       
2039       struct GNUNET_PeerIdentity *next_peer_find_successor;
2040       next_peer_find_successor = find_successor (&(trail_setup->destination_finger),
2041                                            &(trail_setup->current_destination),
2042                                            &(peer_type));
2043       
2044       next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2045       next_hop = find_closest_destination (next_peer_routing_table, 
2046                                            next_peer_find_successor,
2047                                            &(trail_setup->destination_finger) );
2048       #endif
2049     } 
2050     else
2051     {
2052       /* I am the current_destination finger */
2053       next_hop = find_successor (value,
2054                                  current_destination, &(peer_type)); 
2055     }
2056   }
2057   
2058   /* If you are the next hop, then you are the final destination */
2059   if (peer_type == MY_ID)
2060   {
2061     /*SUPU:
2062      1. You were the destination of this message which means you were already added
2063      in the peer list by previous calling function. 
2064      2. current_trail_index should point to the trail element at which the peer
2065      which receives this message should look for the next peer to forward the packet
2066      to. */
2067     current_trail_index = trail_length - 2;
2068     next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); 
2069     memcpy (next_peer, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2070     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
2071     GNUNET_free (next_peer);
2072     
2073     if(current_trail_index != 0)
2074       current_trail_index = current_trail_index - 1; 
2075     
2076     update_predecessor (&(trail_setup->source_peer), trail_peer_list, trail_length );
2077     GDS_NEIGHBOURS_send_trail_setup_result (&(trail_setup->source_peer),
2078                                               &(my_identity),
2079                                               target_friend, trail_length,
2080                                               trail_peer_list, current_trail_index,
2081                                               successor_flag, 
2082                                               predecessor_flag,
2083                                               finger_map_index);
2084   
2085     return GNUNET_YES;
2086   }
2087   
2088   /* Add next hop to list of peers. */
2089   struct GNUNET_PeerIdentity *peer_list;
2090   peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length + 1));
2091   memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2092   memcpy (&peer_list[trail_length], next_hop, sizeof (struct GNUNET_PeerIdentity));
2093   trail_length++;
2094   
2095   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2096   
2097   if(peer_type == FINGER)
2098   {
2099     GDS_ROUTING_add (&(trail_setup->source_peer), 
2100                      &(trail_setup->current_destination), 
2101                      next_hop);
2102   }
2103   
2104   GDS_NEIGHBOURS_send_trail_setup (&(trail_setup->source_peer),
2105                                      trail_setup->destination_finger,
2106                                      target_friend,
2107                                      trail_setup->trail_length,
2108                                      peer_list,trail_setup->successor_flag,
2109                                      trail_setup->predecessor_flag,
2110                                      finger_map_index);
2111
2112 return GNUNET_YES;
2113 }
2114
2115
2116 /**
2117  * Core handle for p2p trail construction result messages.
2118  * @param cls closure
2119  * @param message message
2120  * @param peer peer identity this notification is about
2121  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2122  */
2123 static int
2124 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2125                     const struct GNUNET_MessageHeader *message)
2126 {
2127   struct PeerTrailSetupResultMessage *trail_result;
2128   size_t msize;
2129   unsigned int trail_length;
2130   struct GNUNET_PeerIdentity *trail_peer_list;
2131   unsigned int current_trail_index;
2132   struct GNUNET_PeerIdentity *next_peer;
2133   struct FriendInfo *target_friend;
2134   unsigned int finger_map_index;
2135   unsigned int successor_flag;
2136   unsigned int predecessor_flag;
2137   
2138   msize = ntohs (message->size);
2139   if (msize < sizeof (struct PeerTrailSetupMessage))
2140   {
2141     GNUNET_break_op (0);
2142     return GNUNET_YES;
2143   }
2144   
2145   trail_result = (struct PeerTrailSetupResultMessage *) message; 
2146   trail_length = ntohl (trail_result->trail_length); 
2147   
2148   if ((msize <
2149        sizeof (struct PeerTrailSetupResultMessage) +
2150        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2151        (trail_length >
2152         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2153   {
2154     GNUNET_break_op (0);
2155     return GNUNET_YES;
2156   }
2157   
2158   current_trail_index = ntohl (trail_result->current_index);
2159   successor_flag = ntohl (trail_result->successor_flag);
2160   predecessor_flag = ntohl (trail_result->predecessor_flag);
2161   finger_map_index = ntohl (trail_result->finger_map_index);
2162   
2163   trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
2164   
2165   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->current_destination),
2166                                              &my_identity)))
2167   {
2168     if ( 0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
2169                                                 &my_identity)))
2170     {
2171       #if 0
2172       /* SUPU: Here I have removed myself from the trail before storing it in
2173        th finger table - to save space, but in case of verify successor result
2174        the result trail does not contain me, and I will never get the message back.
2175        So, keeping myself in the trail list. Think of better solution.*/
2176       struct GNUNET_PeerIdentity *finger_trail;
2177       finger_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * (trail_length - 1));
2178       
2179       /* Copy the whole trail_peer_list except the first element into trail */
2180       unsigned int i;
2181       i = trail_length - 1;
2182       while (i > 0)
2183       {
2184         memcpy (&finger_trail[i], &trail_peer_list[i], sizeof (struct GNUNET_PeerIdentity));
2185         i--;
2186       }
2187       trail_length = trail_length -1 ; SUPU: As you removed yourself from the trail.*/
2188       #endif
2189       
2190       finger_table_add (&(trail_result->finger), trail_peer_list, trail_length, 
2191                         successor_flag, predecessor_flag,
2192                         finger_map_index);
2193       
2194       return GNUNET_YES;
2195     }
2196     else
2197     {
2198       next_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2199       memcpy (next_peer, &(trail_peer_list[current_trail_index]), 
2200               sizeof (struct GNUNET_PeerIdentity));
2201       /* SUPU: here current trail index will always be greater than 0.
2202        so no need for this check here. trail index = 0, contains the final
2203        destination, and if we are in this loop we have not yet reached the
2204        final destination. */
2205       current_trail_index = current_trail_index - 1;
2206       
2207       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_peer);
2208       GNUNET_free (next_peer);
2209       
2210       GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
2211                                                 &(trail_result->finger),
2212                                                 target_friend, trail_length,
2213                                                 trail_peer_list,current_trail_index,
2214                                                 trail_result->successor_flag,
2215                                                 trail_result->predecessor_flag,
2216                                                 finger_map_index);
2217       return GNUNET_YES;
2218     }
2219   }
2220   else
2221     return GNUNET_SYSERR;
2222 }
2223
2224
2225 /**
2226  * SUPU: In this function you don't do anything with trail length
2227  * You increment the current trail index so that you find the correct
2228  * peer to send the packet forward.
2229  * Core handle for p2p verify successor messages.
2230  * @param cls closure
2231  * @param message message
2232  * @param peer peer identity this notification is about
2233  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2234  */
2235 static int
2236 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2237                                 const struct GNUNET_MessageHeader *message)
2238 {
2239   struct PeerVerifySuccessorMessage *vsm;
2240   size_t msize;
2241   unsigned int trail_length;
2242   struct GNUNET_PeerIdentity *trail_peer_list;
2243   unsigned int current_trail_index;
2244   struct FriendInfo *target_friend;
2245   struct GNUNET_PeerIdentity *next_hop;
2246    
2247   msize = ntohs (message->size);
2248   if (msize < sizeof (struct PeerVerifySuccessorMessage))
2249   {
2250     GNUNET_break_op (0);
2251     return GNUNET_YES;
2252   }
2253   
2254   vsm = (struct PeerVerifySuccessorMessage *) message;
2255   trail_length = ntohl (vsm->trail_length);
2256   
2257   if ((msize <
2258        sizeof (struct PeerVerifySuccessorMessage) +
2259        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2260        (trail_length >
2261        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2262        {
2263          GNUNET_break_op (0);
2264          return GNUNET_YES;
2265        }
2266   
2267   current_trail_index = ntohl (vsm->current_trail_index);       
2268   trail_peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
2269   
2270   next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2271   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),
2272                                             &my_identity)))
2273   {
2274     struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2275     struct GNUNET_PeerIdentity key_ret;
2276     unsigned int finger_index;
2277     struct FingerInfo *my_predecessor;
2278     struct GNUNET_PeerIdentity *destination_peer;
2279  
2280     /* Iterate over finger peer map and extract your predecessor. */
2281     finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
2282     for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2283     {
2284       if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next 
2285                        (finger_iter,&key_ret,(const void **)&my_predecessor)) 
2286       {
2287         if(1 == my_predecessor->predecessor)
2288           break; 
2289       }
2290     }
2291     GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2292     
2293     destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2294     memcpy (destination_peer, &(vsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
2295     current_trail_index = trail_length - 2; 
2296     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2297     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2298     GNUNET_free (next_hop);
2299     
2300     if (current_trail_index != 0)
2301     current_trail_index = current_trail_index - 1;
2302     
2303     
2304     if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->source_peer),
2305                                                &(my_predecessor->finger_identity))))
2306     {
2307       struct GNUNET_PeerIdentity *new_successor_trail;
2308       unsigned int new_trail_length;
2309       unsigned int i;
2310       
2311       new_trail_length = trail_length + my_predecessor->trail_length - 1;
2312       new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)
2313                                            * new_trail_length);
2314       
2315       /* Copy the trail from source peer to me. */
2316       memcpy (new_successor_trail, trail_peer_list, 
2317               (trail_length) * sizeof (struct GNUNET_PeerIdentity));
2318       
2319       /* Copy the trail from me to my predecessor excluding me. */
2320       struct TrailPeerList *iterator;
2321       iterator = my_predecessor->head->next; 
2322       i = trail_length;
2323       while (i < new_trail_length)
2324       {
2325         memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2326         iterator = iterator->next;
2327         i++;
2328       }
2329  
2330       GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2331                                                      &(my_identity),
2332                                                      &(my_predecessor->finger_identity),
2333                                                      target_friend,
2334                                                      new_successor_trail,
2335                                                      new_trail_length,
2336                                                      current_trail_index); 
2337     }
2338    
2339     GDS_NEIGHBOURS_send_verify_successor_result (destination_peer,
2340                                                    &(my_identity),
2341                                                    &(my_predecessor->finger_identity),
2342                                                    target_friend,
2343                                                    trail_peer_list,
2344                                                    trail_length,
2345                                                    current_trail_index);      
2346    
2347   }
2348   else
2349   {
2350     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2351     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2352     GNUNET_free (next_hop);
2353     
2354     current_trail_index = current_trail_index + 1; 
2355     
2356     GDS_NEIGHBOURS_send_verify_successor(&(vsm->source_peer),
2357                                            &(vsm->successor),
2358                                            target_friend,
2359                                            trail_peer_list,
2360                                            trail_length,
2361                                            current_trail_index); 
2362   }
2363   return GNUNET_YES;
2364 }
2365
2366
2367 /**
2368  * Update successor field in finger table with new successor.
2369  * @param successor New successor which is the predecessor my old successor.
2370  * @param peer_list Trail list to reach to new successor = trail to reach old
2371  *                  successor + trail to reach to new successor from that old successor. 
2372  * @param trail_length Number of peers to reach to the new successor.
2373  */
2374 static void
2375 update_successor (struct GNUNET_PeerIdentity *successor_identity,
2376                   struct GNUNET_PeerIdentity *peer_list,
2377                   unsigned int trail_length)
2378 {
2379   struct FingerInfo *new_finger_entry;
2380   unsigned int i;
2381   struct FingerInfo *finger;
2382   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2383   struct GNUNET_PeerIdentity key_ret;
2384   int finger_index;
2385   int flag = 0;
2386   
2387   /* Check if you already have a predecessor. Then remove it and add the new 
2388    entry. */
2389   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
2390   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2391   {
2392     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
2393                                                                  (const void **)&finger)) 
2394     {
2395       if (1 == finger->successor)
2396       { 
2397         flag = 1;
2398         break;
2399       }
2400     }
2401   }
2402   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2403   /* check if you come out of the loop or because of the conditoin*/
2404   if (flag == 0)
2405   {
2406     goto add_new_successor;
2407   }
2408   else
2409   {
2410     if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains(finger_peermap, &(finger->finger_identity)))
2411     {
2412       /* compare peer ids of new finger and old finger if they are same don't remove and exit 
2413       if different then remove and exit. */
2414       if ( 0 == GNUNET_CRYPTO_cmp_peer_identity (&(finger->finger_identity), successor_identity))
2415       {
2416         //goto do_nothing;
2417         exit(0);
2418       }
2419       else
2420       {
2421         if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove(finger_peermap, &(finger->finger_identity), finger))
2422         {
2423           goto add_new_successor;
2424         }
2425         else
2426           //goto do_nothing;
2427           exit(0);
2428       }
2429     }
2430   }
2431   
2432   add_new_successor:
2433   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
2434   new_finger_entry->predecessor = 0;
2435   new_finger_entry->successor = 1;
2436   new_finger_entry->trail_length = trail_length;
2437   new_finger_entry->finger_map_index = 0;
2438   memcpy (&(new_finger_entry->finger_identity), successor_identity, sizeof (struct GNUNET_PeerIdentity));
2439   
2440   i = 0;
2441   while (i < trail_length)
2442   {
2443     struct TrailPeerList *element;
2444     element = GNUNET_malloc (sizeof (struct TrailPeerList));
2445     element->next = NULL;
2446     element->prev = NULL;
2447     
2448     memcpy (&(element->peer), &peer_list[i], sizeof(struct GNUNET_PeerIdentity));
2449     GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->head, new_finger_entry->tail, element);
2450     i++;
2451   }
2452 }
2453
2454
2455 /**
2456  * Core handle for p2p notify new successor messages.
2457  * @param cls closure
2458  * @param message message
2459  * @param peer peer identity this notification is about
2460  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2461  */
2462 static int
2463 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
2464                                     const struct GNUNET_MessageHeader *message)
2465 {
2466   struct PeerNotifyNewSuccessorMessage *nsm;
2467   size_t msize;
2468   unsigned int trail_length;
2469   struct GNUNET_PeerIdentity *trail_peer_list;
2470   unsigned int current_trail_index;
2471  
2472   msize = ntohs (message->size);
2473   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
2474   {
2475     GNUNET_break_op (0);
2476     return GNUNET_YES;
2477   }
2478   
2479   nsm = (struct PeerNotifyNewSuccessorMessage *) message;
2480   trail_length = ntohl (nsm->trail_length);
2481   
2482   if ((msize <
2483        sizeof (struct PeerNotifyNewSuccessorMessage) +
2484        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2485        (trail_length >
2486        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2487   {
2488     GNUNET_break_op (0);
2489     return GNUNET_YES;
2490   }
2491   
2492   current_trail_index = ntohl (nsm->current_index);
2493   trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
2494   
2495   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(nsm->destination_peer),
2496                                             &my_identity)))
2497   {
2498     update_predecessor (&(nsm->source_peer),
2499                         trail_peer_list,
2500                         trail_length);
2501     return GNUNET_YES;
2502   }
2503   else
2504   {
2505     struct FriendInfo *target_friend;
2506     target_friend = GNUNET_malloc (sizeof (struct FriendInfo));
2507     struct GNUNET_PeerIdentity *next_hop;
2508     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2509     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2510     
2511     
2512     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2513     GNUNET_free (next_hop);
2514     current_trail_index = current_trail_index + 1;
2515     
2516     GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 
2517                                          &(nsm->destination_peer),
2518                                          target_friend, trail_peer_list, trail_length, 
2519                                          current_trail_index);
2520   }
2521   return GNUNET_YES;
2522 }
2523
2524
2525 /**
2526  * Core handle for p2p verify successor result messages.
2527  * @param cls closure
2528  * @param message message
2529  * @param peer peer identity this notification is about
2530  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2531  */
2532 static int
2533 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
2534                                        const struct GNUNET_MessageHeader *message)
2535 {
2536   struct PeerVerifySuccessorResultMessage *vsrm;
2537   size_t msize;
2538   struct FriendInfo *target_friend;
2539   unsigned int current_trail_index;
2540   struct GNUNET_PeerIdentity *trail_peer_list;
2541   struct GNUNET_PeerIdentity *next_hop;
2542   unsigned int trail_length;
2543   
2544   msize = ntohs (message->size);
2545   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
2546   {
2547     GNUNET_break_op (0);
2548     return GNUNET_YES;
2549   }
2550   
2551   /* Again in the function you have the whole trail to reach to the destination. */
2552   vsrm = (struct PeerVerifySuccessorResultMessage *) message;
2553   current_trail_index = ntohl (vsrm->current_index);
2554   trail_length = ntohl (vsrm->trail_length); 
2555
2556   trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
2557   
2558   if ((msize <
2559        sizeof (struct PeerVerifySuccessorResultMessage) +
2560        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
2561        (trail_length >
2562        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2563   {
2564     GNUNET_break_op (0);
2565     return GNUNET_YES;
2566   }
2567   
2568   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer),
2569                                             &(my_identity))))
2570   {
2571     if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor),
2572                                               &(my_identity))))
2573     {
2574       update_successor (&(vsrm->my_predecessor), trail_peer_list, trail_length);
2575       
2576       next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2577       memcpy (next_hop, &trail_peer_list[1], sizeof (struct GNUNET_PeerIdentity));
2578       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2579       current_trail_index = 2;
2580       GNUNET_free (next_hop);
2581       
2582       GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
2583                                            target_friend, trail_peer_list,
2584                                            trail_length, current_trail_index);
2585     }
2586   }
2587   else
2588   {
2589     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2590     
2591     memcpy (next_hop, &trail_peer_list[current_trail_index], sizeof (struct GNUNET_PeerIdentity));
2592     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2593     GNUNET_free (next_hop);
2594     current_trail_index = current_trail_index - 1;
2595     
2596     GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
2597                                                    &(vsrm->source_successor),
2598                                                    &(vsrm->my_predecessor),
2599                                                    target_friend,
2600                                                    trail_peer_list,
2601                                                    trail_length,
2602                                                    current_trail_index); 
2603   }
2604   return GNUNET_YES;
2605 }
2606
2607
2608 /**
2609  * Initialize neighbours subsystem.
2610  * @return GNUNET_OK on success, GNUNET_SYSERR on error
2611  */
2612 int
2613 GDS_NEIGHBOURS_init()
2614 {
2615   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
2616     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
2617     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
2618     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
2619     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
2620     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
2621     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
2622     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
2623     {NULL, 0, 0}
2624   };
2625
2626
2627   /*TODO: What is ATS? Why do we need it? */
2628   atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL);
2629   core_api =
2630     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
2631                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
2632                          GNUNET_NO, core_handlers);
2633   if (NULL == core_api)
2634     return GNUNET_SYSERR;
2635
2636   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
2637   finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS, GNUNET_NO); 
2638  
2639   return GNUNET_OK;
2640 }
2641
2642
2643 /**
2644  * Shutdown neighbours subsystem.
2645  */
2646 void
2647 GDS_NEIGHBOURS_done ()
2648 {
2649   if (NULL == core_api)
2650     return;
2651   
2652   GNUNET_CORE_disconnect (core_api);
2653   core_api = NULL;
2654   GNUNET_ATS_performance_done (atsAPI);
2655   atsAPI = NULL;
2656
2657   /* FIXME: In case of friends, every time we are disconnected from a friend
2658    we remove it from friend table. So, this assertion works for friend.
2659    But in case of finger_peermap, we never remove any entry from our
2660    finger peermap. So, either when we remove the friend from friend peermap,then
2661    I remove all the finger for which that friend was the first trail and leave
2662    it on send_find_finger_trail to eventually find path to that finger. In that
2663    case may be assertion for finger peermap will also succed. Or else if 
2664    peermap are not empty check it and empty it and then destroy because
2665    multipeermpa_destroy does not free individual entries. */
2666   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
2667   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
2668   friend_peermap = NULL;
2669
2670   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
2671   GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
2672   finger_peermap = NULL;
2673
2674   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
2675   {
2676     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
2677     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
2678   }
2679  
2680   if (GNUNET_SCHEDULER_NO_TASK != verify_successor)
2681   {
2682     GNUNET_SCHEDULER_cancel (verify_successor);
2683     verify_successor = GNUNET_SCHEDULER_NO_TASK;
2684   }
2685   
2686 }
2687
2688
2689 /**
2690  * Get the ID of the local node.
2691  *
2692  * @return identity of the local node
2693  */
2694 struct GNUNET_PeerIdentity *
2695 GDS_NEIGHBOURS_get_id ()
2696 {
2697   return &my_identity;
2698 }
2699
2700
2701 /* end of gnunet-service-xdht_neighbours.c */