- Adding a new message type,GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
[oweals/gnunet.git] / src / dht / gnunet-service-xdht_neighbours.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009-2014 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file dht/gnunet-service-xdht_neighbours.c
23  * @brief GNUnet DHT service's finger and friend table management code
24  * @author Supriti Singh
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_block_lib.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_ats_service.h"
34 #include "gnunet_core_service.h"
35 #include "gnunet_datacache_lib.h"
36 #include "gnunet_transport_service.h"
37 #include "gnunet_dht_service.h"
38 #include "gnunet_statistics_service.h"
39 #include "gnunet-service-xdht.h"
40 #include "gnunet-service-xdht_clients.h"
41 #include "gnunet-service-xdht_datacache.h"
42 #include "gnunet-service-xdht_neighbours.h"
43 #include "gnunet-service-xdht_routing.h"
44 #include <fenv.h>
45 #include "dht.h"
46
47 /* TODO:
48  1. to randomly choose one of the routes in case there are multiple
49     routes to reach to the finger. 
50  2. Structure alignment.
51  3. In put, we don't have anything like put result. so we are not adding anything
52     in the routing table.
53  4. Maintain a list of trails --> struct Trail *all_trails_head
54  * struct Trail *all_trails_tail. How do I keep it as an array and not as a list?? 
55  * First will complete the logic everywhere and then make this change.   
56  5. At some places you use memcpy and at some places =, use uniformly.
57  6. I have removed compare_and_update_predecessor from handle_dht_p2p_Trail_setup
58  * (refer to google docs for reason). 
59 */
60
61 /**
62  * Maximum possible fingers of a peer.
63  */
64 #define MAX_FINGERS 66
65
66 /**
67  * Maximum allowed number of pending messages per friend peer.
68  */
69 #define MAXIMUM_PENDING_PER_FRIEND 64
70
71 /**
72  * How long to wait before sending another find finger trail request
73  */
74 #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
75
76 /**
77  * How long at most to wait for transmission of a request to another peer?
78  */
79 #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
80
81 /**
82  * Maximum number of trails stored per finger.
83  */
84 #define TRAILS_COUNT 2
85
86 /**
87  * Used to distinguish put/get request use of find_successor() from others 
88  */
89 #define PUT_GET_REQUEST 68
90
91 GNUNET_NETWORK_STRUCT_BEGIN
92   
93 /**
94  * P2P PUT message
95  */
96 struct PeerPutMessage
97 {
98   /**
99    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_PUT
100    */
101   struct GNUNET_MessageHeader header;
102
103   /**
104    * Processing options
105    */
106   uint32_t options GNUNET_PACKED;
107
108   /**
109    * Content type.
110    */
111   uint32_t block_type GNUNET_PACKED;
112
113   /**
114    * Hop count
115    */
116   uint32_t hop_count GNUNET_PACKED;
117
118   /**
119    * Replication level for this message
120    * In the current implementation, this value is not used. 
121    */
122   uint32_t desired_replication_level GNUNET_PACKED;
123
124   /**
125    * Length of the PUT path that follows (if tracked).
126    */
127   uint32_t put_path_length GNUNET_PACKED;
128   
129   /** 
130    * Current destination to which this message is forwarded.
131    */
132   struct GNUNET_PeerIdentity current_destination;
133   
134   /**
135    * Peer whose finger is current_destination. 
136    */
137   struct GNUNET_PeerIdentity current_source;
138   
139   /**
140    * When does the content expire?
141    */
142   struct GNUNET_TIME_AbsoluteNBO expiration_time;
143   
144   /**
145    * The key to store the value under.
146    */
147   struct GNUNET_HashCode key GNUNET_PACKED;
148
149   /* put path (if tracked) */
150
151   /* Payload */
152  
153 };
154
155
156 /**
157  * P2P Result message
158  */
159 struct PeerGetResultMessage
160 {
161   /**
162    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
163    */
164   struct GNUNET_MessageHeader header;
165
166   /**
167    * The type for the data.
168    */
169   uint32_t type GNUNET_PACKED;
170   
171   /**
172    * Peer which will receive the get result message. 
173    */
174   struct GNUNET_PeerIdentity source_peer;
175
176   /**
177    * Number of peers recorded in the outgoing path from source to the
178    * stored location of this message.
179    */
180   uint32_t put_path_length GNUNET_PACKED;
181   
182   /**
183    * Length of the GET path that follows (if tracked).
184    */
185   uint32_t get_path_length GNUNET_PACKED;
186
187   /**
188    * When does the content expire?
189    */
190   struct GNUNET_TIME_Absolute expiration_time;
191
192   /**
193    * The key of the corresponding GET request.
194    */
195   struct GNUNET_HashCode key;
196  
197   /* put path (if tracked) */
198
199   /* get path (if tracked) */
200
201   /* Payload */
202
203 };
204
205
206 /**
207  * P2P GET message
208  */
209 struct PeerGetMessage
210 {
211   /**
212    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
213    */
214   struct GNUNET_MessageHeader header;
215   
216   /**
217    * Processing options
218    */
219   uint32_t options GNUNET_PACKED;
220
221   /**
222    * Desired content type.
223    */
224   uint32_t block_type GNUNET_PACKED;
225   
226   /**
227    * Hop count
228    */
229   uint32_t hop_count GNUNET_PACKED;
230  
231   /**
232    * Desired replication level for this request.
233    * In the current implementation, this value is not used. 
234    */
235   uint32_t desired_replication_level GNUNET_PACKED;
236   
237   /**
238    * Total number of peers in get path. 
239    */
240   unsigned int get_path_length;
241   
242   /**
243    * Peer which is an intermediate destination. 
244    */
245   struct GNUNET_PeerIdentity current_destination;
246   
247   /**
248    * Source for which current_destination is the finger. 
249    */
250   struct GNUNET_PeerIdentity current_source;
251  
252   /**
253    * The key we are looking for.
254    */
255   struct GNUNET_HashCode key;
256   
257   /* Get path. */
258
259 };
260
261
262 /**
263  * P2P Trail setup message
264  */
265 struct PeerTrailSetupMessage
266 {
267   
268   /**
269    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP
270    */
271   struct GNUNET_MessageHeader header;
272   
273   /**
274    * Successor of this finger value will be our finger peer.
275    */
276   uint64_t destination_finger;
277
278   /**
279    * Source peer which wants to setup the trail to one of its finger. 
280    */
281   struct GNUNET_PeerIdentity source_peer;
282   
283   /**
284    * Peer to which this packet is forwarded.
285    */
286   struct GNUNET_PeerIdentity current_destination;
287   
288   /**
289    * In case the packet is forwarded to an intermediate finger, then 
290    * current_source contains the peer id whose finger is the intermediate
291    * finger. In case the packet is forwarded to a friend, then it is NULL.
292    * FIXME: check the usage of current_source and fix this comment. 
293    */
294   struct GNUNET_PeerIdentity current_source;
295   
296   /**
297    * Index into finger peer map, in Network Byte Order. 
298    */
299   uint32_t finger_map_index;
300   
301   /**
302    * Number of entries in trail list, in Network Byte Order.
303    */
304   uint32_t trail_length GNUNET_PACKED;
305   
306   /* Trail formed in the process. */
307 };
308
309
310 /**
311  * P2P Trail Setup Result message
312  */
313 struct PeerTrailSetupResultMessage
314 {
315   
316   /**
317    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT
318    */
319   struct GNUNET_MessageHeader header;
320   
321   /**
322    * Finger to which we have found the path. 
323    */
324   struct GNUNET_PeerIdentity finger_identity;
325
326   /**
327    * Peer which was looking for the trail to finger. 
328    */
329   struct GNUNET_PeerIdentity destination_peer;
330   
331   /**
332    * Index into finger peer map in NBO.
333    */
334   uint32_t finger_map_index;
335   
336   /**
337    * Number of entries in trail list in NBO.
338    */
339   uint32_t trail_length GNUNET_PACKED;
340   
341   /* Trail from destination_peer to finger_identity */
342   
343 };
344
345
346 /**
347  * P2P Trail Rejection Message. 
348  */
349 struct PeerTrailRejectionMessage
350 {
351   /**
352    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION
353    */
354   struct GNUNET_MessageHeader header;
355   
356   /**
357    * Source peer which wants to set up the trail. 
358    */
359   struct GNUNET_PeerIdentity source_peer;
360   
361   /**
362    * Peer which sent trail rejection message. 
363    */
364   struct GNUNET_PeerIdentity congested_peer;
365   
366   /**
367    * Peer identity which will be successor to this value will be finger of
368    * source_peer. 
369    */
370   uint64_t finger_identity_value;
371   
372   /**
373    * Index in finger peer map of source peer.
374    */
375   uint32_t finger_map_index;
376   
377   /**
378    * Total number of peers in the trail.
379    */
380   uint32_t trail_length;
381   
382   /* Trail_list from source_peer to peer which sent the message for trail setup
383    * to congested peer.*/
384 };
385
386
387 /**
388  * P2P Verify Successor message. 
389  */
390 struct PeerVerifySuccessorMessage
391 {
392   
393   /**
394    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR
395    */
396   struct GNUNET_MessageHeader header;
397   
398   /**
399    * Source peer which wants to verify its successor. 
400    */
401   struct GNUNET_PeerIdentity source_peer;
402   
403   /**
404    * My current successor.
405    */
406   struct GNUNET_PeerIdentity successor;
407   
408   /**
409    * Total number of peers in trail to current successor.
410    */
411   uint32_t trail_length;
412   
413   /* Trail to reach to from source_peer to successor. */
414 };
415
416
417 /**
418  * P2P Verify Successor Result message. 
419  */
420 struct PeerVerifySuccessorResultMessage
421 {
422   
423   /**
424    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT
425    */
426   struct GNUNET_MessageHeader header;
427   
428   /**
429    * Destination peer which sent the request to verify its successor. 
430    */
431   struct GNUNET_PeerIdentity destination_peer;
432   
433   /**
434    * Successor to which PeerVerifySuccessorMessage was sent.
435    */
436   struct GNUNET_PeerIdentity source_successor;
437   
438   /**
439    * source_successor's predecessor
440    */
441   struct GNUNET_PeerIdentity my_predecessor;
442   
443   /**
444    * Total number of peers in trail.
445    */
446   uint32_t trail_length; 
447   
448   /* Trail to reach from destination_peer to its correct successor.
449    * If source_successor is not destination peer, then trail is from destination_peer
450    * to my_predecessor.
451    * If source_successor is destination peer, then trail is from destination_peer
452    * to source_successor. */
453 };
454
455
456 /**
457  * P2P Notify New Successor message.
458  */
459 struct PeerNotifyNewSuccessorMessage
460 {
461   /**
462    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR
463    */
464   struct GNUNET_MessageHeader header;
465   
466   /**
467    * Source peer which wants to notify its new successor. 
468    */
469   struct GNUNET_PeerIdentity source_peer;
470   
471   /** 
472    * Old successor of source peer. 
473    */
474   struct GNUNET_PeerIdentity old_successor;
475   
476   /**
477    * New successor identity.
478    */
479   struct GNUNET_PeerIdentity destination_peer;
480   
481   /**
482    * Number of peers in trail from source_peer to new successor.
483    */
484   uint32_t trail_length;
485   
486   /* Trail to from source_peer to destination_peer. */
487 };
488
489 struct PeerTrailTearDownMessage
490 {
491   /**
492    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN
493    */
494   struct GNUNET_MessageHeader header;
495   
496   /**
497    * Source peer of this trail.  
498    */
499   struct GNUNET_PeerIdentity source_peer;
500   
501   /**
502    * Destination peer of this trail. 
503    */
504   struct GNUNET_PeerIdentity destination_peer;
505   
506   /**
507    * Trail from source_peer to destination_peer compressed such that 
508    * new_first_friend is the first hop in the trail from source to 
509    * destination. 
510    */
511   struct GNUNET_PeerIdentity new_first_friend;
512   /**
513    * Number of peers in trail from source_peer to new first friend.
514    */
515   uint32_t trail_length;
516   
517   /* Trail from source_peer to new first friend. */
518 };
519
520
521 struct PeerAddTrailMessage
522 {
523   /**
524    * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL
525    */
526   struct GNUNET_MessageHeader header;
527   
528   /**
529    * Source peer of the routing trail. 
530    */
531   struct GNUNET_PeerIdentity source_peer;
532   
533   /**
534    * Destination peer of the routing trail. 
535    */
536   struct GNUNET_PeerIdentity destination_peer;
537   
538   /**
539    * Total number of peers from source peer to destination peer. 
540    */
541   unsigned int trail_length;
542   
543   /* Trail from source peer to destination peer. */
544   
545 };
546
547 GNUNET_NETWORK_STRUCT_END
548
549
550 /**
551  * Linked list of messages to send to a particular other peer.
552  */
553 struct P2PPendingMessage
554 {
555   /**
556    * Pointer to next item in the list
557    */
558   struct P2PPendingMessage *next;
559
560   /**
561    * Pointer to previous item in the list
562    */
563   struct P2PPendingMessage *prev;
564
565   /**
566    * Message importance level.  FIXME: used? useful?
567    */
568   unsigned int importance;
569   
570   /**
571    * When does this message time out?
572    */
573   struct GNUNET_TIME_Absolute timeout;
574   
575   /**
576    * Actual message to be sent, allocated at the end of the struct:
577    * // msg = (cast) &pm[1];
578    * // memcpy (&pm[1], data, len);
579    */
580   const struct GNUNET_MessageHeader *msg;
581
582 };
583
584
585 /**
586  * Linked List of peers which are part of trail to reach a particular Finger.
587  */
588 struct TrailPeerList
589 {
590    /**
591     * Pointer to next item in the list
592     */
593    struct TrailPeerList *next;
594
595    /**
596     * Pointer to previous item in the list
597     */
598    struct TrailPeerList *prev;
599    
600    /**
601     * An element in this trail list
602     */
603    struct GNUNET_PeerIdentity peer;
604   
605 };
606
607
608 /** 
609  * FIXME: for congested peer just define a relative time as #define.
610  *  Entry in friend_peermap.
611  */
612 struct FriendInfo
613 {
614   /**
615    * Friend Identity 
616    */
617   struct GNUNET_PeerIdentity id;
618
619   /**
620    * Number of trails for which this friend is the first hop. 
621    */
622   unsigned int trails_count;
623   
624   /**
625    * Count of outstanding messages for this friend.
626    */
627   unsigned int pending_count;
628   
629   /**
630    * FIXME: Refer to time.c and gnunet_time_lib.h for correct functions.
631    * in handle_dht_p2p_trail_rejection, you should update these values
632    * and whenever you are selecting a friend in select_random_friend()
633    * and find_successor(), you should check congestion_duration = 0,
634    * then proceed else if congestion_duration < your current time then also
635    * proceed. 
636    *        struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
637    *        struct GNUNET_TIME_Relative congestion_timeout =  
638    * congestion_duration = GNUNET_TIME_absolute_add (start,congestion_timeout);
639    * in select_random_friend, GNUNET_TIME_absolute_get_remaning()
640    */
641   struct GNUNET_TIME_Absolute congestion_duration;
642   
643   /**
644    * Head of pending messages to be sent to this friend.
645    */
646   struct P2PPendingMessage *head;
647
648   /**
649    * Tail of pending messages to be sent to this friend.
650    */
651   struct P2PPendingMessage *tail;
652  
653   /**
654    * Core handle for sending messages to this friend.
655    */
656   struct GNUNET_CORE_TransmitHandle *th;
657
658 };
659
660
661 /**
662  * FIXME: make an array of trails. #define number of entries in the array = 
663  * number of trails we want to keep. Remove head, tail of trails.
664  * Entry in finger_peermap.
665  */
666 struct FingerInfo
667 {
668   /**
669    * Finger identity.
670    */
671   struct GNUNET_PeerIdentity finger_identity;
672   
673   /**
674    * Index in finger peer map
675    */
676   unsigned int finger_map_index;
677   
678   /**
679    * Number of trails to reach to this finger.
680    */
681   unsigned int trail_count;
682   
683   /**
684    * Total number of entries in first trail from (me,finger)
685    */
686   unsigned int first_trail_length;
687   
688   /**
689    * Total number of entries in second trail from (me,finger)
690    */
691   unsigned int second_trail_length;
692   
693   
694   /**
695    * Number of trail of which the first element to reach to this finger is
696    * part of. 
697    */
698   unsigned int first_friend_trails_count;
699   
700   /**
701    * Head of first trail to reach this finger.
702    */
703   struct TrailPeerList *first_trail_head;
704   
705   /**
706    * Tail of first trail to reach this finger.
707    */
708   struct TrailPeerList *first_trail_tail;
709   
710   /**
711    * Head of second trail to reach this finger.
712    */
713   struct TrailPeerList *second_trail_head;
714   
715   /**
716    * Tail of second trail to reach this finger.
717    */
718   struct TrailPeerList *second_trail_tail;
719   
720 };
721
722
723 /**
724  * FIXME: The name is not correct. 
725  * Used to specify the kind of value stored in the array all_known_peers. 
726  */
727 enum current_destination_type
728 {
729   FRIEND,
730   FINGER,
731   VALUE,
732   MY_ID
733 };
734
735
736 /**
737  * Data structure passed to sorting algorithm in find_successor().
738  */
739 struct Sorting_List
740 {
741   /**
742    * 64 bit value of peer identity
743    */
744   uint64_t peer_id;
745   
746   /**
747    * FIXME: think of a better name for both the struct and destination_type
748    * Type : MY_ID, FINGER, FINGER, Value 
749    */
750   enum current_destination_type type;
751   
752   /**
753    * Pointer to original data structure linked to peer id.
754    */
755   void *data;
756 };
757
758
759 /**
760  * Task that sends FIND FINGER TRAIL requests. This task is started when we have
761  * get our first friend. 
762  */
763 static GNUNET_SCHEDULER_TaskIdentifier find_finger_trail_task;
764
765 /**
766  * Identity of this peer.
767  */
768 static struct GNUNET_PeerIdentity my_identity;
769
770 /**
771  * Hash map of all the friends of a peer
772  */
773 static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap;
774
775 /**
776  * Hash map of all the fingers of a peer
777  */
778 static struct GNUNET_CONTAINER_MultiPeerMap *finger_peermap;
779
780 /**
781  * Handle to CORE.
782  */
783 static struct GNUNET_CORE_Handle *core_api;
784
785 /**
786  * Finger map index for predecessor entry in finger peermap. 
787  */
788 #define PREDECESSOR_FINGER_ID 64
789
790 /**
791  * Maximum number of trails allowed to go through a friend.
792  * FIXME: Better name, Random value at the moment, need to be adjusted to maintain a balance
793  * between performance and Sybil tolerance. 
794  */
795 #define TRAIL_THROUGH_FRIEND_THRESHOLD 64
796
797 /**
798  * Possible number of different trails to reach to a finger. (Redundant routing) 
799  */
800 #define TRAIL_COUNT 2
801
802 /**
803  * The current finger index that we have want to find trail to.
804  */
805 static unsigned int current_search_finger_index;
806
807
808 /**
809  * Iterate over trail and search your index location in the array. 
810  * @param trail Trail which contains list of peers.
811  * @param trail_length Number of peers in the trail.
812  * @return Index in the array.
813  *         #GNUNET_SYSERR, in case there is no entry which should not be the case ideally. 
814  */
815 static int
816 search_my_index (const struct GNUNET_PeerIdentity *trail,
817                 int trail_length)
818 {
819   int i = 0;
820   
821   while (i < trail_length)
822   {
823     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i]))
824     {
825       return i;
826     }
827     i++;
828   }
829   return GNUNET_SYSERR;
830 }
831
832 /**
833  * Compare two peer identities.
834  * @param p1 Peer identity
835  * @param p2 Peer identity
836  * @return 1 if p1 > p2, -1 if p1 < p2 and 0 if p1 == p2. 
837  */
838 static int
839 compare_peer_id (const void *p1, const void *p2)
840 {
841   struct Sorting_List *p11;
842   struct Sorting_List *p22;
843   int ret;
844   p11 = GNUNET_malloc (sizeof (struct Sorting_List));
845   p22 = GNUNET_malloc (sizeof (struct Sorting_List));
846   p11 = (struct Sorting_List *)p1;
847   p22 = (struct Sorting_List *)p2;
848   ret = ( (p11->peer_id) > (p22->peer_id) ) ? 1 : 
849           ( (p11->peer_id) == (p22->peer_id) ) ? 0 : -1;
850   return ret;
851 }
852
853
854 /**
855  * Return the predecessor of value in all_known_peers.
856  * @param all_known_peers list of all the peers
857  * @param value value we have to search in the all_known_peers.
858  * @param size Total numbers of elements
859  * @return Predecessor
860  */
861 static struct Sorting_List *
862 find_closest_predecessor(struct Sorting_List *all_known_peers, uint64_t value,
863                          unsigned int size)
864 {
865   int first;
866   int last;
867   int middle;
868   
869   first = 0;
870   last = size - 1;
871   middle = (first + last)/2;
872   
873   while(first <= last)
874   {
875     if(all_known_peers[middle].peer_id < value)
876     {
877       first = middle + 1; 
878     }
879     else if(all_known_peers[middle].peer_id == value)
880     {
881       if(middle == 0)
882       {
883         return &all_known_peers[size - 1];
884       }
885       else
886       {
887         return &all_known_peers[middle - 1];
888       }
889     }
890     else
891     {
892        last = middle - 1;
893     }
894   
895     middle = (first + last)/2;  
896   }
897   return NULL;
898 }
899
900
901 /**
902  * Return the successor of value in all_known_peers.
903  * @param all_known_peers list of all the peers
904  * @param value value we have to search in the all_known_peers.
905  * @param size Total numbers of elements
906  * @return Successor
907  */
908 static struct Sorting_List *
909 find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
910                        unsigned int size)
911 {
912   int first;
913   int last;
914   int middle;
915   
916   first = 0;
917   last = size - 1;
918   middle = (first + last)/2;
919   
920   while(first <= last)
921   {
922     if(all_known_peers[middle].peer_id < value)
923     {
924       first = middle + 1; 
925     }
926     else if(all_known_peers[middle].peer_id == value)
927     {
928       if(middle == (size -1))
929       {
930         return &all_known_peers[0];
931       }
932       else
933       {
934         return &all_known_peers[middle+1];
935       }
936     }
937     else
938     {
939        last = middle - 1;
940     }
941   
942     middle = (first + last)/2;  
943   }
944   return NULL;
945 }
946
947
948 /**
949  * Called when core is ready to send a message we asked for
950  * out to the destination.
951  *
952  * @param cls the 'struct FriendInfo' of the target friend
953  * @param size number of bytes available in buf
954  * @param buf where the callee should write the message
955  * @return number of bytes written to buf
956  */
957 static size_t
958 core_transmit_notify (void *cls, size_t size, void *buf)
959 {
960   struct FriendInfo *peer = cls;
961   char *cbuf = buf;
962   struct P2PPendingMessage *pending;
963   size_t off;
964   size_t msize;
965   
966   peer->th = NULL;
967   while ((NULL != (pending = peer->head)) &&
968          (0 == GNUNET_TIME_absolute_get_remaining (pending->timeout).rel_value_us))
969   {
970     peer->pending_count--;
971     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);  
972     GNUNET_free (pending);
973   }
974   if (NULL == pending)
975   {
976     /* no messages pending */
977     return 0;
978   }
979   if (NULL == buf)
980   {
981     peer->th =
982         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
983                                            GNUNET_CORE_PRIO_BEST_EFFORT,
984                                            GNUNET_TIME_absolute_get_remaining
985                                            (pending->timeout), &peer->id,
986                                            ntohs (pending->msg->size),
987                                            &core_transmit_notify, peer);
988     GNUNET_break (NULL != peer->th);
989     return 0;
990   }
991   off = 0;
992   while ((NULL != (pending = peer->head)) &&
993          (size - off >= (msize = ntohs (pending->msg->size))))
994   {
995     GNUNET_STATISTICS_update (GDS_stats,
996                               gettext_noop
997                               ("# Bytes transmitted to other peers"), msize,
998                               GNUNET_NO);
999     memcpy (&cbuf[off], pending->msg, msize);
1000     off += msize;
1001     peer->pending_count--;
1002     GNUNET_CONTAINER_DLL_remove (peer->head, peer->tail, pending);
1003     GNUNET_free (pending);
1004   }
1005   if (peer->head != NULL)
1006   {
1007     peer->th =
1008         GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
1009                                            GNUNET_CORE_PRIO_BEST_EFFORT,
1010                                            GNUNET_TIME_absolute_get_remaining
1011                                            (pending->timeout), &peer->id, msize,
1012                                            &core_transmit_notify, peer);
1013     GNUNET_break (NULL != peer->th);
1014   }
1015  
1016   return off;
1017 }
1018
1019
1020 /**
1021  * Transmit all messages in the friend's message queue.
1022  *
1023  * @param peer message queue to process
1024  */
1025 static void
1026 process_friend_queue (struct FriendInfo *peer)
1027 {
1028   struct P2PPendingMessage *pending;
1029   
1030   if (NULL == (pending = peer->head))
1031     return;
1032   if (NULL != peer->th)
1033     return;
1034   
1035   GNUNET_STATISTICS_update (GDS_stats,
1036                             gettext_noop
1037                             ("# Bytes of bandwidth requested from core"),
1038                             ntohs (pending->msg->size), GNUNET_NO);
1039   
1040   /* FIXME: Are we correctly initializing importance and pending. */
1041   peer->th =
1042       GNUNET_CORE_notify_transmit_ready (core_api, GNUNET_NO,
1043                                          pending->importance,
1044                                          GNUNET_TIME_absolute_get_remaining
1045                                          (pending->timeout), &peer->id,
1046                                          ntohs (pending->msg->size),
1047                                          &core_transmit_notify, peer);
1048   GNUNET_break (NULL != peer->th);
1049 }
1050
1051
1052 /**
1053  * Construct a trail setup message and forward it to a friend. 
1054  * @param source_peer Peer which wants to set up the trail to one of its finger.
1055  * @param destination_finger Peer identity closest to this value will be 
1056  *                           @a source_peer's finger.
1057  * @param current_destination next destination corresponding to @a current_source,
1058  *                            can be either a finger or a friend of @a current_source. 
1059  * @param current_source Peer for which @a current_destination is its finger/friend.
1060  * @param target_friend Friend to which this message should be forwarded.
1061  * @param trail_length Numbers of peers in the trail found so far.
1062  * @param trail_peer_list Peers this request has traversed so far  
1063  * @param finger_map_index Index in finger peer map
1064  */
1065 void
1066 GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer,
1067                                  uint64_t destination_finger,
1068                                  struct GNUNET_PeerIdentity *current_destination,
1069                                  struct GNUNET_PeerIdentity *current_source,
1070                                  struct FriendInfo *target_friend,
1071                                  unsigned int trail_length,
1072                                  const struct GNUNET_PeerIdentity *trail_peer_list,
1073                                  unsigned int finger_map_index)
1074 {
1075   struct P2PPendingMessage *pending;
1076   struct PeerTrailSetupMessage *tsm;
1077   struct GNUNET_PeerIdentity *peer_list;
1078   size_t msize;
1079   
1080   msize = sizeof (struct PeerTrailSetupMessage) + 
1081           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1082   
1083   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1084   {
1085     GNUNET_break (0);
1086     return;
1087   }
1088   
1089   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1090   {  
1091     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1092                                 1, GNUNET_NO);
1093   }
1094   
1095   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1096   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1097   tsm = (struct PeerTrailSetupMessage *) &pending[1]; 
1098   pending->msg = &tsm->header;
1099   tsm->header.size = htons (msize);
1100   tsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
1101   memcpy (&(tsm->destination_finger), &destination_finger, sizeof (uint64_t));
1102   memcpy (&(tsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1103   memcpy (&(tsm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1104   memcpy (&(tsm->current_source), current_source, sizeof (struct GNUNET_PeerIdentity));
1105   tsm->trail_length = htonl (trail_length); 
1106   tsm->finger_map_index = htonl (finger_map_index);
1107   
1108   if (trail_length > 0)
1109   {
1110     peer_list = (struct GNUNET_PeerIdentity *) &tsm[1];
1111     memcpy (peer_list, trail_peer_list, trail_length * sizeof(struct GNUNET_PeerIdentity));
1112   }
1113
1114   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1115   target_friend->pending_count++;
1116   process_friend_queue (target_friend);
1117 }
1118
1119
1120 /**
1121  * Construct a trail setup result message and forward it to a friend. 
1122  * @param destination_peer Peer which will get the trail to one of its finger.
1123  * @param source_finger Peer to which the trail has been setup to.
1124  * @param target_friend Friend to which this message should be forwarded.
1125  * @param trail_length Numbers of peers in the trail.
1126  * @param trail_peer_list Peers which are part of the trail from source to destination.
1127  * @param finger_map_index Index in finger peer map 
1128  */
1129 void
1130 GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *destination_peer,
1131                                         const struct GNUNET_PeerIdentity *source_finger,
1132                                         struct FriendInfo *target_friend,
1133                                         unsigned int trail_length,
1134                                         const struct GNUNET_PeerIdentity *trail_peer_list,
1135                                         unsigned int finger_map_index)
1136 {
1137   struct P2PPendingMessage *pending;
1138   struct PeerTrailSetupResultMessage *tsrm;
1139   struct GNUNET_PeerIdentity *peer_list;
1140   size_t msize;
1141   
1142   msize = sizeof (struct PeerTrailSetupResultMessage) + 
1143           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1144   
1145   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1146   {
1147     GNUNET_break (0);
1148     return;
1149   }
1150   
1151   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1152   {  
1153     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1154                                 1, GNUNET_NO);
1155   }
1156   
1157   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1158   pending->importance = 0;    
1159   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1160   tsrm = (struct PeerTrailSetupResultMessage *) &pending[1]; 
1161   pending->msg = &tsrm->header;
1162   tsrm->header.size = htons (msize);
1163   tsrm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT);
1164   memcpy (&(tsrm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1165   memcpy (&(tsrm->finger_identity), source_finger, sizeof (struct GNUNET_PeerIdentity));
1166   tsrm->trail_length = htonl (trail_length);
1167   tsrm->finger_map_index = htonl (finger_map_index);
1168  
1169   peer_list = (struct GNUNET_PeerIdentity *) &tsrm[1];
1170   if (trail_length > 0)
1171   {
1172     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1173   }
1174   /* Send the message to chosen friend. */
1175   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1176   target_friend->pending_count++;
1177   process_friend_queue (target_friend);
1178 }
1179
1180
1181 /**
1182  * Construct a PeerVerifySuccessor message and send it to friend.
1183  * @param source_peer Peer which wants to verify its successor
1184  * @param successor Peer which is our current successor
1185  * @param target_friend Friend to which this message should be forwarded.
1186  * @param trail_peer_list Peer which are part of trail from source to destination
1187  * @param trail_length Number of peers in the trail list.
1188  */
1189 void GDS_NEIGHBOURS_send_verify_successor(const struct GNUNET_PeerIdentity *source_peer,
1190                                           const struct GNUNET_PeerIdentity *successor,
1191                                           struct FriendInfo *target_friend,
1192                                           const struct GNUNET_PeerIdentity *trail_peer_list,
1193                                           unsigned int trail_length)
1194 {
1195   struct PeerVerifySuccessorMessage *vsm;
1196   struct P2PPendingMessage *pending;
1197   struct GNUNET_PeerIdentity *peer_list;
1198   size_t msize;
1199   
1200   msize = sizeof (struct PeerVerifySuccessorMessage) + 
1201           (trail_length * sizeof (struct GNUNET_PeerIdentity));
1202   
1203   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1204   {
1205     GNUNET_break (0);
1206     return;
1207   }
1208  
1209   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1210   {  
1211     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1212                                 1, GNUNET_NO);
1213   }
1214   
1215   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1216   pending->importance = 0;    /* FIXME */
1217   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1218   vsm = (struct PeerVerifySuccessorMessage *) &pending[1];
1219   pending->msg = &vsm->header;
1220   vsm->header.size = htons (msize);
1221   vsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR);
1222   memcpy (&(vsm->successor), successor, sizeof (struct GNUNET_PeerIdentity));
1223   memcpy (&(vsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1224   vsm->trail_length = htonl (trail_length);
1225   
1226   if (trail_length > 0)
1227   {
1228     peer_list = (struct GNUNET_PeerIdentity *) &vsm[1];
1229     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1230   }
1231   
1232   /* Send the message to chosen friend. */
1233   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1234   target_friend->pending_count++;
1235   process_friend_queue (target_friend);
1236   
1237 }
1238
1239
1240 /**
1241  * Construct a PeerVerifySuccessorResult message and send it to friend.
1242  * @param destination_peer Peer which sent verify successor message
1243  * @param source_successor Peer to which verify successor message was sent.
1244  * @param my_predecessor source_successor's predecessor.
1245  * @param target_friend Friend to which this message should be forwarded.
1246  * @param trail_peer_list Peers which are part of trail from source to destination
1247  * @param trail_length Number of peers in the trail list.
1248  */
1249 void GDS_NEIGHBOURS_send_verify_successor_result (const struct GNUNET_PeerIdentity *destination_peer,
1250                                                   const struct GNUNET_PeerIdentity *source_successor,
1251                                                   const struct GNUNET_PeerIdentity *my_predecessor,
1252                                                   struct FriendInfo *target_friend,
1253                                                   const struct GNUNET_PeerIdentity *trail_peer_list,
1254                                                   unsigned int trail_length)
1255 {
1256   struct PeerVerifySuccessorResultMessage *vsmr;
1257   struct P2PPendingMessage *pending;
1258   struct GNUNET_PeerIdentity *peer_list;
1259   size_t msize;
1260   
1261   msize = sizeof (struct PeerVerifySuccessorResultMessage) + 
1262           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1263   
1264   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1265   {
1266     GNUNET_break (0);
1267     return;
1268   }
1269   
1270   
1271   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1272   {  
1273     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1274                                 1, GNUNET_NO);
1275   }
1276
1277   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1278   pending->importance = 0;    /* FIXME */
1279   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1280   vsmr = (struct PeerVerifySuccessorResultMessage *) &pending[1];
1281   pending->msg = &vsmr->header;
1282   vsmr->header.size = htons (msize);
1283   vsmr->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT);
1284   memcpy (&(vsmr->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1285   memcpy (&(vsmr->source_successor), source_successor, sizeof (struct GNUNET_PeerIdentity));
1286   memcpy (&(vsmr->my_predecessor), my_predecessor, sizeof (struct GNUNET_PeerIdentity));
1287   vsmr->trail_length = htonl (trail_length);  
1288   if (trail_length > 0)
1289   {
1290     peer_list = (struct GNUNET_PeerIdentity *) &vsmr[1];
1291     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1292   }
1293   
1294    /* Send the message to chosen friend. */
1295   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1296   target_friend->pending_count++;
1297   process_friend_queue (target_friend);
1298 }
1299
1300
1301 /**
1302  * Construct a PeerNotifyNewSuccessor message and send it to friend.
1303  * @param source_peer Peer which is sending notify message to its new successor.
1304  * @param destination_peer Peer which is the new destination.
1305  * @param target_friend Next friend to pass this message to. 
1306  * @param peer_list List of peers in the trail to reach to destination_peer.
1307  * @param trail_length Total number of peers in peer list 
1308  */
1309 void 
1310 GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *source_peer,
1311                                           const struct GNUNET_PeerIdentity *destination_peer,
1312                                           const struct GNUNET_PeerIdentity *old_successor,
1313                                           struct FriendInfo *target_friend,
1314                                           const struct GNUNET_PeerIdentity *trail_peer_list,
1315                                           unsigned int trail_length)
1316 {
1317   struct PeerNotifyNewSuccessorMessage *nsm;
1318   struct P2PPendingMessage *pending;
1319   struct GNUNET_PeerIdentity *peer_list;
1320   size_t msize;
1321   
1322   msize = sizeof (struct PeerNotifyNewSuccessorMessage) + 
1323           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1324   
1325   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1326   {
1327     GNUNET_break (0);
1328     return;
1329   }
1330   
1331   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1332   {  
1333     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1334                                 1, GNUNET_NO);
1335   }
1336   
1337   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1338   pending->importance = 0;    /* FIXME */
1339   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1340   nsm = (struct PeerNotifyNewSuccessorMessage *) &pending[1];
1341   pending->msg = &nsm->header;
1342   nsm->header.size = htons (msize);
1343   nsm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR);
1344   memcpy (&(nsm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1345   memcpy (&(nsm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1346   memcpy (&(nsm->old_successor), old_successor, sizeof (struct GNUNET_PeerIdentity));
1347   nsm->trail_length = htonl (trail_length);
1348
1349   if (trail_length > 0)
1350   {
1351     peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
1352     memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
1353   }
1354    /* Send the message to chosen friend. */
1355   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1356   target_friend->pending_count++;
1357   process_friend_queue (target_friend);
1358 }
1359
1360 /**
1361  * Send a trail tear down message
1362  * @param source_peer Source of the trail.
1363  * @param destination_peer Destination of the trail. 
1364  * @param discarded_trail Discarded trail from source to destination. 
1365  * @param discarded_trail_length Total number of peers in trail_list. 
1366  * @pararm target_peer Next peer to forward this message to. 
1367  * @param new_first_friend The new first hop in the new trail from source to destination
1368  *                         peer.
1369  */
1370 void
1371 GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_PeerIdentity *source_peer,
1372                                     const struct GNUNET_PeerIdentity *destination_peer,
1373                                     const struct GNUNET_PeerIdentity *discarded_trail,
1374                                     unsigned int discarded_trail_length,
1375                                     struct FriendInfo *target_friend,
1376                                     const struct GNUNET_PeerIdentity *new_first_friend)
1377 {
1378   struct P2PPendingMessage *pending;
1379   struct PeerTrailTearDownMessage *ttdm;
1380   struct GNUNET_PeerIdentity *peer_list;
1381   size_t msize;
1382   
1383   msize = sizeof (struct PeerTrailTearDownMessage) + 
1384           (discarded_trail_length * sizeof(struct GNUNET_PeerIdentity));
1385   
1386   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1387   {
1388     GNUNET_break (0);
1389     return;
1390   }
1391   
1392   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1393   {  
1394     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1395                                 1, GNUNET_NO);
1396   }
1397   
1398   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1399   pending->importance = 0;    /* FIXME */
1400   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1401   ttdm = (struct PeerTrailTearDownMessage *) &pending[1];
1402   pending->msg = &ttdm->header;
1403   ttdm->header.size = htons (msize);
1404   ttdm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN);
1405   memcpy (&(ttdm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1406   memcpy (&(ttdm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1407   memcpy (&(ttdm->new_first_friend),new_first_friend, sizeof (struct GNUNET_PeerIdentity));
1408   ttdm->trail_length = htonl (discarded_trail_length);
1409   
1410   if (discarded_trail_length > 0)
1411   {
1412     peer_list = (struct GNUNET_PeerIdentity *) &ttdm[1];
1413     memcpy (peer_list, discarded_trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1414   }
1415    /* Send the message to chosen friend. */
1416   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1417   target_friend->pending_count++;
1418   process_friend_queue (target_friend);
1419 }
1420
1421
1422 /**
1423  * 
1424  * @param source_peer
1425  * @param destination_peer
1426  * @param trail
1427  * @param trail_length
1428  * @param target_friend
1429  */
1430 void
1431 GDS_NEIGHBOURS_send_add_trail_message (struct GNUNET_PeerIdentity *source_peer,
1432                                        struct GNUNET_PeerIdentity *destination_peer,
1433                                        struct GNUNET_PeerIdentity *trail,
1434                                        unsigned int trail_length,
1435                                        struct FriendInfo *target_friend)
1436 {
1437   struct P2PPendingMessage *pending;
1438   struct PeerAddTrailMessage *adm;
1439   struct GNUNET_PeerIdentity *peer_list;
1440   size_t msize;
1441   
1442   msize = sizeof (struct PeerAddTrailMessage) + 
1443           (trail_length * sizeof(struct GNUNET_PeerIdentity));
1444   
1445   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1446   {
1447     GNUNET_break (0);
1448     return;
1449   }
1450   
1451   if (target_friend->pending_count >= MAXIMUM_PENDING_PER_FRIEND)
1452   {  
1453     GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"),
1454                                 1, GNUNET_NO);
1455   }
1456   
1457   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
1458   pending->importance = 0;    /* FIXME */
1459   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
1460   adm = (struct PeerAddTrailMessage *) &pending[1];
1461   pending->msg = &adm->header;
1462   adm->header.size = htons (msize);
1463   adm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL);
1464   memcpy (&(adm->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1465   memcpy (&(adm->destination_peer), destination_peer, sizeof (struct GNUNET_PeerIdentity));
1466   adm->trail_length = htonl (trail_length);
1467   
1468   if (trail_length > 0)
1469   {
1470     peer_list = (struct GNUNET_PeerIdentity *)&adm[1];
1471     memcpy (peer_list, trail, sizeof (struct GNUNET_PeerIdentity) * trail_length);
1472   }
1473   
1474   /* Send the message to chosen friend. */
1475   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1476   target_friend->pending_count++;
1477   process_friend_queue (target_friend);
1478 }
1479
1480
1481 /**
1482  * FIXME: CONGESTION: check the code once basic code is all correct. s
1483  * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1484  * In case the friend chosen in select_random_friend() is congested or
1485  * has crossed trail_threshold, then get next friend which is not congested or 
1486  * has not crossed trail threshold from friend peermap. 
1487  * @param current_index Index in finger peermap chosen randomly
1488  * @param friend_peermap_size Total number of entries in friend peermap.
1489  * @param count Total number of time this function has been called, in case
1490  *              count == sizeof(friend_peermap) - 1, it means none of the friends are free. 
1491  * @return Friend Friend found.
1492  *         NULL in case all the friends are congested or have crossed trail threshold.
1493  */
1494 static struct FriendInfo *
1495 get_next_friend (unsigned int current_index, 
1496                  unsigned int friend_peermap_size,
1497                  unsigned int count)
1498 {
1499   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1500   struct GNUNET_PeerIdentity key_ret;
1501   struct FriendInfo *friend;
1502   int j = 0;
1503   
1504   current_index = (current_index + 1) % friend_peermap_size;
1505   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1506   while(j < (current_index))
1507   {
1508     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1509     {
1510       j++;
1511     }
1512     else 
1513       return NULL;
1514   }  
1515
1516   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1517   {
1518     if ((friend->trails_count > TRAIL_THROUGH_FRIEND_THRESHOLD) ||
1519         (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1520     {
1521       count++;
1522       if (count == (friend_peermap_size -1))
1523         return NULL;
1524       else
1525         return get_next_friend (j,friend_peermap_size,count);
1526     }
1527     return friend;
1528   }
1529   else
1530     return NULL;
1531 }
1532
1533
1534 /** 
1535  * FIXME: CONGESTION: check the code once basic code is all correct. 
1536  * FIXME: call GNUNET_CONTAINER_multipeermap_iterator_destroy (iter);
1537  * Randomly choose one of your friends from the friends_peer map
1538  * @return Friend Randomly chosen friend. 
1539  *         NULL in case friend peermap is empty, or all the friends are either
1540  *              congested or have crossed trail threshold. 
1541  */
1542 static struct FriendInfo *
1543 select_random_friend ()
1544 {  
1545   unsigned int current_size;
1546   unsigned int *index; 
1547   unsigned int j = 0;
1548   struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
1549   struct GNUNET_PeerIdentity key_ret;
1550   struct FriendInfo *friend;
1551   
1552   current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap);
1553   if (0 == current_size)
1554     return NULL;
1555   
1556   index = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, current_size);
1557   iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap);
1558  
1559   while(j < (*index))
1560   {
1561     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,NULL,NULL))
1562     {
1563       j++;
1564     }
1565     else 
1566     {
1567       return NULL;
1568     }
1569   }  
1570
1571   if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter,&key_ret,(const void **)&friend))
1572   {
1573     if ((TRAIL_THROUGH_FRIEND_THRESHOLD == friend->trails_count) ||
1574         (0 != GNUNET_TIME_absolute_get_remaining (friend->congestion_duration).rel_value_us))
1575     {
1576       return get_next_friend (*index, current_size, 1);
1577     } 
1578     return friend;
1579   }
1580   else
1581     return NULL;
1582 }
1583
1584
1585 /**
1586  * Compute finger_identity to which we want to setup the trail
1587  * @return finger_identity 
1588  */
1589 static uint64_t 
1590 compute_finger_identity()
1591 {
1592   uint64_t my_id64 ;
1593
1594   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1595   my_id64 = GNUNET_ntohll (my_id64);
1596   return (my_id64 + (unsigned long) pow (2, current_search_finger_index));
1597 }
1598
1599
1600 /**
1601  * Compute immediate predecessor identity in the network.
1602  * @return peer identity of immediate predecessor.
1603  */
1604 static uint64_t 
1605 compute_predecessor_identity()
1606 {
1607   uint64_t my_id64;
1608
1609   memcpy (&my_id64, &my_identity, sizeof (uint64_t));
1610   my_id64 = GNUNET_ntohll (my_id64);
1611   return (my_id64 -1);
1612 }
1613
1614
1615 /**
1616  * Ping your successor to verify if it is still your successor or not. 
1617  */
1618 static void
1619 send_verify_successor_message()
1620 {
1621   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
1622   struct GNUNET_PeerIdentity key_ret;
1623   struct FriendInfo *target_friend;
1624   struct GNUNET_PeerIdentity next_hop;
1625   struct GNUNET_PeerIdentity *peer_list;
1626   struct FingerInfo *finger;
1627   unsigned int finger_index;
1628   int flag = 0;
1629   
1630   /* Find the successor from the finger peermap.*/
1631   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
1632   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
1633   {
1634     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, &key_ret,
1635                                                                  (const void **)&finger)) 
1636     {
1637       if (0 == finger->finger_map_index)
1638       {
1639         flag = 1;
1640         break;
1641       }
1642     }
1643   }
1644   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
1645   
1646   /* Either you don't have a successor or you are your own successor, then don't
1647    send a successor message. */
1648   if(( flag == 0) ||
1649     (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, &(finger->finger_identity))))
1650   {
1651     return;
1652   }
1653
1654   if (finger->first_trail_length > 0)
1655   {
1656     struct TrailPeerList *iterate;
1657     int i = 0;
1658     peer_list = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * finger->first_trail_length);
1659     iterate = finger->first_trail_head;
1660     
1661     while ( i < (finger->first_trail_length))
1662     {     
1663       memcpy (&peer_list[i], &(iterate->peer), sizeof (struct GNUNET_PeerIdentity));
1664       iterate = iterate->next;
1665       i++;
1666     }
1667     memcpy (&next_hop, &peer_list[0], sizeof (struct GNUNET_PeerIdentity));
1668     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
1669   }
1670   else
1671   {
1672     /* If trail length = 0, then our successor is our friend. */
1673     peer_list = NULL;
1674     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
1675                                                       &(finger->finger_identity));
1676   }
1677    
1678   GDS_NEIGHBOURS_send_verify_successor (&my_identity,
1679                                         &(finger->finger_identity),
1680                                         target_friend,
1681                                         peer_list,
1682                                         finger->first_trail_length);  
1683 }
1684
1685
1686 /**
1687  * Choose a random friend and start looking for the trail to reach to 
1688  * finger identity through this random friend. 
1689  *
1690  * @param cls closure for this task
1691  * @param tc the context under which the task is running
1692  */
1693 static void
1694 send_find_finger_trail_message (void *cls,
1695                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
1696 {
1697   struct FriendInfo *target_friend;
1698   struct GNUNET_TIME_Relative next_send_time;
1699   uint64_t finger_identity;
1700   unsigned int finger_map_index;
1701   
1702   next_send_time.rel_value_us =
1703       DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us +
1704       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1705                                 DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us);
1706   find_finger_trail_task =
1707       GNUNET_SCHEDULER_add_delayed (next_send_time, &send_find_finger_trail_message,
1708                                     NULL);
1709   
1710   target_friend = select_random_friend (); 
1711   if (NULL == target_friend) 
1712   {
1713     return;
1714   }
1715   
1716   if (PREDECESSOR_FINGER_ID == current_search_finger_index)
1717   {
1718     finger_identity = compute_predecessor_identity();  
1719   }
1720   else
1721   {
1722     finger_identity = compute_finger_identity();
1723   }
1724     
1725   finger_map_index = current_search_finger_index;
1726   GDS_NEIGHBOURS_send_trail_setup (&my_identity, finger_identity, &(target_friend->id),
1727                                    &my_identity, target_friend, 0, NULL, finger_map_index);
1728 }
1729
1730
1731 /**
1732  * Scan the trail to check if any of my own friend is part of trail. If yes
1733  * then shortcut the trail, send a trail teardown for the discarded trail,
1734  * update trail list and trail_length. 
1735  * @param trail[Out] Current trail to reach to @a finger, will be updated
1736  *                          in case we compress the trail. 
1737  * @param trail_length[Out] Number of peers in @a finger_trail, will be updated
1738  *                          in case we compress the trail. 
1739  * @param finger Finger identity 
1740  */
1741 static void
1742 scan_and_compress_trail (struct GNUNET_PeerIdentity *trail,
1743                          unsigned int *trail_length,
1744                          const struct GNUNET_PeerIdentity *finger)
1745 {
1746   int i;
1747   struct FriendInfo *target_friend;
1748    
1749   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger))
1750   {
1751     /* Here you don't send a trail teardown as no one added this in their
1752      routing table. */
1753     *trail_length = 0;
1754     trail = NULL;
1755     return;    
1756   }
1757   if (GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger))
1758   {
1759     int discarded_trail_length = *trail_length;
1760     target_friend = GNUNET_CONTAINER_multipeermap_get(friend_peermap, &trail[0]);
1761     GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, trail,
1762                                         discarded_trail_length, target_friend, finger);
1763     *trail_length = 0;
1764     trail = NULL;
1765     return;
1766   }
1767  
1768   i = *trail_length - 1;
1769
1770   while (i > 1)
1771   {
1772     if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[i]))
1773     {
1774       /* This element of trail is not my friend. */
1775       i--;
1776     }
1777     else
1778     {
1779       /* A --> B(friend 1) --> C(friend 2)--> D ---> E, then we can rewrite the trail as
1780        * C --> D --> E,
1781        * Now, we should remove the entry from A's routing table, B's routing table
1782        * and update the entry in C's routing table. Rest everything will be same.
1783        * C's routing table should have source peer as the prev.hop. 
1784        */
1785       struct GNUNET_PeerIdentity *discarded_trail;
1786       struct FriendInfo *target_friend;
1787       int discarded_trail_length;
1788       int j = 0;
1789
1790       discarded_trail_length = i - 1;
1791       discarded_trail = GNUNET_malloc (discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1792       memcpy (discarded_trail, trail, discarded_trail_length * sizeof (struct GNUNET_PeerIdentity));
1793       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail[0]);
1794       GDS_NEIGHBOURS_send_trail_teardown (&my_identity, finger, discarded_trail,
1795                                          discarded_trail_length, target_friend,
1796                                          &trail[i]);
1797      
1798       /* Copy the trail from index i to index trail_length -1 and change
1799        trail length and return */
1800       while (i < *trail_length)
1801       {
1802         memcpy (&trail[j], &trail[i], sizeof(struct GNUNET_PeerIdentity));
1803         j++;
1804         i++;
1805       }
1806       *trail_length = j+1;
1807       return;
1808     }
1809   }
1810   return;
1811 }
1812
1813
1814 /** 
1815  * FIXME: Adapt the code for List of trails. 
1816  * Free finger and its trail.  
1817  * @param finger Finger to be freed.
1818  */
1819 static void
1820 free_finger (struct FingerInfo *finger)
1821 {
1822   struct TrailPeerList *peer;
1823
1824   if(finger->first_trail_head != NULL)
1825   {
1826     while (NULL != (peer = finger->first_trail_head))
1827     {
1828       GNUNET_CONTAINER_DLL_remove (finger->first_trail_head, finger->first_trail_tail, peer);
1829       GNUNET_free (peer);
1830     }
1831   }
1832   
1833   if (finger->second_trail_head != NULL)
1834   {
1835     while (NULL != (peer = finger->second_trail_head))
1836     {
1837       GNUNET_CONTAINER_DLL_remove (finger->second_trail_head, finger->second_trail_tail, peer);
1838       GNUNET_free (peer);
1839     }
1840     GNUNET_free (finger);
1841   }
1842 }
1843
1844
1845 /**
1846  * FIXME: First check if both the trails are present if yes then send it
1847  * for both of them. Currently sending it only for one trail.
1848  * Send a trail teardown message for the trail of removed finger from the finger
1849  * peermap. 
1850  * @param existing_finger Finger to removed from the finger peermap.
1851  */
1852 static
1853 void send_trail_teardown (struct FingerInfo *removed_finger)
1854 {
1855  struct GNUNET_PeerIdentity *peer_list; 
1856  struct FriendInfo *friend; 
1857  struct TrailPeerList *finger_trail;
1858  int removed_finger_trail_length = removed_finger->first_trail_length;
1859  int i = 0;
1860
1861  if (removed_finger->first_trail_length == 0)
1862     return;
1863  
1864  finger_trail = removed_finger->first_trail_head;
1865  friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(finger_trail->peer)); 
1866  peer_list = GNUNET_malloc ( removed_finger_trail_length * sizeof (struct GNUNET_PeerIdentity));
1867  while (i < removed_finger->first_trail_length)
1868  {
1869    memcpy (&peer_list[i], &(finger_trail->peer), sizeof (struct GNUNET_PeerIdentity));
1870    finger_trail = finger_trail->next;
1871    i++;
1872  }
1873
1874  GDS_NEIGHBOURS_send_trail_teardown (&my_identity, &(removed_finger->finger_identity),
1875                                      peer_list, removed_finger_trail_length, friend,
1876                                      &(removed_finger->finger_identity)); 
1877 }
1878
1879
1880 /**
1881  * FIXME: How do we understand which is the correct trail head? 
1882  * Add a new trail to reach an existing finger in finger peermap and increment
1883  * the count of number of trails to reach to this finger. 
1884  * @param existing_finger Finger 
1885  * @param trail New trail to be added
1886  * @param trail_length Total number of peers in the trail. 
1887  */
1888 static
1889 void add_new_trail (struct FingerInfo *existing_finger, 
1890                     struct GNUNET_PeerIdentity *trail,
1891                     unsigned int trail_length)
1892 {
1893   int i;
1894   i = 0;
1895   /* FIXME: Here you need to understand which trail is there and which not. 
1896    In case first_trail_head != NULL, then that trail is present 
1897    so you should add the second one. Need to verify this logic. */    
1898   if (existing_finger->first_trail_head != NULL)
1899   {
1900     while (i < trail_length)
1901     {
1902       struct TrailPeerList *element;
1903       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1904       element->next = NULL;
1905       element->prev = NULL;
1906     
1907       memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1908       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1909       i++;
1910     }
1911   }
1912   else if (existing_finger->second_trail_head != NULL)
1913   {
1914     while (i < trail_length)
1915     {
1916       struct TrailPeerList *element;
1917       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1918       element->next = NULL;
1919       element->prev = NULL;
1920     
1921       memcpy (&(element->peer), &trail[i], sizeof(struct GNUNET_PeerIdentity));
1922       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->first_trail_head, existing_finger->first_trail_tail, element);
1923       i++;
1924     }
1925   }  
1926   existing_finger->trail_count++;
1927 }
1928
1929
1930 /**
1931  * In case there are already maximum number of possible trail to reach to a finger,
1932  * then check if the new trail's length is lesser than any of the existing trails.
1933  * If yes then replace that old trail by new trail.
1934  * Note: Here we are taking length as a parameter to choose the best possible trail,
1935  * but there could be other parameters also like - 1. duration of existence of a
1936  * trail - older the better. 2. if the new trail is completely disjoint than the 
1937  * other trails, then may be choosing it is better. 
1938  * @param existing_finger
1939  * @param trail
1940  * @param trail_length
1941  * @return #GNUNET_YES 
1942  *         #GNUNET_NO
1943  */
1944 static 
1945 void select_and_replace_trail (struct FingerInfo *existing_finger, 
1946                                struct GNUNET_PeerIdentity *new_trail,
1947                                unsigned int new_trail_length)
1948 {
1949   if (existing_finger->first_trail_length == existing_finger->second_trail_length)
1950   {
1951     if (new_trail_length < existing_finger->first_trail_length)
1952     {
1953       /* Randomly choose one of the trail. FIXME:currently I am just replacing the
1954        first trail.*/
1955       struct TrailPeerList *peer;
1956       int i = 0;
1957         
1958       while (NULL != (peer = existing_finger->first_trail_head))
1959       {
1960         GNUNET_CONTAINER_DLL_remove (existing_finger->first_trail_head, existing_finger->first_trail_tail, peer);
1961         GNUNET_free (peer);
1962       } 
1963         
1964       while (i < new_trail_length)
1965       {
1966         struct TrailPeerList *element;
1967         element = GNUNET_malloc (sizeof (struct TrailPeerList));
1968         element->next = NULL;
1969         element->prev = NULL;
1970     
1971         memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
1972         GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1973         i++;
1974       }
1975     }
1976   }
1977   else if ((new_trail_length < existing_finger->second_trail_length) && 
1978           (existing_finger->second_trail_length < existing_finger->first_trail_length))
1979   {
1980     /* Replace the first trail by the new trail. */
1981     struct TrailPeerList *peer;
1982     int i = 0;
1983         
1984     while (NULL != (peer = existing_finger->first_trail_head))
1985     {
1986       GNUNET_CONTAINER_DLL_remove (existing_finger->first_trail_head, existing_finger->first_trail_tail, peer);
1987       GNUNET_free (peer);
1988     } 
1989         
1990     while (i < new_trail_length)
1991     {
1992       struct TrailPeerList *element;
1993       element = GNUNET_malloc (sizeof (struct TrailPeerList));
1994       element->next = NULL;
1995       element->prev = NULL;
1996     
1997       memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
1998       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
1999       i++;
2000     }
2001   }
2002   else if ( (new_trail_length < existing_finger->first_trail_length) &&
2003            (existing_finger->first_trail_length < existing_finger->second_trail_length))
2004   {
2005     /* Replace the second trail by the new trail. */
2006     struct TrailPeerList *peer;
2007     int i = 0;
2008         
2009     while (NULL != (peer = existing_finger->second_trail_head))
2010     {
2011       GNUNET_CONTAINER_DLL_remove (existing_finger->second_trail_head, existing_finger->second_trail_tail, peer);
2012       GNUNET_free (peer);
2013     }
2014         
2015     while (i < new_trail_length)
2016     {
2017       struct TrailPeerList *element;
2018       element = GNUNET_malloc (sizeof (struct TrailPeerList));
2019       element->next = NULL;
2020       element->prev = NULL;
2021     
2022       memcpy (&(element->peer), &new_trail[i], sizeof(struct GNUNET_PeerIdentity));
2023       GNUNET_CONTAINER_DLL_insert_tail(existing_finger->second_trail_head, existing_finger->second_trail_tail, element);
2024       i++;
2025      }
2026   } 
2027 }
2028
2029
2030 /**
2031  * FIXME: If we remove a finger which is our friend, then how should we handle it. 
2032  * Ideally only in case if the trail_length > 0,we increment the trail count
2033  * of the first friend in the trail to reach to the finger. in case finger is
2034  * our friend then trail length = 0, and hence, we have never incremented the
2035  * trail count associated with that friend. 
2036  * Decrement the trail count for the first friend to reach to the finger. 
2037  * @param finger
2038  */
2039 static void
2040 decrement_friend_trail_count (struct FingerInfo *finger)
2041 {
2042   struct FriendInfo *first_trail_friend;
2043   struct FriendInfo *second_trail_friend;
2044   
2045   if(finger->first_trail_head != NULL)
2046   {
2047     first_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
2048                                                             &(finger->first_trail_head->peer));
2049     first_trail_friend->trails_count--;
2050   }
2051     
2052   if(finger->second_trail_head != NULL)
2053   {
2054     second_trail_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 
2055                                                            &(finger->second_trail_head->peer));
2056     second_trail_friend->trails_count--;
2057   }
2058   
2059 #if 0
2060   /* We will not need this variable any more, all_friends_trail_threshold,
2061    FIXME: REMOVE IT. */
2062   if (GNUNET_YES == all_friends_trail_threshold)
2063   {
2064     all_friends_trail_threshold = GNUNET_NO;
2065     /* FIXME; Here you should reschedule the send_find_finger_task here. or
2066      make a call.*/
2067   }
2068 #endif
2069 }
2070
2071
2072 /**
2073  * FIXME: create a different data structure for storing the peer ids here. 
2074  * Select the closest finger. Used for both predecessor and other fingers..
2075  * But internally calls different functions for predecessor and other fingers.
2076  * @param existing_finger Finger in finger peermap. 
2077  * @param new_finger New finger identity
2078  * @param finger_map_index Index in finger peermap where @a existing_finger is stored.
2079  * @return #GNUNET_YES if the new finger is closest.
2080  *         #GNUNET_NO if the old finger is closest.
2081  *         #GNUNET_SYSERR in case our own identity is closest (should never happen).
2082  */
2083 static 
2084 int select_finger (struct FingerInfo *existing_finger,
2085                    const struct GNUNET_PeerIdentity *new_finger,
2086                    unsigned int finger_map_index)
2087 {
2088   struct Sorting_List peers[3]; /* 3 for existing_finger, new_finger, my_identity */
2089   struct Sorting_List *closest_finger; 
2090   uint64_t value;
2091   int k;
2092   
2093   for (k = 0; k < 3; k++)
2094     peers[k].data = 0;
2095   
2096   /* Add your entry to peers. */
2097   memcpy (&peers[0], &my_identity, sizeof (uint64_t));
2098   peers[0].type = MY_ID;
2099   peers[0].data = NULL;
2100   
2101   /* Add existing_finger identity to the peers. */
2102   memcpy (&peers[1], &(existing_finger->finger_identity), sizeof (uint64_t));
2103   peers[1].type = FINGER;
2104   peers[1].data = existing_finger;
2105   
2106   /* Add new_finger identity to the peers. s*/
2107   memcpy (&peers[2], &new_finger, sizeof (uint64_t));
2108   peers[2].type = VALUE;
2109   peers[2].data = NULL;
2110   
2111   memcpy (&value, &my_identity, sizeof (uint64_t));
2112   qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
2113   
2114   if (PREDECESSOR_FINGER_ID == finger_map_index)
2115     closest_finger = find_closest_predecessor (peers, value, 3);
2116   else
2117     closest_finger = find_closest_successor (peers, value, 3);
2118   
2119   if (closest_finger->type  == FINGER)
2120   {
2121     return GNUNET_NO;
2122   }
2123   else if (closest_finger->type == VALUE)
2124   {
2125     return GNUNET_YES;
2126   }
2127   else if (closest_finger->type == MY_ID);
2128   {
2129     return GNUNET_SYSERR;  
2130   }
2131 }
2132
2133
2134 /**
2135  * FIXME: Better name, and make the code more cleaner.
2136  * Compare the new finger entry added and our successor. 
2137  * @return #GNUNET_YES if same.
2138  *         #GNUNET_NO if not. 
2139  */
2140 static int
2141 compare_new_entry_and_successor (const struct GNUNET_PeerIdentity *new_finger,
2142                                  int finger_map_index)
2143 {
2144   int successor_flag = 0;
2145   struct FingerInfo *successor_finger;
2146   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2147   int i;
2148
2149   if (PREDECESSOR_FINGER_ID == finger_map_index)
2150     return GNUNET_NO;
2151   
2152   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
2153   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
2154   {
2155     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
2156                                                                  (const void **)&successor_finger)) 
2157     {
2158       if (successor_finger->finger_map_index == 0)
2159       {
2160         successor_flag = 1;
2161         break;
2162       }
2163     }
2164   }
2165   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2166   
2167   /* Ideally we should never reach here. */
2168   if (successor_flag == 0)
2169   {
2170     GNUNET_break (0);
2171     return GNUNET_NO;
2172   }
2173   
2174   if (0 == GNUNET_CRYPTO_cmp_peer_identity (new_finger, &(successor_finger->finger_identity)))
2175     return GNUNET_YES;
2176   else
2177     return GNUNET_NO;
2178 }
2179
2180
2181 /**
2182  * Add a new entry in finger table. 
2183  * @param finger_identity PeerIdentity of the new finger
2184  * @param finger_trail Trail to reach to the finger, can be NULL in case I am my own
2185  *                     finger.
2186  * @param finger_trail_length Number of peers in the trail, can be 0 in case finger
2187  *                            is a friend or I am my own finger.
2188  * @param finger_map_index Index in finger map. 
2189  */
2190 static int
2191 add_new_entry (const struct GNUNET_PeerIdentity *finger_identity,
2192                struct GNUNET_PeerIdentity *finger_trail,
2193                uint32_t finger_trail_length,
2194                uint32_t finger_map_index)
2195 {
2196   struct FriendInfo *first_friend_trail;
2197   struct FingerInfo *new_finger_entry;
2198   int i;
2199   
2200   /* Add a new entry. */
2201   new_finger_entry = GNUNET_malloc (sizeof (struct FingerInfo));
2202   memcpy (&(new_finger_entry->finger_identity), finger_identity, sizeof (struct GNUNET_PeerIdentity));
2203   new_finger_entry->finger_map_index = finger_map_index;
2204   new_finger_entry->first_trail_length = finger_trail_length;
2205   new_finger_entry->trail_count = 1;
2206   
2207   if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger_identity)) /* finger_trail is NULL in case I am my own finger identity. */
2208   {
2209     /* Incrementing the friend trails count. */
2210     if (finger_trail_length > 0)   
2211     {
2212       first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &finger_trail[0]);
2213       first_friend_trail->trails_count++;
2214     }
2215     else
2216     {
2217       /* It means the finger is my friend. */
2218       first_friend_trail = GNUNET_CONTAINER_multipeermap_get (friend_peermap, finger_identity);
2219       first_friend_trail->trails_count++;
2220     }
2221     new_finger_entry->first_friend_trails_count = first_friend_trail->trails_count; 
2222     
2223     /* Copy the trail. */
2224     i = 0;
2225     while (i < finger_trail_length)
2226     {
2227       struct TrailPeerList *element;
2228       element = GNUNET_malloc (sizeof (struct TrailPeerList));
2229       element->next = NULL;
2230       element->prev = NULL;
2231     
2232       memcpy (&(element->peer), &finger_trail[i], sizeof(struct GNUNET_PeerIdentity));
2233       GNUNET_CONTAINER_DLL_insert_tail(new_finger_entry->first_trail_head, new_finger_entry->first_trail_tail, element);
2234       i++;
2235     }
2236   }
2237  
2238   return GNUNET_CONTAINER_multipeermap_put (finger_peermap,
2239                                             &(new_finger_entry->finger_identity),
2240                                             new_finger_entry,
2241                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);    
2242 }
2243
2244
2245 /**
2246  * Choose the closest finger between existing finger and new finger.
2247  * If the new finger is closest, then send a trail_teardown message along 
2248  * existing_finger's trail. In case both the id's are same, and there is a place
2249  * to add more trails, then store both of them. In case there is no space to 
2250  * store any more trail, then choose the best trail (best - depends on length in
2251  * current_implementation) and discard the others. 
2252  * @param existing_finger
2253  * @param new_finger Existing finger in finger_peermap for @a finger_map_index
2254  * @param trail Trail to reach from me to @a new_finger
2255  * @param trail_length Total number of peers in @a trail.
2256  * @param finger_map_index Index in finger peermap. 
2257  * @return #GNUNET_YES In case we want to store the new entry.
2258  *         #GNUNET_NO In case we want the existing entry.
2259  *         #GNUNET_SYSERR Error. 
2260  */
2261 static 
2262 int select_closest_finger (struct FingerInfo *existing_finger,
2263                            const struct GNUNET_PeerIdentity *new_finger,
2264                            struct GNUNET_PeerIdentity *trail,
2265                            unsigned int trail_length,
2266                            unsigned int finger_map_index)
2267 {
2268   if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), new_finger))
2269   {
2270     /* New entry and existing entry are same. */
2271     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(existing_finger->finger_identity), &my_identity))
2272     {
2273       /* If existing_finger is my_identity then trail_length = 0, trail = NULL. In
2274        this case you don't need to check the trails. Exit. */
2275       return GNUNET_NO;
2276     }
2277     if (trail_length > 0)
2278     {
2279       scan_and_compress_trail (trail, &trail_length, new_finger);
2280     }
2281     if (existing_finger->trail_count < TRAIL_COUNT)
2282     {
2283       add_new_trail (existing_finger, trail, trail_length);
2284       return GNUNET_NO;
2285     }
2286     else
2287     {
2288       select_and_replace_trail (existing_finger, trail, trail_length);
2289       return GNUNET_NO;
2290     }  
2291   }
2292   else if (GNUNET_YES == select_finger (existing_finger, new_finger, finger_map_index))
2293   {
2294     /* New finger is the closest finger. */
2295     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, new_finger))
2296     {
2297       /* FIXME: Here in case the new finger is my_identity and old entry is not,
2298        should we keep the old entry even if the old entry is not the closest? */
2299       return GNUNET_NO;    
2300     }
2301     send_trail_teardown (existing_finger);
2302     decrement_friend_trail_count (existing_finger);
2303     free_finger (existing_finger);
2304     
2305     if (trail_length > 0)
2306     {
2307       scan_and_compress_trail (trail, &trail_length, new_finger);
2308     }
2309     return GNUNET_YES;
2310   }
2311   else if (GNUNET_NO == select_finger (existing_finger, new_finger,finger_map_index))
2312   {
2313     /* existing_finger is the closest finger. */
2314     return GNUNET_NO;
2315   }
2316   return GNUNET_SYSERR;
2317 }
2318
2319
2320 /**
2321  * Check if there is already an entry for finger map index in finger table.
2322  * If yes then choose the closest finger. 
2323  * @param finger_identity Peer Identity of finger. 
2324  * @param finger_trail Trail to reach from me to @a finger_identity
2325  * @param finger_trail_length Total number of peers in finger_trail.
2326  * @param finger_map_index Index in finger_peermap.
2327  * @return #GNUNET_YES if the new entry is added.
2328  *         #GNUNET_NO if the new entry is discarded.
2329  */
2330 static 
2331 int finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
2332                       struct GNUNET_PeerIdentity *finger_trail,
2333                       uint32_t finger_trail_length,
2334                       uint32_t finger_map_index)
2335 {
2336   struct FingerInfo *existing_finger;
2337   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2338   int i;
2339   int old_entry_found = GNUNET_NO;
2340   int new_entry_added = GNUNET_NO;  
2341   
2342   /* Check if there is already an entry for the finger map index in the finger peer map. */
2343   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap); 
2344   for (i= 0; i < GNUNET_CONTAINER_multipeermap_size (finger_peermap); i++)
2345   {
2346     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (finger_iter, NULL,
2347                                                                  (const void **)&existing_finger)) 
2348     {
2349       if (existing_finger->finger_map_index == finger_map_index)
2350       {
2351         old_entry_found = GNUNET_YES;
2352         if ( GNUNET_NO == select_closest_finger (existing_finger, finger_identity, 
2353                                                  finger_trail, finger_trail_length,
2354                                                  finger_map_index)) 
2355           goto update_current_search_finger_index;
2356         else
2357           break;
2358       }
2359     } 
2360   }
2361   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2362   
2363   if (GNUNET_NO == old_entry_found)
2364   {
2365     if (finger_trail_length > 0)
2366     {
2367       scan_and_compress_trail (finger_trail, &finger_trail_length, finger_identity);
2368     }
2369   }
2370   
2371   /* FIXME: handle the case when addition in peer map failed. */
2372   if(GNUNET_OK == add_new_entry (finger_identity,finger_trail,finger_trail_length, finger_map_index))
2373     new_entry_added = GNUNET_YES;
2374   else
2375     return GNUNET_NO;
2376   
2377   update_current_search_finger_index:
2378   if (0 == finger_map_index)
2379   {
2380     current_search_finger_index = PREDECESSOR_FINGER_ID;
2381     if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,finger_identity))
2382       send_verify_successor_message();
2383   }
2384   else if (GNUNET_YES == compare_new_entry_and_successor (finger_identity,finger_map_index))
2385   {
2386     current_search_finger_index = 0;
2387   }
2388   else 
2389   {
2390     current_search_finger_index = current_search_finger_index - 1;
2391   }
2392   
2393   return new_entry_added;
2394 }
2395
2396
2397 /**
2398  * 
2399  * @param all_known_peers
2400  * @param array_size
2401  * @param friend
2402  * @param key_value
2403  * @return 
2404  */
2405 static struct Sorting_List *
2406 get_next_successor (struct Sorting_List *all_known_peers,
2407                     unsigned int array_size,
2408                     struct FriendInfo *friend,
2409                     uint64_t key_value)
2410 {
2411   /* 1. search friend in all_known_peers.
2412      2. get the next peer. if peer == my_identity or peer == value, then go to
2413          next element.
2414      3. if friend then again check if threshold crossed or not . If not then return
2415         or else again increment. remember starting index of friend in all_known_peers
2416        and when you reach to it again then return NULL as it means all the friend
2417         are congested or threshold reached. 
2418   */
2419   return NULL;
2420 }
2421
2422
2423 /**
2424  * Check if the friend is congested or has crossed TRAIL_THRESHOLD. If yes
2425  * then choose the peer next to it in the array. In case number of times this 
2426  * function is called is equal to total number of entries in the array then it
2427  * means that none of the friends are busy. But remember in this array you also
2428  * have your own identity, value that you were searching, You should skip those
2429  * and also keep the count = size -2. But if we call in this order is our get/put
2430  * not getting wrong. 
2431  * @param all_known_peers
2432  * @param array_size
2433  * @param friend Friend to be checked if 
2434  * @param key_value To be ignored 
2435  * @return #GNUNET_YES
2436  *         #GNUNET_NO
2437  */
2438 static int
2439 check_friend_threshold_and_congestion (struct Sorting_List *all_known_peers,
2440                                        unsigned int array_size,
2441                                        struct FriendInfo *friend,
2442                                        uint64_t key_value)
2443 {  
2444   if (friend->trails_count == TRAIL_THROUGH_FRIEND_THRESHOLD)
2445   {
2446     return GNUNET_YES;
2447   }
2448   return GNUNET_NO;
2449 }
2450
2451
2452 /**
2453  * FIXME: Complete the code for checking the threshold and getting the next
2454  * peer, add the case in finger. 
2455  * In case a friend is either congested or has crossed its trail threshold,
2456  * then don't consider it as next successor, In case of finger if its first
2457  * friend has crossed the threshold then don't consider it. In case no finger
2458  * or friend is found, then return NULL.
2459  * Find closest successor for the value.
2460  * @param value Value for which we are looking for successor
2461  * @param[out] current_destination set to my_identity in case I am the final destination,
2462  *                                 set to friend identity in case friend is final destination,
2463  *                                 set to first friend to reach to finger, in case finger
2464  *                                 is final destination. 
2465  * @param[out] current_source set to my_identity.
2466  * @param finger_map_index Index in finger peer map. 
2467  * @return Peer identity of next hop to send trail setup message to,
2468  *         NULL in case all the friends are either congested or have crossed
2469  *              their trail threshold.
2470  */
2471 static struct GNUNET_PeerIdentity *
2472 find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
2473                struct GNUNET_PeerIdentity *current_source, unsigned int finger_map_index)
2474 {
2475   struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
2476   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
2477   struct GNUNET_PeerIdentity key_ret;
2478   struct FriendInfo *friend;
2479   struct FingerInfo *finger;
2480   unsigned int finger_index;
2481   unsigned int friend_index;
2482   struct Sorting_List *successor;
2483   unsigned int size;
2484   int j;
2485   
2486   /* 2 is added in size for my_identity and value which will part of all_known_peers. */
2487   size = GNUNET_CONTAINER_multipeermap_size (friend_peermap)+
2488          GNUNET_CONTAINER_multipeermap_size (finger_peermap)+
2489          2;
2490   
2491   struct Sorting_List all_known_peers[size];
2492   
2493   int k;
2494   for (k = 0; k < size; k++)
2495     all_known_peers[k].peer_id = 0;
2496   
2497   /* Copy your identity at 0th index in all_known_peers. */
2498   j = 0;
2499   memcpy (&(all_known_peers[j].peer_id), &my_identity, sizeof (uint64_t));
2500   all_known_peers[j].type = MY_ID;
2501   all_known_peers[j].data = 0;
2502   j++;
2503   
2504   /* Copy value */
2505   all_known_peers[j].peer_id = value;
2506   all_known_peers[j].type = VALUE;
2507   all_known_peers[j].data = 0;
2508   j++;
2509   
2510   /* Iterate over friend peer map and copy all the elements into array. */
2511   friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); 
2512   for (friend_index = 0; friend_index < GNUNET_CONTAINER_multipeermap_size (friend_peermap); friend_index++)
2513   {
2514     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(friend_iter,&key_ret,(const void **)&friend)) 
2515     {
2516       memcpy (&(all_known_peers[j].peer_id), &(friend->id), sizeof (uint64_t));
2517       all_known_peers[j].type = FRIEND;
2518       all_known_peers[j].data = friend;
2519       j++;
2520     }
2521   }
2522   
2523  
2524   /* Iterate over finger map and copy all the entries into all_known_peers array. */
2525   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
2526   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
2527   {
2528     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next(finger_iter,&key_ret,(const void **)&finger)) 
2529     {
2530       memcpy (&(all_known_peers[j].peer_id), &(finger->finger_identity), sizeof (uint64_t));
2531       all_known_peers[j].type = FINGER;
2532       all_known_peers[j].data = finger;
2533       j++;
2534     }
2535   }
2536   
2537   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
2538   GNUNET_CONTAINER_multipeermap_iterator_destroy (friend_iter); 
2539   
2540  
2541   qsort (&all_known_peers, size, sizeof (struct Sorting_List), &compare_peer_id);
2542   
2543   /* search value in all_known_peers array. */
2544   if (PREDECESSOR_FINGER_ID == finger_map_index)
2545     successor = find_closest_predecessor (all_known_peers, value, size);
2546   else
2547     successor = find_closest_successor (all_known_peers, value, size);
2548   
2549   if (successor->type == MY_ID)
2550   {
2551     memcpy (current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2552     return &my_identity;
2553   }
2554   else if (successor->type == FRIEND)
2555   {
2556     struct FriendInfo *target_friend;
2557     target_friend = (struct FriendInfo *)successor->data;
2558     if( GNUNET_YES == check_friend_threshold_and_congestion (all_known_peers, size, target_friend, value))
2559     {
2560       get_next_successor (all_known_peers, size, friend, value);
2561     }
2562     memcpy (current_destination, &(target_friend->id), sizeof (struct GNUNET_PeerIdentity));
2563     memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2564     return current_destination;
2565   }
2566   else if (successor->type == FINGER)
2567   {
2568     struct GNUNET_PeerIdentity *next_hop;
2569     struct FingerInfo *finger;
2570     finger = successor->data;
2571     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2572     
2573     if (finger->first_trail_length > 0)
2574     {
2575       struct TrailPeerList *iterator;
2576       iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
2577       iterator = finger->first_trail_head;
2578       memcpy (next_hop, &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
2579     }
2580     else /* This means finger is our friend. */
2581       memcpy (next_hop, &(finger->finger_identity), sizeof(struct GNUNET_PeerIdentity));
2582     
2583     memcpy (current_destination, &(finger->finger_identity), sizeof (struct GNUNET_PeerIdentity));
2584     memcpy (current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
2585     return next_hop;
2586   }
2587   else
2588   {
2589     GNUNET_assert (0);
2590     return NULL;
2591   }
2592 }
2593
2594
2595 /**
2596  * Construct a Put message and send it to target_peer. 
2597  * @param key Key for the content  
2598  * @param data Content to store
2599  * @param data_size Size of content @a data in bytes
2600  * @param block_type Type of the block
2601  * @param options Routing options
2602  * @param desired_replication_level Desired replication count
2603  * @param expiration_time When does the content expire
2604  * @param current_destination 
2605  * @param current_source 
2606  * @param target_peer Peer to which this message will be forwarded.
2607  * @param hop_count Number of hops traversed so far.
2608  * @param put_path_length Total number of peers in @a put_path
2609  * @param put_path Number of peers traversed so far 
2610  */
2611 void
2612 GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
2613                          const void *data, size_t data_size,
2614                          enum GNUNET_BLOCK_Type block_type,
2615                          enum GNUNET_DHT_RouteOption options,
2616                          uint32_t desired_replication_level,
2617                          struct GNUNET_TIME_Absolute expiration_time,
2618                          struct GNUNET_PeerIdentity current_destination,
2619                          struct GNUNET_PeerIdentity current_source,
2620                          struct GNUNET_PeerIdentity *target_peer,
2621                          uint32_t hop_count,
2622                          uint32_t put_path_length,
2623                          struct GNUNET_PeerIdentity *put_path)
2624 {
2625   struct PeerPutMessage *ppm;
2626   struct P2PPendingMessage *pending;
2627   struct FriendInfo *target_friend;
2628   struct GNUNET_PeerIdentity *pp;
2629   size_t msize;
2630
2631   msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2632           sizeof (struct PeerPutMessage);
2633   
2634   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2635   {
2636     put_path_length = 0;
2637     msize = data_size + sizeof (struct PeerPutMessage);
2638   }
2639   
2640   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2641   {
2642     GNUNET_break (0);
2643     return;
2644   }
2645   
2646   /* This is the first call made from clients file. So, we should search for the
2647      target_friend. */
2648   if (NULL == target_peer)
2649   {
2650     uint64_t key_value;
2651     struct GNUNET_PeerIdentity *next_hop;
2652    
2653     memcpy (&key_value, key, sizeof (uint64_t));
2654     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
2655     if (0 == GNUNET_CRYPTO_cmp_peer_identity(next_hop, &my_identity)) /* I am the destination do datacache_put */
2656     {
2657       GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
2658                                 block_type, data_size, data);
2659       return;
2660     }
2661     else
2662       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);   
2663   }
2664   
2665   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2666   pending->timeout = expiration_time;
2667   ppm = (struct PeerPutMessage *) &pending[1];
2668   pending->msg = &ppm->header;
2669   ppm->header.size = htons (msize);
2670   ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
2671   ppm->options = htonl (options);
2672   ppm->block_type = htonl (block_type);
2673   ppm->hop_count = htonl (hop_count + 1);
2674   ppm->desired_replication_level = htonl (desired_replication_level);
2675   ppm->put_path_length = htonl (put_path_length);
2676   ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
2677   ppm->key = *key;
2678   ppm->current_destination = current_destination;
2679   ppm->current_source = current_source;
2680  
2681   pp = (struct GNUNET_PeerIdentity *) &ppm[1];
2682   if (put_path_length != 0)
2683   {
2684     memcpy (pp, put_path,
2685             sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2686   }
2687   memcpy (&pp[put_path_length], data, data_size);
2688   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2689   target_friend->pending_count++;
2690   process_friend_queue (target_friend);
2691 }
2692
2693
2694
2695 /** 
2696  * Construct a Get message and send it to target_peer. 
2697  * @param key Key for the content  
2698  * @param block_type Type of the block
2699  * @param options Routing options
2700  * @param desired_replication_level Desired replication count
2701  * @param expiration_time When does the content expire
2702  * @param current_destination 
2703  * @param current_source 
2704  * @param target_peer Peer to which this message will be forwarded.
2705  * @param hop_count Number of hops traversed so far.
2706  * @param put_path_length Total number of peers in @a put_path
2707  * @param put_path Number of peers traversed so far 
2708  */
2709 void
2710 GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2711                          enum GNUNET_BLOCK_Type block_type,
2712                          enum GNUNET_DHT_RouteOption options,
2713                          uint32_t desired_replication_level,
2714                          struct GNUNET_PeerIdentity current_destination,
2715                          struct GNUNET_PeerIdentity current_source,
2716                          struct GNUNET_PeerIdentity *target_peer,
2717                          uint32_t hop_count,
2718                          uint32_t get_path_length,
2719                          struct GNUNET_PeerIdentity *get_path)
2720 {
2721   struct PeerGetMessage *pgm;
2722   struct P2PPendingMessage *pending;
2723   struct FriendInfo *target_friend;
2724   struct GNUNET_PeerIdentity *gp;
2725   size_t msize;
2726
2727   msize = sizeof (struct PeerGetMessage) + 
2728           (get_path_length * sizeof (struct GNUNET_PeerIdentity));
2729   
2730   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2731   {
2732     GNUNET_break (0);
2733     return;
2734   }
2735   
2736   if (NULL == target_peer)
2737   {
2738     /* This is the first call from client file, we need to search for next_hop*/
2739     struct GNUNET_PeerIdentity *next_hop;
2740     uint64_t key_value;
2741     
2742     memcpy (&key_value, key, sizeof (uint64_t));
2743         // FIXME: endianess of key_value!?
2744     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);
2745     if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity,next_hop)) /* I am the destination do datacache_put */
2746     {
2747       GDS_DATACACHE_handle_get (key,block_type, NULL, 0, 
2748                                 NULL, 0, 1, &my_identity, NULL,&my_identity);
2749       return;
2750     }
2751     else
2752     {
2753       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2754     }
2755   }
2756   
2757   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2758   pending->importance = 0;    /* FIXME */
2759   pgm = (struct PeerGetMessage *) &pending[1];
2760   pending->msg = &pgm->header;
2761   pgm->header.size = htons (msize);
2762   pgm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
2763   pgm->get_path_length = htonl (get_path_length);
2764   pgm->key = *key;
2765   pgm->current_destination = current_destination;
2766   pgm->current_source = current_source;
2767   pgm->hop_count = htonl (hop_count + 1);
2768   
2769   if (get_path != 0)
2770   {
2771     gp = (struct GNUNET_PeerIdentity *) &pgm[1];
2772     memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
2773   }
2774   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2775   target_friend->pending_count++;
2776   process_friend_queue (target_friend);
2777 }
2778
2779
2780 /**
2781  * Send the get result to requesting client.
2782  * @param expiration When will this result expire?
2783  * @param key Key of the requested data.
2784  * @param put_path_length Number of peers in @a put_path
2785  * @param put_path Path taken to put the data at its stored location.
2786  * @param type Block type
2787  * @param data_size Size of the @a data 
2788  * @param data Payload to store
2789  * @param get_path Path taken to reach to the location of the key.
2790  * @param get_path_length Number of peers in @a get_path
2791  * @param next_hop Next peer to forward the message to. 
2792  * @param source_peer Peer which has the data for the key.
2793  */
2794 void 
2795 GDS_NEIGHBOURS_send_get_result (struct GNUNET_TIME_Absolute expiration,
2796                                 const struct GNUNET_HashCode *key,
2797                                 unsigned int put_path_length,
2798                                 const struct GNUNET_PeerIdentity *put_path,
2799                                 enum GNUNET_BLOCK_Type type, size_t data_size,
2800                                 const void *data,
2801                                 struct GNUNET_PeerIdentity *get_path,
2802                                 unsigned int get_path_length,
2803                                 struct GNUNET_PeerIdentity *next_hop,
2804                                 struct GNUNET_PeerIdentity *source_peer)
2805 {
2806   struct PeerGetResultMessage *get_result;
2807   struct GNUNET_PeerIdentity *get_result_path;
2808   struct GNUNET_PeerIdentity *pp;
2809   struct P2PPendingMessage *pending;
2810   struct FriendInfo *target_friend;
2811   int current_path_index;
2812   size_t msize;
2813   
2814   msize = get_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
2815           sizeof (struct PeerPutMessage);
2816  
2817   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2818   {
2819     GNUNET_break (0);
2820     return;
2821   }
2822   
2823   if(get_path_length > 0)
2824   {
2825     current_path_index = search_my_index(get_path, get_path_length);
2826     if (GNUNET_SYSERR == current_path_index)
2827     {
2828       /* FIXME: This assertion always fails. FIX IT. */
2829       GNUNET_break (0);
2830       return;
2831     }
2832   }
2833   if (0 == current_path_index)
2834   {
2835     GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length,
2836                               put_path, type, data_size, data);
2837     return;
2838   }
2839   
2840   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
2841   pending->importance = 0;   
2842   get_result = (struct PeerGetResultMessage *)&pending[1];
2843   pending->msg = &get_result->header;
2844   get_result->header.size = htons (msize);
2845   get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT);
2846   get_result->key = *key;
2847   memcpy (&(get_result->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2848   get_result->expiration_time = expiration;
2849   
2850   if (get_path_length != 0)
2851   {
2852     get_result_path = (struct GNUNET_PeerIdentity *)&get_result[1];
2853     memcpy (get_result_path, get_path,
2854             sizeof (struct GNUNET_PeerIdentity) * get_path_length);
2855   }
2856   memcpy (&get_result_path[get_path_length], data, data_size);
2857   
2858   /* FIXME: Is this correct? */
2859   if (put_path_length != 0)
2860   {
2861     pp = (struct GNUNET_PeerIdentity *)&get_result_path[1];
2862     memcpy (pp, put_path,sizeof (struct GNUNET_PeerIdentity) * put_path_length);
2863   }
2864   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2865   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2866   target_friend->pending_count++;
2867   process_friend_queue (target_friend);
2868 }
2869
2870
2871 /**
2872  * Send trail rejection message to the peer which sent me a trail setup message. 
2873  * @param source_peer Source peer which wants to set up the trail.
2874  * @param finger_identity Value whose successor will be the finger of @a source_peer.
2875  * @param congested_peer Peer which has send trail rejection message.
2876  * @param next_hop Peer to which this message should be forwarded.
2877  * @param finger_map_index Index in @a source_peer finger peermap.
2878  * @param trail_peer_list Trail followed to reach from @a source_peer to next_hop,
2879  *                        NULL, in case the @a congested_peer was the first peer 
2880  *                        to which trail setup message was forwarded.
2881  * @param trail_length Number of peers in trail_peer_list. 
2882  */
2883 void
2884 GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_peer,
2885                                      uint64_t finger_identity,
2886                                      const struct GNUNET_PeerIdentity *congested_peer,
2887                                      const struct GNUNET_PeerIdentity *next_hop,
2888                                      unsigned int finger_map_index,
2889                                      struct GNUNET_PeerIdentity *trail_peer_list,
2890                                      unsigned int trail_length)
2891 {
2892   struct PeerTrailRejectionMessage *trail_rejection;
2893   struct GNUNET_PeerIdentity *trail_list;
2894   struct P2PPendingMessage *pending;
2895   struct FriendInfo *target_friend;
2896   size_t msize;
2897   
2898   msize = trail_length * sizeof(struct GNUNET_PeerIdentity) +
2899           sizeof (struct PeerTrailRejectionMessage);
2900   
2901   if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2902   {
2903     GNUNET_break (0);
2904     return;
2905   }
2906   
2907   pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize); 
2908   pending->importance = 0;    
2909   pending->timeout = GNUNET_TIME_relative_to_absolute (GET_TIMEOUT);
2910   trail_rejection = (struct PeerTrailRejectionMessage *) &pending[1]; 
2911   pending->msg = &trail_rejection->header;
2912   trail_rejection->header.size = htons (msize);
2913   trail_rejection->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP);
2914   memcpy (&(trail_rejection->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
2915   memcpy (&(trail_rejection->congested_peer), congested_peer, sizeof (struct GNUNET_PeerIdentity));
2916   memcpy (&(trail_rejection->finger_identity_value), &finger_identity, sizeof (uint64_t));
2917   trail_rejection->finger_map_index = htonl (finger_map_index);
2918   trail_rejection->trail_length = htonl (trail_length);
2919   
2920   if (trail_length != 0)
2921   {
2922     trail_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
2923     memcpy (trail_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
2924   }
2925   
2926   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
2927   GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
2928   target_friend->pending_count++;
2929   process_friend_queue (target_friend);
2930 }
2931
2932
2933 /**
2934  * Core handler for P2P put messages. 
2935  * @param cls closure
2936  * @param peer sender of the request
2937  * @param message message
2938  * @return #GNUNET_OK to keep the connection open,
2939  *         #GNUNET_SYSERR to close it (signal serious error)
2940  */
2941 static int 
2942 handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
2943                     const struct GNUNET_MessageHeader *message)
2944 {
2945   struct PeerPutMessage *put;
2946   struct GNUNET_PeerIdentity *put_path;
2947   struct GNUNET_HashCode test_key;
2948   enum GNUNET_DHT_RouteOption options;
2949   struct GNUNET_PeerIdentity current_destination;
2950   struct GNUNET_PeerIdentity current_source;
2951   struct GNUNET_PeerIdentity *next_hop;
2952   void *payload;
2953   size_t msize;
2954   uint32_t putlen;
2955   size_t payload_size;
2956   uint64_t key_value;
2957   
2958   msize = ntohs (message->size);
2959   if (msize < sizeof (struct PeerPutMessage))
2960   {
2961     GNUNET_break_op (0);
2962     return GNUNET_YES;
2963   }
2964   
2965   put = (struct PeerPutMessage *) message;
2966   putlen = ntohl (put->put_path_length);
2967    
2968   if ((msize <
2969        sizeof (struct PeerPutMessage) +
2970        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
2971       (putlen >
2972        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2973   {
2974     GNUNET_break_op (0);
2975     return GNUNET_YES;
2976   }
2977
2978   current_destination = put->current_destination;
2979   current_source = put->current_source;
2980   put_path = (struct GNUNET_PeerIdentity *) &put[1];
2981   payload = &put_path[putlen];
2982   options = ntohl (put->options);
2983   payload_size = msize - (sizeof (struct PeerPutMessage) + 
2984                           putlen * sizeof (struct GNUNET_PeerIdentity));
2985   
2986   switch (GNUNET_BLOCK_get_key (GDS_block_context, ntohl (put->block_type),
2987                                 payload, payload_size, &test_key))
2988   {
2989     case GNUNET_YES:
2990       if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
2991       {
2992         char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
2993         GNUNET_break_op (0);
2994         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2995                     "PUT with key `%s' for block with key %s\n",
2996                      put_s, GNUNET_h2s_full (&test_key));
2997         GNUNET_free (put_s);
2998         return GNUNET_YES;
2999       }
3000     break;
3001     case GNUNET_NO:
3002       GNUNET_break_op (0);
3003       return GNUNET_YES;
3004     case GNUNET_SYSERR:
3005       /* cannot verify, good luck */
3006       break;
3007   }
3008   
3009    if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
3010   {
3011     switch (GNUNET_BLOCK_evaluate (GDS_block_context,
3012                                    ntohl (put->block_type),
3013                                    NULL,    /* query */
3014                                    NULL, 0, /* bloom filer */
3015                                    NULL, 0, /* xquery */
3016                                    payload, payload_size))
3017     {
3018     case GNUNET_BLOCK_EVALUATION_OK_MORE:
3019     case GNUNET_BLOCK_EVALUATION_OK_LAST:
3020       break;
3021
3022     case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
3023     case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
3024     case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
3025     case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
3026     case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
3027     case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
3028     default:
3029       GNUNET_break_op (0);
3030       return GNUNET_OK;
3031     }
3032   }
3033   
3034    struct GNUNET_PeerIdentity pp[putlen + 1];
3035   /* extend 'put path' by sender */
3036   /* FIXME: Check what are we doing here? */
3037   if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
3038   {
3039     memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
3040     pp[putlen] = *peer;
3041     putlen++;
3042   }
3043   else
3044     putlen = 0;
3045   
3046   memcpy (&key_value, &(put->key), sizeof (uint64_t));
3047   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3048   {
3049     GDS_ROUTING_print();
3050     next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3051     if (next_hop == NULL)
3052     {
3053        /* refer to handle_dht_p2p_trail_setup. */
3054     }
3055   }
3056   else
3057   {
3058     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST); 
3059   }
3060   
3061   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop)) /* I am the final destination */
3062   {
3063     GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
3064                               &(put->key),putlen, pp, ntohl (put->block_type), 
3065                               payload_size, payload);
3066      return GNUNET_YES;
3067   }
3068   else
3069   {
3070     GDS_CLIENTS_process_put (options,
3071                               ntohl (put->block_type),
3072                               ntohl (put->hop_count),
3073                               ntohl (put->desired_replication_level),
3074                               putlen, pp,
3075                               GNUNET_TIME_absolute_ntoh (put->expiration_time),
3076                               &put->key,
3077                               payload,
3078                               payload_size);
3079     GDS_NEIGHBOURS_send_put (&put->key, payload, payload_size, 
3080                              ntohl (put->block_type),ntohl (put->options),
3081                              ntohl (put->desired_replication_level),
3082                              GNUNET_TIME_absolute_ntoh (put->expiration_time),
3083                              current_destination, current_source, next_hop,
3084                              ntohl (put->hop_count), putlen, pp);
3085  
3086      return GNUNET_YES;
3087   }
3088   return GNUNET_SYSERR;
3089 }
3090
3091
3092 /**
3093  * Core handler for p2p get requests.
3094  *
3095  * @param cls closure
3096  * @param peer sender of the request
3097  * @param message message
3098  * @return #GNUNET_OK to keep the connection open,
3099  *         #GNUNET_SYSERR to close it (signal serious error)
3100  */
3101 static int
3102 handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
3103                     const struct GNUNET_MessageHeader *message)
3104 {
3105   struct PeerGetMessage *get;
3106   struct GNUNET_PeerIdentity *get_path;
3107   struct GNUNET_PeerIdentity current_destination;
3108   struct GNUNET_PeerIdentity current_source;
3109   struct GNUNET_PeerIdentity *next_hop;
3110   uint32_t get_length;
3111   uint64_t key_value;
3112   size_t msize;
3113   
3114   msize = ntohs (message->size);
3115   if (msize < sizeof (struct PeerGetMessage))
3116   {
3117     GNUNET_break_op (0);
3118     return GNUNET_YES;
3119   }
3120   
3121   get = (struct PeerGetMessage *)message;
3122   get_length = ntohl (get->get_path_length);
3123   get_path = (struct GNUNET_PeerIdentity *)&get[1];
3124   current_destination = get->current_destination;
3125   current_source = get->current_source;
3126   
3127   if ((msize <
3128        sizeof (struct PeerGetMessage) +
3129        get_length * sizeof (struct GNUNET_PeerIdentity)) ||
3130        (get_length >
3131         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3132   {
3133     GNUNET_break_op (0);
3134     return GNUNET_YES; 
3135   }
3136
3137   /* Add sender to get path */
3138   struct GNUNET_PeerIdentity gp[get_length + 1];
3139   memcpy (gp, get_path, get_length * sizeof (struct GNUNET_PeerIdentity));
3140   gp[get_length + 1] = *peer;
3141   get_length = get_length + 1;
3142   
3143   memcpy (&key_value, &(get->key), sizeof (uint64_t));
3144   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3145   {
3146     GDS_ROUTING_print();
3147     next_hop = GDS_ROUTING_search (&current_source, &current_destination, peer);
3148     if (next_hop == NULL)
3149     {
3150        /* refer to handle_dht_p2p_trail_setup. */
3151     }
3152   }
3153   else
3154   {
3155     next_hop = find_successor (key_value, &current_destination, &current_source,PUT_GET_REQUEST);  
3156   }
3157   
3158   if (0 == GNUNET_CRYPTO_cmp_peer_identity(&my_identity, next_hop))
3159   {
3160     /* I am the destination.*/
3161     struct GNUNET_PeerIdentity final_get_path[get_length+1];
3162     struct GNUNET_PeerIdentity next_hop;
3163
3164     memcpy (final_get_path, gp, get_length * sizeof (struct GNUNET_PeerIdentity));
3165     memcpy (&final_get_path[get_length+1], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3166     get_length = get_length + 1;
3167     memcpy (&next_hop, &final_get_path[get_length-2], sizeof (struct GNUNET_PeerIdentity));
3168     GDS_DATACACHE_handle_get (&(get->key),(get->block_type), NULL, 0, NULL, 0,
3169                               get_length, final_get_path,&next_hop, &my_identity);
3170
3171     return GNUNET_YES;
3172   }
3173   else
3174   {
3175     GDS_NEIGHBOURS_send_get (&(get->key), get->block_type, get->options, 
3176                              get->desired_replication_level,current_destination,
3177                              current_source, next_hop, 0,
3178                              get_length, gp);  
3179   }
3180   return GNUNET_SYSERR;
3181 }
3182
3183
3184 /**
3185  * FIXME: In case of trail, we don't have source and destination part of the trail,
3186  * Check if we follow the same in case of get/put/get_result. Also, in case of 
3187  * put should we do a routing table add.
3188  * Core handler for get result
3189  * @param cls closure
3190  * @param peer sender of the request
3191  * @param message message
3192  * @return #GNUNET_OK to keep the connection open,
3193  *         #GNUNET_SYSERR to close it (signal serious error)
3194  */
3195 static int
3196 handle_dht_p2p_get_result (void *cls, const struct GNUNET_PeerIdentity *peer,
3197                            const struct GNUNET_MessageHeader *message)
3198 {
3199   struct PeerGetResultMessage *get_result;
3200   struct GNUNET_PeerIdentity *get_path;
3201   struct GNUNET_PeerIdentity *put_path;
3202   void *payload;
3203   size_t payload_size;
3204   size_t msize;
3205   unsigned int getlen;
3206   unsigned int putlen;
3207   int current_path_index;
3208   
3209   msize = ntohs (message->size);
3210   if (msize < sizeof (struct PeerGetResultMessage))
3211   {
3212     GNUNET_break_op (0);
3213     return GNUNET_YES;
3214   }
3215   
3216   get_result = (struct PeerGetResultMessage *)message;
3217   getlen = ntohl (get_result->get_path_length);
3218   putlen = ntohl (get_result->put_path_length);
3219   
3220   if ((msize <
3221        sizeof (struct PeerGetResultMessage) +
3222        getlen * sizeof (struct GNUNET_PeerIdentity) + 
3223        putlen * sizeof (struct GNUNET_PeerIdentity)) ||
3224       (getlen >
3225        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) ||
3226       (putlen >
3227          GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))))
3228   {
3229     GNUNET_break_op (0);
3230     return GNUNET_YES;
3231   }
3232   
3233   get_path = (struct GNUNET_PeerIdentity *) &get_result[1];
3234   payload = &get_path[getlen];
3235   payload_size = msize - (sizeof (struct PeerGetResultMessage) + 
3236                           getlen * sizeof (struct GNUNET_PeerIdentity));
3237   /* FIXME: Check if its correct or not. */
3238
3239   if (putlen > 0)
3240     put_path = &get_path[1];
3241   else
3242     put_path = NULL;
3243   
3244   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(get_path[0]))))
3245   {
3246     GDS_CLIENTS_handle_reply (get_result->expiration_time, &(get_result->key), 
3247                               getlen, get_path, putlen,
3248                               put_path, get_result->type, payload_size, payload);
3249     return GNUNET_YES;
3250   }
3251   else
3252   {
3253     struct GNUNET_PeerIdentity *next_hop;
3254     next_hop = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
3255     /* FIXME: handle the case when current_path_index = GNUNET_SYSERR;*/
3256     current_path_index = search_my_index (get_path, getlen);
3257     /* FIXME: First check if you are adding yourself to the get path or not.
3258      if yes then don't check if current_path_index == 0, if not then check 
3259      and next_hop == source_peer. */
3260     memcpy (next_hop, &get_path[current_path_index - 1], sizeof (struct GNUNET_PeerIdentity));
3261   
3262     GDS_NEIGHBOURS_send_get_result (get_result->expiration_time, &(get_result->key),
3263                                      putlen, put_path,
3264                                      get_result->type, payload_size,payload,
3265                                      get_path, getlen,
3266                                      next_hop, &(get_result->source_peer));
3267     return GNUNET_YES;
3268   }  
3269   return GNUNET_SYSERR;
3270 }
3271
3272
3273 /**
3274  * FIXME: URGENT: refactor it. 
3275  * FIXME; now we can make a new ds to store 2 peers and one value as we are
3276  * using it at two places. Will complete the logic and then add a new ds.
3277  * In case finger map index is 64 do we need to call find_closest_predecessor? 
3278  * Select the closest peer.
3279  * @param prev_hop
3280  * @param current_destination
3281  * @param current_source
3282  * @param value
3283  * @para finger_map_index
3284  * @return Peer which is closest, in case of error NULL.
3285  */
3286 struct GNUNET_PeerIdentity *
3287 select_closest_peer (const struct GNUNET_PeerIdentity *prev_hop,
3288                      struct GNUNET_PeerIdentity *current_destination,
3289                      struct GNUNET_PeerIdentity *current_source,
3290                      uint64_t value,
3291                      unsigned int finger_map_index)
3292 {
3293   struct GNUNET_PeerIdentity *peer1;
3294   struct GNUNET_PeerIdentity *peer2;
3295   struct Sorting_List peers[3];
3296   struct Sorting_List *closest_finger;
3297   
3298   peer1 = GDS_ROUTING_search (current_source, current_destination, prev_hop);
3299   peer2 = find_successor (value, current_destination, current_source,finger_map_index);
3300   
3301   /* SUPU TEST CODE */
3302   struct GNUNET_PeerIdentity print_peer;
3303   memcpy (&print_peer, &peer1, sizeof (struct GNUNET_PeerIdentity));
3304   FPRINTF (stderr,_("\nSUPU  %s, %s, %d,routing_peer = %s"), __FILE__, __func__,__LINE__,GNUNET_i2s(&print_peer));
3305   memcpy (&print_peer, &peer2, sizeof (struct GNUNET_PeerIdentity));
3306   FPRINTF (stderr,_("\nSUPU  %s, %s, %d,find_successor_peer = %s"), __FILE__, __func__,__LINE__,GNUNET_i2s(&print_peer));
3307   /* SUPU TEST CODE ENDS*/
3308   if( (peer1 != NULL) && (peer2 != NULL))
3309   {
3310     /* Add peer 1 to the list. */
3311     memcpy (&peers[0], &peer1, sizeof (uint64_t));
3312     peers[0].type = FINGER;
3313     peers[0].data = NULL;
3314   
3315     /* Add peer 2 to the list. */
3316     memcpy (&peers[1], &peer1, sizeof (uint64_t));
3317     peers[0].type = FRIEND;
3318     peers[0].data = NULL;
3319   
3320     /* Add value to the list. */
3321     memcpy (&peers[2], &peer1, sizeof (uint64_t));
3322     peers[0].type = VALUE;
3323     peers[0].data = NULL;
3324   
3325     qsort (&peers, 3, sizeof (struct Sorting_List), &compare_peer_id);
3326     if (PREDECESSOR_FINGER_ID == finger_map_index)
3327       closest_finger = find_closest_predecessor (peers, value, 3);
3328     else
3329       closest_finger = find_closest_successor (peers, value, 3);
3330     
3331     /* SUPU TEST CODE*/
3332     if (closest_finger->type == FINGER)
3333     {
3334       FPRINTF (stderr,_("\nSUPU  %s, %s, %d"), __FILE__, __func__,__LINE__);
3335       return peer2;
3336     }
3337     else if (closest_finger->type == VALUE)
3338     { 
3339       return NULL;
3340     }
3341     else if (closest_finger->type == FRIEND);
3342     {
3343       /* If we are returning peer2 then find_successor has already taken care
3344        of setting up current_destination and current_source. */
3345       return peer1;  
3346     }
3347   }
3348   else if ((peer1 == NULL) && (peer2 == NULL))
3349   {
3350     return NULL;
3351   }
3352   else if (peer1 == NULL)
3353   {
3354     return peer2;
3355   }
3356   else if (peer2 == NULL)
3357   {
3358     return peer1;
3359   }
3360   return NULL;
3361 }
3362
3363
3364 /** 
3365  * Core handle for PeerTrailSetupMessage. 
3366  * @param cls closure
3367  * @param message message
3368  * @param peer peer identity this notification is about
3369  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3370  */
3371 static int
3372 handle_dht_p2p_trail_setup (void *cls, const struct GNUNET_PeerIdentity *peer,
3373                             const struct GNUNET_MessageHeader *message)
3374 {
3375   const struct PeerTrailSetupMessage *trail_setup; 
3376   struct GNUNET_PeerIdentity current_destination;
3377   struct GNUNET_PeerIdentity current_source;
3378   struct GNUNET_PeerIdentity source;
3379   struct GNUNET_PeerIdentity *next_hop;
3380   struct GNUNET_PeerIdentity next_peer;
3381   struct GNUNET_PeerIdentity *trail_peer_list;
3382   struct FriendInfo *target_friend;
3383   uint64_t destination_finger_value;
3384   uint32_t trail_length;
3385   uint32_t finger_map_index;
3386   size_t msize;
3387
3388   msize = ntohs (message->size);
3389   if (msize < sizeof (struct PeerTrailSetupMessage))
3390   {
3391     GNUNET_break_op (0);
3392     return GNUNET_YES;
3393   }
3394   
3395   trail_setup = (const struct PeerTrailSetupMessage *) message; 
3396   trail_length = ntohl (trail_setup->trail_length); 
3397  
3398   if ((msize < sizeof (struct PeerTrailSetupMessage) +
3399        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3400        (trail_length >
3401         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3402   {
3403     GNUNET_break_op (0);
3404     return GNUNET_OK; 
3405   }
3406   
3407   if (trail_length > 0)
3408     trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_setup[1];
3409   memcpy (&current_destination, &(trail_setup->current_destination), sizeof (struct GNUNET_PeerIdentity));
3410   memcpy (&current_source,&(trail_setup->current_source), sizeof (struct GNUNET_PeerIdentity));
3411   memcpy (&source, &(trail_setup->source_peer), sizeof (struct GNUNET_PeerIdentity));
3412   finger_map_index = ntohl (trail_setup->finger_map_index);
3413   destination_finger_value = ntohl (trail_setup->destination_finger);
3414   
3415   /* Check your routing table size, and if you can handle any more trails through you. */
3416   if (GNUNET_YES == GDS_ROUTING_check_threshold())
3417   {
3418     GDS_NEIGHBOURS_send_trail_rejection (&source, destination_finger_value, &my_identity,
3419                                          peer, finger_map_index, trail_peer_list, trail_length);
3420     return GNUNET_OK;
3421   }
3422   
3423    /* Check if you are current_destination or not. */
3424   if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_destination, &my_identity)))
3425   {
3426     next_hop = select_closest_peer (peer, &current_destination, &current_source,
3427                                     destination_finger_value, finger_map_index);
3428   }
3429   else
3430   {
3431     next_hop = find_successor (destination_finger_value, &current_destination, 
3432                                &current_source,finger_map_index); 
3433   } 
3434   
3435   if (NULL == next_hop)
3436   {
3437     GNUNET_STATISTICS_update (GDS_stats,
3438                                 gettext_noop ("# Trail not found in routing table during"
3439                                 "trail setup request, packet dropped."),
3440                                 1, GNUNET_NO);
3441     return GNUNET_SYSERR;
3442   }
3443   else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)))/* This means I am the final destination */
3444   {
3445     if (trail_length == 0)
3446     {
3447       memcpy (&next_peer, &source, sizeof (struct GNUNET_PeerIdentity));
3448     }
3449     else
3450     {
3451       memcpy (&next_peer, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3452     }
3453     
3454     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer);
3455     GDS_NEIGHBOURS_send_trail_setup_result (&source,
3456                                             &(my_identity),
3457                                             target_friend, trail_length,
3458                                             trail_peer_list,
3459                                             finger_map_index);
3460     return GNUNET_OK;
3461   }
3462   else
3463   {
3464     /* Now add yourself to the trail. */
3465     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
3466     if (trail_length != 0)
3467       memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
3468     peer_list[trail_length] = my_identity;
3469     trail_length++;
3470     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
3471     GDS_NEIGHBOURS_send_trail_setup (&source,
3472                                      destination_finger_value,
3473                                      &current_destination, &current_source,
3474                                      target_friend, trail_length, peer_list, 
3475                                      finger_map_index);
3476      return GNUNET_OK;
3477   }
3478 }
3479
3480
3481 /**
3482  * Core handle for p2p trail construction result messages.
3483  * @param closure
3484  * @param message message
3485  * @param peer peer identity this notification is about
3486  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3487  */
3488 static int
3489 handle_dht_p2p_trail_setup_result(void *cls, const struct GNUNET_PeerIdentity *peer,
3490                                   const struct GNUNET_MessageHeader *message)
3491 {
3492   const struct PeerTrailSetupResultMessage *trail_result;
3493   struct GNUNET_PeerIdentity *trail_peer_list;
3494   struct GNUNET_PeerIdentity destination_peer;
3495   struct GNUNET_PeerIdentity finger_identity;    
3496   uint32_t trail_length;
3497   uint32_t finger_map_index;
3498   size_t msize;
3499   
3500   msize = ntohs (message->size);
3501   if (msize < sizeof (struct PeerTrailSetupResultMessage))
3502   {
3503     GNUNET_break_op (0);
3504     return GNUNET_YES;
3505   }
3506   
3507   trail_result = (const struct PeerTrailSetupResultMessage *) message; 
3508   trail_length = ntohl (trail_result->trail_length); 
3509   
3510   if ((msize <
3511        sizeof (struct PeerTrailSetupResultMessage) +
3512        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3513        (trail_length >
3514         GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3515   {
3516     GNUNET_break_op (0);
3517     return GNUNET_YES;
3518   }
3519   
3520   finger_map_index = htonl (trail_result->finger_map_index);
3521   memcpy (&destination_peer, &(trail_result->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3522   memcpy (&finger_identity, &(trail_result->finger_identity), sizeof (struct GNUNET_PeerIdentity));
3523   
3524   if (trail_length > 0)
3525     trail_peer_list = (struct GNUNET_PeerIdentity *) &trail_result[1];
3526   
3527   
3528   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3529                                              &my_identity)))
3530   {
3531     finger_table_add (&(trail_result->finger_identity), trail_peer_list, trail_length, 
3532                       finger_map_index);
3533     return GNUNET_YES;
3534   }
3535   else
3536   {
3537     struct GNUNET_PeerIdentity next_hop;
3538     struct FriendInfo *target_friend;
3539     int my_index;
3540     
3541     my_index =  search_my_index (trail_peer_list, trail_length);
3542     if (my_index == GNUNET_SYSERR)
3543       return GNUNET_SYSERR;
3544     
3545     if (my_index == 0)
3546     {
3547       next_hop = trail_result->destination_peer;
3548     }
3549     else
3550       next_hop = trail_peer_list[my_index - 1];
3551   
3552     if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&(trail_result->destination_peer),
3553                                                &(trail_result->finger_identity))))
3554     {
3555       struct GNUNET_PeerIdentity *routing_next_hop;
3556       
3557       routing_next_hop = GDS_ROUTING_search (&destination_peer,&finger_identity,
3558                                              peer);
3559       if ((NULL == routing_next_hop) || 
3560           (0 != GNUNET_CRYPTO_cmp_peer_identity(routing_next_hop, &next_hop)))
3561       {
3562         GDS_ROUTING_add (&(trail_result->destination_peer), &(trail_result->finger_identity),
3563                          peer, &next_hop);
3564       }
3565       GDS_ROUTING_print();
3566     }
3567     
3568     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3569     GDS_NEIGHBOURS_send_trail_setup_result (&(trail_result->destination_peer),
3570                                             &(trail_result->finger_identity),
3571                                             target_friend, trail_length,
3572                                             trail_peer_list,
3573                                             finger_map_index);
3574     return GNUNET_YES;
3575   }
3576   return GNUNET_SYSERR;
3577 }
3578
3579
3580 /**
3581  * Get my current predecessor from the finger peer map
3582  * @return Current predecessor.
3583  */
3584 static struct FingerInfo *
3585 get_predecessor()
3586 {
3587   struct GNUNET_CONTAINER_MultiPeerMapIterator *finger_iter;
3588   struct GNUNET_PeerIdentity key_ret;
3589   unsigned int finger_index;
3590   struct FingerInfo *my_predecessor;
3591   int flag = 0;
3592  
3593   /* Iterate over finger peer map and extract your predecessor. */
3594   finger_iter = GNUNET_CONTAINER_multipeermap_iterator_create (finger_peermap);  
3595   for (finger_index = 0; finger_index < GNUNET_CONTAINER_multipeermap_size (finger_peermap); finger_index++)
3596   {
3597     if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next 
3598                        (finger_iter,&key_ret,(const void **)&my_predecessor)) 
3599     {
3600       if(PREDECESSOR_FINGER_ID == my_predecessor->finger_map_index)
3601       {
3602         flag = 1;
3603         break;
3604       }
3605     }
3606   }
3607   GNUNET_CONTAINER_multipeermap_iterator_destroy (finger_iter);
3608   
3609   if (0 == flag)
3610     return NULL;
3611   else
3612     return my_predecessor;
3613 }
3614
3615
3616 /**
3617  * Core handle for p2p verify successor messages.
3618  * @param cls closure
3619  * @param message message
3620  * @param peer peer identity this notification is about
3621  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3622  */
3623 static int
3624 handle_dht_p2p_verify_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3625                                 const struct GNUNET_MessageHeader *message)
3626 {
3627   const struct PeerVerifySuccessorMessage *vsm;
3628   const struct GNUNET_PeerIdentity *trail_peer_list;
3629   struct GNUNET_PeerIdentity source_peer;
3630   struct GNUNET_PeerIdentity next_hop;
3631   struct FriendInfo *target_friend;
3632   size_t msize;
3633   uint32_t trail_length;
3634    
3635   msize = ntohs (message->size);
3636   if (msize < sizeof (struct PeerVerifySuccessorMessage))
3637   {
3638     GNUNET_break_op (0);
3639     return GNUNET_YES;
3640   }
3641   
3642   vsm = (struct PeerVerifySuccessorMessage *) message;
3643   trail_length = ntohl (vsm->trail_length);
3644   
3645   if ((msize < sizeof (struct PeerVerifySuccessorMessage) +
3646                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3647       (trail_length > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3648   {
3649     GNUNET_break_op (0);
3650     return GNUNET_YES;
3651   }
3652   if (trail_length > 0)
3653     trail_peer_list = (const struct GNUNET_PeerIdentity *)&vsm[1];
3654   memcpy (&source_peer, &(vsm->source_peer), sizeof(struct GNUNET_PeerIdentity));
3655   
3656   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsm->successor),&my_identity)))
3657   {
3658     struct FingerInfo *my_predecessor;
3659     if (trail_length == 0)
3660     {
3661       memcpy (&next_hop, &source_peer, sizeof (struct GNUNET_PeerIdentity));
3662     }
3663     else
3664     {
3665       memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
3666     }
3667     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3668     
3669     my_predecessor = get_predecessor();
3670     if (NULL == my_predecessor)
3671     {
3672       /* FIXME: should we just return. */
3673       return GNUNET_OK;
3674     }
3675     
3676     if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&source_peer,
3677                                                &(my_predecessor->finger_identity))))
3678     {
3679       /* Source peer and my predecessor, both are same. */
3680       GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
3681                                                    &(my_identity),
3682                                                    &(my_predecessor->finger_identity),
3683                                                    target_friend,
3684                                                    trail_peer_list,
3685                                                    trail_length);
3686     }
3687     else
3688     {
3689       struct GNUNET_PeerIdentity *new_successor_trail;
3690       struct TrailPeerList *iterator;
3691       int new_trail_length;
3692       int i;
3693
3694       new_trail_length = trail_length + my_predecessor->first_trail_length + 1;
3695       new_successor_trail = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * new_trail_length);
3696       if (trail_length > 0)
3697         memcpy (new_successor_trail, trail_peer_list, (trail_length) * sizeof (struct GNUNET_PeerIdentity));
3698       
3699       memcpy (&new_successor_trail[trail_length], &my_identity, sizeof (struct GNUNET_PeerIdentity));
3700      
3701       if (my_predecessor->first_trail_length)
3702       {
3703         iterator = GNUNET_malloc (sizeof (struct TrailPeerList));
3704         iterator = my_predecessor->first_trail_head; 
3705         i = trail_length + 1;
3706         while (i < new_trail_length)
3707         {
3708           memcpy (&new_successor_trail[i], &(iterator->peer), sizeof (struct GNUNET_PeerIdentity));
3709           iterator = iterator->next;
3710           i++;
3711         }
3712       }
3713       GDS_NEIGHBOURS_send_verify_successor_result (&source_peer,
3714                                                    &(my_identity),
3715                                                    &(my_predecessor->finger_identity),
3716                                                    target_friend,
3717                                                    new_successor_trail,
3718                                                    new_trail_length); 
3719     }      
3720     
3721   }
3722   else
3723   {
3724    int my_index;
3725    
3726    if (trail_length == 0)
3727    {
3728      GNUNET_break (0);
3729      return GNUNET_SYSERR;
3730    }
3731    
3732    my_index = search_my_index (trail_peer_list, trail_length);
3733    if (my_index == GNUNET_SYSERR)
3734    {
3735      GNUNET_break (0);
3736      return GNUNET_SYSERR;
3737    }
3738    if (my_index == (trail_length - 1))
3739    {
3740       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(vsm->successor));
3741    }
3742    else
3743    {
3744      memcpy (&next_hop, &trail_peer_list[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
3745      target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3746    }   
3747
3748    GDS_NEIGHBOURS_send_verify_successor (&(vsm->source_peer), &(vsm->successor),target_friend,
3749                                           trail_peer_list, trail_length); 
3750   }
3751   return GNUNET_SYSERR;
3752 }
3753
3754
3755 /**
3756  * Core handle for p2p verify successor result messages.
3757  * @param cls closure
3758  * @param message message
3759  * @param peer peer identity this notification is about
3760  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3761  */
3762 static int
3763 handle_dht_p2p_verify_successor_result(void *cls, const struct GNUNET_PeerIdentity *peer,
3764                                        const struct GNUNET_MessageHeader *message)
3765 {
3766   const struct PeerVerifySuccessorResultMessage *vsrm;
3767   struct GNUNET_PeerIdentity *trail_peer_list;
3768   struct GNUNET_PeerIdentity next_hop;
3769   struct FriendInfo *target_friend;
3770   size_t msize;
3771   uint32_t trail_length;
3772   
3773   msize = ntohs (message->size);
3774   if (msize < sizeof (struct PeerVerifySuccessorResultMessage))
3775   {
3776     GNUNET_break_op (0);
3777     return GNUNET_YES;
3778   }
3779   vsrm = (const struct PeerVerifySuccessorResultMessage *) message;
3780   trail_length = ntohl (vsrm->trail_length); 
3781   
3782   if ((msize <
3783        sizeof (struct PeerVerifySuccessorResultMessage) +
3784        trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3785        (trail_length >
3786        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3787   {
3788     GNUNET_break_op (0);
3789     return GNUNET_YES;
3790   }
3791   
3792   if (trail_length > 0)
3793     trail_peer_list = (struct GNUNET_PeerIdentity *) &vsrm[1];
3794   
3795   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->destination_peer), &(my_identity))))
3796   {
3797     if(0 != (GNUNET_CRYPTO_cmp_peer_identity (&(vsrm->my_predecessor), &(my_identity))))
3798     {
3799       if (GNUNET_YES == finger_table_add (&(vsrm->my_predecessor), trail_peer_list, trail_length, 0))
3800       {
3801         memcpy (&next_hop, &trail_peer_list[0], sizeof (struct GNUNET_PeerIdentity));
3802         target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3803         /* FIXME: first call scan_and_compress_trail and then call the notify new
3804          successor with new trail. */
3805         GDS_NEIGHBOURS_send_notify_new_successor (&my_identity, &(vsrm->my_predecessor),
3806                                                   &(vsrm->source_successor),
3807                                                   target_friend, trail_peer_list,
3808                                                   trail_length);
3809         return GNUNET_OK;
3810       }
3811       else
3812         return GNUNET_OK;
3813     }
3814   }
3815   else
3816   {
3817     int my_index;
3818     
3819     my_index = search_my_index (trail_peer_list, trail_length);
3820     if (GNUNET_SYSERR == my_index)
3821     {
3822       GNUNET_break (0);
3823       return GNUNET_SYSERR;
3824     }
3825     
3826     if (my_index == 0)
3827     {
3828       memcpy (&next_hop, &(vsrm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3829     }
3830     else
3831     {
3832       memcpy (&next_hop, &trail_peer_list[my_index-1], sizeof (struct GNUNET_PeerIdentity));
3833     }
3834     
3835     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
3836     GDS_NEIGHBOURS_send_verify_successor_result (&(vsrm->destination_peer),
3837                                                  &(vsrm->source_successor),
3838                                                  &(vsrm->my_predecessor),
3839                                                  target_friend,
3840                                                  trail_peer_list,
3841                                                  trail_length); 
3842     return GNUNET_OK;
3843   }
3844   return GNUNET_SYSERR;
3845 }
3846
3847
3848 /**
3849  * Core handle for p2p notify new successor messages.
3850  * @param cls closure
3851  * @param message message
3852  * @param peer peer identity this notification is about
3853  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3854  */
3855 static int
3856 handle_dht_p2p_notify_new_successor(void *cls, const struct GNUNET_PeerIdentity *peer,
3857                                     const struct GNUNET_MessageHeader *message)
3858 {
3859   const struct PeerNotifyNewSuccessorMessage *nsm;
3860   struct GNUNET_PeerIdentity *trail_peer_list;
3861   struct GNUNET_PeerIdentity source_peer;
3862   struct GNUNET_PeerIdentity old_successor;
3863   struct GNUNET_PeerIdentity new_successor;
3864   size_t msize;
3865   uint32_t trail_length;
3866   
3867   msize = ntohs (message->size);
3868   if (msize < sizeof (struct PeerNotifyNewSuccessorMessage))
3869   {
3870     GNUNET_break_op (0);
3871     return GNUNET_YES;
3872   }
3873   nsm = (const struct PeerNotifyNewSuccessorMessage *) message;
3874   trail_length = ntohl (nsm->trail_length);
3875   
3876   if ((msize < sizeof (struct PeerNotifyNewSuccessorMessage) +
3877                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3878       (trail_length >
3879        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3880   {
3881     GNUNET_break_op (0);
3882     return GNUNET_YES;
3883   }
3884   
3885   if( trail_length > 0)
3886     trail_peer_list = (struct GNUNET_PeerIdentity *) &nsm[1];
3887   memcpy (&source_peer, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3888   memcpy (&old_successor, &(nsm->old_successor), sizeof (struct GNUNET_PeerIdentity));
3889   memcpy (&new_successor, &(nsm->destination_peer), sizeof (struct GNUNET_PeerIdentity));
3890   
3891   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&new_successor, &my_identity)))
3892   {
3893     /* I am the new successor. */
3894     struct GNUNET_PeerIdentity *new_predecessor;
3895     new_predecessor = GNUNET_new (struct GNUNET_PeerIdentity);
3896     memcpy (new_predecessor, &(nsm->source_peer), sizeof (struct GNUNET_PeerIdentity));
3897     if (GNUNET_YES == finger_table_add (new_predecessor, trail_peer_list, trail_length, PREDECESSOR_FINGER_ID))
3898     {
3899       /* You are adding a new predecessor in your finger table. but the intermediate
3900           peers don't have an entry in their routing table. So, you need to check the
3901           return value of finger_table_Add and if its successful then you should send
3902           routing_add_message. */
3903     }
3904     return GNUNET_OK;
3905   }
3906   else
3907   {
3908     struct FriendInfo *target_friend;
3909     struct GNUNET_PeerIdentity next_hop;
3910     int my_index;
3911     
3912     if (trail_length == 0)
3913       return GNUNET_SYSERR;
3914     
3915     my_index = search_my_index (trail_peer_list, trail_length);
3916     if (GNUNET_SYSERR == my_index)
3917     {
3918       /* FIXME: happend once */
3919       GNUNET_break(0);
3920       return GNUNET_SYSERR;
3921     }
3922     
3923     if (my_index == (trail_length - 1))
3924     {
3925       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &(nsm->destination_peer));
3926     }
3927     else
3928     {
3929       memcpy (&next_hop, &trail_peer_list[my_index+1], sizeof (struct GNUNET_PeerIdentity));
3930       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
3931     }
3932
3933     GDS_ROUTING_remove_trail (&source_peer, &old_successor, peer);
3934     GDS_ROUTING_add (&(nsm->source_peer), &(nsm->destination_peer), &next_hop, peer);
3935     GDS_NEIGHBOURS_send_notify_new_successor (&(nsm->source_peer), 
3936                                               &(nsm->destination_peer),
3937                                               &(nsm->old_successor),
3938                                               target_friend, trail_peer_list,
3939                                               trail_length);
3940     return GNUNET_OK;
3941   }
3942   return GNUNET_SYSERR;
3943 }
3944
3945 /**
3946  * FIXME: pass congestion time in struct PeerTrailRejectionMessage,
3947  * we are calling exact same thing here as in handle_dht_p2p_trail_seutp.set
3948  * that value here. 
3949  * if we make it a function then we can it here. 
3950  * Core handler for P2P trail rejection message 
3951  * @param cls closure
3952  * @param message message
3953  * @param peer peer identity this notification is about
3954  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
3955  */
3956 static
3957 int handle_dht_p2p_trail_rejection(void *cls, const struct GNUNET_PeerIdentity *peer,
3958                                    const struct GNUNET_MessageHeader *message)
3959 {
3960   const struct PeerTrailRejectionMessage *trail_rejection;
3961   struct GNUNET_PeerIdentity *trail_peer_list;
3962   struct FriendInfo *target_friend;
3963   struct GNUNET_PeerIdentity next_hop;
3964   struct GNUNET_PeerIdentity *next_peer;
3965   struct GNUNET_PeerIdentity source;
3966   struct GNUNET_PeerIdentity current_destination;
3967   struct GNUNET_PeerIdentity current_source;
3968   uint32_t trail_length;
3969   uint32_t finger_map_index;
3970   uint64_t destination_finger_value;
3971   size_t msize;
3972   
3973   msize = ntohs (message->size);
3974   if (msize < sizeof (struct PeerTrailRejectionMessage))
3975   {
3976     GNUNET_break_op (0);
3977     return GNUNET_YES;
3978   }
3979   
3980   trail_rejection = (struct PeerTrailRejectionMessage *) message;
3981   trail_length = ntohl (trail_rejection->trail_length);
3982   
3983   if ((msize < sizeof (struct PeerTrailRejectionMessage) +
3984                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
3985       (trail_length >
3986        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
3987   {
3988     GNUNET_break_op (0);
3989     return GNUNET_YES;
3990   }
3991   
3992   if (trail_length > 0)
3993     trail_peer_list = (struct GNUNET_PeerIdentity *)&trail_rejection[1];
3994   finger_map_index = ntohl (trail_rejection->finger_map_index);
3995   memcpy (&destination_finger_value, &(trail_rejection->finger_identity_value), sizeof (uint64_t));
3996   memcpy (&source, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
3997   
3998   /* First set the congestion time of the friend that sent you this message. */
3999   target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4000   //FIXME: target_friend->congestion_time ==? 
4001   
4002   if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &(trail_rejection->source_peer))))
4003   {
4004     return GNUNET_OK;
4005   }
4006   
4007   if(GNUNET_YES == GDS_ROUTING_check_threshold())
4008   {
4009     struct GNUNET_PeerIdentity *new_trail;
4010     unsigned int new_trail_length;
4011     
4012     if (trail_length == 1)
4013     {
4014       new_trail = NULL;
4015       new_trail_length = 0;
4016       memcpy (&next_hop, &(trail_rejection->source_peer), sizeof (struct GNUNET_PeerIdentity));
4017     }
4018     else 
4019     {
4020       memcpy (&next_hop, &trail_peer_list[trail_length - 2], sizeof (struct GNUNET_PeerIdentity));
4021       /* Remove myself from the trail. */
4022       new_trail_length = trail_length -1;
4023       new_trail = GNUNET_malloc (new_trail_length * sizeof (struct GNUNET_PeerIdentity));
4024       memcpy (new_trail, trail_peer_list, new_trail_length * sizeof (struct GNUNET_PeerIdentity));
4025     }
4026     GDS_NEIGHBOURS_send_trail_rejection (&(trail_rejection->source_peer), 
4027                                          destination_finger_value,
4028                                          &my_identity, &next_hop,finger_map_index,
4029                                          new_trail,new_trail_length);
4030     return GNUNET_YES;
4031   }
4032   
4033   {
4034   memcpy (&current_destination, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4035   memcpy (&current_source, &my_identity, sizeof (struct GNUNET_PeerIdentity));
4036   next_peer = find_successor (destination_finger_value,&current_destination,
4037                              &current_source, finger_map_index);
4038   if (NULL == next_peer)
4039   {
4040     GNUNET_STATISTICS_update (GDS_stats,
4041                                 gettext_noop ("# Trail not found in routing table during"
4042                                 "trail setup request, packet dropped."),
4043                                 1, GNUNET_NO);
4044     return GNUNET_SYSERR;
4045   }
4046   else if (0 == (GNUNET_CRYPTO_cmp_peer_identity (next_peer, &my_identity)))/* This means I am the final destination */
4047   {
4048     if (trail_length == 0)
4049     {
4050       memcpy (&next_hop, &source, sizeof (struct GNUNET_PeerIdentity));
4051     }
4052     else
4053     {
4054       memcpy (&next_hop, &trail_peer_list[trail_length-1], sizeof (struct GNUNET_PeerIdentity));
4055     }
4056     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4057     GDS_NEIGHBOURS_send_trail_setup_result (&source,
4058                                             &(my_identity),
4059                                             target_friend, trail_length,
4060                                             trail_peer_list,
4061                                             finger_map_index);
4062     return GNUNET_OK;
4063   }
4064   else
4065   {
4066     /* Now add yourself to the trail. */
4067     struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4068     if (trail_length != 0)
4069       memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity));
4070     peer_list[trail_length] = my_identity;
4071     trail_length++;
4072     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop);
4073     GDS_NEIGHBOURS_send_trail_setup (&source,
4074                                      destination_finger_value,
4075                                      &current_destination, &current_source,
4076                                      target_friend, trail_length, peer_list, 
4077                                      finger_map_index);
4078      return GNUNET_OK;
4079   }
4080   }
4081   
4082 }
4083
4084
4085 /* FIXME: there is a loop between in call from notify new successor to this function
4086  * check why and fix it. 
4087  * Core handle for p2p trail tear down messages.
4088  * @param cls closure
4089  * @param message message
4090  * @param peer peer identity this notification is about
4091  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4092  */
4093 static
4094 int handle_dht_p2p_trail_teardown (void *cls, const struct GNUNET_PeerIdentity *peer,
4095                                    const struct GNUNET_MessageHeader *message)
4096 {
4097   struct PeerTrailTearDownMessage *trail_teardown;
4098   struct GNUNET_PeerIdentity *discarded_trail;
4099   struct GNUNET_PeerIdentity next_hop;
4100   struct FriendInfo *target_friend;
4101   uint32_t discarded_trail_length;
4102   size_t msize;
4103   int my_index;
4104   
4105   msize = ntohs (message->size);
4106   if (msize < sizeof (struct PeerTrailTearDownMessage))
4107   {
4108     GNUNET_break_op (0);
4109     return GNUNET_OK;
4110   }
4111   
4112   trail_teardown = (struct PeerTrailTearDownMessage *) message;
4113   discarded_trail_length = ntohl (trail_teardown->trail_length);
4114   
4115   if ((msize < sizeof (struct PeerTrailTearDownMessage) +
4116                discarded_trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4117       (discarded_trail_length >
4118        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4119   {
4120     GNUNET_break_op (0);
4121     return GNUNET_OK;
4122   }
4123   
4124   if (discarded_trail_length > 0)
4125   discarded_trail = (struct GNUNET_PeerIdentity *) &trail_teardown[1];
4126   
4127   /* SUPU TEST CODE */
4128   struct GNUNET_PeerIdentity print_peer;
4129   int k = 0;
4130   while ( k < discarded_trail_length)
4131   {
4132     memcpy (&print_peer, &discarded_trail[k], sizeof (struct GNUNET_PeerIdentity));
4133     FPRINTF (stderr,_("\nSUPU %s, %s, %d,discarded_trail[%d]=%s"),
4134     __FILE__, __func__,__LINE__,k,GNUNET_i2s(&print_peer));
4135     k++;
4136   }
4137   /* SUPU TEST CODE ENDS*/
4138   if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->new_first_friend),
4139                                              &my_identity)))
4140   {
4141      if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&(trail_teardown->destination_peer), 
4142                                               &my_identity)))
4143      {
4144        return GNUNET_OK;
4145      }
4146      else
4147      {
4148         /* FIXME: 
4149          * I am the new first hop in the trail to reach from source to destination.
4150            Update the trail in routing table with prev_hop == source peer. */
4151        return GDS_ROUTING_trail_update (&(trail_teardown->source_peer),
4152                                         &(trail_teardown->destination_peer), peer);
4153      }
4154   }
4155   else
4156   {
4157     /* This should always be the case. */
4158     if (discarded_trail_length > 0)
4159     {
4160       my_index = search_my_index (discarded_trail, discarded_trail_length);
4161       if(GNUNET_SYSERR == my_index)
4162         return GNUNET_SYSERR;
4163     }
4164     else
4165     {
4166       GNUNET_break (0);
4167       return GNUNET_SYSERR;
4168     }
4169     GDS_ROUTING_print();
4170     if (GNUNET_NO == GDS_ROUTING_remove_trail (&(trail_teardown->source_peer),
4171                                                &(trail_teardown->destination_peer),peer))
4172     {
4173       /* Here we get GNUNET_NO, only if there is no matching entry found in routing
4174          table. */
4175       GNUNET_break (0);
4176       return GNUNET_YES;
4177     }  
4178     
4179     /* In case we got this message when we removed an entry from finger table,
4180      then we need to send the message to destination. */
4181     if (my_index != (discarded_trail_length - 1))
4182       memcpy (&next_hop, &discarded_trail[my_index + 1], sizeof (struct GNUNET_PeerIdentity));
4183     else
4184       memcpy (&next_hop, &(trail_teardown->destination_peer), sizeof (struct GNUNET_PeerIdentity));
4185     target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
4186    
4187     GDS_NEIGHBOURS_send_trail_teardown (&(trail_teardown->source_peer), 
4188                                         &(trail_teardown->destination_peer),
4189                                         discarded_trail, discarded_trail_length, 
4190                                         target_friend, &(trail_teardown->new_first_friend));
4191     return GNUNET_YES;
4192   }
4193   return GNUNET_SYSERR;
4194 }
4195
4196 /**
4197  * Core handle for p2p routing table add messages.
4198  * @param cls closure
4199  * @param message message
4200  * @param peer peer identity this notification is about
4201  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4202  */
4203 static int 
4204 handle_dht_p2p_add_trail (void *cls, const struct GNUNET_PeerIdentity *peer,
4205                                   const struct GNUNET_MessageHeader *message)
4206 {
4207   /* This function is called in case when we update our predecessor as a new peer
4208    claims to be our successor. In that case as we did not do a trail setup, 
4209    intermediate nodes don't know about this trail. our predecessor has added 
4210    that trail but not we. So, we need to add it. Its only in case of predecessor
4211    and succcessor that we have a symmetric relation. */
4212   struct PeerAddTrailMessage *add_trail;
4213   struct GNUNET_PeerIdentity *trail;
4214   struct GNUNET_PeerIdentity next_hop;
4215   struct FriendInfo *target_friend;
4216   size_t msize;
4217   uint32_t trail_length;
4218   int my_index;
4219   
4220   msize = ntohs (message->size);
4221   if (msize < sizeof (struct PeerAddTrailMessage))
4222   {
4223     GNUNET_break_op (0);
4224     return GNUNET_OK;
4225   }
4226   
4227   add_trail = (struct PeerAddTrailMessage *) message;
4228   trail_length = ntohl (add_trail->trail_length);
4229   
4230   if ((msize < sizeof (struct PeerAddTrailMessage) +
4231                trail_length * sizeof (struct GNUNET_PeerIdentity)) ||
4232       (trail_length >
4233        GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
4234   {
4235     GNUNET_break_op (0);
4236     return GNUNET_OK;
4237   }
4238   
4239   if (trail_length > 0)
4240     trail = (struct GNUNET_PeerIdentity *)&add_trail[1];
4241   
4242   my_index = search_my_index (trail, trail_length);
4243   if (GNUNET_SYSERR == my_index)
4244   {
4245     GNUNET_break (0);
4246     return GNUNET_SYSERR;
4247   }
4248   if (my_index == 0)
4249     memcpy(&next_hop, &(add_trail->source_peer), sizeof (struct GNUNET_PeerIdentity));
4250   else
4251     memcpy (&next_hop, &trail[my_index - 1], sizeof (struct GNUNET_PeerIdentity));
4252   
4253   if (GNUNET_YES == GDS_ROUTING_add (&(add_trail->source_peer), &(add_trail->destination_peer),
4254                                      peer,&next_hop))
4255   {
4256     if (my_index != 0)
4257     {
4258       target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_hop); 
4259       GDS_NEIGHBOURS_send_add_trail_message (&(add_trail->source_peer), 
4260                                              &(add_trail->destination_peer),
4261                                              trail, trail_length,target_friend);
4262     }
4263     return GNUNET_OK;
4264   }
4265   else
4266   {
4267     /* FIXME: there is not space in routing table to add the trail. What should 
4268      be done. */
4269     return GNUNET_SYSERR;
4270   }
4271 }
4272
4273
4274 /**
4275  * FIXME: Adapt the code for List of trails. 
4276  * Iterate over finger_peermap, and remove entries with peer as the first element
4277  * of their trail.  
4278  * @param cls closure
4279  * @param key current public key
4280  * @param value value in the hash map
4281  * @return #GNUNET_YES if we should continue to
4282  *         iterate,
4283  *         #GNUNET_NO if not.
4284  */
4285 static int
4286 remove_matching_finger (void *cls,
4287                         const struct GNUNET_PeerIdentity *key,
4288                         void *value)
4289 {
4290   struct FingerInfo *remove_finger = value;
4291   const struct GNUNET_PeerIdentity *disconnected_peer = cls;
4292   
4293   if (remove_finger->first_trail_length > 0)
4294   {
4295     if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_finger->first_trail_head->peer, disconnected_peer))
4296     {
4297       GNUNET_assert (GNUNET_YES ==
4298                    GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
4299                                                          key, 
4300                                                          remove_finger));
4301       free_finger (remove_finger);
4302     }
4303   }
4304   else if (0 == GNUNET_CRYPTO_cmp_peer_identity (&(remove_finger->finger_identity), 
4305                                                  disconnected_peer))
4306   {
4307     GNUNET_assert (GNUNET_YES ==
4308                    GNUNET_CONTAINER_multipeermap_remove (finger_peermap,
4309                                                          key, 
4310                                                          remove_finger));
4311     free_finger (remove_finger);
4312   }
4313   
4314   return GNUNET_YES;
4315 }
4316
4317
4318 /**
4319  * Method called whenever a peer disconnects.
4320  *
4321  * @param cls closure
4322  * @param peer peer identity this notification is about
4323  */
4324 static void
4325 handle_core_disconnect (void *cls,
4326                                           const struct GNUNET_PeerIdentity *peer)
4327 {
4328   struct FriendInfo *remove_friend;
4329   
4330   /* Check for self message. */
4331   if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity)))
4332     return;
4333   
4334   /* Search for peer to remove in your friend_peermap. */
4335   remove_friend =
4336       GNUNET_CONTAINER_multipeermap_get (friend_peermap, peer);
4337   
4338   if (NULL == remove_friend)
4339   {
4340     GNUNET_break (0);
4341     return;
4342   }
4343
4344   /* Remove fingers for which this peer is the first element in the trail or if
4345    * the friend is a finger.  */
4346   GNUNET_CONTAINER_multipeermap_iterate (finger_peermap,
4347                                          &remove_matching_finger, (void *)peer);
4348   GDS_ROUTING_remove_entry (peer);
4349   
4350   /* Remove the peer from friend_peermap. */
4351   GNUNET_assert (GNUNET_YES ==
4352                  GNUNET_CONTAINER_multipeermap_remove (friend_peermap,
4353                                                        peer,
4354                                                        remove_friend));
4355   
4356   if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap))
4357     return;
4358   
4359   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
4360   {
4361       GNUNET_SCHEDULER_cancel (find_finger_trail_task);
4362       find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
4363   }
4364   else
4365     GNUNET_break (0);
4366 }
4367
4368
4369 /**
4370  * Method called whenever a peer connects.
4371  *
4372  * @param cls closure
4373  * @param peer_identity peer identity this notification is about
4374  */
4375 static void
4376 handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer_identity)
4377 {
4378   struct FriendInfo *friend;
4379
4380   /* Check for connect to self message */
4381   if (0 == memcmp (&my_identity, peer_identity, sizeof (struct GNUNET_PeerIdentity)))
4382     return;
4383   
4384   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to %s\n", GNUNET_i2s (peer_identity));
4385   
4386   /* If peer already exists in our friend_peermap, then exit. */
4387   if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (friend_peermap, peer_identity))
4388   {
4389     GNUNET_break (0);
4390     return;
4391   }
4392   
4393   GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# peers connected"), 1,
4394                             GNUNET_NO);
4395
4396   friend = GNUNET_new (struct FriendInfo);
4397   friend->id = *peer_identity;
4398   friend->trails_count = 0;
4399   
4400   GNUNET_assert (GNUNET_OK ==
4401                  GNUNET_CONTAINER_multipeermap_put (friend_peermap,
4402                                                     peer_identity, friend,
4403                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
4404
4405   /* got a first connection, good time to start with FIND FINGER TRAIL requests... */
4406   if (GNUNET_SCHEDULER_NO_TASK == find_finger_trail_task)
4407     find_finger_trail_task = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, NULL);
4408 }
4409
4410
4411 /**
4412  * To be called on core init/fail.
4413  *
4414  * @param cls service closure
4415  * @param identity the public identity of this peer
4416  */
4417 static void
4418 core_init (void *cls,
4419            const struct GNUNET_PeerIdentity *identity)
4420 {
4421   my_identity = *identity;
4422 }
4423
4424
4425 /**
4426  * Initialize neighbours subsystem.
4427  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
4428  */
4429 int
4430 GDS_NEIGHBOURS_init (void)
4431 {
4432   static struct GNUNET_CORE_MessageHandler core_handlers[] = {
4433     {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
4434     {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
4435     {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},   
4436     {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
4437     {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},
4438     {&handle_dht_p2p_verify_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR, 0},
4439     {&handle_dht_p2p_verify_successor_result, GNUNET_MESSAGE_TYPE_DHT_P2P_VERIFY_SUCCESSOR_RESULT, 0},
4440     {&handle_dht_p2p_notify_new_successor, GNUNET_MESSAGE_TYPE_DHT_P2P_NOTIFY_NEW_SUCCESSOR, 0},
4441     {&handle_dht_p2p_trail_rejection, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_REJECTION, 0},
4442     {&handle_dht_p2p_trail_teardown, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_TEARDOWN, 0},
4443     {&handle_dht_p2p_add_trail, GNUNET_MESSAGE_TYPE_DHT_P2P_ADD_TRAIL, 0},
4444     {NULL, 0, 0}
4445   };
4446   
4447   core_api =
4448     GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect,
4449                          &handle_core_disconnect, NULL, GNUNET_NO, NULL,
4450                          GNUNET_NO, core_handlers);
4451   if (NULL == core_api)
4452     return GNUNET_SYSERR;
4453   
4454   friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO);
4455   finger_peermap = GNUNET_CONTAINER_multipeermap_create (MAX_FINGERS * 4/3, GNUNET_NO);
4456   
4457   return GNUNET_OK;
4458 }
4459
4460
4461 /**
4462  * Shutdown neighbours subsystem.
4463  */
4464 void
4465 GDS_NEIGHBOURS_done (void)
4466 {
4467   if (NULL == core_api)
4468     return;
4469   
4470   GNUNET_CORE_disconnect (core_api);
4471   core_api = NULL;
4472   
4473   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap));
4474   GNUNET_CONTAINER_multipeermap_destroy (friend_peermap);
4475   friend_peermap = NULL;
4476   
4477   GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (finger_peermap));
4478   GNUNET_CONTAINER_multipeermap_destroy (finger_peermap);
4479   finger_peermap = NULL;
4480
4481   if (GNUNET_SCHEDULER_NO_TASK != find_finger_trail_task)
4482   {
4483     GNUNET_break (0);
4484     GNUNET_SCHEDULER_cancel (find_finger_trail_task);
4485     find_finger_trail_task = GNUNET_SCHEDULER_NO_TASK;
4486   }
4487 }
4488
4489
4490 /**
4491  * Get my identity
4492  *
4493  * @return my identity
4494  */
4495 struct GNUNET_PeerIdentity 
4496 GDS_NEIGHBOURS_get_my_id (void)
4497 {
4498   return my_identity;
4499 }
4500
4501
4502 /* end of gnunet-service-xdht_neighbours.c */