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